Skip to content

Commit 0e109f9

Browse files
committed
refactor: code clean up and add doc comments
1 parent 9561146 commit 0e109f9

File tree

6 files changed

+207
-264
lines changed

6 files changed

+207
-264
lines changed

src/Common/SegmentedControl/NSegmentedControl.component.tsx

Lines changed: 0 additions & 156 deletions
This file was deleted.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { ReactElement } from 'react'
2+
import { Icon } from '@Shared/Components'
3+
import { ComponentSizeType } from '@Shared/constants'
4+
import { Tooltip } from '@Common/Tooltip'
5+
import { SegmentProps, SegmentType } from './types'
6+
import { COMPONENT_SIZE_TO_ICON_CLASS_MAP, COMPONENT_SIZE_TO_SEGMENT_CLASS_MAP } from './constants'
7+
import { ConditionalWrap } from '..'
8+
9+
const wrapWithTooltip = (tooltipProps: SegmentType['tooltipProps']) => (children: ReactElement) => (
10+
<Tooltip content={tooltipProps.content} placement="bottom" {...tooltipProps} alwaysShowTippyOnHover>
11+
{children}
12+
</Tooltip>
13+
)
14+
15+
const Segment = ({ segment, isSelected, name, selectedSegmentRef, onChange, fullWidth, size }: SegmentProps) => {
16+
const { value, icon, isError, label, tooltipProps, ariaLabel } = segment
17+
const handleChange = () => {
18+
onChange(segment)
19+
}
20+
21+
return (
22+
<ConditionalWrap key={value} condition={!!tooltipProps?.content} wrap={wrapWithTooltip(tooltipProps)}>
23+
<div
24+
className={`dc__position-rel dc__text-center ${fullWidth ? 'flex-grow-1' : ''}`}
25+
ref={selectedSegmentRef}
26+
>
27+
<input
28+
type="radio"
29+
value={value}
30+
id={`${name}-${value}`}
31+
name={name}
32+
onChange={handleChange}
33+
checked={isSelected}
34+
className="dc__opacity-0 m-0-imp dc__top-0 dc__left-0 dc__position-abs dc__bottom-0 dc__right-0 w-100 pointer h-100 dc__visibility-hidden"
35+
/>
36+
37+
<label
38+
htmlFor={`${name}-${value}`}
39+
className={`pointer m-0 flex ${!fullWidth ? 'left' : ''} dc__gap-4 br-4 segmented-control__segment segmented-control__segment--${size} ${isSelected ? 'fw-6 segmented-control__segment--selected' : 'fw-4'} ${segment.isError ? 'cr-5' : 'cn-9'} ${COMPONENT_SIZE_TO_SEGMENT_CLASS_MAP[size]}`}
40+
aria-label={ariaLabel}
41+
>
42+
{(isError || icon) && (
43+
<span className={`flex ${COMPONENT_SIZE_TO_ICON_CLASS_MAP[size]}`}>
44+
<Icon
45+
{...(isError
46+
? {
47+
name: 'ic-error',
48+
color: null,
49+
}
50+
: {
51+
name: icon,
52+
color: isSelected ? 'N900' : 'N700',
53+
})}
54+
size={size === ComponentSizeType.xs ? 14 : 16}
55+
/>
56+
</span>
57+
)}
58+
{label && <span>{label}</span>}
59+
</label>
60+
</div>
61+
</ConditionalWrap>
62+
)
63+
}
64+
65+
export default Segment
Lines changed: 59 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,68 @@
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'
172
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'
216

227
const SegmentedControl = ({
23-
tabs,
24-
initialTab,
8+
segments,
259
onChange,
26-
tooltips,
27-
disabled = false,
28-
rootClassName = '',
2910
name,
30-
variant = SegmentedControlVariant.WHITE_ON_GRAY,
3111
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}
5046
>
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+
}
5667

5768
export default SegmentedControl
Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,14 @@
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-
171
import { ComponentSizeType } from '@Shared/constants'
182
import { SegmentedControlProps } from './types'
193

20-
export const SEGMENTED_CONTROL_SIZE_TO_CLASS_MAP: Record<SegmentedControlProps['size'], string> = {
21-
[ComponentSizeType.medium]: '',
22-
[ComponentSizeType.large]: 'gui-yaml-switch--lg',
23-
}
4+
export const COMPONENT_SIZE_TO_SEGMENT_CLASS_MAP: Record<SegmentedControlProps['size'], string> = {
5+
[ComponentSizeType.xs]: 'py-2 px-6 fs-12 lh-18',
6+
[ComponentSizeType.small]: 'py-2 px-6 fs-12 lh-20',
7+
[ComponentSizeType.medium]: 'py-4 px-8 fs-13 lh-20',
8+
} as const
9+
10+
export const COMPONENT_SIZE_TO_ICON_CLASS_MAP: Record<SegmentedControlProps['size'], string> = {
11+
[ComponentSizeType.xs]: 'py-1',
12+
[ComponentSizeType.small]: 'py-2',
13+
[ComponentSizeType.medium]: 'py-2',
14+
} as const

src/Common/SegmentedControl/index.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,5 @@
1414
* limitations under the License.
1515
*/
1616

17-
export { type SegmentedControlProps, SegmentedControlVariant } from './types'
1817
export { default as SegmentedControl } from './SegmentedControl.component'
19-
20-
export { default as NSegmentedControl } from './NSegmentedControl.component'
21-
export { type NSegmentedControlProps } from './NSegmentedControl.component'
18+
export { type SegmentedControlProps } from './types'

0 commit comments

Comments
 (0)