Merged in fix/BOOK-293-button-variants (pull request #3371)

fix(BOOK-293): changed variants and props on IconButton component

* fix(BOOK-293): changed variants and props on IconButton component

* fix(BOOK-293): inherit color for icon


Approved-by: Bianca Widstam
Approved-by: Christel Westerberg
This commit is contained in:
Erik Tiekstra
2025-12-19 12:32:52 +00:00
committed by Bianca Widstam
parent 2197ab2137
commit 3f632e6031
169 changed files with 665 additions and 944 deletions

View File

@@ -2,8 +2,8 @@ import type { Meta, StoryObj } from '@storybook/nextjs-vite'
import { expect, fn } from 'storybook/test'
import { MaterialIcon, MaterialIconProps } from '../Icons/MaterialIcon'
import { IconButton } from './IconButton'
import { iconButtonIconNames, IconButtonProps } from './types'
import { config } from './variants'
const meta: Meta<typeof IconButton> = {
@@ -12,13 +12,10 @@ const meta: Meta<typeof IconButton> = {
argTypes: {
onPress: {
table: {
disable: true,
},
},
children: {
table: {
disable: true,
type: { summary: 'function' },
defaultValue: { summary: 'undefined' },
},
description: 'Callback function to handle button press events.',
},
variant: {
control: 'select',
@@ -58,43 +55,25 @@ const meta: Meta<typeof IconButton> = {
},
},
},
iconName: {
control: 'select',
options: iconButtonIconNames,
table: {
type: { summary: iconButtonIconNames.join(' | ') },
defaultValue: { summary: 'undefined' },
},
description: 'Name of the Material Icon to use as icon.',
},
isDisabled: {
control: 'boolean',
table: {
type: { summary: 'boolean' },
defaultValue: { summary: 'false' },
},
},
},
}
const buttonAndIconSizesMap = Object.keys(config.variants.size).map<{
size: keyof typeof config.variants.size
iconSize: number
}>((key) => {
const typedKey = key as keyof typeof config.variants.size
switch (typedKey) {
case 'sm':
return {
size: typedKey,
iconSize: 16,
}
case 'md':
return {
size: typedKey,
iconSize: 20,
}
case 'lg':
return {
size: typedKey,
iconSize: 24,
}
case 'xl':
return {
size: typedKey,
iconSize: 28,
}
default:
return {
size: typedKey,
iconSize: 24,
}
}
})
const globalStoryPropsInverted = {
backgrounds: { value: 'scandicPrimaryDark' },
}
@@ -104,11 +83,11 @@ type Story = StoryObj<typeof IconButton>
function renderAllSizesFn(
args: Story['args'],
iconName: MaterialIconProps['icon'] = 'search'
iconName: IconButtonProps['iconName'] = 'search'
) {
return (
<div style={{ display: 'flex', gap: '16px', alignItems: 'center' }}>
{buttonAndIconSizesMap.map(({ size, iconSize }) => (
{Object.keys(config.variants.size).map((size) => (
<div
style={{
display: 'flex',
@@ -118,13 +97,12 @@ function renderAllSizesFn(
}}
key={size}
>
<IconButton {...args} size={size} key={size}>
<MaterialIcon
icon={iconName}
size={iconSize}
color="CurrentColor"
/>
</IconButton>
<IconButton
{...args}
iconName={iconName}
size={size as keyof typeof config.variants.size}
key={size}
/>
<span>{size}</span>
</div>
))}
@@ -135,7 +113,7 @@ function renderAllSizesFn(
export const Default: Story = {
args: {
onPress: fn(),
children: <MaterialIcon icon="search" size={24} color="CurrentColor" />,
iconName: 'search',
},
play: async ({ canvas, userEvent, args }) => {
await userEvent.click(canvas.getByRole('button'))
@@ -283,6 +261,7 @@ export const Examples: Story = {
)
},
}
export const Filled: Story = {
args: {
...Default.args,
@@ -319,9 +298,7 @@ export const FilledOnDarkBackground: Story = {
export const FilledWithEmphasis: Story = {
args: {
...Filled.args,
children: (
<MaterialIcon icon="arrow_forward" size={24} color="CurrentColor" />
),
iconName: 'arrow_forward',
emphasis: true,
},
play: async ({ canvas, userEvent, args }) => {
@@ -344,9 +321,7 @@ export const FilledWithEmphasisDisabled: Story = {
export const Outlined: Story = {
args: {
...Default.args,
children: (
<MaterialIcon icon="arrow_forward" size={24} color="CurrentColor" />
),
iconName: 'arrow_forward',
variant: 'Outlined',
},
play: async ({ canvas, userEvent, args }) => {
@@ -369,9 +344,7 @@ export const OutlinedDisabled: Story = {
export const Elevated: Story = {
args: {
...Default.args,
children: (
<MaterialIcon icon="arrow_forward" size={24} color="CurrentColor" />
),
iconName: 'arrow_forward',
variant: 'Elevated',
},
play: async ({ canvas, userEvent, args }) => {
@@ -395,9 +368,7 @@ export const Faded: Story = {
globals: globalStoryPropsInverted,
args: {
...Default.args,
children: (
<MaterialIcon icon="arrow_forward" size={24} color="CurrentColor" />
),
iconName: 'arrow_forward',
variant: 'Faded',
},
play: async ({ canvas, userEvent, args }) => {
@@ -422,9 +393,7 @@ export const Muted: Story = {
globals: globalStoryPropsInverted,
args: {
...Default.args,
children: (
<MaterialIcon icon="arrow_forward" size={24} color="CurrentColor" />
),
iconName: 'arrow_forward',
variant: 'Muted',
},
play: async ({ canvas, userEvent, args }) => {

View File

@@ -1,16 +1,14 @@
import { Button as ButtonRAC } from 'react-aria-components'
import { VariantProps } from 'class-variance-authority'
import { ComponentProps } from 'react'
import { MaterialIcon } from '../Icons/MaterialIcon'
import { IconButtonProps } from './types'
import { variants } from './variants'
interface IconButtonProps
extends ComponentProps<typeof ButtonRAC>, VariantProps<typeof variants> {}
export function IconButton({
variant,
emphasis,
size,
iconName,
className,
...props
}: IconButtonProps) {
@@ -21,5 +19,27 @@ export function IconButton({
className,
})
return <ButtonRAC {...props} className={classNames} />
return (
<ButtonRAC {...props} className={classNames}>
<MaterialIcon
icon={iconName}
size={getIconSize(size)}
color="CurrentColor"
/>
</ButtonRAC>
)
}
function getIconSize(size: IconButtonProps['size']) {
switch (size) {
case 'sm':
return 16
case 'md':
return 20
case 'xl':
return 28
case 'lg':
default:
return 24
}
}

View File

@@ -73,7 +73,7 @@
&.emphasis {
background-color: var(--Component-Button-Brand-Tertiary-Fill-Default);
color: var(--Component-Button-Brand-Tertiary-On-fill-Default);
color: inherit;
&[data-disabled] {
background-color: var(--Component-Button-Brand-Tertiary-Fill-Disabled);
@@ -231,7 +231,7 @@
}
&.emphasis {
color: var(--Component-Button-Muted-On-fill-Default);
color: inherit;
&[data-disabled] {
background-color: var(--Component-Button-Muted-Fill-Disabled-inverted);

View File

@@ -0,0 +1,39 @@
import { Button as ButtonRAC } from 'react-aria-components'
import type { VariantProps } from 'class-variance-authority'
import type { ComponentProps } from 'react'
import type { SymbolCodepoints } from '../Icons/MaterialIcon/MaterialSymbol/types'
import type { variants } from './variants'
export const iconButtonIconNames = [
'arrow_forward',
'arrow_back',
'remove',
'close',
'add',
'search',
'info_circle',
'help_circle',
'info',
'delete',
'visibility',
'visibility_off',
'keyboard_arrow_down',
'keyboard_arrow_up',
'cancel',
'chevron_left',
'chevron_right',
] as const
export type IconButtonIconName = Extract<
SymbolCodepoints,
(typeof iconButtonIconNames)[number]
>
export interface IconButtonProps
extends
Omit<ComponentProps<typeof ButtonRAC>, 'children'>,
VariantProps<typeof variants> {
iconName: IconButtonIconName
}