From 64b00156812f8204566ca662b4d4c92c570b920d Mon Sep 17 00:00:00 2001 From: Danilo Alves <138066684+danilo-moreira-brisa@users.noreply.github.com> Date: Mon, 8 Apr 2024 15:08:15 -0300 Subject: [PATCH] refactor: ion button (#124) Co-authored-by: Iury Nogueira --- .codeclimate.yml | 6 + src/components/alert/alert.tsx | 8 +- .../button/__snapshots__/button.test.tsx.snap | 245 +++++++++ src/components/button/button.test.tsx | 81 ++- src/components/button/button.tsx | 46 +- src/components/button/styles.ts | 481 +++++++----------- src/components/icons/icons.tsx | 3 +- src/components/utils/test-utils.tsx | 6 + src/stitches.config.ts | 1 - src/stories/button/button.stories.tsx | 34 +- 10 files changed, 538 insertions(+), 373 deletions(-) create mode 100644 .codeclimate.yml create mode 100644 src/components/button/__snapshots__/button.test.tsx.snap create mode 100644 src/components/utils/test-utils.tsx diff --git a/.codeclimate.yml b/.codeclimate.yml new file mode 100644 index 0000000..1bd4d7b --- /dev/null +++ b/.codeclimate.yml @@ -0,0 +1,6 @@ +version: "2" +checks: + similar-code: + enabled: false +exclude_patterns: + - "**/styles.ts" diff --git a/src/components/alert/alert.tsx b/src/components/alert/alert.tsx index cebaf27..d556d55 100644 --- a/src/components/alert/alert.tsx +++ b/src/components/alert/alert.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import { useState } from 'react'; import { StatusType } from '../../core/types/status'; import ErrorBoundary from '../error/error-boundary'; @@ -40,7 +40,7 @@ export const IonAlert = ({ const icon = getIcon(type); if (!isValidLabel(message)) { - return ; + return ; } if (!showAlert) { @@ -49,7 +49,7 @@ export const IonAlert = ({ return ( @@ -57,7 +57,7 @@ export const IonAlert = ({ {message} {closable && (
setShowAlert(false)}> - +
)}
diff --git a/src/components/button/__snapshots__/button.test.tsx.snap b/src/components/button/__snapshots__/button.test.tsx.snap new file mode 100644 index 0000000..0df48e6 --- /dev/null +++ b/src/components/button/__snapshots__/button.test.tsx.snap @@ -0,0 +1,245 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Button Button Sizes should render button with lg size variation 1`] = ` +.c0 { + appearance: none; + font-family: Source Sans Pro,sans-serif; + font-weight: 600; + border-radius: 10px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + gap: 0px; + flex-direction: row; + padding: 8px 20px; + font-size: 1.6rem; + line-height: 2.4rem; + background-color: #0858ce; + color: #fcfcfd; + border: 1px solid #0858ce; +} + +.c0 svg { + fill: #fcfcfd; +} + +.c0:hover, +.c0:focus-visible { + background-color: #146ff5; + border: 1px solid #146ff5; +} + +.c0:active { + background-color: #06439d; + border: 1px solid #06439d; +} + +.c0:disabled { + background-color: #e4e6eb; + color: #aeb2bd; + border: 1px solid #e4e6eb; + cursor: not-allowed; +} + +.c0:disabled svg { + fill: #aeb2bd; +} + +.c0:focus-visible { + outline: 2px solid #146ff5; + outline-offset: 2px; +} + + +`; + +exports[`Button Button Sizes should render button with md size variation 1`] = ` +.c0 { + appearance: none; + font-family: Source Sans Pro,sans-serif; + font-weight: 600; + border-radius: 6px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + gap: 0px; + flex-direction: row; + padding: 6px 16px; + font-size: 1.4rem; + line-height: 2rem; + background-color: #0858ce; + color: #fcfcfd; + border: 1px solid #0858ce; +} + +.c0 svg { + fill: #fcfcfd; +} + +.c0:hover, +.c0:focus-visible { + background-color: #146ff5; + border: 1px solid #146ff5; +} + +.c0:active { + background-color: #06439d; + border: 1px solid #06439d; +} + +.c0:disabled { + background-color: #e4e6eb; + color: #aeb2bd; + border: 1px solid #e4e6eb; + cursor: not-allowed; +} + +.c0:disabled svg { + fill: #aeb2bd; +} + +.c0:focus-visible { + outline: 2px solid #146ff5; + outline-offset: 2px; +} + + +`; + +exports[`Button Button Sizes should render button with sm size variation 1`] = ` +.c0 { + appearance: none; + font-family: Source Sans Pro,sans-serif; + font-weight: 600; + border-radius: 6px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + gap: 0px; + flex-direction: row; + padding: 4px 12px; + font-size: 1.2rem; + line-height: 1.6rem; + background-color: #0858ce; + color: #fcfcfd; + border: 1px solid #0858ce; +} + +.c0 svg { + fill: #fcfcfd; +} + +.c0:hover, +.c0:focus-visible { + background-color: #146ff5; + border: 1px solid #146ff5; +} + +.c0:active { + background-color: #06439d; + border: 1px solid #06439d; +} + +.c0:disabled { + background-color: #e4e6eb; + color: #aeb2bd; + border: 1px solid #e4e6eb; + cursor: not-allowed; +} + +.c0:disabled svg { + fill: #aeb2bd; +} + +.c0:focus-visible { + outline: 2px solid #146ff5; + outline-offset: 2px; +} + + +`; + +exports[`Button Button Sizes should render button with xl size variation 1`] = ` +.c0 { + appearance: none; + font-family: Source Sans Pro,sans-serif; + font-weight: 600; + border-radius: 10px; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + gap: 0px; + flex-direction: row; + padding: 12px 24px; + font-size: 1.6rem; + line-height: 2.4rem; + background-color: #0858ce; + color: #fcfcfd; + border: 1px solid #0858ce; +} + +.c0 svg { + fill: #fcfcfd; +} + +.c0:hover, +.c0:focus-visible { + background-color: #146ff5; + border: 1px solid #146ff5; +} + +.c0:active { + background-color: #06439d; + border: 1px solid #06439d; +} + +.c0:disabled { + background-color: #e4e6eb; + color: #aeb2bd; + border: 1px solid #e4e6eb; + cursor: not-allowed; +} + +.c0:disabled svg { + fill: #aeb2bd; +} + +.c0:focus-visible { + outline: 2px solid #146ff5; + outline-offset: 2px; +} + + +`; diff --git a/src/components/button/button.test.tsx b/src/components/button/button.test.tsx index 494b829..73d037e 100644 --- a/src/components/button/button.test.tsx +++ b/src/components/button/button.test.tsx @@ -1,18 +1,19 @@ -import React from 'react'; -import { render, screen } from '@testing-library/react'; +import theme from '@ion/styles/theme'; +import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; - -import { IonButton, ButtonProps } from './button'; +import 'jest-styled-components'; +import { renderWithTheme } from '../utils/test-utils'; +import { ButtonProps, ButtonSizes, ButtonVariants, IonButton } from './button'; +import { variantsColors } from './styles'; const clickEvent = jest.fn(); const defaultButton: ButtonProps = { label: 'Button', - handleClick: clickEvent, + onClick: clickEvent, }; -function sut(props: ButtonProps = defaultButton) { - render(); -} +const sut = (props: ButtonProps = defaultButton) => + renderWithTheme(); const getButton = () => { return screen.getByTestId('ion-button'); @@ -23,7 +24,7 @@ describe('Button', () => { it('should render the Button component', () => { const label = 'Hello world!'; sut({ ...defaultButton, label: label }); - expect(screen.getByText(label)).toBeInTheDocument(); + expect(screen.getByRole('button', { name: label })).toBeInTheDocument(); }); it('should execute user event when the button is clicked', async () => { @@ -34,7 +35,7 @@ describe('Button', () => { it('should be disabled', () => { sut({ ...defaultButton, disabled: true }); - expect(getButton()).toHaveAttribute('disabled'); + expect(getButton()).toBeDisabled(); }); afterEach(() => { @@ -43,35 +44,56 @@ describe('Button', () => { }); describe('Button Types', () => { - const buttonTypes: Array = [ + const buttonTypes: ButtonVariants[] = [ 'primary', 'secondary', 'ghost', 'dashed', ]; - it.each(buttonTypes)('should render button with %s style type', (type) => { - sut({ ...defaultButton, type: type }); - const { className } = getButton(); - expect(className).toContain(`type-${type}`); + it.each(buttonTypes)('should render button with %s styles', (type) => { + const colors = variantsColors(theme, type); + sut({ ...defaultButton, variant: type }); + expect(getButton()).toHaveStyleRule( + 'background-color', + colors.default.background + ); + expect(getButton()).toHaveStyleRule('color', colors.default.color); }); - it.each(buttonTypes)('should render %s danger button', (type) => { - sut({ ...defaultButton, type: type, danger: true }); - const { className } = getButton(); - expect(className).toContain('danger-true'); - expect(className).toContain(`type-${type}`); - }); + it.each(buttonTypes)( + 'should render %s button with danger styles', + (type) => { + const colors = variantsColors(theme, type, true); + sut({ ...defaultButton, variant: type, danger: true }); + expect(getButton()).toHaveStyleRule( + 'background-color', + colors.default.background + ); + expect(getButton()).toHaveStyleRule('color', colors.default.color); + } + ); }); describe('Button Sizes', () => { - const buttonSizes: Array = ['sm', 'md', 'lg', 'xl']; + const buttonSizes: ButtonSizes[] = ['sm', 'md', 'lg', 'xl']; it.each(buttonSizes)( 'should render button with %s size variation', (size) => { sut({ ...defaultButton, size: size }); - expect(getButton().className).toContain(`size-${size}`); + expect(getButton()).toMatchSnapshot(); + } + ); + + it.each<{ borderRadius: string; size: ButtonSizes }>([ + { borderRadius: '6px', size: 'md' }, + { borderRadius: '10px', size: 'lg' }, + ])( + 'should render borderRadius as $borderRadius for button with size $size', + ({ borderRadius, size }) => { + sut({ ...defaultButton, size }); + expect(getButton()).toHaveStyleRule('border-radius', borderRadius); } ); }); @@ -103,15 +125,18 @@ describe('Button', () => { it('should render icon in right side', () => { const icon = 'alert'; sut({ ...defaultButton, icon: icon, iconOnRight: true }); - expect(getButton().className).toContain('iconOnRight-true'); + expect(screen.getByRole('button')).toHaveStyleRule( + 'flex-direction', + 'row-reverse' + ); }); it('should render icon in left by default', () => { sut({ ...defaultButton, icon: 'alert' }); - const buttonContainer = screen.getByTestId('ion-button-container'); - const ContainerFirstChild = buttonContainer.children.item(0); - - expect(ContainerFirstChild?.tagName).toBe('svg'); + expect(screen.getByRole('button')).toHaveStyleRule( + 'flex-direction', + 'row' + ); }); }); }); diff --git a/src/components/button/button.tsx b/src/components/button/button.tsx index 02aeeaf..fc22d26 100644 --- a/src/components/button/button.tsx +++ b/src/components/button/button.tsx @@ -1,33 +1,30 @@ -import React from 'react'; -import { IonIcon } from '../icons/icons'; +import { ButtonHTMLAttributes } from 'react'; import { SizeType } from '../../core/types/size'; +import { IonIcon } from '../icons'; import { iconType } from '../icons/svgs/icons'; -import { ButtonStyles } from './styles'; +import { Button } from './styles'; -type StitchesButtonProps = React.ComponentProps; +export type ButtonSizes = Exclude | 'xl'; -type ButtonSizes = Exclude | 'xl'; +export type ButtonVariants = 'primary' | 'secondary' | 'ghost' | 'dashed'; export type ButtonProps = { label: string; - type?: string; - disabled?: boolean; - handleClick?: () => void; + variant?: ButtonVariants; danger?: boolean; size?: ButtonSizes; icon?: iconType; iconOnRight?: boolean; -} & StitchesButtonProps; +} & ButtonHTMLAttributes; export const IonButton = ({ - type = 'primary', - disabled = false, + variant = 'primary', danger = false, size = 'md', icon, iconOnRight, label, - handleClick, + ...props }: ButtonProps) => { const iconSize = { sm: 16, @@ -37,20 +34,17 @@ export const IonButton = ({ }; return ( - -
- {icon && } - {label} -
-
+ {icon && } + {label} + ); }; diff --git a/src/components/button/styles.ts b/src/components/button/styles.ts index 9253e4e..4044ee9 100644 --- a/src/components/button/styles.ts +++ b/src/components/button/styles.ts @@ -1,323 +1,204 @@ -import stitches from '../../stitches.config'; -import { spacing } from '../utils/spacing'; +import styled, { RuleSet, css } from 'styled-components'; +import { DefaultTheme } from 'styled-components/dist/types'; +import { ButtonProps, ButtonSizes, ButtonVariants } from './button'; -const { styled } = stitches; +type ButtonStylesProps = { + $variant?: ButtonProps['variant']; + $danger?: ButtonProps['danger']; + $size?: ButtonProps['size']; + $hasIcon?: boolean; + $iconOnRight?: ButtonProps['iconOnRight']; +}; -export const ButtonStyles = styled('button', { - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - borderRadius: '8px', - fontWeight: '600', - cursor: 'pointer', - gap: '8px', +type ColorByState = { + background: string; + color?: string; + border?: string; +}; - variants: { - type: { - primary: { - background: '$primaryColor', - color: '$neutral1', - svg: { - fill: '$neutral1', - }, +type ColorDefinitions = { + default: ColorByState; + hover: ColorByState; + active: ColorByState; + disabled: ColorByState; +}; - '&:hover': { background: '$primary5' }, - '&:active': { background: '$primary7' }, - '&:disabled': { - background: '$neutral2', - color: '$neutral5', - cursor: 'not-allowed', - svg: { - fill: '$neutral5', - }, - }, - }, - secondary: { - background: '$neutral1', - color: '$primaryColor', - border: '1px solid $neutral4', - svg: { - fill: '$primaryColor', - }, +const sizes: (theme: DefaultTheme) => Record> = ({ + font, +}) => { + return { + sm: css` + padding: 4px 12px; + ${font.size[12]} + `, + md: css` + padding: 6px 16px; + ${font.size[14]} + `, + lg: css` + padding: 8px 20px; + ${font.size[16]} + `, + xl: css` + padding: 12px 24px; + ${font.size[16]} + `, + }; +}; - '&:hover': { - background: '$primary1', - color: '$primary5', - border: '1px solid $primary4', - svg: { - fill: '$primary5', - }, - }, - '&:active': { - background: '$primary2', - color: '$primary5', - border: '1px solid $primary7', - svg: { - fill: '$primary5', - }, - }, - '&:disabled': { - background: '$neutral2 ', - color: '$neutral5 ', - border: '1px solid $neutral5 ', - cursor: 'not-allowed', - svg: { - fill: '$neutral5', - }, - }, - }, - ghost: { - background: 'transparent', - color: '$primaryColor', - svg: { - fill: '$primaryColor', - }, +export const variantsColors: ( + theme: DefaultTheme, + variant: ButtonVariants, + danger?: boolean +) => ColorDefinitions = ({ colors }, variant, danger) => { + const type = danger ? 'negative' : 'primary'; - '&:hover': { - background: '$primary1', - color: '$primary5', - svg: { - fill: '$primary5', - }, - }, - '&:active': { - background: '$primary2', - color: '$primary7', - svg: { - fill: '$primary7', - }, - }, - '&:disabled': { - background: 'transparent', - color: '$neutral5', - cursor: 'not-allowed', - svg: { - fill: '$neutral5', - }, - }, + return { + primary: { + default: { + background: colors.main[type], + color: colors.neutral[1], }, - dashed: { - background: 'transparent', - color: '$primary7', - border: '1px dashed $neutral4', - svg: { - fill: '$primary7', - }, - - '&:hover': { - background: '$primary1', - color: '$primary5', - border: '1px dashed $primary4', - svg: { - fill: '$primary5', - }, - }, - '&:active': { - background: '$primary2', - color: '$primary7', - border: '1px dashed $primary5', - svg: { - fill: '$primary7', - }, - }, - '&:disabled': { - background: '$neutral3', - color: '$neutral5', - border: '1px dashed $neutral5', - cursor: 'not-allowed', - svg: { - fill: '$neutral5', - }, - }, + hover: { + background: colors[type][5], }, - }, - - danger: { - true: { - background: 'transparent', + active: { + background: colors[type][7], + }, + disabled: { + background: colors.neutral[3], + color: colors.neutral[5], }, }, - - size: { - sm: { - minWidth: '24px', - height: '24px', - padding: '4px 12px', - fontSize: '12px', + secondary: { + default: { + background: colors.neutral[1], + color: colors.main[type], + border: `1px solid ${colors.neutral[4]}`, }, - md: { - minWidth: '32px', - height: '32px', - padding: '6px 16px', - fontSize: '14px', + hover: { + background: colors[type][1], + border: `1px solid ${colors[type][3]}`, + color: colors[type][5], }, - lg: { - minWidth: '40px', - height: '40px', - padding: '8px 20px', - fontSize: '16px', + active: { + background: colors[type][2], + color: colors[type][7], + border: `1px solid ${colors[type][5]}`, }, - xl: { - minWidth: '48px', - height: '48px', - padding: '12px 24px', - fontSize: '16px', + disabled: { + background: colors.neutral[3], + color: colors.neutral[5], + border: `1px solid ${colors.neutral[5]}`, }, }, - - withIcon: { - true: { - div: { - display: 'flex', - alignItems: 'center', - justifyContent: 'space-between', - gap: spacing(1), - }, + ghost: { + default: { + background: 'transparent', + color: colors.main[type], }, - }, - - iconOnRight: { - true: { - div: { - flexDirection: 'row-reverse', - }, + hover: { + background: colors[type][1], + color: colors[type][5], }, - }, - }, - - compoundVariants: [ - { - type: 'primary', - danger: true, - css: { - background: '$negative6', - color: '$negative1', - svg: { - fill: '$negative1', - }, - - '&:hover': { - background: '$negative5', - color: '$neutral1', - svg: { - fill: '$primary1', - }, - }, - '&:active': { - background: '$negative7', - }, - '&:disabled': { - background: '$neutral2', - color: '$neutral5', - cursor: 'not-allowed', - svg: { - fill: '$neutral5', - }, - }, + active: { + background: colors[type][2], + color: colors[type][7], }, - }, - { - type: 'secondary', - danger: true, - css: { - color: '$negativeColor', - svg: { - fill: '$negativeColor', - }, - '&:hover': { - background: '$negative1', - color: '$negative5', - border: '1px solid $negative3', - svg: { - fill: '$negative5', - }, - }, - '&:active': { - background: '$negative2', - color: '$negative7', - border: '1px solid $negative7', - svg: { - fill: '$negative7', - }, - }, - '&:disabled': { - background: '$neutral2 ', - color: '$neutral5 ', - border: '1px solid $neutral5', - cursor: 'not-allowed', - svg: { - fill: '$neutral5', - }, - }, + disabled: { + background: 'transparent', + color: colors.neutral[5], }, }, - { - type: 'ghost', - danger: true, - css: { - color: '$negative6', - svg: { - fill: '$negative6', - }, - '&:hover': { - background: '$negative1', - color: '$negative5', - svg: { - fill: '$negative5', - }, - }, - '&:active': { - background: '$negative2', - color: '$negative7', - svg: { - fill: '$negative7', - }, - }, - '&:disabled': { - background: 'transparent', - color: '$neutral5', - cursor: 'not-allowed', - svg: { - fill: '$neutral5', - }, - }, + dashed: { + default: { + background: colors.neutral[1], + color: colors.main[type], + border: `1px dashed ${colors.neutral[4]}`, }, - }, - { - type: 'dashed', - danger: true, - css: { - border: '1px dashed $neutral4', - color: '$negative6', - svg: { - fill: '$negative6', - }, - '&:hover': { - background: '$negative1', - color: '$negative5', - border: '1px dashed $negative3', - svg: { - fill: '$negative5', - }, - }, - '&:active': { - background: '$negative2', - color: '$negative7', - border: '1px dashed $negative6', - svg: { - fill: '$negative7', - }, - }, - '&:disabled': { - background: '$neutral3', - color: '$neutral5', - border: '1px dashed $neutral5', - cursor: 'not-allowed', - svg: { - fill: '$neutral5', - }, - }, + hover: { + background: colors[type][1], + hoverBorder: `1px dashed ${colors[type][3]}`, + color: colors[type][5], + }, + active: { + background: colors[type][2], + color: colors[type][7], + border: `1px dashed ${colors[type][5]}`, + }, + disabled: { + background: colors.neutral[3], + color: colors.neutral[5], + border: `1px dashed ${colors.neutral[5]}`, }, }, - ], -}); + }[variant]; +}; + +const variants: ( + theme: DefaultTheme, + variant: ButtonVariants, + danger?: boolean +) => RuleSet = (theme, variant, danger) => { + const colorDef = variantsColors(theme, variant, danger); + + return css` + background-color: ${colorDef.default.background}; + color: ${colorDef.default.color}; + border: ${colorDef.default.border || + `1px solid ${colorDef.default.background}`}; + + svg { + fill: ${colorDef.default.color}; + } + + &:hover, + &:focus-visible { + background-color: ${colorDef.hover.background}; + ${colorDef.hover.color && `color: ${colorDef.hover.color}`}; + border: ${colorDef.hover.border || + `1px solid ${colorDef.hover.background}`}; + + ${colorDef.hover.color && `svg { fill: ${colorDef.hover.color} }`} + } + + &:active { + background-color: ${colorDef.active.background}; + ${colorDef.active.color && `color: ${colorDef.active.color}`}; + border: ${colorDef.active.border || + `1px solid ${colorDef.active.background}`}; + + ${colorDef.active.color && `svg { fill: ${colorDef.active.color} }`} + } + + &:disabled { + background-color: ${colorDef.disabled.background}; + color: ${colorDef.disabled.color}; + border: ${colorDef.disabled.border || + `1px solid ${colorDef.disabled.background}`}; + cursor: not-allowed; + + svg { + fill: ${colorDef.disabled.color}; + } + } + `; +}; + +export const Button = styled.button` + ${({ theme, $variant, $danger, $size, $hasIcon, $iconOnRight }) => + css` + appearance: none; + font-family: ${theme.font.family}; + font-weight: 600; + border-radius: ${$size && ['lg', 'xl'].includes($size) ? '10px' : '6px'}; + cursor: pointer; + + ${theme.utils.flex.center($hasIcon ? 8 : 0)}; + flex-direction: ${$iconOnRight ? 'row-reverse' : 'row'}; + + ${!!$size && sizes(theme)[$size]} + ${!!$variant && variants(theme, $variant, $danger)} + ${theme.utils.focus} + `} +`; diff --git a/src/components/icons/icons.tsx b/src/components/icons/icons.tsx index e88e54b..59bd479 100644 --- a/src/components/icons/icons.tsx +++ b/src/components/icons/icons.tsx @@ -1,6 +1,5 @@ import DOMPurify from 'dompurify'; import { iconsPaths, iconType } from './svgs/icons'; -import React from 'react'; export type SvgModule = typeof import('./svgs/icons'); export type IconPaths = keyof typeof iconsPaths; @@ -30,7 +29,7 @@ export const IonIcon = ({ type, color, size = defaultSize }: IonIconProps) => { return ( + render({children}); diff --git a/src/stitches.config.ts b/src/stitches.config.ts index b556043..4bee1a7 100644 --- a/src/stitches.config.ts +++ b/src/stitches.config.ts @@ -116,7 +116,6 @@ const injectGlobalStyles = stitches.globalCss({ boxSizing: 'borderbox', fontFamily: 'Source Sans Pro, sans-serif', border: 'none', - transition: 'all 0.3s', }, '*:after': { boxSizing: 'borderbox', diff --git a/src/stories/button/button.stories.tsx b/src/stories/button/button.stories.tsx index 683c2f8..db74fa8 100644 --- a/src/stories/button/button.stories.tsx +++ b/src/stories/button/button.stories.tsx @@ -1,10 +1,20 @@ -import { ComponentStory, ComponentMeta } from '@storybook/react'; +import { ComponentMeta, ComponentStory } from '@storybook/react'; -import { IonButton, ButtonProps } from '../../components/button/button'; +import { ButtonProps, IonButton } from '../../components/button/button'; export default { - title: 'Ion/Navigation/Buttons', + title: 'Ion/Navigation/Button', component: IonButton, + argTypes: { + danger: { + control: { type: 'boolean' }, + defaultValue: false, + }, + iconOnRight: { + control: { type: 'boolean' }, + defaultValue: false, + }, + }, } as ComponentMeta; const Template: ComponentStory = (args: ButtonProps) => ( @@ -14,59 +24,59 @@ const Template: ComponentStory = (args: ButtonProps) => ( export const ButtonPrimary = Template.bind({}); ButtonPrimary.args = { label: 'Primary', - type: 'primary', + variant: 'primary', }; export const ButtonSecondary = Template.bind({}); ButtonSecondary.args = { label: 'Secondary', - type: 'secondary', + variant: 'secondary', }; export const ButtonGhost = Template.bind({}); ButtonGhost.args = { label: 'Ghost', - type: 'ghost', + variant: 'ghost', }; export const ButtonDashed = Template.bind({}); ButtonDashed.args = { label: 'Dashed', - type: 'dashed', + variant: 'dashed', }; export const PrimaryDisabled = Template.bind({}); PrimaryDisabled.args = { label: 'Primary', - type: 'primary', + variant: 'primary', disabled: true, }; export const PrimaryDanger = Template.bind({}); PrimaryDanger.args = { label: 'Primary', - type: 'primary', + variant: 'primary', danger: true, }; export const PrimarySmall = Template.bind({}); PrimarySmall.args = { label: 'Primary', - type: 'primary', + variant: 'primary', size: 'sm', }; export const WithIcon = Template.bind({}); WithIcon.args = { label: 'Primary', - type: 'primary', + variant: 'primary', icon: 'pencil', }; export const WithRightIcon = Template.bind({}); WithRightIcon.args = { label: 'Primary', - type: 'primary', + variant: 'primary', icon: 'pencil', iconOnRight: true, };