From 6bbe6544e0782c39a0f5989ef5768524c0e16882 Mon Sep 17 00:00:00 2001 From: AbhishekA1509 Date: Fri, 16 May 2025 13:48:02 +0530 Subject: [PATCH 01/11] feat: add Switch component with customizable shapes and variants --- .../Components/Switch/Switch.component.tsx | 113 ++++++++++++++++++ src/Shared/Components/Switch/constants.ts | 11 ++ src/Shared/Components/Switch/index.ts | 1 + src/Shared/Components/Switch/types.ts | 106 ++++++++++++++++ src/Shared/Components/Switch/utils.ts | 60 ++++++++++ src/Shared/Components/index.ts | 1 + 6 files changed, 292 insertions(+) create mode 100644 src/Shared/Components/Switch/Switch.component.tsx create mode 100644 src/Shared/Components/Switch/constants.ts create mode 100644 src/Shared/Components/Switch/index.ts create mode 100644 src/Shared/Components/Switch/types.ts create mode 100644 src/Shared/Components/Switch/utils.ts diff --git a/src/Shared/Components/Switch/Switch.component.tsx b/src/Shared/Components/Switch/Switch.component.tsx new file mode 100644 index 000000000..e84f5e598 --- /dev/null +++ b/src/Shared/Components/Switch/Switch.component.tsx @@ -0,0 +1,113 @@ +import { AriaAttributes, HTMLAttributes } from 'react' +import { AnimatePresence, motion } from 'framer-motion' + +import { Tooltip } from '@Common/Tooltip' + +import { Icon } from '../Icon' +import { SwitchProps } from './types' +import { getSwitchContainerClass, getSwitchIconColor, getSwitchThumbClass, getSwitchTrackColor } from './utils' + +const Switch = ({ + ariaLabel, + dataTestId, + isDisabled, + isLoading, + isChecked, + tooltipContent, + shape = 'rounded', + variant = 'positive', + iconColor, + iconName, + indeterminate = false, + handleChange, +}: SwitchProps) => { + const getAriaChecked = (): AriaAttributes['aria-checked'] => { + if (!isChecked) { + return false + } + + return indeterminate ? 'mixed' : true + } + + const ariaChecked = getAriaChecked() + + const showIndeterminateIcon = ariaChecked === 'mixed' + const role: HTMLAttributes['role'] = showIndeterminateIcon ? 'checkbox' : 'switch' + + const renderContent = () => { + if (isLoading) { + return + } + + return ( + + + + {showIndeterminateIcon ? ( + + ) : ( + iconName && ( + + + + ) + )} + + + + ) + } + + // TODO: Can add hidden input for accessibility in case name [for forms] is given + return ( + +
+ +
+
+ ) +} + +export default Switch diff --git a/src/Shared/Components/Switch/constants.ts b/src/Shared/Components/Switch/constants.ts new file mode 100644 index 000000000..e8fe803d2 --- /dev/null +++ b/src/Shared/Components/Switch/constants.ts @@ -0,0 +1,11 @@ +import { SwitchProps } from './types' + +export const SWITCH_VARIANTS: Record = { + theme: null, + positive: null, +} + +export const SWITCH_SHAPES: Record = { + rounded: null, + square: null, +} diff --git a/src/Shared/Components/Switch/index.ts b/src/Shared/Components/Switch/index.ts new file mode 100644 index 000000000..22aab781a --- /dev/null +++ b/src/Shared/Components/Switch/index.ts @@ -0,0 +1 @@ +export { default as Switch } from './Switch.component' diff --git a/src/Shared/Components/Switch/types.ts b/src/Shared/Components/Switch/types.ts new file mode 100644 index 000000000..e150fa34f --- /dev/null +++ b/src/Shared/Components/Switch/types.ts @@ -0,0 +1,106 @@ +import { IconBaseColorType } from '@Shared/types' + +import { IconName } from '../Icon' + +/** + * Represents the properties for configuring the shape and behavior of a switch component. + * + * - When `shape` is `rounded`: + * - The switch will have a rounded appearance. + * - `iconName`, `iconColor`, and `indeterminate` are not applicable. + * + * - When `shape` is `square`: + * - The switch will have a square appearance. + * - `iconName` specifies the name of the icon to display. + * - `iconColor` allows customization of the icon's color in the active state. + * - `indeterminate` indicates whether the switch is in an indeterminate state, typically used for checkboxes to represent a mixed state. + * If `indeterminate` is true, the switch will not be fully checked or unchecked, and its role will change to `checkbox`. + */ +type SwitchShapeProps = + | { + /** + * The shape of the switch. Defaults to `rounded` if not specified. + */ + shape?: 'rounded' + + /** + * Icon name is not applicable for the `rounded` shape. + */ + iconName?: never + + /** + * Icon color is not applicable for the `rounded` shape. + */ + iconColor?: never + indeterminate?: never + } + | { + /** + * The shape of the switch. Must be `square` to enable icon-related properties. + */ + shape: 'square' + + /** + * The name of the icon to display when the shape is `square`. + */ + iconName: IconName + + /** + * The color of the icon. If provided, this will override the default color in the active state. + */ + iconColor?: IconBaseColorType + /** + * Indicates whether the switch is in an indeterminate state. + * This state is typically used for checkboxes to indicate a mixed state. + * If true, the switch will not be fully checked or unchecked. We will change the role to checkbox in this case since the indeterminate state is not applicable for the switch. + * This property is not applicable for the `rounded` shape. + * @default false + */ + indeterminate?: boolean + } + +/** + * Represents the properties for the `Switch` component. + */ +export type SwitchProps = { + /** + * The ARIA label for the switch, used for accessibility purposes. + */ + ariaLabel: string + + /** + * A unique identifier for testing purposes. + */ + dataTestId: string + + /** + * The visual variant of the switch. + * + * @default `positive` + */ + variant?: 'theme' | 'positive' + + handleChange: () => void + + /** + * Indicates whether the switch is disabled. + */ + isDisabled?: boolean + + /** + * Indicates whether the switch is in a loading state. + */ + isLoading?: boolean + + /** + * Indicates whether the switch is currently checked (on). + */ + isChecked: boolean + + /** + * Optional tooltip content to display when hovering over the switch. + * + * @default undefined + */ + tooltipContent?: string +} & SwitchShapeProps diff --git a/src/Shared/Components/Switch/utils.ts b/src/Shared/Components/Switch/utils.ts new file mode 100644 index 000000000..3f2759eb3 --- /dev/null +++ b/src/Shared/Components/Switch/utils.ts @@ -0,0 +1,60 @@ +import { IconBaseColorType } from '@Shared/types' + +import { SwitchProps } from './types' + +// On intro of size there will changes in almost all methods +export const getSwitchContainerClass = ({ shape }: Required>): string => { + if (shape === 'rounded') { + return 'py-3 h-24 w-20' + } + + return 'w-28 h-18' +} + +export const getSwitchTrackColor = ({ + shape, + variant, + isChecked, +}: Required>): `var(--${IconBaseColorType})` => { + if (!isChecked) { + return 'var(--N200)' + } + + if (shape === 'rounded') { + if (variant === 'theme') { + return 'var(--B500)' + } + + return 'var(--G500)' + } + + if (variant === 'theme') { + return 'var(--B300)' + } + + return 'var(--G300)' +} + +export const getSwitchThumbClass = ({ + indeterminate, + shape, + isChecked, +}: Pick) => { + if (isChecked && indeterminate) { + return 'w-100 h-100 flex' + } + + return `flex p-2 ${shape === 'rounded' ? 'dc__border-radius-50-per icon-dim-10' : 'br-3'} bg__white` +} + +export const getSwitchIconColor = ({ + iconColor, + isChecked, + variant, +}: Pick): IconBaseColorType => { + if (!isChecked) { + return 'N200' + } + + return iconColor || (variant === 'theme' ? 'B500' : 'G500') +} diff --git a/src/Shared/Components/index.ts b/src/Shared/Components/index.ts index 3747ac491..43b590a17 100644 --- a/src/Shared/Components/index.ts +++ b/src/Shared/Components/index.ts @@ -87,6 +87,7 @@ export * from './SelectPicker' export * from './ShowMoreText' export * from './SSOProviderIcon' export * from './StatusComponent' +export * from './Switch' export * from './TabGroup' export * from './Table' export * from './TagsKeyValueTable' From 0228618037443c0e00395044f32864950b02c981 Mon Sep 17 00:00:00 2001 From: AbhishekA1509 Date: Mon, 19 May 2025 00:53:21 +0530 Subject: [PATCH 02/11] feat: enhance Switch component with size and loading state support --- .../Components/Switch/Switch.component.tsx | 28 +++++----- src/Shared/Components/Switch/constants.ts | 52 ++++++++++++++++++- src/Shared/Components/Switch/types.ts | 29 +++++++---- src/Shared/Components/Switch/utils.ts | 42 ++++++--------- 4 files changed, 99 insertions(+), 52 deletions(-) diff --git a/src/Shared/Components/Switch/Switch.component.tsx b/src/Shared/Components/Switch/Switch.component.tsx index e84f5e598..c593ca819 100644 --- a/src/Shared/Components/Switch/Switch.component.tsx +++ b/src/Shared/Components/Switch/Switch.component.tsx @@ -2,8 +2,10 @@ import { AriaAttributes, HTMLAttributes } from 'react' import { AnimatePresence, motion } from 'framer-motion' import { Tooltip } from '@Common/Tooltip' +import { ComponentSizeType } from '@Shared/constants' import { Icon } from '../Icon' +import { INDETERMINATE_ICON_WIDTH_MAP, LOADING_COLOR_MAP, SQUARE_ICON_DIMENSION_MAP } from './constants' import { SwitchProps } from './types' import { getSwitchContainerClass, getSwitchIconColor, getSwitchThumbClass, getSwitchTrackColor } from './utils' @@ -19,9 +21,10 @@ const Switch = ({ iconColor, iconName, indeterminate = false, - handleChange, + size = ComponentSizeType.medium, + onChange, }: SwitchProps) => { - const getAriaChecked = (): AriaAttributes['aria-checked'] => { + const getAriaCheckedValue = (): AriaAttributes['aria-checked'] => { if (!isChecked) { return false } @@ -29,19 +32,19 @@ const Switch = ({ return indeterminate ? 'mixed' : true } - const ariaChecked = getAriaChecked() + const ariaCheckedValue = getAriaCheckedValue() - const showIndeterminateIcon = ariaChecked === 'mixed' + const showIndeterminateIcon = ariaCheckedValue === 'mixed' const role: HTMLAttributes['role'] = showIndeterminateIcon ? 'checkbox' : 'switch' const renderContent = () => { if (isLoading) { - return + return } return ( @@ -57,7 +60,7 @@ const Switch = ({ {showIndeterminateIcon ? ( ) @@ -92,16 +94,16 @@ const Switch = ({ // TODO: Can add hidden input for accessibility in case name [for forms] is given return ( -
+
diff --git a/src/Shared/Components/Switch/constants.ts b/src/Shared/Components/Switch/constants.ts index e8fe803d2..3bb9a5f8e 100644 --- a/src/Shared/Components/Switch/constants.ts +++ b/src/Shared/Components/Switch/constants.ts @@ -1,11 +1,59 @@ +import { ComponentSizeType } from '@Shared/constants' +import { IconBaseColorType } from '@Shared/types' + import { SwitchProps } from './types' -export const SWITCH_VARIANTS: Record = { +export const SWITCH_VARIANTS: Readonly> = { theme: null, positive: null, } -export const SWITCH_SHAPES: Record = { +export const SWITCH_SHAPES: Readonly> = { rounded: null, square: null, } + +export const ROUNDED_SWITCH_SIZE_MAP: Readonly> = { + [ComponentSizeType.medium]: 'w-32', + [ComponentSizeType.small]: 'w-24', +} + +export const SQUARE_SWITCH_SIZE_MAP: typeof ROUNDED_SWITCH_SIZE_MAP = { + [ComponentSizeType.medium]: 'w-28', + [ComponentSizeType.small]: 'w-24', +} + +export const SWITCH_HEIGHT_MAP: Readonly> = { + [ComponentSizeType.medium]: 'h-24', + [ComponentSizeType.small]: 'h-20', +} + +export const LOADING_COLOR_MAP: Record = { + theme: 'B500', + positive: 'G500', +} + +export const ROUNDED_SWITCH_TRACK_COLOR_MAP: Record = { + theme: 'var(--B500)', + positive: 'var(--G500)', +} + +export const SQUARE_SWITCH_TRACK_COLOR_MAP: typeof ROUNDED_SWITCH_TRACK_COLOR_MAP = { + theme: 'var(--B300)', + positive: 'var(--G300)', +} + +export const ROUNDED_SWITCH_THUMB_SIZE_MAP: Record = { + [ComponentSizeType.medium]: 'icon-dim-16', + [ComponentSizeType.small]: 'icon-dim-12', +} + +export const INDETERMINATE_ICON_WIDTH_MAP: Record = { + [ComponentSizeType.medium]: 'w-12', + [ComponentSizeType.small]: 'w-10', +} + +export const SQUARE_ICON_DIMENSION_MAP: Record = { + [ComponentSizeType.medium]: 'icon-dim-12', + [ComponentSizeType.small]: 'icon-dim-8', +} diff --git a/src/Shared/Components/Switch/types.ts b/src/Shared/Components/Switch/types.ts index e150fa34f..d61b92c20 100644 --- a/src/Shared/Components/Switch/types.ts +++ b/src/Shared/Components/Switch/types.ts @@ -1,3 +1,4 @@ +import { ComponentSizeType } from '@Shared/constants' import { IconBaseColorType } from '@Shared/types' import { IconName } from '../Icon' @@ -14,7 +15,7 @@ import { IconName } from '../Icon' * - `iconName` specifies the name of the icon to display. * - `iconColor` allows customization of the icon's color in the active state. * - `indeterminate` indicates whether the switch is in an indeterminate state, typically used for checkboxes to represent a mixed state. - * If `indeterminate` is true, the switch will not be fully checked or unchecked, and its role will change to `checkbox`. + * If `indeterminate` is true, the switch will not be fully checked or unchecked. */ type SwitchShapeProps = | { @@ -32,7 +33,14 @@ type SwitchShapeProps = * Icon color is not applicable for the `rounded` shape. */ iconColor?: never - indeterminate?: never + /** + * Indicates whether the switch is in an indeterminate state. + * This state is typically used for checkboxes to indicate a mixed state. + * If true, the switch will not be fully checked or unchecked. Due this state alone we are keeping role as `checkbox` instead of `switch`. + * This property is not applicable for the `square` shape. + * @default false + */ + indeterminate?: boolean } | { /** @@ -49,14 +57,7 @@ type SwitchShapeProps = * The color of the icon. If provided, this will override the default color in the active state. */ iconColor?: IconBaseColorType - /** - * Indicates whether the switch is in an indeterminate state. - * This state is typically used for checkboxes to indicate a mixed state. - * If true, the switch will not be fully checked or unchecked. We will change the role to checkbox in this case since the indeterminate state is not applicable for the switch. - * This property is not applicable for the `rounded` shape. - * @default false - */ - indeterminate?: boolean + indeterminate?: never } /** @@ -80,7 +81,13 @@ export type SwitchProps = { */ variant?: 'theme' | 'positive' - handleChange: () => void + /** + * The size of the switch. + * @default `ComponentSizeType.medium` + */ + size?: Extract + + onChange: () => void /** * Indicates whether the switch is disabled. diff --git a/src/Shared/Components/Switch/utils.ts b/src/Shared/Components/Switch/utils.ts index 3f2759eb3..2826859f1 100644 --- a/src/Shared/Components/Switch/utils.ts +++ b/src/Shared/Components/Switch/utils.ts @@ -1,15 +1,17 @@ import { IconBaseColorType } from '@Shared/types' +import { + ROUNDED_SWITCH_SIZE_MAP, + ROUNDED_SWITCH_THUMB_SIZE_MAP, + ROUNDED_SWITCH_TRACK_COLOR_MAP, + SQUARE_SWITCH_SIZE_MAP, + SQUARE_SWITCH_TRACK_COLOR_MAP, + SWITCH_HEIGHT_MAP, +} from './constants' import { SwitchProps } from './types' -// On intro of size there will changes in almost all methods -export const getSwitchContainerClass = ({ shape }: Required>): string => { - if (shape === 'rounded') { - return 'py-3 h-24 w-20' - } - - return 'w-28 h-18' -} +export const getSwitchContainerClass = ({ shape, size }: Required>): string => + `${SWITCH_HEIGHT_MAP[size]} ${shape === 'rounded' ? ROUNDED_SWITCH_SIZE_MAP[size] : SQUARE_SWITCH_SIZE_MAP[size]}` export const getSwitchTrackColor = ({ shape, @@ -20,31 +22,19 @@ export const getSwitchTrackColor = ({ return 'var(--N200)' } - if (shape === 'rounded') { - if (variant === 'theme') { - return 'var(--B500)' - } - - return 'var(--G500)' - } - - if (variant === 'theme') { - return 'var(--B300)' - } - - return 'var(--G300)' + return shape === 'rounded' ? ROUNDED_SWITCH_TRACK_COLOR_MAP[variant] : SQUARE_SWITCH_TRACK_COLOR_MAP[variant] } export const getSwitchThumbClass = ({ - indeterminate, shape, - isChecked, -}: Pick) => { - if (isChecked && indeterminate) { + size, + showIndeterminateIcon, +}: Pick & { showIndeterminateIcon: boolean }) => { + if (showIndeterminateIcon) { return 'w-100 h-100 flex' } - return `flex p-2 ${shape === 'rounded' ? 'dc__border-radius-50-per icon-dim-10' : 'br-3'} bg__white` + return `flex p-3 ${shape === 'rounded' ? `dc__border-radius-50-per ${ROUNDED_SWITCH_THUMB_SIZE_MAP[size]}` : 'br-3'} bg__white` } export const getSwitchIconColor = ({ From cb4315d18bb21fe7920aff8ba02bbf9d84126f77 Mon Sep 17 00:00:00 2001 From: AbhishekA1509 Date: Mon, 19 May 2025 01:11:26 +0530 Subject: [PATCH 03/11] feat: enhance Switch component with accessibility improvements and new padding constants --- .../Components/Switch/Switch.component.tsx | 33 ++++++++++++++----- src/Shared/Components/Switch/constants.ts | 6 ++-- src/Shared/Components/Switch/types.ts | 8 ++++- src/Shared/Components/Switch/utils.ts | 3 +- 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/Shared/Components/Switch/Switch.component.tsx b/src/Shared/Components/Switch/Switch.component.tsx index c593ca819..bbcc7f13e 100644 --- a/src/Shared/Components/Switch/Switch.component.tsx +++ b/src/Shared/Components/Switch/Switch.component.tsx @@ -1,11 +1,12 @@ -import { AriaAttributes, HTMLAttributes } from 'react' +import { AriaAttributes, useRef } from 'react' import { AnimatePresence, motion } from 'framer-motion' import { Tooltip } from '@Common/Tooltip' import { ComponentSizeType } from '@Shared/constants' +import { getUniqueId } from '@Shared/Helpers' import { Icon } from '../Icon' -import { INDETERMINATE_ICON_WIDTH_MAP, LOADING_COLOR_MAP, SQUARE_ICON_DIMENSION_MAP } from './constants' +import { INDETERMINATE_ICON_WIDTH_MAP, LOADING_COLOR_MAP } from './constants' import { SwitchProps } from './types' import { getSwitchContainerClass, getSwitchIconColor, getSwitchThumbClass, getSwitchTrackColor } from './utils' @@ -22,8 +23,11 @@ const Switch = ({ iconName, indeterminate = false, size = ComponentSizeType.medium, + name, onChange, }: SwitchProps) => { + const inputId = useRef(getUniqueId()) + const getAriaCheckedValue = (): AriaAttributes['aria-checked'] => { if (!isChecked) { return false @@ -35,7 +39,6 @@ const Switch = ({ const ariaCheckedValue = getAriaCheckedValue() const showIndeterminateIcon = ariaCheckedValue === 'mixed' - const role: HTMLAttributes['role'] = showIndeterminateIcon ? 'checkbox' : 'switch' const renderContent = () => { if (isLoading) { @@ -69,7 +72,7 @@ const Switch = ({ iconName && ( + ) return ( @@ -119,7 +129,7 @@ const Switch = ({ data-testid={dataTestId} disabled={isDisabled || isLoading} aria-disabled={isDisabled} - className={`p-0-imp h-100 flex flex-grow-1 dc__transparent ${isDisabled ? 'dc__disabled' : ''} dc__fill-available-space`} + 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`} onClick={onChange} > {renderContent()} diff --git a/src/Shared/Components/Switch/constants.ts b/src/Shared/Components/Switch/constants.ts index b54ff33e2..f97fabe61 100644 --- a/src/Shared/Components/Switch/constants.ts +++ b/src/Shared/Components/Switch/constants.ts @@ -33,14 +33,14 @@ export const LOADING_COLOR_MAP: Record = { - theme: 'var(--B500)', - positive: 'var(--G500)', +export const ROUNDED_SWITCH_TRACK_COLOR_MAP: Record = { + theme: 'bcb-5', + positive: 'bcg-5', } export const SQUARE_SWITCH_TRACK_COLOR_MAP: typeof ROUNDED_SWITCH_TRACK_COLOR_MAP = { - theme: 'var(--B300)', - positive: 'var(--G300)', + theme: 'bcb-3', + positive: 'bcg-3', } export const ROUNDED_SWITCH_THUMB_SIZE_MAP: Record = { @@ -57,3 +57,8 @@ export const SWITCH_THUMB_PADDING_MAP: Record = { [ComponentSizeType.medium]: 'p-3', [ComponentSizeType.small]: 'p-1', } + +export const THUMB_OUTER_PADDING_MAP: Record = { + rounded: 'p-2', + square: 'p-1', +} diff --git a/src/Shared/Components/Switch/utils.ts b/src/Shared/Components/Switch/utils.ts index db363134b..afef4ee98 100644 --- a/src/Shared/Components/Switch/utils.ts +++ b/src/Shared/Components/Switch/utils.ts @@ -8,6 +8,7 @@ import { SQUARE_SWITCH_TRACK_COLOR_MAP, SWITCH_HEIGHT_MAP, SWITCH_THUMB_PADDING_MAP, + THUMB_OUTER_PADDING_MAP, } from './constants' import { SwitchProps } from './types' @@ -18,9 +19,14 @@ export const getSwitchTrackColor = ({ shape, variant, isChecked, -}: Required>): `var(--${IconBaseColorType})` => { + isLoading, +}: Required>): string => { + if (isLoading) { + return 'dc__transparent--unstyled' + } + if (!isChecked) { - return 'var(--N200)' + return 'bcn-2' } return shape === 'rounded' ? ROUNDED_SWITCH_TRACK_COLOR_MAP[variant] : SQUARE_SWITCH_TRACK_COLOR_MAP[variant] @@ -49,3 +55,22 @@ export const getSwitchIconColor = ({ return iconColor || (variant === 'theme' ? 'B500' : 'G500') } + +export const getThumbPosition = ({ + isLoading, + isChecked, +}: Pick): 'left' | 'right' | 'center' => { + if (isLoading) { + return 'center' + } + + return isChecked ? 'right' : 'left' +} + +export const getThumbPadding = ({ shape, isLoading }: Pick): string => { + if (isLoading) { + return '' + } + + return THUMB_OUTER_PADDING_MAP[shape] +} From 5ff39fcf8df008a9cf4706bbe1a8a094df5dc6ca Mon Sep 17 00:00:00 2001 From: AbhishekA1509 Date: Wed, 21 May 2025 10:28:18 +0530 Subject: [PATCH 07/11] chore: update version from 1.13.0-pre-6 to 1.13.0-beta-8 in package.json and package-lock.json --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4ba478ef3..8354898a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "1.13.0-pre-6", + "version": "1.13.0-beta-8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "1.13.0-pre-6", + "version": "1.13.0-beta-8", "hasInstallScript": true, "license": "ISC", "dependencies": { diff --git a/package.json b/package.json index 4227d5d2a..f763c0442 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@devtron-labs/devtron-fe-common-lib", - "version": "1.13.0-pre-6", + "version": "1.13.0-beta-8", "description": "Supporting common component library", "type": "module", "main": "dist/index.js", From 95faa766aba96800807dcdb6e3de580a14d6733e Mon Sep 17 00:00:00 2001 From: AbhishekA1509 Date: Wed, 21 May 2025 16:29:15 +0530 Subject: [PATCH 08/11] refactor: rename SwitchProps to DTSwitchProps for consistency across Switch component --- .../Components/Switch/Switch.component.tsx | 4 ++-- src/Shared/Components/Switch/constants.ts | 22 +++++++++---------- src/Shared/Components/Switch/index.ts | 4 ++-- src/Shared/Components/Switch/types.ts | 2 +- src/Shared/Components/Switch/utils.ts | 14 ++++++------ 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/Shared/Components/Switch/Switch.component.tsx b/src/Shared/Components/Switch/Switch.component.tsx index 8882e1cea..3aa635887 100644 --- a/src/Shared/Components/Switch/Switch.component.tsx +++ b/src/Shared/Components/Switch/Switch.component.tsx @@ -7,7 +7,7 @@ import { getUniqueId } from '@Shared/Helpers' import { Icon } from '../Icon' import { INDETERMINATE_ICON_WIDTH_MAP, LOADING_COLOR_MAP } from './constants' -import { SwitchProps } from './types' +import { DTSwitchProps } from './types' import { getSwitchContainerClass, getSwitchIconColor, @@ -32,7 +32,7 @@ const Switch = ({ size = ComponentSizeType.medium, name, onChange, -}: SwitchProps) => { +}: DTSwitchProps) => { const inputId = useRef(getUniqueId()) const getAriaCheckedValue = (): AriaAttributes['aria-checked'] => { diff --git a/src/Shared/Components/Switch/constants.ts b/src/Shared/Components/Switch/constants.ts index f97fabe61..2e808ed81 100644 --- a/src/Shared/Components/Switch/constants.ts +++ b/src/Shared/Components/Switch/constants.ts @@ -1,19 +1,19 @@ import { ComponentSizeType } from '@Shared/constants' import { IconBaseColorType } from '@Shared/types' -import { SwitchProps } from './types' +import { DTSwitchProps } from './types' -export const SWITCH_VARIANTS: Readonly> = { +export const SWITCH_VARIANTS: Readonly> = { theme: null, positive: null, } -export const SWITCH_SHAPES: Readonly> = { +export const SWITCH_SHAPES: Readonly> = { rounded: null, square: null, } -export const ROUNDED_SWITCH_SIZE_MAP: Readonly> = { +export const ROUNDED_SWITCH_SIZE_MAP: Readonly> = { [ComponentSizeType.medium]: 'w-32', [ComponentSizeType.small]: 'w-24', } @@ -23,17 +23,17 @@ export const SQUARE_SWITCH_SIZE_MAP: typeof ROUNDED_SWITCH_SIZE_MAP = { [ComponentSizeType.small]: 'w-24', } -export const SWITCH_HEIGHT_MAP: Readonly> = { +export const SWITCH_HEIGHT_MAP: Readonly> = { [ComponentSizeType.medium]: 'h-24', [ComponentSizeType.small]: 'h-20', } -export const LOADING_COLOR_MAP: Record = { +export const LOADING_COLOR_MAP: Record = { theme: 'B500', positive: 'G500', } -export const ROUNDED_SWITCH_TRACK_COLOR_MAP: Record = { +export const ROUNDED_SWITCH_TRACK_COLOR_MAP: Record = { theme: 'bcb-5', positive: 'bcg-5', } @@ -43,22 +43,22 @@ export const SQUARE_SWITCH_TRACK_COLOR_MAP: typeof ROUNDED_SWITCH_TRACK_COLOR_MA positive: 'bcg-3', } -export const ROUNDED_SWITCH_THUMB_SIZE_MAP: Record = { +export const ROUNDED_SWITCH_THUMB_SIZE_MAP: Record = { [ComponentSizeType.medium]: 'icon-dim-16', [ComponentSizeType.small]: 'icon-dim-12', } -export const INDETERMINATE_ICON_WIDTH_MAP: Record = { +export const INDETERMINATE_ICON_WIDTH_MAP: Record = { [ComponentSizeType.medium]: 'w-12', [ComponentSizeType.small]: 'w-10', } -export const SWITCH_THUMB_PADDING_MAP: Record = { +export const SWITCH_THUMB_PADDING_MAP: Record = { [ComponentSizeType.medium]: 'p-3', [ComponentSizeType.small]: 'p-1', } -export const THUMB_OUTER_PADDING_MAP: Record = { +export const THUMB_OUTER_PADDING_MAP: Record = { rounded: 'p-2', square: 'p-1', } diff --git a/src/Shared/Components/Switch/index.ts b/src/Shared/Components/Switch/index.ts index 59377635f..e4732a3e0 100644 --- a/src/Shared/Components/Switch/index.ts +++ b/src/Shared/Components/Switch/index.ts @@ -1,3 +1,3 @@ export { SWITCH_SHAPES, SWITCH_VARIANTS } from './constants' -export { default as Switch } from './Switch.component' -export type { SwitchProps } from './types' +export { default as DTSwitch } from './Switch.component' +export type { DTSwitchProps } from './types' diff --git a/src/Shared/Components/Switch/types.ts b/src/Shared/Components/Switch/types.ts index ea7167745..32f3d58e5 100644 --- a/src/Shared/Components/Switch/types.ts +++ b/src/Shared/Components/Switch/types.ts @@ -63,7 +63,7 @@ type SwitchShapeProps = /** * Represents the properties for the `Switch` component. */ -export type SwitchProps = { +export type DTSwitchProps = { /** * The ARIA label for the switch, used for accessibility purposes. */ diff --git a/src/Shared/Components/Switch/utils.ts b/src/Shared/Components/Switch/utils.ts index afef4ee98..16113290b 100644 --- a/src/Shared/Components/Switch/utils.ts +++ b/src/Shared/Components/Switch/utils.ts @@ -10,9 +10,9 @@ import { SWITCH_THUMB_PADDING_MAP, THUMB_OUTER_PADDING_MAP, } from './constants' -import { SwitchProps } from './types' +import { DTSwitchProps } from './types' -export const getSwitchContainerClass = ({ shape, size }: Required>): string => +export const getSwitchContainerClass = ({ shape, size }: Required>): string => `${SWITCH_HEIGHT_MAP[size]} ${shape === 'rounded' ? ROUNDED_SWITCH_SIZE_MAP[size] : SQUARE_SWITCH_SIZE_MAP[size]}` export const getSwitchTrackColor = ({ @@ -20,7 +20,7 @@ export const getSwitchTrackColor = ({ variant, isChecked, isLoading, -}: Required>): string => { +}: Required>): string => { if (isLoading) { return 'dc__transparent--unstyled' } @@ -36,7 +36,7 @@ export const getSwitchThumbClass = ({ shape, size, showIndeterminateIcon, -}: Pick & { showIndeterminateIcon: boolean }) => { +}: Pick & { showIndeterminateIcon: boolean }) => { if (showIndeterminateIcon) { return 'w-100 h-100 flex' } @@ -48,7 +48,7 @@ export const getSwitchIconColor = ({ iconColor, isChecked, variant, -}: Pick): IconBaseColorType => { +}: Pick): IconBaseColorType => { if (!isChecked) { return 'N200' } @@ -59,7 +59,7 @@ export const getSwitchIconColor = ({ export const getThumbPosition = ({ isLoading, isChecked, -}: Pick): 'left' | 'right' | 'center' => { +}: Pick): 'left' | 'right' | 'center' => { if (isLoading) { return 'center' } @@ -67,7 +67,7 @@ export const getThumbPosition = ({ return isChecked ? 'right' : 'left' } -export const getThumbPadding = ({ shape, isLoading }: Pick): string => { +export const getThumbPadding = ({ shape, isLoading }: Pick): string => { if (isLoading) { return '' } From b263a1d32c8de6405fa280f6bda0e48bdcb5e7c0 Mon Sep 17 00:00:00 2001 From: AbhishekA1509 Date: Sun, 25 May 2025 18:36:46 +0530 Subject: [PATCH 09/11] feat: add hover color support for Switch component and refactor styles --- .../Components/Switch/Switch.component.tsx | 17 ++++++++++++++--- src/Shared/Components/Switch/constants.ts | 10 ++++++++++ src/Shared/Components/Switch/switch.scss | 9 +++++++++ src/Shared/Components/Switch/utils.ts | 18 ++++++++++++++++++ 4 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 src/Shared/Components/Switch/switch.scss diff --git a/src/Shared/Components/Switch/Switch.component.tsx b/src/Shared/Components/Switch/Switch.component.tsx index 3aa635887..161f530cd 100644 --- a/src/Shared/Components/Switch/Switch.component.tsx +++ b/src/Shared/Components/Switch/Switch.component.tsx @@ -13,10 +13,13 @@ import { getSwitchIconColor, getSwitchThumbClass, getSwitchTrackColor, + getSwitchTrackHoverColor, getThumbPadding, getThumbPosition, } from './utils' +import './switch.scss' + const Switch = ({ ariaLabel, dataTestId, @@ -56,14 +59,14 @@ const Switch = ({ {isLoading ? ( ) : ( {renderContent()} diff --git a/src/Shared/Components/Switch/constants.ts b/src/Shared/Components/Switch/constants.ts index 2e808ed81..28c8ef79f 100644 --- a/src/Shared/Components/Switch/constants.ts +++ b/src/Shared/Components/Switch/constants.ts @@ -38,11 +38,21 @@ export const ROUNDED_SWITCH_TRACK_COLOR_MAP: Record = { + theme: 'var(--B600)', + positive: 'var(--G600)', +} + export const SQUARE_SWITCH_TRACK_COLOR_MAP: typeof ROUNDED_SWITCH_TRACK_COLOR_MAP = { theme: 'bcb-3', positive: 'bcg-3', } +export const SQUARE_SWITCH_TRACK_HOVER_COLOR_MAP: typeof ROUNDED_SWITCH_TRACK_HOVER_COLOR_MAP = { + theme: 'var(--B400)', + positive: 'var(--G400)', +} + export const ROUNDED_SWITCH_THUMB_SIZE_MAP: Record = { [ComponentSizeType.medium]: 'icon-dim-16', [ComponentSizeType.small]: 'icon-dim-12', diff --git a/src/Shared/Components/Switch/switch.scss b/src/Shared/Components/Switch/switch.scss new file mode 100644 index 000000000..522b011c0 --- /dev/null +++ b/src/Shared/Components/Switch/switch.scss @@ -0,0 +1,9 @@ +.dt-switch { + &__track { + --switch-track-hover-color: 'transparent'; + + &:hover { + background-color: var(--switch-track-hover-color); + } + } +} \ No newline at end of file diff --git a/src/Shared/Components/Switch/utils.ts b/src/Shared/Components/Switch/utils.ts index 16113290b..2dd6cf73a 100644 --- a/src/Shared/Components/Switch/utils.ts +++ b/src/Shared/Components/Switch/utils.ts @@ -4,8 +4,10 @@ import { ROUNDED_SWITCH_SIZE_MAP, ROUNDED_SWITCH_THUMB_SIZE_MAP, ROUNDED_SWITCH_TRACK_COLOR_MAP, + ROUNDED_SWITCH_TRACK_HOVER_COLOR_MAP, SQUARE_SWITCH_SIZE_MAP, SQUARE_SWITCH_TRACK_COLOR_MAP, + SQUARE_SWITCH_TRACK_HOVER_COLOR_MAP, SWITCH_HEIGHT_MAP, SWITCH_THUMB_PADDING_MAP, THUMB_OUTER_PADDING_MAP, @@ -32,6 +34,22 @@ export const getSwitchTrackColor = ({ return shape === 'rounded' ? ROUNDED_SWITCH_TRACK_COLOR_MAP[variant] : SQUARE_SWITCH_TRACK_COLOR_MAP[variant] } +export const getSwitchTrackHoverColor = ({ + shape, + variant, + isChecked, +}: Required< + Pick +>): (typeof ROUNDED_SWITCH_TRACK_HOVER_COLOR_MAP)[DTSwitchProps['variant']] => { + if (!isChecked) { + return 'var(--N300)' + } + + return shape === 'rounded' + ? ROUNDED_SWITCH_TRACK_HOVER_COLOR_MAP[variant] + : SQUARE_SWITCH_TRACK_HOVER_COLOR_MAP[variant] +} + export const getSwitchThumbClass = ({ shape, size, From b8f14c0fd228c9653fbd6d806d931d7fe895012b Mon Sep 17 00:00:00 2001 From: AbhishekA1509 Date: Mon, 26 May 2025 10:55:40 +0530 Subject: [PATCH 10/11] fix: remove unnecessary keys from loading and icon spans in Switch component --- src/Shared/Components/Switch/Switch.component.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Shared/Components/Switch/Switch.component.tsx b/src/Shared/Components/Switch/Switch.component.tsx index 161f530cd..b006d743c 100644 --- a/src/Shared/Components/Switch/Switch.component.tsx +++ b/src/Shared/Components/Switch/Switch.component.tsx @@ -62,7 +62,7 @@ const Switch = ({ layoutId={`${name}-loader`} className="flex-grow-1 h-100 dc__fill-available-space dc__no-shrink" > - + ) : ( {showIndeterminateIcon ? ( Date: Mon, 26 May 2025 11:33:51 +0530 Subject: [PATCH 11/11] refactor: remove unused SWITCH_VARIANTS and SWITCH_SHAPES constants from Switch component --- src/Shared/Components/Switch/constants.ts | 10 ---------- src/Shared/Components/Switch/index.ts | 1 - src/Shared/Components/Switch/types.ts | 4 ++++ 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/Shared/Components/Switch/constants.ts b/src/Shared/Components/Switch/constants.ts index 28c8ef79f..6d1c97cbc 100644 --- a/src/Shared/Components/Switch/constants.ts +++ b/src/Shared/Components/Switch/constants.ts @@ -3,16 +3,6 @@ import { IconBaseColorType } from '@Shared/types' import { DTSwitchProps } from './types' -export const SWITCH_VARIANTS: Readonly> = { - theme: null, - positive: null, -} - -export const SWITCH_SHAPES: Readonly> = { - rounded: null, - square: null, -} - export const ROUNDED_SWITCH_SIZE_MAP: Readonly> = { [ComponentSizeType.medium]: 'w-32', [ComponentSizeType.small]: 'w-24', diff --git a/src/Shared/Components/Switch/index.ts b/src/Shared/Components/Switch/index.ts index e4732a3e0..a5ff57e39 100644 --- a/src/Shared/Components/Switch/index.ts +++ b/src/Shared/Components/Switch/index.ts @@ -1,3 +1,2 @@ -export { SWITCH_SHAPES, SWITCH_VARIANTS } from './constants' export { default as DTSwitch } from './Switch.component' export type { DTSwitchProps } from './types' diff --git a/src/Shared/Components/Switch/types.ts b/src/Shared/Components/Switch/types.ts index 32f3d58e5..2af63d037 100644 --- a/src/Shared/Components/Switch/types.ts +++ b/src/Shared/Components/Switch/types.ts @@ -92,6 +92,10 @@ export type DTSwitchProps = { */ size?: Extract + /** + * Callback function that is called when the switch state changes. + * This function should handle the logic for toggling the switch. + */ onChange: () => void /**