Skip to content

Commit

Permalink
tech: Add IconButton component (#4706)
Browse files Browse the repository at this point in the history
<!--
PR title: tech/ Add IconButton component
-->

## Describe your changes
Small wrapper around the `Button` component for icon only buttons similar to the one we have in Hope.

<!--
What changes are made?
If there are many changes, a list might be a good format.
If it makes sense, add screenshots and/or screen recordings here.
-->

## Justify why they are needed
Reuse styles needed for icon buttons.

## Checklist before requesting a review

- [x] I have performed a self-review of my code
  • Loading branch information
Youakeem authored Sep 19, 2024
1 parent 8859dd3 commit 1decb8c
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 3 deletions.
12 changes: 12 additions & 0 deletions packages/ui/src/components/Button/Button.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,13 +197,18 @@ const SIZE_STYLES = {
textAlign: 'center',
borderRadius: tokens.radius.md,
},
icon: {
borderRadius: tokens.radius.xxs,
padding: tokens.space.xxxs,
},
} as const

export const buttonSizeStyles = {
base: {
small: style(SIZE_STYLES.small),
medium: style(SIZE_STYLES.medium),
large: style(SIZE_STYLES.large),
icon: style(SIZE_STYLES.icon),
},
lg: {
small: style({
Expand All @@ -221,9 +226,16 @@ export const buttonSizeStyles = {
[minWidth.lg]: SIZE_STYLES.large,
},
}),
icon: style({
'@media': {
[minWidth.lg]: SIZE_STYLES.icon,
},
}),
},
}

export const iconButtonStyles = style({ aspectRatio: '1', height: 'auto' })

export const childrenWrapper = style({
display: 'flex',
alignItems: 'center',
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/src/components/Button/Button.helpers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { buttonSizeStyles } from './Button.css'

type ButtonSizeVariant = 'small' | 'medium' | 'large'
type ButtonSizeVariant = 'small' | 'medium' | 'large' | 'icon'
type ButtonLevels = 'base' | 'lg'

export type ButtonSize = ButtonSizeVariant | Record<ButtonLevels, ButtonSizeVariant>
Expand Down
14 changes: 12 additions & 2 deletions packages/ui/src/components/Button/Button.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import type { Meta, StoryFn } from '@storybook/react'
import { CheckIcon, yStack } from 'ui'
import { type ComponentProps } from 'react'
import { CheckIcon, CrossIcon, yStack } from 'ui'
import { Button } from './Button'
import { IconButton } from './IconButton'

type Controls = typeof Button
type Controls = ComponentProps<typeof Button>

const meta: Meta<Controls> = {
title: 'Button',
Expand Down Expand Up @@ -109,3 +111,11 @@ export const WithIcon = {
Icon: <CheckIcon size="18px" />,
},
}

export const IconButtonDefault = {
render: (args: Controls) => <IconButton variant={args.variant}>{args.Icon}</IconButton>,
args: {
Icon: <CrossIcon size="18px" />,
variant: 'primary',
},
}
21 changes: 21 additions & 0 deletions packages/ui/src/components/Button/IconButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import clsx from 'clsx'
import { type ComponentProps, forwardRef } from 'react'
import { Button } from './Button'
import { iconButtonStyles } from './Button.css'

type ButtonProps = ComponentProps<typeof Button<'button'>>

export const IconButton = forwardRef<HTMLButtonElement, ButtonProps>(
({ className, children, ...props }, forwardedRef) => (
<Button
className={clsx(iconButtonStyles, className)}
variant="ghost"
size="icon"
Icon={children}
{...props}
ref={forwardedRef}
/>
),
)

IconButton.displayName = 'IconButton'
2 changes: 2 additions & 0 deletions packages/ui/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ export { HedvigLogo } from './components/HedvigLogo/HedvigLogo'
export { HedvigSymbol } from './components/HedvigSymbol/HedvigSymbol'
export { Space } from './components/Space'
export { Button, type ButtonProps } from './components/Button/Button'
export { IconButton } from './components/Button/IconButton'

export { InputBase } from './components/InputBase'
export type { InputBaseProps } from './components/InputBase'
export { Heading } from './components/Heading/Heading'
Expand Down

0 comments on commit 1decb8c

Please sign in to comment.