From d59655c3d45f336084dd8bcb11a1e2eb46061cbd Mon Sep 17 00:00:00 2001 From: Dominika Hustinova Date: Mon, 8 Jul 2024 16:51:45 +0200 Subject: [PATCH] chore: replace deprecated addon-knobs with addon-controls --- .../orbit-components/.storybook/preview.tsx | 9 +- .../AirportIllustration.stories.tsx | 77 ++- .../src/Alert/Alert.stories.tsx | 490 ++++++++++-------- .../src/utils/Grid/Grid.stories.tsx | 132 +++-- 4 files changed, 412 insertions(+), 296 deletions(-) diff --git a/packages/orbit-components/.storybook/preview.tsx b/packages/orbit-components/.storybook/preview.tsx index a4d755b84d..22a6687039 100644 --- a/packages/orbit-components/.storybook/preview.tsx +++ b/packages/orbit-components/.storybook/preview.tsx @@ -6,7 +6,7 @@ import { Subtitle, Description, Primary, - // Controls, + Controls, // Story, Stories, // Source, @@ -49,12 +49,9 @@ const preview: Preview = { <Description /> <Subtitle /> - {/* <Story /> */} - {/* <Controls /> */} <Primary /> - {/* <Source /> */} - <Stories /> - {/* <Controls /> */} + <Controls /> + <Stories includePrimary={false} /> </> ), // source: { diff --git a/packages/orbit-components/src/AirportIllustration/AirportIllustration.stories.tsx b/packages/orbit-components/src/AirportIllustration/AirportIllustration.stories.tsx index 7a94666f1b..4ab136690c 100644 --- a/packages/orbit-components/src/AirportIllustration/AirportIllustration.stories.tsx +++ b/packages/orbit-components/src/AirportIllustration/AirportIllustration.stories.tsx @@ -1,36 +1,67 @@ -import React from "react"; -import { select, text } from "@storybook/addon-knobs"; +import type { Meta, StoryObj } from "@storybook/react"; import { NAMES } from "./consts.mts"; import { SIZE_OPTIONS } from "../primitives/IllustrationPrimitive"; import { SPACINGS_AFTER } from "../common/consts"; -import type { Name } from "./types"; import AirportIllustration from "."; -export default { +const meta: Meta<typeof AirportIllustration> = { title: "AirportIllustration", + component: AirportIllustration, + parameters: { + componentSubtitle: "Explore our new set of Airport illustrations for Kiwi.com.", + }, }; -export const Playground = () => { - const size = select("Size", Object.values(SIZE_OPTIONS), SIZE_OPTIONS.MEDIUM); - const name = select("Name", NAMES, "BGYFastTrack") as Name; - const dataTest = text("dataTest", "test"); - const alt = text("alt", "null"); - const spaceAfter = select("spaceAfter", Object.values(SPACINGS_AFTER), SPACINGS_AFTER.SMALL); - return ( - <AirportIllustration - size={size} - name={name} - dataTest={dataTest} - spaceAfter={spaceAfter} - alt={alt} - /> - ); -}; +export default meta; +type Story = StoryObj<typeof AirportIllustration>; -Playground.story = { - parameters: { - info: "Explore our new set of Airportillustrations for Kiwi.com.", +export const Playground: Story = { + args: { + size: SIZE_OPTIONS.MEDIUM, + name: "BGYFastTrack", + dataTest: "test", + alt: "null", + spaceAfter: SPACINGS_AFTER.SMALL, + }, + argTypes: { + size: { + name: "size", + options: Object.values(SIZE_OPTIONS), + control: { + type: "select", + }, + table: { + defaultValue: { summary: "medium" }, + type: { summary: "string" }, + }, + }, + name: { + name: "name", + options: NAMES, + control: { + type: "select", + }, + }, + dataTest: { + name: "dataTest", + control: { + type: "text", + }, + }, + alt: { + name: "alt", + control: { + type: "text", + }, + }, + spaceAfter: { + name: "spaceAfter", + options: Object.values(SPACINGS_AFTER), + control: { + type: "select", + }, + }, }, }; diff --git a/packages/orbit-components/src/Alert/Alert.stories.tsx b/packages/orbit-components/src/Alert/Alert.stories.tsx index 66e9d612fe..7fe30f1db7 100644 --- a/packages/orbit-components/src/Alert/Alert.stories.tsx +++ b/packages/orbit-components/src/Alert/Alert.stories.tsx @@ -1,11 +1,12 @@ import * as React from "react"; import { action } from "@storybook/addon-actions"; -import { text, boolean, select } from "@storybook/addon-knobs"; +// import { text, boolean, select } from "@storybook/addon-knobs"; +import type { Meta, StoryObj } from "@storybook/react"; import * as Icons from "../icons"; import { TYPE_OPTIONS } from "./consts"; import { TYPE_OPTIONS as BUTTON_TYPE_OPTIONS } from "./AlertButton/consts"; -import RenderInRtl from "../utils/rtl/RenderInRtl"; +// import RenderInRtl from "../utils/rtl/RenderInRtl"; import { SPACINGS_AFTER } from "../common/consts"; import List from "../List"; import ListItem from "../List/ListItem"; @@ -17,257 +18,322 @@ import TextLink from "../TextLink"; import Alert, { AlertButton } from "."; -const getIcons = (defaultIcon: string) => select("Icon", ["", ...Object.keys(Icons)], defaultIcon); - const getIcon = (source: string): React.ReactNode => Icons[source]; -export default { - title: "Alert", -}; - -export const Default = () => { - const message = "The quick, brown fox jumps over a lazy dog."; - return <Alert icon title={message} />; +type AlertPropsAndCustomArgs = React.ComponentProps<typeof Alert> & { + message?: string; + button?: string; + Icon?: React.ReactNode; }; -Default.story = { - parameters: { - info: "This is the default configuration of this component. Visit Orbit.Kiwi for more detailed guidelines.", +const meta: Meta<AlertPropsAndCustomArgs> = { + title: "Alert", + component: Alert, + argTypes: { + spaceAfter: { + name: "spaceAfter", + options: Object.values(SPACINGS_AFTER), + control: { + type: "select", + }, + }, + type: { + name: "type", + options: Object.values(TYPE_OPTIONS), + control: { + type: "select", + }, + }, + Icon: { + name: "icon", + options: Object.keys(Icons), + control: "select", + }, + inlineActions: { + table: { + disable: true, + }, + }, + labelClose: { + table: { + disable: true, + }, + }, + onClose: { + table: { + disable: true, + }, + }, + id: { + table: { + disable: true, + }, + }, }, }; -export const Content = () => { - const message = "The quick, brown fox jumps over a lazy dog."; - return <Alert icon>{message}</Alert>; -}; - -export const Button = () => { - const type = select("type", Object.values(BUTTON_TYPE_OPTIONS), BUTTON_TYPE_OPTIONS.INFO); - - return <AlertButton type={type}>AlertButton</AlertButton>; -}; - -export const InfoAlert = () => { - const title = text("Title", "Some additional information"); - const message = text("Message", "The quick, brown fox jumps over a lazy dog."); - return ( - <Alert title={title} icon> - {message} - </Alert> - ); -}; - -InfoAlert.story = { - name: "Info alert", - - parameters: { - info: "Use when you need to inform users about something that is happening in their booking or a trip. If the issue is potentially dangerous, consider using warning alert. Keep in mind that warning alert can stress users more than the informational one. Visit Orbit.Kiwi for more detailed guidelines.", +export default meta; +type Story = StoryObj<typeof meta>; + +/** + * You can try all possible configurations of this component. + * However, check Orbit.Kiwi for more detailed design guidelines. + */ +export const Playground: Story = { + args: { + type: TYPE_OPTIONS.INFO, + title: "You can change the title by changing the Title knob", + message: "Also you can change the message by changing the Message knob", + dataTest: "test", + button: "I am a link", + closable: false, + Icon: getIcon("Airplane"), // TODO fix this + spaceAfter: SPACINGS_AFTER.SMALL, + suppressed: false, }, -}; + render: args => { + const { type, title, message, dataTest, button, closable, Icon, spaceAfter, suppressed } = args; -export const SuccessAlert = () => { - const title = text("Title", "You did it!"); - const message = text("Message", "The quick, brown fox jumps over a lazy dog."); - return ( - <Alert type="success" title={title} icon> - {message} - </Alert> - ); -}; - -SuccessAlert.story = { - name: "Success alert", - - parameters: { - info: "Use when a user just performed some action and we need to tell them that action was successful. This button is usually used without an action button.Avoid using success banner if there is any follow-up action, for example, in cases where we need to confirm something to users by e-mail later. It's recommended to use informational alert instead. Visit Orbit.Kiwi for more detailed guidelines.", + return ( + <Alert + type={type} + icon={Icon} + title={title} + suppressed={suppressed} + closable={closable} + onClose={action("Close")} + dataTest={dataTest} + spaceAfter={spaceAfter} + > + <Stack spacing="small"> + <Stack spacing="XXSmall"> + <div>{message}</div> + <List> + <ListItem> + <Text type={type}>623 Kč will be refunded by your payment card</Text> + </ListItem> + <ListItem>623 Kč will be refunded by your payment card</ListItem> + </List> + </Stack> + <Stack direction="row" spacing="XSmall"> + <AlertButton type={type} href="#"> + {button} + </AlertButton> + <AlertButton type={suppressed ? "secondary" : undefined} href="#"> + {button} + </AlertButton> + </Stack> + </Stack> + </Alert> + ); }, }; -export const WarningAlert = () => { - const title = text("Title", "Be careful!"); - const message = text("Message", "The quick, brown fox jumps over a lazy dog."); - return ( - <Alert type="warning" title={title} icon> - {message} - </Alert> - ); +/** + * This is the default configuration of this component. + * Visit Orbit.Kiwi for more detailed guidelines. + */ +export const Default: Story = { + args: { + title: "The quick, brown fox jumps over a lazy dog.", + }, + render: args => <Alert icon {...args} />, }; -WarningAlert.story = { - name: "Warning alert", - - parameters: { - info: "Use in cases when you need to inform users about a potentially dangerous situation in their trip and it requires some action from them. However, if the issue requires immediate attention, use critical alert instead. Visit Orbit.Kiwi for more detailed guidelines.", +export const Content: Story = { + args: { + message: "The quick, brown fox jumps over a lazy dog.", }, + render: ({ message }) => <Alert icon>{message}</Alert>, }; -export const CriticalAlert = () => { - const title = text("Title", "Something has gone horribly wrong"); - const message = text("Message", "The quick, brown fox jumps over a lazy dog."); - return ( - <Alert type="critical" title={title} icon> - {message} - </Alert> - ); +export const Button: Story = { + args: { type: BUTTON_TYPE_OPTIONS.INFO }, + render: ({ type }) => <AlertButton type={type}>AlertButton</AlertButton>, }; -CriticalAlert.story = { - name: "Critical alert", - - parameters: { - info: "Use when something is blocking users from continuing or when some issue needs to be resolved immediately. A critical alert should provide some form of solution for their problem. If something is important for users to solve as soon as possible, automatic open of a modal window is worthy of considering. Visit Orbit.Kiwi for more detailed guidelines.", +/** + * Use when you need to inform users about something that is happening in their booking or a trip. + * If the issue is potentially dangerous, consider using warning alert. + * Keep in mind that warning alert can stress users more than the informational one. + * Visit Orbit.Kiwi for more detailed guidelines. + */ +export const InfoAlert: Story = { + args: { + title: "Some additional information", + message: "The quick, brown fox jumps over a lazy dog.", + }, + render: args => { + const { title, message } = args; + return ( + <Alert title={title} icon> + {message} + </Alert> + ); }, }; -export const OnlyTitle = () => { - const title = text("Title", "The quick, brown fox jumps over a lazy dog."); - return <Alert title={title} closable />; +/** + * Use when a user just performed some action and we need to tell them that action was successful. + * This button is usually used without an action button. + * Avoid using success banner if there is any follow-up action, + * for example, in cases where we need to confirm something to users by e-mail later. + * It's recommended to use informational alert instead. + * Visit Orbit.Kiwi for more detailed guidelines. + */ +export const SuccessAlert: Story = { + args: { + title: "You did it!", + message: "The quick, brown fox jumps over a lazy dog.", + }, + render: args => { + const { title, message } = args; + return ( + <Alert type={TYPE_OPTIONS.SUCCESS} title={title} icon> + {message} + </Alert> + ); + }, }; -OnlyTitle.story = { - name: "Only title", - - parameters: { - info: "This is the default configuration of this component. Visit Orbit.Kiwi for more detailed guidelines.", +/** + * Use in cases when you need to inform users about a potentially dangerous situation in their trip + * and it requires some action from them. + * However, if the issue requires immediate attention, use critical alert instead. + * Visit Orbit.Kiwi for more detailed guidelines. + */ +export const WarningAlert: Story = { + args: { + title: "Be careful!", + message: "The quick, brown fox jumps over a lazy dog.", + }, + render: args => { + const { title, message } = args; + return ( + <Alert type={TYPE_OPTIONS.WARNING} title={title} icon> + {message} + </Alert> + ); }, }; -export const InlineActions = () => { - const type = select("Type", Object.values(TYPE_OPTIONS), "info"); - const title = text("Title", "You can change the title by changing the Title knob"); - const button = text("Button", "I am a link"); - const closable = boolean("Closable", false); - const Icon = getIcon(getIcons("Airplane")); - - return ( - <Alert - type={type} - icon={Icon} - title={title} - closable={closable} - onClose={action("Close")} - inlineActions={ - <AlertButton type={type} href="#"> - {button} - </AlertButton> - } - /> - ); +/** + * Use when something is blocking users from continuing or when some issue needs to be resolved immediately. + * A critical alert should provide some form of solution for their problem. + * If something is important for users to solve as soon as possible, + * automatic open of a modal window is worthy of considering. + * Visit Orbit.Kiwi for more detailed guidelines. + */ +export const CriticalAlert: Story = { + args: { + title: "Something has gone horribly wrong", + message: "The quick, brown fox jumps over a lazy dog.", + }, + render: args => { + const { title, message } = args; + return ( + <Alert type={TYPE_OPTIONS.CRITICAL} title={title} icon> + {message} + </Alert> + ); + }, }; -InlineActions.story = { - parameters: { - info: "You can try all possible configurations of this component. However, check Orbit.Kiwi for more detailed design guidelines.", +/** + * This is the default configuration of this component. + * Visit Orbit.Kiwi for more detailed guidelines. + */ +export const OnlyTitle: Story = { + args: { + title: "The quick, brown fox jumps over a lazy dog.", }, + render: ({ title }) => <Alert title={title} closable />, }; -export const WithTextLink = () => { - const type = select("Type", Object.values(TYPE_OPTIONS), "info"); - - return ( - <Alert type={type}> - <p> - <TextLink type="primary">This is</TextLink> a primary textlink. - <br /> - <TextLink type="secondary">This is</TextLink> a secondary textlink. - </p> - </Alert> - ); +/** + * You can try all possible configurations of this component. + * However, check Orbit.Kiwi for more detailed design guidelines. + */ +export const InlineActions: Story = { + args: { + type: TYPE_OPTIONS.INFO, + title: "You can change the title by changing the Title knob", + button: "I am a link", + closable: false, + Icon: getIcon("Airplane"), // TODO fix this + }, + render: args => { + const { type, title, button, closable, Icon } = args; + return ( + <Alert + type={type} + icon={Icon} + title={title} + closable={closable} + onClose={action("Close")} + inlineActions={ + <AlertButton type={type} href="#"> + {button} + </AlertButton> + } + /> + ); + }, }; -WithTextLink.story = { - parameters: { - info: "You can try all possible configurations of this component. However, check Orbit.Kiwi for more detailed design guidelines.", +// TODO: fix icon +/** + * You can try all possible configurations of this component. + * However, check Orbit.Kiwi for more detailed design guidelines. + */ +export const WithTextLink: Story = { + args: { + type: TYPE_OPTIONS.INFO, + }, + argTypes: { + icon: { + table: { + disable: true, + }, + }, + }, + render: args => { + return ( + <Alert {...args}> + <p> + <TextLink type="primary">This is</TextLink> a primary textlink. + <br /> + <TextLink type="secondary">This is</TextLink> a secondary textlink. + </p> + </Alert> + ); }, }; -export const Playground = () => { - const type = select("Type", Object.values(TYPE_OPTIONS), "info"); - const title = text("Title", "You can change the title by changing the Title knob"); - const message = text("Message", "Also you can change the message by changing the Message knob"); - const dataTest = text("dataTest", "test"); - const button = text("Button", "I am a link"); - const closable = boolean("Closable", false); - const Icon = getIcon(getIcons("Airplane")); - const spaceAfter = select("spaceAfter", Object.values(SPACINGS_AFTER), SPACINGS_AFTER.SMALL); - const suppressed = boolean("suppressed", false); - - return ( - <Alert - type={type} - icon={Icon} - title={title} - suppressed={suppressed} - closable={closable} - onClose={action("Close")} - dataTest={dataTest} - spaceAfter={spaceAfter} - > - <Stack spacing="small"> +// TODO: fix RTL +/** + * This is a preview of this component in RTL setup. + */ +export const Rtl: Story = { + render: () => ( + // <RenderInRtl> + <Alert type="info" title="The title of the Alert" closable onClose={action("Close")}> + <Stack spacing="XSmall"> <Stack spacing="XXSmall"> - <div>{message}</div> + <Text> + Requirements found here are for reference purposes only. Contact the embassy or your + foreign ministry for more information. + </Text> + <Heading type="title4"> + Make sure you know your visa requirements for these countries: + </Heading> <List> - <ListItem> - <Text type={type}>623 Kč will be refunded by your payment card</Text> - </ListItem> - <ListItem>623 Kč will be refunded by your payment card</ListItem> + <ListItem icon={<CountryFlag code="pl" name="Poland" />}>Poland</ListItem> </List> </Stack> - <Stack direction="row" spacing="XSmall"> - <AlertButton type={type} href="#"> - {button} - </AlertButton> - <AlertButton type={suppressed ? "secondary" : `${type}Subtle`} href="#"> - {button} - </AlertButton> - </Stack> + <AlertButton type="info">Check Visa Requirements</AlertButton> </Stack> </Alert> - ); -}; - -Playground.story = { - parameters: { - info: "You can try all possible configurations of this component. However, check Orbit.Kiwi for more detailed design guidelines.", - }, -}; - -export const Rtl = () => { - const Icon = getIcon(getIcons("Airplane")); - - return ( - <RenderInRtl> - <Alert - type="info" - icon={Icon} - title="The title of the Alert" - closable - onClose={action("Close")} - > - <Stack spacing="XSmall"> - <Stack spacing="XXSmall"> - <Text> - Requirements found here are for reference purposes only. Contact the embassy or your - foreign ministry for more information. - </Text> - <Heading type="title4"> - Make sure you know your visa requirements for these countries: - </Heading> - <List> - <ListItem icon={<CountryFlag code="pl" name="Poland" />}>Poland</ListItem> - </List> - </Stack> - <AlertButton type="info">Check Visa Requirements</AlertButton> - </Stack> - </Alert> - </RenderInRtl> - ); -}; - -Rtl.story = { - name: "RTL", - - parameters: { - info: "This is a preview of this component in RTL setup.", - }, + // </RenderInRtl> + ), }; diff --git a/packages/orbit-components/src/utils/Grid/Grid.stories.tsx b/packages/orbit-components/src/utils/Grid/Grid.stories.tsx index cc29d0d2e3..b3f310d86a 100644 --- a/packages/orbit-components/src/utils/Grid/Grid.stories.tsx +++ b/packages/orbit-components/src/utils/Grid/Grid.stories.tsx @@ -1,70 +1,92 @@ import * as React from "react"; -import { text, boolean, number, object, select } from "@storybook/addon-knobs"; +import type { Meta, StoryObj } from "@storybook/react"; import { SPACINGS_AFTER } from "../../common/consts"; import Grid from "."; -export default { +type GridPropsAndCustomArgs = React.ComponentProps<typeof Grid> & { + divsCount: number; +}; + +const meta: Meta<GridPropsAndCustomArgs> = { title: "Grid", + component: Grid, }; -export const Playground = () => { - const inline = boolean("inline", false); - const maxWidth = text("maxWidth", "1440px"); - const width = text("width", "100%"); - const columns = text("columns", ""); - const rows = text("rows", "repeat(8, 40px)"); - const gap = text("gap", ""); - const columnGap = text("columnGap", ""); - const rowGap = text("rowGap", "10px"); - const as = text("as", "div"); - const dataTest = text("dataTest", "test"); - const divsCount = number("divsCount", 8); - const mediumMobile = object("mediumMobile", { - rowGap: "0", - }); - const largeMobile = object("largeMobile", { - columns: "repeat(4, 1fr)", - rows: "repeat(2, 40px)", - gap: "20px", - }); - const tablet = object("tablet", { - columnGap: "40px", - }); - const desktop = object("desktop", { - columns: "repeat(2, minmax(100px, 1fr))", - rows: "repeat(4, 40px)", - gap: "40px", - }); - const largeDesktop = object("largeDesktop", { - columns: "repeat(8, minmax(10px, 1fr))", - rows: "40px", - }); - const spaceAfter = select("spaceAfter", Object.values(SPACINGS_AFTER), SPACINGS_AFTER.NORMAL); - return ( - <Grid - inline={inline} - spaceAfter={spaceAfter} - maxWidth={maxWidth} - width={width} - columns={columns} - rows={rows} - gap={gap} - columnGap={columnGap} - rowGap={rowGap} - as={as} - dataTest={dataTest} - mediumMobile={mediumMobile} - largeMobile={largeMobile} - tablet={tablet} - desktop={desktop} - largeDesktop={largeDesktop} - > +export default meta; +type Story = StoryObj<typeof meta>; + +export const Playground: Story = { + args: { + inline: false, + maxWidth: "1440px", + width: "100%", + columns: "", + rows: "repeat(8, 40px)", + gap: "", + columnGap: "", + rowGap: "10px", + as: "div", + dataTest: "test", + divsCount: 8, + mediumMobile: { + rowGap: "0", + }, + largeMobile: { + columns: "repeat(4, 1fr)", + rows: "repeat(2, 40px)", + gap: "20px", + }, + tablet: { + columnGap: "40px", + }, + desktop: { + columns: "repeat(2, minmax(100px, 1fr))", + rows: "repeat(4, 40px)", + gap: "40px", + }, + largeDesktop: { + columns: "repeat(8, minmax(10px, 1fr))", + rows: "40px", + }, + spaceAfter: SPACINGS_AFTER.NORMAL, + }, + argTypes: { + spaceAfter: { + name: "spaceAfter", + options: Object.values(SPACINGS_AFTER), + control: { + type: "select", + }, + }, + inline: { + table: { + type: { summary: "boolean" }, + }, + }, + columns: { + table: { + type: { summary: "string" }, + }, + }, + rows: { + table: { + type: { summary: "string" }, + }, + }, + as: { + table: { + type: { summary: "string" }, + }, + }, + }, + render: ({ divsCount, ...args }) => ( + <Grid {...args}> {Array(...Array(divsCount)).map((_, key) => ( // eslint-disable-next-line <div key={key} style={{ background: "rgba(0, 169, 145, 0.2)" }} /> ))} </Grid> - ); + ), };