From e7861d2313af19ed278ff9a01a7b0eef5db6861b Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Mon, 13 Apr 2026 13:52:54 +0100 Subject: [PATCH 01/14] =?UTF-8?q?chore:=20=F0=9F=A4=96=20create=20CSS=20mo?= =?UTF-8?q?dule=20for=20ButtonGroup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ButtonGroup/ButtonGroup.module.css | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 src/components/ButtonGroup/ButtonGroup.module.css diff --git a/src/components/ButtonGroup/ButtonGroup.module.css b/src/components/ButtonGroup/ButtonGroup.module.css new file mode 100644 index 000000000..e9c6d3a21 --- /dev/null +++ b/src/components/ButtonGroup/ButtonGroup.module.css @@ -0,0 +1,83 @@ +.buttonGroup { + display: inline-flex; + box-sizing: border-box; + flex-direction: row; + justify-content: center; + align-items: center; + background: var(--click-button-group-color-background-panel); + border-radius: var(--click-button-group-radii-panel-all); +} + +.buttonGroup_type-default { + padding: var(--click-button-group-space-panel-default-x) + var(--click-button-group-space-panel-default-y); + gap: var(--click-button-group-space-panel-default-gap); + border: 1px solid var(--click-button-group-color-panel-stroke-default); +} + +.buttonGroup_type-borderless { + padding: var(--click-button-group-space-panel-borderless-x) + var(--click-button-group-space-panel-borderless-y); + gap: var(--click-button-group-space-panel-borderless-gap); + border: none; +} + +.buttonGroup_fillWidth { + width: 100%; +} + +.button { + box-sizing: border-box; + display: flex; + flex-direction: row; + justify-content: center; + align-items: center; + border: none; + cursor: pointer; + background: var(--click-button-group-color-background-default); + color: var(--click-button-group-color-text-default); + font: var(--click-button-group-typography-label-default); + white-space: nowrap; +} + +.button_type-default { + padding: var(--click-button-group-space-button-default-y) + var(--click-button-group-space-button-default-x); + border-radius: var(--click-button-group-radii-button-default-all); +} + +.button_type-borderless { + padding: var(--click-button-group-space-button-borderless-y) + var(--click-button-group-space-button-borderless-x); + border-radius: var(--click-button-group-radii-button-borderless-all); +} + +.button_fillWidth { + flex: 1; +} + +.button:hover:not(:disabled) { + background: var(--click-button-group-color-background-hover); + font: var(--click-button-group-typography-label-hover); + color: var(--click-button-group-color-text-hover); +} + +.button_active, +.button[aria-pressed='true'] { + background: var(--click-button-group-color-background-active); + font: var(--click-button-group-typography-label-active); + color: var(--click-button-group-color-text-active); +} + +.button:disabled { + cursor: not-allowed; + font: var(--click-button-group-typography-label-disabled); + color: var(--click-button-group-color-text-disabled); + background: var(--click-button-group-color-background-disabled); +} + +.button_active:disabled, +.button[aria-pressed='true']:disabled { + background: var(--click-button-group-color-background-disabled-active); + color: var(--click-button-group-color-text-disabled-active); +} From 18561cc162a2dad1e0e2a215dab376816d26ced7 Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Mon, 13 Apr 2026 14:00:16 +0100 Subject: [PATCH 02/14] =?UTF-8?q?chore:=20=F0=9F=A4=96=20Migrated=20from?= =?UTF-8?q?=20styled-components=20to=20CSS=20Modules?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ButtonGroup/ButtonGroup.tsx | 133 +++++++-------------- 1 file changed, 40 insertions(+), 93 deletions(-) diff --git a/src/components/ButtonGroup/ButtonGroup.tsx b/src/components/ButtonGroup/ButtonGroup.tsx index 7895b2046..66e90592b 100644 --- a/src/components/ButtonGroup/ButtonGroup.tsx +++ b/src/components/ButtonGroup/ButtonGroup.tsx @@ -1,6 +1,33 @@ import { useCallback, useState } from 'react'; -import { styled } from 'styled-components'; +import { cn, cva } from '@/lib/cva'; import { ButtonGroupProps, SelectionValue } from './ButtonGroup.types'; +import styles from './ButtonGroup.module.css'; + +const wrapperVariants = cva(styles.buttonGroup, { + variants: { + type: { + default: styles['buttonGroup_type-default'], + borderless: styles['buttonGroup_type-borderless'], + }, + fillWidth: { + true: styles['buttonGroup_fillWidth'], + }, + }, + defaultVariants: { type: 'default' }, +}); + +const buttonVariants = cva(styles.button, { + variants: { + type: { + default: styles['button_type-default'], + borderless: styles['button_type-borderless'], + }, + fillWidth: { + true: styles['button_fillWidth'], + }, + }, + defaultVariants: { type: 'default' }, +}); const normalizeToSet = (value: SelectionValue | undefined): Set => { if (value === undefined) { @@ -25,6 +52,7 @@ export const ButtonGroup = ({ type = 'default', multiple = false, 'aria-label': ariaLabel, + className, ...props }: ButtonGroupProps) => { const [internalSelection, setInternalSelection] = useState>(() => @@ -65,115 +93,34 @@ export const ButtonGroup = ({ [currentSelection, multiple, isControlled, onClick] ); - const buttons = options.map(({ value, label, ...buttonProps }) => { + const buttons = options.map(({ value, label, disabled, ...buttonProps }) => { const isActive = isValueSelected(value, currentSelection); return ( - + ); }); return ( - {buttons} - + ); }; - -import { ButtonGroupType } from './ButtonGroup.types'; - -const ButtonGroupWrapper = styled.div<{ $fillWidth: boolean; $type: ButtonGroupType }>` - display: inline-flex; - box-sizing: border-box; - flex-direction: row; - justify-content: center; - align-items: center; - padding: ${({ theme, $type }) => - `${theme.click.button.group.space.panel[$type].x} ${theme.click.button.group.space.panel[$type].y}`}; - gap: ${({ theme, $type }) => theme.click.button.group.space.panel[$type].gap}; - border: ${({ theme, $type }) => - $type === 'default' - ? `1px solid ${theme.click.button.group.color.panel.stroke[$type]}` - : 'none'}; - background: ${({ theme }) => theme.click.button.group.color.background.panel}; - border-radius: ${({ theme }) => theme.click.button.group.radii.panel.all}; - width: ${({ $fillWidth }) => ($fillWidth ? '100%' : 'auto')}; -`; - -const Button = styled.button.attrs<{ - disabled?: boolean; -}>(props => ({ - 'aria-disabled': props.disabled ? 'true' : undefined, -}))<{ - $active: boolean; - $fillWidth: boolean; - $type: ButtonGroupType; - disabled?: boolean; -}>` - box-sizing: border-box; - display: flex; - flex-direction: row; - justify-content: center; - align-items: center; - background: ${({ $active, theme }) => - $active - ? theme.click.button.group.color.background.active - : theme.click.button.group.color.background.default}; - color: ${({ theme }) => theme.click.button.group.color.text.default}; - font: ${({ theme }) => theme.click.button.group.typography.label.default}; - padding: ${({ theme, $type }) => - `${theme.click.button.group.space.button[$type].y} ${theme.click.button.group.space.button[$type].x}`}; - ${({ $fillWidth }) => ($fillWidth ? 'flex: 1;' : '')}; - border-radius: ${({ theme, $type }) => - theme.click.button.group.radii.button[$type].all}; - cursor: pointer; - border: none; - - &:hover { - background: ${({ theme }) => theme.click.button.group.color.background.hover}; - font: ${({ theme }) => theme.click.button.group.typography.label.hover}; - color: ${({ theme }) => theme.click.button.group.color.text.hover}; - } - - &:disabled { - cursor: not-allowed; - font: ${({ theme }) => theme.click.button.group.typography.label.disabled}; - color: ${({ theme }) => theme.click.button.group.color.text.disabled}; - background: ${({ theme, $active }) => - theme.click.button.group.color.background[ - $active ? 'disabled-active' : 'disabled' - ]}; - - &:active, - &:focus, - &[aria-pressed='true'] { - color: ${({ theme }) => theme.click.button.group.color.text.disabled}; - } - } - - &[aria-pressed='true'] { - background: ${({ theme }) => theme.click.button.group.color.background.active}; - font: ${({ theme }) => theme.click.button.group.typography.label.active}; - color: ${({ theme }) => theme.click.button.group.color.text.active}; - &:disabled { - background: ${({ theme }) => - theme.click.button.group.color.background['disabled-active']}; - } - } -`; From 634aa643cde143ae7ed800cefe2616997a32d2e6 Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Mon, 13 Apr 2026 14:39:53 +0100 Subject: [PATCH 03/14] =?UTF-8?q?chore:=20=F0=9F=A4=96=20add=20changeset?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/dull-suits-tell.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/dull-suits-tell.md diff --git a/.changeset/dull-suits-tell.md b/.changeset/dull-suits-tell.md new file mode 100644 index 000000000..aa8f0cf06 --- /dev/null +++ b/.changeset/dull-suits-tell.md @@ -0,0 +1,5 @@ +--- +'@clickhouse/click-ui': patch +--- + +Migrate ButtonGroup component from Styled-Components to CSS Modules From c4bcff67210ede3367d58133f99e27dcb9728b38 Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Mon, 13 Apr 2026 16:12:21 +0100 Subject: [PATCH 04/14] fix(ButtonGroup): comply with CSS linting rules - Rename classes to follow BEM convention (lowercase with underscores) - Reorder CSS properties alphabetically - Update component to use new class names --- .../ButtonGroup/ButtonGroup.module.css | 48 +++++++++---------- src/components/ButtonGroup/ButtonGroup.tsx | 14 +++--- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/components/ButtonGroup/ButtonGroup.module.css b/src/components/ButtonGroup/ButtonGroup.module.css index e9c6d3a21..db344b4c8 100644 --- a/src/components/ButtonGroup/ButtonGroup.module.css +++ b/src/components/ButtonGroup/ButtonGroup.module.css @@ -1,79 +1,66 @@ -.buttonGroup { +.buttongroup { display: inline-flex; box-sizing: border-box; flex-direction: row; justify-content: center; align-items: center; - background: var(--click-button-group-color-background-panel); border-radius: var(--click-button-group-radii-panel-all); + background: var(--click-button-group-color-background-panel); } -.buttonGroup_type-default { +.buttongroup_type_default { padding: var(--click-button-group-space-panel-default-x) var(--click-button-group-space-panel-default-y); gap: var(--click-button-group-space-panel-default-gap); border: 1px solid var(--click-button-group-color-panel-stroke-default); } -.buttonGroup_type-borderless { +.buttongroup_type_borderless { padding: var(--click-button-group-space-panel-borderless-x) var(--click-button-group-space-panel-borderless-y); gap: var(--click-button-group-space-panel-borderless-gap); border: none; } -.buttonGroup_fillWidth { +.buttongroup_fillwidth { width: 100%; } .button { - box-sizing: border-box; display: flex; + box-sizing: border-box; flex-direction: row; justify-content: center; align-items: center; border: none; - cursor: pointer; background: var(--click-button-group-color-background-default); color: var(--click-button-group-color-text-default); font: var(--click-button-group-typography-label-default); white-space: nowrap; + cursor: pointer; } -.button_type-default { +.button_type_default { padding: var(--click-button-group-space-button-default-y) var(--click-button-group-space-button-default-x); border-radius: var(--click-button-group-radii-button-default-all); } -.button_type-borderless { +.button_type_borderless { padding: var(--click-button-group-space-button-borderless-y) var(--click-button-group-space-button-borderless-x); border-radius: var(--click-button-group-radii-button-borderless-all); } -.button_fillWidth { +.button_fillwidth { flex: 1; } -.button:hover:not(:disabled) { - background: var(--click-button-group-color-background-hover); - font: var(--click-button-group-typography-label-hover); - color: var(--click-button-group-color-text-hover); -} - .button_active, .button[aria-pressed='true'] { background: var(--click-button-group-color-background-active); - font: var(--click-button-group-typography-label-active); color: var(--click-button-group-color-text-active); -} - -.button:disabled { - cursor: not-allowed; - font: var(--click-button-group-typography-label-disabled); - color: var(--click-button-group-color-text-disabled); - background: var(--click-button-group-color-background-disabled); + font: var(--click-button-group-typography-label-active); } .button_active:disabled, @@ -81,3 +68,16 @@ background: var(--click-button-group-color-background-disabled-active); color: var(--click-button-group-color-text-disabled-active); } + +.button:disabled { + background: var(--click-button-group-color-background-disabled); + color: var(--click-button-group-color-text-disabled); + font: var(--click-button-group-typography-label-disabled); + cursor: not-allowed; +} + +.button:hover:not(:disabled) { + background: var(--click-button-group-color-background-hover); + color: var(--click-button-group-color-text-hover); + font: var(--click-button-group-typography-label-hover); +} diff --git a/src/components/ButtonGroup/ButtonGroup.tsx b/src/components/ButtonGroup/ButtonGroup.tsx index 66e90592b..0de4dcf3a 100644 --- a/src/components/ButtonGroup/ButtonGroup.tsx +++ b/src/components/ButtonGroup/ButtonGroup.tsx @@ -3,14 +3,14 @@ import { cn, cva } from '@/lib/cva'; import { ButtonGroupProps, SelectionValue } from './ButtonGroup.types'; import styles from './ButtonGroup.module.css'; -const wrapperVariants = cva(styles.buttonGroup, { +const wrapperVariants = cva(styles.buttongroup, { variants: { type: { - default: styles['buttonGroup_type-default'], - borderless: styles['buttonGroup_type-borderless'], + default: styles['buttongroup_type_default'], + borderless: styles['buttongroup_type_borderless'], }, fillWidth: { - true: styles['buttonGroup_fillWidth'], + true: styles['buttongroup_fillwidth'], }, }, defaultVariants: { type: 'default' }, @@ -19,11 +19,11 @@ const wrapperVariants = cva(styles.buttonGroup, { const buttonVariants = cva(styles.button, { variants: { type: { - default: styles['button_type-default'], - borderless: styles['button_type-borderless'], + default: styles['button_type_default'], + borderless: styles['button_type_borderless'], }, fillWidth: { - true: styles['button_fillWidth'], + true: styles['button_fillwidth'], }, }, defaultVariants: { type: 'default' }, From e1afe16d4616ddd5653f3b8ae4a3cbd694f017c1 Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Mon, 13 Apr 2026 16:20:54 +0100 Subject: [PATCH 05/14] =?UTF-8?q?fix:=20=F0=9F=90=9B=20pupdate=20snapshot?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...up-disabled-active-dark-chromium-linux.png | Bin 2719 -> 2873 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/buttons/buttongroup.spec.ts-snapshots/buttongroup-disabled-active-dark-chromium-linux.png b/tests/buttons/buttongroup.spec.ts-snapshots/buttongroup-disabled-active-dark-chromium-linux.png index 61be6a5f65f4740125860900da76a3ae93702e28..0e2c7cc7fbabf0b39431c0ac929b3b0bcabbac5c 100644 GIT binary patch delta 2866 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 Q+W-In07*qoM6N<$g4G+NegFUf delta 2711 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 R>|Ou>002ovPDHLkV1j$cF8BZd From 19a016c0465484ed5b13baf3856d5fbcfaf944f5 Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Mon, 13 Apr 2026 16:26:15 +0100 Subject: [PATCH 06/14] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Added=20:focus-visi?= =?UTF-8?q?ble=20rule=20to=20.button=20in=20the=20CSS=20Module?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ButtonGroup/ButtonGroup.module.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/ButtonGroup/ButtonGroup.module.css b/src/components/ButtonGroup/ButtonGroup.module.css index db344b4c8..4dd5b5bc9 100644 --- a/src/components/ButtonGroup/ButtonGroup.module.css +++ b/src/components/ButtonGroup/ButtonGroup.module.css @@ -81,3 +81,8 @@ color: var(--click-button-group-color-text-hover); font: var(--click-button-group-typography-label-hover); } + +.button:focus-visible:not(:disabled) { + outline: 2px solid var(--click-button-group-color-background-active); + outline-offset: 2px; +} From 0b44b829506daf1408d755797a39ceeaae17fae6 Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Mon, 13 Apr 2026 16:27:32 +0100 Subject: [PATCH 07/14] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Added=20aria-disabl?= =?UTF-8?q?ed=20attribute=20to=20disabled=20buttons?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ButtonGroup/ButtonGroup.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/ButtonGroup/ButtonGroup.tsx b/src/components/ButtonGroup/ButtonGroup.tsx index 0de4dcf3a..0cca99c92 100644 --- a/src/components/ButtonGroup/ButtonGroup.tsx +++ b/src/components/ButtonGroup/ButtonGroup.tsx @@ -105,6 +105,7 @@ export const ButtonGroup = ({ )} aria-pressed={isActive} disabled={disabled} + aria-disabled={disabled ? true : undefined} onClick={() => onButtonGroupClickCommonHandler(value)} {...buttonProps} > From 27eada0dcdf7feeb8f854a0e120cfad30714d1ab Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Mon, 13 Apr 2026 16:31:41 +0100 Subject: [PATCH 08/14] =?UTF-8?q?fix:=20=F0=9F=90=9B=20missing=20aria=20la?= =?UTF-8?q?bel,=20remove=20redundant,=20update=20snapshot?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ButtonGroup/ButtonGroup.module.css | 2 -- .../ButtonGroup/ButtonGroup.stories.tsx | 13 +++++++++++++ src/components/ButtonGroup/ButtonGroup.tsx | 5 +---- ...group-button-focus-light-chromium-linux.png | Bin 1040 -> 971 bytes 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/components/ButtonGroup/ButtonGroup.module.css b/src/components/ButtonGroup/ButtonGroup.module.css index 4dd5b5bc9..5271ee960 100644 --- a/src/components/ButtonGroup/ButtonGroup.module.css +++ b/src/components/ButtonGroup/ButtonGroup.module.css @@ -56,14 +56,12 @@ flex: 1; } -.button_active, .button[aria-pressed='true'] { background: var(--click-button-group-color-background-active); color: var(--click-button-group-color-text-active); font: var(--click-button-group-typography-label-active); } -.button_active:disabled, .button[aria-pressed='true']:disabled { background: var(--click-button-group-color-background-disabled-active); color: var(--click-button-group-color-text-disabled-active); diff --git a/src/components/ButtonGroup/ButtonGroup.stories.tsx b/src/components/ButtonGroup/ButtonGroup.stories.tsx index d16b1d18b..ceeb85582 100644 --- a/src/components/ButtonGroup/ButtonGroup.stories.tsx +++ b/src/components/ButtonGroup/ButtonGroup.stories.tsx @@ -33,6 +33,7 @@ export const Default: StoryObj = { { label: 'Option 3', value: 'option3' }, ], type: 'default', + 'aria-label': 'Button group', }, }; @@ -44,6 +45,7 @@ export const Borderless: StoryObj = { { label: 'Option 3', value: 'option3' }, ], type: 'borderless', + 'aria-label': 'Button group', }, }; @@ -56,6 +58,7 @@ export const DefaultSelected: StoryObj = { ], type: 'default', selected: 'option1', + 'aria-label': 'Button group', }, }; @@ -68,6 +71,7 @@ export const BorderlessSelected: StoryObj = { ], type: 'borderless', selected: 'option1', + 'aria-label': 'Button group', }, }; @@ -78,6 +82,7 @@ export const WithDisabledButton: StoryObj = { { label: 'Disabled', value: 'disabled', disabled: true }, ], type: 'default', + 'aria-label': 'Button group', }, }; @@ -89,6 +94,7 @@ export const WithDisabledSelectedButton: StoryObj = { ], type: 'default', selected: 'disabled', + 'aria-label': 'Button group', }, }; @@ -100,6 +106,7 @@ export const FillWidthDefault: StoryObj = { ], type: 'default', fillWidth: true, + 'aria-label': 'Button group', }, }; @@ -111,6 +118,7 @@ export const FillWidthBorderless: StoryObj = { ], type: 'borderless', fillWidth: true, + 'aria-label': 'Button group', }, }; @@ -124,6 +132,7 @@ export const MultiSelectSelected: StoryObj = { type: 'default', multiple: true, selected: new Set(['option1', 'option3']), + 'aria-label': 'Button group', }, }; @@ -137,6 +146,7 @@ export const MultiSelectBorderless: StoryObj = { type: 'borderless', multiple: true, selected: new Set(['option1', 'option3']), + 'aria-label': 'Button group', }, }; @@ -151,6 +161,7 @@ export const MultiSelect: StoryObj = { type: 'default', multiple: true, defaultSelected: new Set(['option1', 'option3']), + 'aria-label': 'Button group', onClick: (_value, selected) => { console.log('🔎 Selected:', [...selected]); }, @@ -167,6 +178,7 @@ export const ConsumerControlledStateSingle: StoryObj = { fillWidth: false, type: 'default', selected: 'option2', + 'aria-label': 'Button group', }, render: args => { const [selected, setSelected] = useState(args.selected); @@ -194,6 +206,7 @@ export const ConsumerControlledStateMulti: StoryObj = { type: 'default', multiple: true, selected: new Set(['option2']), + 'aria-label': 'Button group', }, render: args => { const [selected, setSelected] = useState(args.selected); diff --git a/src/components/ButtonGroup/ButtonGroup.tsx b/src/components/ButtonGroup/ButtonGroup.tsx index 0cca99c92..77ad99be2 100644 --- a/src/components/ButtonGroup/ButtonGroup.tsx +++ b/src/components/ButtonGroup/ButtonGroup.tsx @@ -99,10 +99,7 @@ export const ButtonGroup = ({ return (