Merged in feat/SW-3636-storybook-structure (pull request #3309)

feat(SW-3636): Storybook structure

* New sections in Storybook sidebar

* Group Storybook content files and add token files for spacing, border radius and shadows


Approved-by: Joakim Jäderberg
This commit is contained in:
Rasmus Langvad
2025-12-08 12:35:14 +00:00
parent 177c2e7176
commit ca6cc5ab6c
83 changed files with 1272 additions and 525 deletions

View File

@@ -7,7 +7,7 @@ import { IconName } from '../Icons/iconName'
import { Typography } from '../Typography'
const meta: Meta<typeof Accordion> = {
title: 'Components/Accordion',
title: 'Core Components/Accordion',
component: Accordion,
argTypes: {
type: {

View File

@@ -4,7 +4,7 @@ import { AlertTypeEnum } from '@scandic-hotels/common/constants/alert'
import { expect, fn } from 'storybook/test'
const meta: Meta<typeof Alert> = {
title: 'Components/Alert',
title: 'Core Components/Alert',
component: Alert,
parameters: {
layout: 'centered',

View File

@@ -4,7 +4,7 @@ import { Avatar } from '.'
import { config } from './variants'
const meta: Meta<typeof Avatar> = {
title: 'Components/Avatar',
title: 'Core Components/Avatar',
component: Avatar,
parameters: {
layout: 'centered',

View File

@@ -6,7 +6,7 @@ import { BackToTopButton } from '.'
import { config as backToTopButtonConfig } from './variants'
const meta: Meta<typeof BackToTopButton> = {
title: 'Components/BackToTopButton',
title: 'Patterns/BackToTopButton',
component: BackToTopButton,
argTypes: {
onPress: {

View File

@@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/nextjs-vite'
import { Badge } from './Badge.tsx'
const meta: Meta<typeof Badge> = {
title: 'Components/Badge',
title: 'Core Components/Badge',
component: Badge,
}

View File

@@ -3,7 +3,7 @@ import { fn } from 'storybook/test'
import { BookingCodeChip } from './index'
const meta = {
title: 'Components/BookingCodeChip',
title: 'Product Components/BookingCodeChip',
component: BookingCodeChip,
parameters: {
layout: 'centered',

View File

@@ -8,7 +8,7 @@ import { Button } from './Button'
import { config as buttonConfig } from './variants'
const meta: Meta<typeof Button> = {
title: 'Components/Button',
title: 'Core Components/Button',
component: Button,
argTypes: {
onPress: {

View File

@@ -8,7 +8,7 @@ import { MaterialIcon } from '../Icons/MaterialIcon'
import { config as typographyConfig } from '../Typography/variants'
const meta: Meta<typeof ButtonLink> = {
title: 'Components/ButtonLink',
title: 'Core Components/ButtonLink',
component: ButtonLink,
argTypes: {
onClick: {

View File

@@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/nextjs-vite'
import { Card } from './Card.tsx'
const meta: Meta<typeof Card> = {
title: 'Components/Card',
title: 'Core Components/Card',
component: Card,
}

View File

@@ -7,7 +7,7 @@ import { ChipButton } from './ChipButton.tsx'
import { config as chipButtonConfig } from './variants'
const meta: Meta<typeof ChipButton> = {
title: 'Components/Chip/ChipButton',
title: 'Core Components/ChipButton',
component: ChipButton,
argTypes: {
variant: {

View File

@@ -4,7 +4,7 @@ import { MaterialIcon } from '../Icons/MaterialIcon'
import { ChipLink } from './ChipLink.tsx'
const meta: Meta<typeof ChipLink> = {
title: 'Components/Chip/ChipLink',
title: 'Core Components/ChipLink',
component: ChipLink,
}

View File

@@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/nextjs-vite'
import { Divider } from './Divider'
const meta: Meta<typeof Divider> = {
title: 'Components/Divider',
title: 'Core Components/Divider',
component: Divider,
argTypes: {},
}

View File

@@ -12,7 +12,7 @@ const facilityMapping: Record<string, FacilityEnum> = Object.fromEntries(
const colorOptions = Object.keys(iconVariantConfig.variants.color)
const meta: Meta<typeof FacilityToIcon> = {
title: 'Components/Facility To Icon',
title: 'Core Components/Facility To Icon',
component: FacilityToIcon,
argTypes: {
id: {

View File

@@ -1,18 +0,0 @@
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
import Checkbox from './index'
import { FormDecorator } from '../../../../.storybook/decorators/FormDecorator'
const meta: Meta<typeof Checkbox> = {
title: 'Components/Form/Checkbox',
component: Checkbox,
decorators: [FormDecorator],
args: { name: 'checkbox' },
}
export default meta
type Story = StoryObj<typeof Checkbox>
export const Default: Story = {
args: {},
}

View File

@@ -7,7 +7,7 @@ import { PaymentMethodEnum } from '@scandic-hotels/common/constants/paymentMetho
import { FormDecorator } from '../../../../.storybook/decorators/FormDecorator'
const meta: Meta<typeof PaymentOptionsGroup> = {
title: 'Components/Payment/PaymentOptionsGroup',
title: 'Patterns/Form/Payment/PaymentOptionsGroup',
component: PaymentOptionsGroup,
decorators: [FormDecorator],
}

View File

@@ -6,7 +6,7 @@ import { PaymentMethodEnum } from '@scandic-hotels/common/constants/paymentMetho
import { FormDecorator } from '../../../../.storybook/decorators/FormDecorator'
const meta: Meta<typeof SelectPaymentMethod> = {
title: 'Components/Payment/SelectCreditCard',
title: 'Patterns/Form/Payment/SelectCreditCard',
component: SelectPaymentMethod,
argTypes: {},
decorators: [FormDecorator],

View File

@@ -7,7 +7,7 @@ import { Button } from '../Button'
import { MaterialIcon } from '../Icons/MaterialIcon'
const meta: Meta<typeof HotelCard> = {
title: 'Components/HotelCard',
title: 'Product Components/HotelCard/HotelCard',
component: HotelCard,
argTypes: {
state: {

View File

@@ -6,7 +6,7 @@ import { fn } from 'storybook/test'
import { hotelPins } from '../../../Map/InteractiveMap/storybookData'
const meta: Meta<typeof StandaloneHotelCardDialog> = {
title: 'Components/StandaloneHotelCardDialog',
title: 'Product Components/HotelCard/StandaloneHotelCardDialog',
component: StandaloneHotelCardDialog,
argTypes: {},
}

View File

@@ -6,8 +6,9 @@ import { fn } from 'storybook/test'
import { Button } from '../Button'
import { MaterialIcon } from '../Icons/MaterialIcon'
import { HotelInfoCard } from './index'
const meta: Meta<typeof HotelInfoCard> = {
title: 'Components/HotelInfoCard',
title: 'Product Components/HotelInfoCard',
component: HotelInfoCard,
argTypes: {},
}

View File

@@ -7,7 +7,7 @@ import { IconButton } from './IconButton'
import { config } from './variants'
const meta: Meta<typeof IconButton> = {
title: 'Components/IconButton',
title: 'Core Components/IconButton',
component: IconButton,
argTypes: {
onPress: {

View File

@@ -7,7 +7,8 @@ import { HTMLAttributes } from 'react'
import { getIconAriaProps } from '../utils'
export interface MaterialIconProps
extends Pick<MaterialSymbolProps, 'size' | 'icon' | 'className' | 'style'>,
extends
Pick<MaterialSymbolProps, 'size' | 'icon' | 'className' | 'style'>,
Omit<HTMLAttributes<HTMLSpanElement>, 'color' | 'id'>,
VariantProps<typeof iconVariants> {
isFilled?: boolean

View File

@@ -4,7 +4,7 @@ import { InfoBox, Props } from './InfoBox'
import { IconName } from '../Icons/iconName'
const meta: Meta<typeof InfoBox> = {
title: 'Components/InfoBox',
title: 'Core Components/InfoBox',
component: InfoBox,
parameters: {
layout: 'padded',

View File

@@ -20,7 +20,7 @@ const DEFAULT_ARGS = {
}
const meta: Meta<typeof InfoCard> = {
title: 'Components/InfoCard',
title: 'Product Components/InfoCard',
component: InfoCard,
argTypes: {
topTitle: {

View File

@@ -6,7 +6,7 @@ import { Input } from './Input'
import { TextField } from 'react-aria-components'
const meta: Meta<typeof Input> = {
title: 'Components/Input',
title: 'Core Components/Input',
// @ts-expect-error Input does not support this, but wrapping <TextField> does
component: ({ isInvalid, ...props }) => (
<TextField isInvalid={isInvalid}>

View File

@@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/nextjs-vite'
import { InputLabel } from './InputLabel'
const meta: Meta<typeof InputLabel> = {
title: 'Components/InputLabel',
title: 'Core Components/InputLabel',
component: InputLabel,
argTypes: {},
}

View File

@@ -7,7 +7,7 @@ import { TextField } from 'react-aria-components'
import { MaterialIcon } from '../Icons/MaterialIcon'
const meta: Meta<typeof Input> = {
title: 'Components/Input (New)',
title: 'Core Components/Input (New)',
// @ts-expect-error Input does not support this, but wrapping <TextField> does
component: ({ isInvalid, validationState, ...props }) => (
<TextField isInvalid={isInvalid} data-validation-state={validationState}>

View File

@@ -5,7 +5,7 @@ import { RTETypeEnum } from './types/rte/enums'
import { RTEImageVaultNode, RTENode } from './types/rte/node'
const meta: Meta<typeof JsonToHtml> = {
title: 'Components/JsonToHtml',
title: 'Core Components/JsonToHtml',
component: JsonToHtml,
}

View File

@@ -4,7 +4,7 @@ import { IconName } from '../Icons/iconName'
import type { LinkListItemProps } from './LinkListItem'
const meta: Meta<typeof LinkList> = {
title: 'Components/LinkList',
title: 'Core Components/LinkList/LinkList',
component: LinkList,
argTypes: {},
}

View File

@@ -3,7 +3,7 @@ import { LinkListItem } from './index'
import { IconName } from '../../Icons/iconName'
const meta: Meta<typeof LinkListItem> = {
title: 'Components/LinkListItem',
title: 'Core Components/LinkList/LinkListItem',
component: LinkListItem,
argTypes: {
isExternal: {

View File

@@ -4,7 +4,7 @@ import { Loading } from './Loading'
import { config } from './variants'
const meta: Meta<typeof Loading> = {
title: 'Components/Loading',
title: 'Patterns/Loading',
component: Loading,
argTypes: {
type: {

View File

@@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/nextjs-vite'
import { LoadingSpinner } from './index'
const meta: Meta<typeof LoadingSpinner> = {
title: 'Components/LoadingSpinner',
title: 'Patterns/LoadingSpinner',
component: LoadingSpinner,
argTypes: {
fullPage: {

View File

@@ -8,7 +8,7 @@ import { InteractiveMap } from '.'
import { hotelPins } from './storybookData'
const meta: Meta<typeof InteractiveMap> = {
title: 'Components/Map/Interactive Map',
title: 'Patterns/Map/Interactive Map',
component: InteractiveMap,
argTypes: {},
}

View File

@@ -5,7 +5,7 @@ import { SignatureHotelEnum } from '@scandic-hotels/common/constants/signatureHo
import { Typography } from '../../Typography'
const meta: Meta<typeof HotelMarkerByType> = {
title: 'Components/Map/Hotel Marker By Type',
title: 'Patterns/Map/Hotel Marker By Type',
component: HotelMarkerByType,
argTypes: {
hotelType: {

View File

@@ -5,7 +5,7 @@ type MessageBannerType = 'default' | 'error' | 'info'
type TextColor = 'default' | 'error'
const meta: Meta<typeof MessageBanner> = {
title: 'Components/MessageBanner',
title: 'Core Components/MessageBanner',
component: MessageBanner,
argTypes: {
type: {

View File

@@ -1,71 +0,0 @@
import type { Meta, StoryObj } from '@storybook/nextjs-vite'
import { expect } from 'storybook/test'
import OldDSLink from '.'
const meta: Meta<typeof OldDSLink> = {
title: 'Components/OldDSLink',
component: OldDSLink,
argTypes: {
size: {
control: 'select',
options: ['small', 'regular', 'tiny', 'none'],
},
scroll: {
table: {
disable: true,
},
},
prefetch: {
table: {
disable: true,
},
},
partialMatch: {
table: {
disable: true,
},
},
},
}
export default meta
type Story = StoryObj<typeof OldDSLink>
export const Default: Story = {
args: {
active: false,
href: 'https://www.scandichotels.com/en',
},
render: (args) => <OldDSLink {...args}>{args.href}</OldDSLink>,
play: async ({ canvasElement }) => {
const link = canvasElement.querySelector('a')
if (!link) throw new Error('Link not found')
expect(link).toBeInTheDocument()
},
}
export const Focused: Story = {
args: {
...Default.args,
},
render: Default.render,
play: async ({ canvasElement }) => {
const link = canvasElement.querySelector('a')
if (!link) throw new Error('Link not found')
expect(link).toBeInTheDocument()
expect(link).not.toHaveFocus()
let styles = getComputedStyle(link)
expect(styles.outlineStyle).toBe('none')
expect(parseFloat(styles.outlineWidth)).toBe(0)
link?.focus()
expect(link).toHaveFocus()
styles = getComputedStyle(link)
expect(styles.outlineStyle).not.toBe('none')
expect(parseFloat(styles.outlineWidth)).toBeGreaterThan(0)
},
}

View File

@@ -8,7 +8,7 @@ import { expect } from 'storybook/test'
const methods = Object.values(PaymentMethodEnum).toSorted()
const meta: Meta<typeof PaymentMethodIcon> = {
title: 'Components/Payment/PaymentMethodIcon',
title: 'Product Components/Payment/PaymentMethodIcon',
component: PaymentMethodIcon,
parameters: {
layout: 'centered',

View File

@@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/nextjs-vite'
import { Progress } from './index'
const meta: Meta<typeof Progress> = {
title: 'Components/Progress',
title: 'Core Components/Progress',
component: Progress,
parameters: {
backgrounds: { disable: true },

View File

@@ -2,7 +2,7 @@ import type { Meta, StoryObj } from '@storybook/nextjs-vite'
import CampaignRateCard from '.'
const meta: Meta<typeof CampaignRateCard> = {
title: 'Components/RateCard/Campaign',
title: 'Product Components/RateCard/Campaign',
component: CampaignRateCard,
decorators: [
(Story) => (

View File

@@ -2,7 +2,7 @@ import type { Meta, StoryObj } from '@storybook/nextjs-vite'
import CodeRateCard from '.'
const meta: Meta<typeof CodeRateCard> = {
title: 'Components/RateCard/Code',
title: 'Product Components/RateCard/Code',
component: CodeRateCard,
decorators: [
(Story) => (

View File

@@ -2,7 +2,7 @@ import type { Meta, StoryObj } from '@storybook/nextjs-vite'
import NoRateAvailableCard from '.'
const meta: Meta<typeof NoRateAvailableCard> = {
title: 'Components/RateCard/NoRateAvailable',
title: 'Product Components/RateCard/NoRateAvailable',
component: NoRateAvailableCard,
decorators: [
(Story) => (

View File

@@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/nextjs-vite'
import PointsRateCard from '.'
const meta: Meta<typeof PointsRateCard> = {
title: 'Components/RateCard/Points',
title: 'Product Components/RateCard/Points',
component: PointsRateCard,
decorators: [
(Story) => (

View File

@@ -2,7 +2,7 @@ import type { Meta, StoryObj } from '@storybook/nextjs-vite'
import RegularRateCard from '.'
const meta: Meta<typeof RegularRateCard> = {
title: 'Components/RateCard/Regular',
title: 'Product Components/RateCard/Regular',
component: RegularRateCard,
decorators: [
(Story) => (

View File

@@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/nextjs-vite'
import { Select } from './Select'
const meta: Meta<typeof Select> = {
title: 'Components/Select',
title: 'Core Components/Select',
component: Select,
argTypes: {},
}

View File

@@ -8,7 +8,7 @@ import { Typography } from '../Typography'
import { config } from './variants'
const meta: Meta<typeof TextLink> = {
title: 'Components/TextLink',
title: 'Core Components/TextLink',
component: TextLink,
argTypes: {
theme: {

View File

@@ -6,7 +6,7 @@ import { expect } from 'storybook/test'
import { config } from './variants.ts'
const meta: Meta<typeof Toast> = {
title: 'Components/Toasts/Toast',
title: 'Core Components/Toast/Toast',
component: Toast,
argTypes: {
variant: {

View File

@@ -9,7 +9,7 @@ import { Button } from '../Button/Button.tsx'
import { expect, waitFor } from 'storybook/test'
const meta: Meta<typeof Toast> = {
title: 'Components/Toasts/ToastHandler',
title: 'Core Components/Toast/ToastHandler',
component: Toast,
argTypes: {
variant: {

View File

@@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/nextjs-vite'
import { TripAdvisorChip } from './index'
const meta: Meta<typeof TripAdvisorChip> = {
title: 'Components/TripAdvisorChip',
title: 'Product Components/TripAdvisorChip',
component: TripAdvisorChip,
argTypes: {
rating: {

View File

@@ -7,7 +7,7 @@ import TypographyDocs from './Typography.docs.mdx'
import { config as typographyConfig } from './variants'
const meta: Meta<typeof Typography> = {
title: 'Components/Typography',
title: 'Core Components/Typography',
component: Typography,
args: { variant: typographyConfig.defaultVariants.variant },
argTypes: {

View File

@@ -5,7 +5,7 @@ import { VideoPlayer } from '.'
import { config as videoPlayerConfig } from './variants'
const meta: Meta<typeof VideoPlayer> = {
title: 'Components/🚧 VideoPlayer 🚧',
title: 'Core Components/🚧 VideoPlayer 🚧',
component: VideoPlayer,
parameters: {