|
1 |
| -/* |
2 |
| - * Copyright (c) 2024. Devtron Inc. |
3 |
| - * |
4 |
| - * Licensed under the Apache License, Version 2.0 (the "License"); |
5 |
| - * you may not use this file except in compliance with the License. |
6 |
| - * You may obtain a copy of the License at |
7 |
| - * |
8 |
| - * http://www.apache.org/licenses/LICENSE-2.0 |
9 |
| - * |
10 |
| - * Unless required by applicable law or agreed to in writing, software |
11 |
| - * distributed under the License is distributed on an "AS IS" BASIS, |
12 |
| - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 |
| - * See the License for the specific language governing permissions and |
14 |
| - * limitations under the License. |
15 |
| - */ |
16 |
| - |
| 1 | +import { useEffect, useRef, useState } from 'react' |
17 | 2 | import { ComponentSizeType } from '@Shared/constants'
|
18 |
| -import StyledRadioGroup from '../RadioGroup/RadioGroup' |
19 |
| -import { SegmentedControlProps, SegmentedControlVariant } from './types' |
20 |
| -import { SEGMENTED_CONTROL_SIZE_TO_CLASS_MAP } from './constants' |
| 3 | +import { SegmentedControlProps, SegmentType } from './types' |
| 4 | +import './segmentedControl.scss' |
| 5 | +import Segment from './Segment' |
21 | 6 |
|
22 | 7 | const SegmentedControl = ({
|
23 |
| - tabs, |
24 |
| - initialTab, |
| 8 | + segments, |
25 | 9 | onChange,
|
26 |
| - tooltips, |
27 |
| - disabled = false, |
28 |
| - rootClassName = '', |
29 | 10 | name,
|
30 |
| - variant = SegmentedControlVariant.WHITE_ON_GRAY, |
31 | 11 | size = ComponentSizeType.medium,
|
32 |
| - isControlled = false, |
33 |
| -}: SegmentedControlProps) => ( |
34 |
| - <StyledRadioGroup |
35 |
| - className={`${variant} ${SEGMENTED_CONTROL_SIZE_TO_CLASS_MAP[size]} ${rootClassName}`} |
36 |
| - onChange={onChange} |
37 |
| - initialTab={initialTab} |
38 |
| - name={name} |
39 |
| - disabled={disabled} |
40 |
| - > |
41 |
| - {tabs.map((tab, index) => ( |
42 |
| - <StyledRadioGroup.Radio |
43 |
| - value={tab.value} |
44 |
| - key={tab.value} |
45 |
| - className="fs-12 cn-7 fw-6 lh-20" |
46 |
| - showTippy={!!tooltips?.[index]} |
47 |
| - tippyContent={tooltips?.[index] ?? ''} |
48 |
| - dataTestId={`${name}-${tab.value}`} |
49 |
| - canSelect={!isControlled} |
| 12 | + value: controlledValue, |
| 13 | + fullWidth = false, |
| 14 | +}: SegmentedControlProps) => { |
| 15 | + const isUnControlledComponent = controlledValue === undefined |
| 16 | + |
| 17 | + const segmentedControlRefContainer = useRef<HTMLDivElement>(null) |
| 18 | + const selectedSegmentRef = useRef<HTMLDivElement>(null) |
| 19 | + const [selectedSegmentValue, setSelectedSegmentValue] = useState<SegmentType['value'] | null>(segments[0].value) |
| 20 | + const segmentValue = isUnControlledComponent ? selectedSegmentValue : controlledValue |
| 21 | + |
| 22 | + useEffect(() => { |
| 23 | + if (segmentValue) { |
| 24 | + const { offsetWidth, offsetLeft } = selectedSegmentRef.current |
| 25 | + const { style } = segmentedControlRefContainer.current |
| 26 | + |
| 27 | + style.setProperty('--segmented-control-highlight-width', `${offsetWidth}px`) |
| 28 | + style.setProperty('--segmented-control-highlight-x-position', `${offsetLeft}px`) |
| 29 | + } |
| 30 | + }, [segmentValue, size, fullWidth]) |
| 31 | + |
| 32 | + const handleSegmentChange = (updatedSegment: SegmentType) => { |
| 33 | + if (isUnControlledComponent) { |
| 34 | + setSelectedSegmentValue(updatedSegment.value) |
| 35 | + } |
| 36 | + onChange?.(updatedSegment) |
| 37 | + } |
| 38 | + |
| 39 | + return ( |
| 40 | + <div |
| 41 | + className={`segmented-control ${!fullWidth ? 'dc__inline-flex' : ''} br-6 ${size === ComponentSizeType.xs ? 'p-1' : 'p-2'}`} |
| 42 | + > |
| 43 | + <div |
| 44 | + className="segmented-control__container flex left dc__position-rel dc__align-items-center dc__gap-2" |
| 45 | + ref={segmentedControlRefContainer} |
50 | 46 | >
|
51 |
| - {tab.label} |
52 |
| - </StyledRadioGroup.Radio> |
53 |
| - ))} |
54 |
| - </StyledRadioGroup> |
55 |
| -) |
| 47 | + {segments.map((segment) => { |
| 48 | + const isSelected = segment.value === segmentValue |
| 49 | + |
| 50 | + return ( |
| 51 | + <Segment |
| 52 | + selectedSegmentRef={isSelected ? selectedSegmentRef : undefined} |
| 53 | + segment={segment} |
| 54 | + key={segment.value} |
| 55 | + name={name} |
| 56 | + onChange={handleSegmentChange} |
| 57 | + isSelected={isSelected} |
| 58 | + fullWidth={fullWidth} |
| 59 | + size={size} |
| 60 | + /> |
| 61 | + ) |
| 62 | + })} |
| 63 | + </div> |
| 64 | + </div> |
| 65 | + ) |
| 66 | +} |
56 | 67 |
|
57 | 68 | export default SegmentedControl
|
0 commit comments