From a77cd091f16fdab0e791c72e8728b6255bb05916 Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Tue, 14 Apr 2026 11:28:08 +0100 Subject: [PATCH 1/7] =?UTF-8?q?style:=20=F0=9F=92=84=20Created=20IconButto?= =?UTF-8?q?n.module.css=20with=20BEM=20naming=20convention?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IconButton/IconButton.module.css | 219 ++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 src/components/IconButton/IconButton.module.css diff --git a/src/components/IconButton/IconButton.module.css b/src/components/IconButton/IconButton.module.css new file mode 100644 index 000000000..c98f5c2fe --- /dev/null +++ b/src/components/IconButton/IconButton.module.css @@ -0,0 +1,219 @@ +.icon-button { + display: inline-flex; + position: relative; + overflow: hidden; + flex-shrink: 0; + justify-content: center; + align-items: center; + border: var(--click-button-stroke) solid transparent; + border-radius: var(--click-button-icon-button-radii-all); + background: transparent; + color: inherit; + cursor: pointer; +} + +.icon-button:disabled { + cursor: not-allowed; +} + +/* Default Size (base styles) */ +.icon-button { + padding: var(--click-button-icon-button-default-space-y) var(--click-button-icon-button-default-space-x); +} + +/* Small Size Modifier */ +.icon-button_sm { + padding: var(--click-button-icon-button-sm-space-y) var(--click-button-icon-button-sm-space-x); +} + +/* Extra Small Size Modifier */ +.icon-button_xs { + padding: var(--click-button-icon-button-xs-space-y) var(--click-button-icon-button-xs-space-x); +} + +/* Primary Type */ +.icon-button_primary { + border-color: var(--click-button-icon-button-color-primary-stroke-default); + background-color: var(--click-button-icon-button-color-primary-background-default); + color: var(--click-button-icon-button-color-primary-text-default); +} + +.icon-button_primary:disabled { + border-color: var(--click-button-icon-button-color-disabled-stroke-default); + background-color: var(--click-button-icon-button-color-disabled-background-default); + color: var(--click-button-icon-button-color-disabled-text-default); +} + +.icon-button_primary:hover:not(:disabled) { + border-color: var(--click-button-icon-button-color-primary-stroke-hover); + background-color: var(--click-button-icon-button-color-primary-background-hover); + color: var(--click-button-icon-button-color-primary-text-hover); + transition: var(--click-transition-default); +} + +.icon-button_primary:focus-visible:not(:disabled) { + border-color: var(--click-button-icon-button-color-primary-stroke-active); + background-color: var(--click-button-icon-button-color-primary-background-active); + color: var(--click-button-icon-button-color-primary-text-active); + outline: 2px solid var(--click-button-icon-button-color-primary-stroke-active); + outline-offset: 2px; +} + +.icon-button_primary:active:not(:disabled), +.icon-button_primary:focus:not(:focus-visible, :disabled) { + border-color: var(--click-button-icon-button-color-primary-stroke-active); + background-color: var(--click-button-icon-button-color-primary-background-active); + color: var(--click-button-icon-button-color-primary-text-active); + outline: none; +} + +/* Secondary Type */ +.icon-button_secondary { + border-color: var(--click-button-icon-button-color-secondary-stroke-default); + background-color: var(--click-button-icon-button-color-secondary-background-default); + color: var(--click-button-icon-button-color-secondary-text-default); +} + +.icon-button_secondary:disabled { + border-color: var(--click-button-icon-button-color-disabled-stroke-default); + background-color: var(--click-button-icon-button-color-disabled-background-default); + color: var(--click-button-icon-button-color-disabled-text-default); +} + +.icon-button_secondary:hover:not(:disabled) { + border-color: var(--click-button-icon-button-color-secondary-stroke-hover); + background-color: var(--click-button-icon-button-color-secondary-background-hover); + color: var(--click-button-icon-button-color-secondary-text-hover); + transition: var(--click-transition-default); +} + +.icon-button_secondary:focus-visible:not(:disabled) { + border-color: var(--click-button-icon-button-color-secondary-stroke-active); + background-color: var(--click-button-icon-button-color-secondary-background-active); + color: var(--click-button-icon-button-color-secondary-text-active); + outline: 2px solid var(--click-button-icon-button-color-secondary-stroke-active); + outline-offset: 2px; +} + +.icon-button_secondary:active:not(:disabled), +.icon-button_secondary:focus:not(:focus-visible, :disabled) { + border-color: var(--click-button-icon-button-color-secondary-stroke-active); + background-color: var(--click-button-icon-button-color-secondary-background-active); + color: var(--click-button-icon-button-color-secondary-text-active); + outline: none; +} + +/* Ghost Type */ +.icon-button_ghost { + border-color: var(--click-button-icon-button-color-ghost-stroke-default); + background-color: var(--click-button-icon-button-color-ghost-background-default); + color: var(--click-button-icon-button-color-ghost-text-default); +} + +.icon-button_ghost:disabled { + border-color: var(--click-button-icon-button-color-disabled-stroke-default); + background-color: var(--click-button-icon-button-color-disabled-background-default); + color: var(--click-button-icon-button-color-disabled-text-default); +} + +.icon-button_ghost:hover:not(:disabled) { + border-color: var(--click-button-icon-button-color-ghost-stroke-hover); + background-color: var(--click-button-icon-button-color-ghost-background-hover); + color: var(--click-button-icon-button-color-ghost-text-hover); + transition: var(--click-transition-default); +} + +.icon-button_ghost:focus-visible:not(:disabled) { + border-color: var(--click-button-icon-button-color-ghost-stroke-active); + background-color: var(--click-button-icon-button-color-ghost-background-active); + color: var(--click-button-icon-button-color-ghost-text-active); + outline: 2px solid var(--click-button-icon-button-color-ghost-stroke-active); + outline-offset: 2px; +} + +.icon-button_ghost:active:not(:disabled), +.icon-button_ghost:focus:not(:focus-visible, :disabled) { + border-color: var(--click-button-icon-button-color-ghost-stroke-active); + background-color: var(--click-button-icon-button-color-ghost-background-active); + color: var(--click-button-icon-button-color-ghost-text-active); + outline: none; +} + +/* Danger Type */ +.icon-button_danger { + border-color: var(--click-button-icon-button-color-danger-stroke-default); + background-color: var(--click-button-icon-button-color-danger-background-default); + color: var(--click-button-icon-button-color-danger-text-default); +} + +.icon-button_danger:disabled { + border-color: var(--click-button-icon-button-color-disabled-stroke-default); + background-color: var(--click-button-icon-button-color-disabled-background-default); + color: var(--click-button-icon-button-color-disabled-text-default); +} + +.icon-button_danger:hover:not(:disabled) { + border-color: var(--click-button-icon-button-color-danger-stroke-hover); + background-color: var(--click-button-icon-button-color-danger-background-hover); + color: var(--click-button-icon-button-color-danger-text-hover); + transition: var(--click-transition-default); +} + +.icon-button_danger:focus-visible:not(:disabled) { + border-color: var(--click-button-icon-button-color-danger-stroke-active); + background-color: var(--click-button-icon-button-color-danger-background-active); + color: var(--click-button-icon-button-color-danger-text-active); + outline: 2px solid var(--click-button-icon-button-color-danger-stroke-active); + outline-offset: 2px; +} + +.icon-button_danger:active:not(:disabled), +.icon-button_danger:focus:not(:focus-visible, :disabled) { + border-color: var(--click-button-icon-button-color-danger-stroke-active); + background-color: var(--click-button-icon-button-color-danger-background-active); + color: var(--click-button-icon-button-color-danger-text-active); + outline: none; +} + +/* Info Type */ +.icon-button_info { + border-color: var(--click-button-icon-button-color-info-stroke-default); + background-color: var(--click-button-icon-button-color-info-background-default); + color: var(--click-button-icon-button-color-info-text-default); +} + +.icon-button_info:disabled { + border-color: var(--click-button-icon-button-color-disabled-stroke-default); + background-color: var(--click-button-icon-button-color-disabled-background-default); + color: var(--click-button-icon-button-color-disabled-text-default); +} + +.icon-button_info:hover:not(:disabled) { + border-color: var(--click-button-icon-button-color-info-stroke-hover); + background-color: var(--click-button-icon-button-color-info-background-hover); + color: var(--click-button-icon-button-color-info-text-hover); + transition: var(--click-transition-default); +} + +.icon-button_info:focus-visible:not(:disabled) { + border-color: var(--click-button-icon-button-color-info-stroke-active); + background-color: var(--click-button-icon-button-color-info-background-active); + color: var(--click-button-icon-button-color-info-text-active); + outline: 2px solid var(--click-button-icon-button-color-info-stroke-active); + outline-offset: 2px; +} + +.icon-button_info:active:not(:disabled), +.icon-button_info:focus:not(:focus-visible, :disabled) { + border-color: var(--click-button-icon-button-color-info-stroke-active); + background-color: var(--click-button-icon-button-color-info-background-active); + color: var(--click-button-icon-button-color-info-text-active); + outline: none; +} + +/* Reduced Motion */ +@media (prefers-reduced-motion: reduce) { + .icon-button { + transition: none; + } +} From 15c3f2b7a64f120958191f7d7b31660703add621 Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Tue, 14 Apr 2026 11:29:44 +0100 Subject: [PATCH 2/7] =?UTF-8?q?refactor:=20=F0=9F=92=A1=20IconButton=20Com?= =?UTF-8?q?ponent=20Migrated=20to=20CSS=20Modules?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/IconButton/IconButton.tsx | 81 ++++++++---------------- 1 file changed, 27 insertions(+), 54 deletions(-) diff --git a/src/components/IconButton/IconButton.tsx b/src/components/IconButton/IconButton.tsx index bf89f8b61..44ea3dac4 100644 --- a/src/components/IconButton/IconButton.tsx +++ b/src/components/IconButton/IconButton.tsx @@ -1,17 +1,38 @@ import { forwardRef } from 'react'; -import { styled } from 'styled-components'; import { Icon } from '@/components/Icon'; +import { cn, cva } from '@/lib/cva'; import { IconButtonProps } from './IconButton.types'; +import styles from './IconButton.module.css'; + +const iconButtonVariants = cva(styles['icon-button'], { + variants: { + type: { + primary: styles['icon-button_primary'], + secondary: styles['icon-button_secondary'], + ghost: styles['icon-button_ghost'], + danger: styles['icon-button_danger'], + info: styles['icon-button_info'], + }, + size: { + default: undefined, + sm: styles['icon-button_sm'], + xs: styles['icon-button_xs'], + }, + }, + defaultVariants: { + type: 'primary', + size: 'default', + }, +}); export const IconButton = forwardRef( - ({ type = 'primary', icon, size, disabled, ...props }, ref) => { + ({ type = 'primary', icon, size = 'default', disabled, className, ...props }, ref) => { const iconName = icon ? icon.toString() : 'unknown icon'; return ( - + ); } ); IconButton.displayName = 'IconButton'; - -const Button = styled.button<{ - $styleType?: 'primary' | 'secondary' | 'ghost' | 'danger' | 'info'; - $size?: 'default' | 'sm' | 'xs'; -}>` - ${({ theme, $size, $styleType = 'primary' }) => ` - border-radius: ${theme.click.button.iconButton.radii.all}; - border: ${theme.click.button.stroke} solid ${ - theme.click.button.iconButton.color[$styleType].stroke.default - }; - cursor: pointer; - padding: ${ - $size - ? `${theme.click.button.iconButton[$size].space.y} ${theme.click.button.iconButton[$size].space.x}` - : `${theme.click.button.iconButton.default.space.y} ${theme.click.button.iconButton.default.space.x}` - }; - - background-color: ${theme.click.button.iconButton.color[$styleType].background.default}; - - color: ${theme.click.button.iconButton.color[$styleType].text.default}; - &:not([disabled]) { - &:hover { - background-color: ${theme.click.button.iconButton.color[$styleType].background.hover}; - color: ${theme.click.button.iconButton.color[$styleType].text.hover}; - border-color: ${theme.click.button.iconButton.color[$styleType].stroke.hover}; - } - - &:focus, &:active, &:focus-within { - background-color: ${ - theme.click.button.iconButton.color[$styleType].background.active - }; - color: ${theme.click.button.iconButton.color[$styleType].text.active}; - border-color: ${theme.click.button.iconButton.color[$styleType].stroke.active}; - } - } - &:visited { - background-color: ${ - theme.click.button.iconButton.color[$styleType].background.default - }; - } - - &[disabled] { - background-color: ${theme.click.button.iconButton.color.disabled.background.default}; - color: ${theme.click.button.iconButton.color.disabled.text.default}; - cursor: not-allowed; - } - `} -`; From eca2042e41b665f3a349e19b131e6f842de7a7aa Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Tue, 14 Apr 2026 11:54:35 +0100 Subject: [PATCH 3/7] =?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/migrate-iconbutton-css-modules.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .changeset/migrate-iconbutton-css-modules.md diff --git a/.changeset/migrate-iconbutton-css-modules.md b/.changeset/migrate-iconbutton-css-modules.md new file mode 100644 index 000000000..e0395c75b --- /dev/null +++ b/.changeset/migrate-iconbutton-css-modules.md @@ -0,0 +1,12 @@ +--- +'@clickhouse/click-ui': minor +--- + +The `IconButton` component has been migrated from Styled Components to CSS Modules (Web Standards + BEM class name convention). This change is part of our ongoing effort to modernize the component library. + +**Changes (non-breaking):** +- Migrated from `styled-components` to CSS Modules (`IconButton.module.css`) +- Using BEM naming convention (`.icon-button`, `.icon-button_primary`, `.icon-button_sm`, etc.) +- Maintained full API compatibility - no breaking changes +- All variants (primary, secondary, ghost, danger, info) and sizes (default, sm, xs) preserved +- Interactive states (hover, focus, active) maintained with CSS pseudo-classes From dcb96907adfcd6b0ff0b6b5a8828b5a7ec2bb090 Mon Sep 17 00:00:00 2001 From: Helder Oliveira Date: Tue, 14 Apr 2026 12:33:21 +0100 Subject: [PATCH 4/7] =?UTF-8?q?test(IconButton):=20=F0=9F=92=8D=20simplify?= =?UTF-8?q?=20assertion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .storybook/main.ts | 29 +- .../IconButton/IconButton.module.css | 44 +- src/components/IconButton/IconButton.tsx | 3 +- yarn.lock | 3033 +++++++---------- 4 files changed, 1267 insertions(+), 1842 deletions(-) diff --git a/.storybook/main.ts b/.storybook/main.ts index 3af48cc27..d4b30bb34 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -1,24 +1,26 @@ -import type { StorybookConfig } from "@storybook/react-vite"; +import type { StorybookConfig } from '@storybook/react-vite'; const config: StorybookConfig = { core: { - disableTelemetry: true + disableTelemetry: true, }, - stories: [ - "./Introduction.mdx", - "../src/**/*.stories.@(ts|tsx)", - ], + stories: ['./Introduction.mdx', '../src/**/*.stories.@(ts|tsx)'], - addons: ["@storybook/addon-links", //"@storybook/addon-interactions", - "storybook-addon-pseudo-states", "@storybook/addon-a11y", "@storybook/addon-docs"], + addons: [ + '@storybook/addon-links', + //"@storybook/addon-interactions", + 'storybook-addon-pseudo-states', + '@storybook/addon-a11y', + '@storybook/addon-docs', + ], framework: { - name: "@storybook/react-vite", + name: '@storybook/react-vite', options: {}, }, - staticDirs: ["../public"], + staticDirs: ['../public'], typescript: { - reactDocgen: "react-docgen-typescript", + reactDocgen: 'react-docgen-typescript', reactDocgenTypescriptOptions: { compilerOptions: { allowSyntheticDefaultImports: false, @@ -32,8 +34,9 @@ const config: StorybookConfig = { }, async viteFinal(config, { configType }) { - config.plugins = (config.plugins || []).filter((plugin) => { - const pluginName = plugin && typeof plugin === 'object' && 'name' in plugin ? plugin.name : null; + config.plugins = (config.plugins || []).filter(plugin => { + const pluginName = + plugin && typeof plugin === 'object' && 'name' in plugin ? plugin.name : null; return pluginName !== 'css-external'; }); config.plugins.push({ diff --git a/src/components/IconButton/IconButton.module.css b/src/components/IconButton/IconButton.module.css index c98f5c2fe..b671fce9e 100644 --- a/src/components/IconButton/IconButton.module.css +++ b/src/components/IconButton/IconButton.module.css @@ -1,26 +1,23 @@ .icon-button { display: inline-flex; position: relative; + padding: var(--click-button-icon-button-default-space-y) var(--click-button-icon-button-default-space-x); overflow: hidden; flex-shrink: 0; justify-content: center; align-items: center; - border: var(--click-button-stroke) solid transparent; + border: none; border-radius: var(--click-button-icon-button-radii-all); background: transparent; color: inherit; cursor: pointer; + transition: var(--click-transition-default); } .icon-button:disabled { cursor: not-allowed; } -/* Default Size (base styles) */ -.icon-button { - padding: var(--click-button-icon-button-default-space-y) var(--click-button-icon-button-default-space-x); -} - /* Small Size Modifier */ .icon-button_sm { padding: var(--click-button-icon-button-sm-space-y) var(--click-button-icon-button-sm-space-x); @@ -33,26 +30,21 @@ /* Primary Type */ .icon-button_primary { - border-color: var(--click-button-icon-button-color-primary-stroke-default); background-color: var(--click-button-icon-button-color-primary-background-default); color: var(--click-button-icon-button-color-primary-text-default); } .icon-button_primary:disabled { - border-color: var(--click-button-icon-button-color-disabled-stroke-default); background-color: var(--click-button-icon-button-color-disabled-background-default); color: var(--click-button-icon-button-color-disabled-text-default); } .icon-button_primary:hover:not(:disabled) { - border-color: var(--click-button-icon-button-color-primary-stroke-hover); background-color: var(--click-button-icon-button-color-primary-background-hover); color: var(--click-button-icon-button-color-primary-text-hover); - transition: var(--click-transition-default); } .icon-button_primary:focus-visible:not(:disabled) { - border-color: var(--click-button-icon-button-color-primary-stroke-active); background-color: var(--click-button-icon-button-color-primary-background-active); color: var(--click-button-icon-button-color-primary-text-active); outline: 2px solid var(--click-button-icon-button-color-primary-stroke-active); @@ -61,34 +53,29 @@ .icon-button_primary:active:not(:disabled), .icon-button_primary:focus:not(:focus-visible, :disabled) { - border-color: var(--click-button-icon-button-color-primary-stroke-active); background-color: var(--click-button-icon-button-color-primary-background-active); color: var(--click-button-icon-button-color-primary-text-active); + /* suppress mouse-click focus ring; keyboard focus handled by :focus-visible */ outline: none; } /* Secondary Type */ .icon-button_secondary { - border-color: var(--click-button-icon-button-color-secondary-stroke-default); background-color: var(--click-button-icon-button-color-secondary-background-default); color: var(--click-button-icon-button-color-secondary-text-default); } .icon-button_secondary:disabled { - border-color: var(--click-button-icon-button-color-disabled-stroke-default); background-color: var(--click-button-icon-button-color-disabled-background-default); color: var(--click-button-icon-button-color-disabled-text-default); } .icon-button_secondary:hover:not(:disabled) { - border-color: var(--click-button-icon-button-color-secondary-stroke-hover); background-color: var(--click-button-icon-button-color-secondary-background-hover); color: var(--click-button-icon-button-color-secondary-text-hover); - transition: var(--click-transition-default); } .icon-button_secondary:focus-visible:not(:disabled) { - border-color: var(--click-button-icon-button-color-secondary-stroke-active); background-color: var(--click-button-icon-button-color-secondary-background-active); color: var(--click-button-icon-button-color-secondary-text-active); outline: 2px solid var(--click-button-icon-button-color-secondary-stroke-active); @@ -97,34 +84,29 @@ .icon-button_secondary:active:not(:disabled), .icon-button_secondary:focus:not(:focus-visible, :disabled) { - border-color: var(--click-button-icon-button-color-secondary-stroke-active); background-color: var(--click-button-icon-button-color-secondary-background-active); color: var(--click-button-icon-button-color-secondary-text-active); + /* suppress mouse-click focus ring; keyboard focus handled by :focus-visible */ outline: none; } /* Ghost Type */ .icon-button_ghost { - border-color: var(--click-button-icon-button-color-ghost-stroke-default); background-color: var(--click-button-icon-button-color-ghost-background-default); color: var(--click-button-icon-button-color-ghost-text-default); } .icon-button_ghost:disabled { - border-color: var(--click-button-icon-button-color-disabled-stroke-default); background-color: var(--click-button-icon-button-color-disabled-background-default); color: var(--click-button-icon-button-color-disabled-text-default); } .icon-button_ghost:hover:not(:disabled) { - border-color: var(--click-button-icon-button-color-ghost-stroke-hover); background-color: var(--click-button-icon-button-color-ghost-background-hover); color: var(--click-button-icon-button-color-ghost-text-hover); - transition: var(--click-transition-default); } .icon-button_ghost:focus-visible:not(:disabled) { - border-color: var(--click-button-icon-button-color-ghost-stroke-active); background-color: var(--click-button-icon-button-color-ghost-background-active); color: var(--click-button-icon-button-color-ghost-text-active); outline: 2px solid var(--click-button-icon-button-color-ghost-stroke-active); @@ -133,34 +115,29 @@ .icon-button_ghost:active:not(:disabled), .icon-button_ghost:focus:not(:focus-visible, :disabled) { - border-color: var(--click-button-icon-button-color-ghost-stroke-active); background-color: var(--click-button-icon-button-color-ghost-background-active); color: var(--click-button-icon-button-color-ghost-text-active); + /* suppress mouse-click focus ring; keyboard focus handled by :focus-visible */ outline: none; } /* Danger Type */ .icon-button_danger { - border-color: var(--click-button-icon-button-color-danger-stroke-default); background-color: var(--click-button-icon-button-color-danger-background-default); color: var(--click-button-icon-button-color-danger-text-default); } .icon-button_danger:disabled { - border-color: var(--click-button-icon-button-color-disabled-stroke-default); background-color: var(--click-button-icon-button-color-disabled-background-default); color: var(--click-button-icon-button-color-disabled-text-default); } .icon-button_danger:hover:not(:disabled) { - border-color: var(--click-button-icon-button-color-danger-stroke-hover); background-color: var(--click-button-icon-button-color-danger-background-hover); color: var(--click-button-icon-button-color-danger-text-hover); - transition: var(--click-transition-default); } .icon-button_danger:focus-visible:not(:disabled) { - border-color: var(--click-button-icon-button-color-danger-stroke-active); background-color: var(--click-button-icon-button-color-danger-background-active); color: var(--click-button-icon-button-color-danger-text-active); outline: 2px solid var(--click-button-icon-button-color-danger-stroke-active); @@ -169,34 +146,29 @@ .icon-button_danger:active:not(:disabled), .icon-button_danger:focus:not(:focus-visible, :disabled) { - border-color: var(--click-button-icon-button-color-danger-stroke-active); background-color: var(--click-button-icon-button-color-danger-background-active); color: var(--click-button-icon-button-color-danger-text-active); + /* suppress mouse-click focus ring; keyboard focus handled by :focus-visible */ outline: none; } /* Info Type */ .icon-button_info { - border-color: var(--click-button-icon-button-color-info-stroke-default); background-color: var(--click-button-icon-button-color-info-background-default); color: var(--click-button-icon-button-color-info-text-default); } .icon-button_info:disabled { - border-color: var(--click-button-icon-button-color-disabled-stroke-default); background-color: var(--click-button-icon-button-color-disabled-background-default); color: var(--click-button-icon-button-color-disabled-text-default); } .icon-button_info:hover:not(:disabled) { - border-color: var(--click-button-icon-button-color-info-stroke-hover); background-color: var(--click-button-icon-button-color-info-background-hover); color: var(--click-button-icon-button-color-info-text-hover); - transition: var(--click-transition-default); } .icon-button_info:focus-visible:not(:disabled) { - border-color: var(--click-button-icon-button-color-info-stroke-active); background-color: var(--click-button-icon-button-color-info-background-active); color: var(--click-button-icon-button-color-info-text-active); outline: 2px solid var(--click-button-icon-button-color-info-stroke-active); @@ -205,9 +177,9 @@ .icon-button_info:active:not(:disabled), .icon-button_info:focus:not(:focus-visible, :disabled) { - border-color: var(--click-button-icon-button-color-info-stroke-active); background-color: var(--click-button-icon-button-color-info-background-active); color: var(--click-button-icon-button-color-info-text-active); + /* suppress mouse-click focus ring; keyboard focus handled by :focus-visible */ outline: none; } diff --git a/src/components/IconButton/IconButton.tsx b/src/components/IconButton/IconButton.tsx index 44ea3dac4..bb00f3bcf 100644 --- a/src/components/IconButton/IconButton.tsx +++ b/src/components/IconButton/IconButton.tsx @@ -31,11 +31,12 @@ export const IconButton = forwardRef( return (