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: {

View File

@@ -1,35 +0,0 @@
import { Meta } from '@storybook/addon-docs/blocks'
<Meta title="Introduction" />
# Scandic Hotels design system ✨
## Components
### File structure
```
[Component]
├── Compositions/ # A folder with Storybook stories to showcase compositions with other components
├──── [CompositionX].stories.tsx # Storybook stories that showcase component compositions
├── [component].module.css # The CSS for the component
├── [Component].stories.tsx # Storybook stories for the component, without compositions
├── [Component].tsx # The main component file
├── index.tsx # Entrypoint for the component exports
├── types.ts # TypeScript typings for the component
└── variants.ts # Class Variance Authority configuration for variants of the component
```
### Components
Each component of the design system is defined in `lib/components`.
Each component has an `index.tsx` file that exports the component and its optional subcomponents. Subcomponents are components that are meant to be used together/nested with the component.
The components that are considered public API from a consumer standpoint **must** have Storybook stories that showcases and documents their use. It should at least contain one default story that showcases the component by itself in its default state. More stories are added to showcase other variants or usages of the component.
Styling is done with CSS modules.
Variants are implemented with [Class Variance Authority](https://cva.style/).
The typings for each components live in their respective `types.ts` file inside the component folder.

View File

@@ -1,153 +0,0 @@
/* eslint-disable formatjs/no-literal-string-in-jsx */
import copy from 'copy-to-clipboard'
import { kebabify } from '../../generate/utils'
export type ThemeValue = Record<'resolved' | 'alias', string | number>
export type Theme = Record<string, ThemeValue>
export type ColorsProps = {
theme: Theme
}
import styles from './colors.module.css'
function getContrastColor(bgColor: string) {
const r = parseInt(bgColor.substring(1, 3), 16)
const g = parseInt(bgColor.substring(3, 5), 16)
const b = parseInt(bgColor.substring(5, 7), 16)
let a = parseInt(bgColor.substring(7, 9), 16)
if (isNaN(a)) {
a = 255
}
const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255
if (luminance > 0.5) {
return '#000'
} else {
if (a < 255 / 2) {
return '#000'
}
return '#fff'
}
}
export function Colors({ theme }: ColorsProps) {
const grouping: Record<string, Theme> = {}
for (const [k, v] of Object.entries(theme)) {
if (typeof v.resolved === 'string' && v.resolved.startsWith('#')) {
const key = k.replace(/\/[^/]+$/, '')
if (!grouping[key]) {
grouping[key] = {}
}
grouping[key][k] = v
}
}
return (
<div className={styles.container}>
<div className={styles.jumpTo}>
<label>
Jump to:
<select
onChange={(e) => {
const el = document.getElementById(e.target.value)
el?.scrollIntoView({
behavior: 'smooth',
})
}}
>
<option>- Select a grouping -</option>
{Object.keys(grouping)
.sort((a, b) => a.localeCompare(b))
.map((title) => {
return (
<option key={title} value={kebabify(title)}>
{title}
</option>
)
})}
</select>
</label>
<span className={styles.tip}>
Click on any of the values to copy to clipboard!
</span>
</div>
<div className={styles.groups}>
{Object.entries(grouping)
.sort((a, b) => {
return a[0].localeCompare(b[0])
})
.map(([title, values]) => {
return (
<div className={styles.group} key={title}>
<h2 id={kebabify(title)} className={styles.title}>
{title}
</h2>
<div className={styles.values}>
{Object.entries(values).map(([k, v]) => {
return (
<div className={styles.value} key={k}>
<div className={styles.colorContainer}>
<div
className={styles.color}
style={{
color: getContrastColor(v.resolved.toString()),
backgroundColor: v.resolved.toString(),
}}
onClick={() => {
copy(`var(--${kebabify(k)})`)
}}
>
var(--{kebabify(k)})
</div>
</div>
<div
className={styles.tokenName}
onClick={() => {
copy(k)
}}
>
Figma: {k}
</div>
<div
className={styles.tokenName}
onClick={() => {
copy(kebabify(k))
}}
>
CSS: {kebabify(k)}
</div>
{v.alias ? (
<div
className={styles.tokenAlias}
onClick={() => {
copy(v.alias.toString())
}}
>
Alias: {v.alias}
</div>
) : null}
<div
className={styles.tokenValue}
onClick={() => {
copy(v.resolved.toString())
}}
>
Value: {v.resolved}
</div>
</div>
)
})}
</div>
</div>
)
})}
</div>
</div>
)
}

View File

@@ -1,11 +0,0 @@
import { Meta } from '@storybook/addon-docs/blocks'
import { Colors } from './Colors'
import { base } from '.'
<Meta title="Global/Colors/Base" />
# Colors: Base
<Colors theme={base} />

View File

@@ -1,130 +0,0 @@
.container {
display: grid;
gap: 2em;
}
.jumpTo {
position: sticky;
top: 0;
background: #fff;
padding: 0.5em;
z-index: 100;
border: solid 1px #ccc;
border-radius: 4px;
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: row;
flex-wrap: nowrap;
}
.jumpTo select {
margin-left: 1em;
padding: 0.3em;
border-radius: 3px;
border: solid 1px #ccc;
font-size: 14px;
}
.tip {
font-size: 12px !important;
background: #fffcdd;
padding: 0.5em;
border-radius: 4px;
border: solid 1px #e8db45;
}
.groups {
display: flex;
flex-direction: column;
}
.title {
font-weight: bold;
padding-top: 60px !important; /* jumpTo element height:ish */
}
.values {
display: flex;
flex-wrap: wrap;
}
.value {
box-sizing: border-box;
width: 50%;
min-width: 500px;
padding: 1em;
}
.colorContainer {
--opacity: 0.1;
background:
linear-gradient(
45deg,
rgba(0, 0, 0, var(--opacity)) 25%,
transparent 25%,
transparent 75%,
rgba(0, 0, 0, var(--opacity)) 75%,
rgba(0, 0, 0, var(--opacity)) 0
),
linear-gradient(
45deg,
rgba(0, 0, 0, var(--opacity)) 25%,
transparent 25%,
transparent 75%,
rgba(0, 0, 0, var(--opacity)) 75%,
rgba(0, 0, 0, var(--opacity)) 0
),
white;
background-position:
0px 0,
5px 5px;
background-size:
10px 10px,
10px 10px;
border-radius: 12px;
overflow: hidden;
will-change: transform;
transition: transform 0.2s ease-out;
margin-bottom: 1em;
cursor: pointer;
border: solid 1px #d9d9d9;
}
.color {
display: flex;
justify-content: center;
align-items: center;
height: 4em;
width: 100%;
}
.colorContainer:hover {
transform: scale(1.02);
}
.colorContainer:active {
transform: scale(1.01);
}
.tokenName,
.tokenValue,
.tokenAlias {
cursor: pointer;
padding: 0.1em 0.5em;
white-space: nowrap;
}
.tokenName:hover,
.tokenValue:hover,
.tokenAlias:hover {
transform-origin: left;
font-weight: bold;
word-break: break-all;
}
.tokenName:active,
.tokenValue:active,
.tokenAlias:active {
transform: scale(0.98);
}

View File

@@ -1,11 +0,0 @@
import { Meta } from '@storybook/addon-docs/blocks'
import { Colors } from './Colors'
import { downtownCamper } from '.'
<Meta title="Global/Colors/Downtown Camper" />
# Colors: Downtown Camper
<Colors theme={downtownCamper} />

View File

@@ -1,11 +0,0 @@
import { Meta } from '@storybook/addon-docs/blocks'
import { Colors } from './Colors'
import { grandHotel } from '.'
<Meta title="Global/Colors/Grand Hotel" />
# Colors: Grand Hotel
<Colors theme={grandHotel} />

View File

@@ -1,11 +0,0 @@
import { Meta } from '@storybook/addon-docs/blocks'
import { Colors } from './Colors'
import { haymarket } from '.'
<Meta title="Global/Colors/Haymarket" />
# Colors: Haymarket
<Colors theme={haymarket} />

View File

@@ -1,11 +0,0 @@
import { Meta } from '@storybook/addon-docs/blocks'
import { Colors } from './Colors'
import { hotelNorge } from '.'
<Meta title="Global/Colors/Hotel Norge" />
# Colors: Hotel Norge
<Colors theme={hotelNorge} />

View File

@@ -1,11 +0,0 @@
import { Meta } from '@storybook/addon-docs/blocks'
import { Colors } from './Colors'
import { marski } from '.'
<Meta title="Global/Colors/Marski" />
# Colors: Marski
<Colors theme={marski} />

View File

@@ -1,11 +0,0 @@
import { Meta } from '@storybook/addon-docs/blocks'
import { Colors } from './Colors'
import { scandic } from '.'
<Meta title="Global/Colors/Scandic" />
# Colors: Scandic
<Colors theme={scandic} />

View File

@@ -1,11 +0,0 @@
import { Meta } from '@storybook/addon-docs/blocks'
import { Colors } from './Colors'
import { scandicGo } from '.'
<Meta title="Global/Colors/Scandic Go" />
# Colors: Scandic Go
<Colors theme={scandicGo} />

View File

@@ -1,11 +0,0 @@
import { Meta } from '@storybook/addon-docs/blocks'
import { Colors } from './Colors'
import { theDock } from '.'
<Meta title="Global/Colors/The Dock" />
# Colors: The Dock
<Colors theme={theDock} />