Skip to content

Commit 4297876

Browse files
committed
feat: enhance Switch component with loading state handling and improved utility functions
1 parent 478600e commit 4297876

File tree

3 files changed

+67
-27
lines changed

3 files changed

+67
-27
lines changed

src/Shared/Components/Switch/Switch.component.tsx

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,14 @@ import { getUniqueId } from '@Shared/Helpers'
88
import { Icon } from '../Icon'
99
import { INDETERMINATE_ICON_WIDTH_MAP, LOADING_COLOR_MAP } from './constants'
1010
import { SwitchProps } from './types'
11-
import { getSwitchContainerClass, getSwitchIconColor, getSwitchThumbClass, getSwitchTrackColor } from './utils'
11+
import {
12+
getSwitchContainerClass,
13+
getSwitchIconColor,
14+
getSwitchThumbClass,
15+
getSwitchTrackColor,
16+
getThumbPadding,
17+
getThumbPosition,
18+
} from './utils'
1219

1320
const Switch = ({
1421
ariaLabel,
@@ -40,24 +47,26 @@ const Switch = ({
4047

4148
const showIndeterminateIcon = ariaCheckedValue === 'mixed'
4249

43-
const renderContent = () => {
44-
if (isLoading) {
45-
return <Icon name="ic-circle-loader" color={LOADING_COLOR_MAP[variant]} />
46-
}
47-
48-
return (
49-
<motion.span
50-
className={`flex flex-grow-1 ${shape === 'rounded' ? 'p-2 br-12' : 'p-1 br-4'} ${isChecked ? 'right' : 'left'}`}
51-
layout
52-
animate={{
53-
backgroundColor: getSwitchTrackColor({ shape, variant, isChecked }),
54-
}}
55-
transition={{ type: 'spring', stiffness: 300, damping: 30 }}
56-
>
50+
const renderContent = () => (
51+
<motion.span
52+
className={`flex flex-grow-1 ${getThumbPadding({ shape, isLoading })} ${getThumbPosition({ isChecked, isLoading })}`}
53+
layout
54+
transition={{ ease: 'easeInOut', duration: 0.2 }}
55+
>
56+
{isLoading ? (
57+
<motion.span
58+
transition={{ ease: 'easeInOut', duration: 0.2 }}
59+
layoutId="loader"
60+
className="flex-grow-1 h-100 dc__fill-available-space dc__no-shrink"
61+
>
62+
<Icon key="progressing" name="ic-circle-loader" color={LOADING_COLOR_MAP[variant]} size={null} />
63+
</motion.span>
64+
) : (
5765
<motion.span
66+
layoutId="thumb"
5867
className={getSwitchThumbClass({ shape, size, showIndeterminateIcon })}
5968
layout
60-
transition={{ type: 'spring', stiffness: 500, damping: 35 }}
69+
transition={{ ease: 'easeInOut', duration: 0.2 }}
6170
>
6271
<AnimatePresence>
6372
{showIndeterminateIcon ? (
@@ -84,15 +93,16 @@ const Switch = ({
8493
iconColor,
8594
variant,
8695
})}
96+
size={null}
8797
/>
8898
</motion.span>
8999
)
90100
)}
91101
</AnimatePresence>
92102
</motion.span>
93-
</motion.span>
94-
)
95-
}
103+
)}
104+
</motion.span>
105+
)
96106

97107
return (
98108
<Tooltip alwaysShowTippyOnHover={!!tooltipContent} content={tooltipContent}>
@@ -119,7 +129,7 @@ const Switch = ({
119129
data-testid={dataTestId}
120130
disabled={isDisabled || isLoading}
121131
aria-disabled={isDisabled}
122-
className={`p-0-imp h-100 flex flex-grow-1 dc__transparent ${isDisabled ? 'dc__disabled' : ''} dc__fill-available-space`}
132+
className={`p-0-imp h-100 flex flex-grow-1 dc__no-border ${shape === 'rounded' ? 'br-12' : 'br-4'} ${getSwitchTrackColor({ shape, variant, isChecked, isLoading })} ${isDisabled ? 'dc__disabled' : ''} dc__fill-available-space`}
123133
onClick={onChange}
124134
>
125135
{renderContent()}

src/Shared/Components/Switch/constants.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,14 @@ export const LOADING_COLOR_MAP: Record<SwitchProps['variant'], IconBaseColorType
3333
positive: 'G500',
3434
}
3535

36-
export const ROUNDED_SWITCH_TRACK_COLOR_MAP: Record<SwitchProps['variant'], `var(--${IconBaseColorType})`> = {
37-
theme: 'var(--B500)',
38-
positive: 'var(--G500)',
36+
export const ROUNDED_SWITCH_TRACK_COLOR_MAP: Record<SwitchProps['variant'], string> = {
37+
theme: 'bcb-5',
38+
positive: 'bcg-5',
3939
}
4040

4141
export const SQUARE_SWITCH_TRACK_COLOR_MAP: typeof ROUNDED_SWITCH_TRACK_COLOR_MAP = {
42-
theme: 'var(--B300)',
43-
positive: 'var(--G300)',
42+
theme: 'bcb-3',
43+
positive: 'bcg-3',
4444
}
4545

4646
export const ROUNDED_SWITCH_THUMB_SIZE_MAP: Record<SwitchProps['size'], string> = {
@@ -57,3 +57,8 @@ export const SWITCH_THUMB_PADDING_MAP: Record<SwitchProps['size'], string> = {
5757
[ComponentSizeType.medium]: 'p-3',
5858
[ComponentSizeType.small]: 'p-1',
5959
}
60+
61+
export const THUMB_OUTER_PADDING_MAP: Record<SwitchProps['shape'], string> = {
62+
rounded: 'p-2',
63+
square: 'p-1',
64+
}

src/Shared/Components/Switch/utils.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
SQUARE_SWITCH_TRACK_COLOR_MAP,
99
SWITCH_HEIGHT_MAP,
1010
SWITCH_THUMB_PADDING_MAP,
11+
THUMB_OUTER_PADDING_MAP,
1112
} from './constants'
1213
import { SwitchProps } from './types'
1314

@@ -18,9 +19,14 @@ export const getSwitchTrackColor = ({
1819
shape,
1920
variant,
2021
isChecked,
21-
}: Required<Pick<SwitchProps, 'shape' | 'variant' | 'isChecked'>>): `var(--${IconBaseColorType})` => {
22+
isLoading,
23+
}: Required<Pick<SwitchProps, 'shape' | 'variant' | 'isChecked' | 'isLoading'>>): string => {
24+
if (isLoading) {
25+
return 'dc__transparent--unstyled'
26+
}
27+
2228
if (!isChecked) {
23-
return 'var(--N200)'
29+
return 'bcn-2'
2430
}
2531

2632
return shape === 'rounded' ? ROUNDED_SWITCH_TRACK_COLOR_MAP[variant] : SQUARE_SWITCH_TRACK_COLOR_MAP[variant]
@@ -49,3 +55,22 @@ export const getSwitchIconColor = ({
4955

5056
return iconColor || (variant === 'theme' ? 'B500' : 'G500')
5157
}
58+
59+
export const getThumbPosition = ({
60+
isLoading,
61+
isChecked,
62+
}: Pick<SwitchProps, 'isLoading' | 'isChecked'>): 'left' | 'right' | 'center' => {
63+
if (isLoading) {
64+
return 'center'
65+
}
66+
67+
return isChecked ? 'right' : 'left'
68+
}
69+
70+
export const getThumbPadding = ({ shape, isLoading }: Pick<SwitchProps, 'shape' | 'isLoading'>): string => {
71+
if (isLoading) {
72+
return ''
73+
}
74+
75+
return THUMB_OUTER_PADDING_MAP[shape]
76+
}

0 commit comments

Comments
 (0)