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:
committed by
Bianca Widstam
parent
2197ab2137
commit
3f632e6031
@@ -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 }) => {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
39
packages/design-system/lib/components/IconButton/types.ts
Normal file
39
packages/design-system/lib/components/IconButton/types.ts
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user