import React from 'react'; import { StoryMetaType } from '@lg-tools/storybook-utils'; import { type StoryObj } from '@storybook/react'; import { within } from '@storybook/test'; import startCase from 'lodash/startCase'; import { css, cx } from '@leafygreen-ui/emotion'; import { Theme } from '@leafygreen-ui/lib'; import { palette } from '@leafygreen-ui/palette'; import { scrollbarColor } from './scrollbars'; import { addOverflowShadow, borderRadius, boxShadows, color, focusRing, fontFamilies, hoverRing, type ShadowKey, Side, spacing, transitionDuration, typeScales, Variant, } from '.'; const DemoCard = ({ children, darkMode, className, ...rest }: { children: React.ReactNode; darkMode: boolean; className?: string; [key: string]: any; }) => { const theme = darkMode ? Theme.Dark : Theme.Light; return (
{children}
); }; const meta: StoryMetaType = { title: 'Internal/Tokens', component: null, parameters: { default: 'Spacing' }, }; export default meta; type HoverRingColor = keyof typeof hoverRing.dark; type TypeScale = keyof typeof typeScales; type FontFamily = keyof typeof fontFamilies; const gutter = css` margin-left: ${spacing[400]}px; `; const spacingBlockVariants = Object.keys(spacing) .filter(num => Number(num) === 0 || Number(num) > 25) .reduce((acc: Partial>, index) => { const key = index as PropertyKey as keyof typeof spacing; acc[key] = css` background-color: ${palette.purple.light2}; width: ${spacing[key]}px; height: ${spacing[key]}px; `; return acc; }, {}); function SpacingBlock({ space }: { space: keyof typeof spacing }) { return (
spacing[{space}]: {spacing[space]}
); } export const OverflowShadows = () => { return (
{Object.values(Theme).map((theme: Theme) => { const isDarkMode = theme === Theme.Dark; const backgroundColor = isDarkMode ? palette.gray.dark4 : palette.white; return (
{Object.values(Side).map(side => (
Inside {side} shadow
))} {Object.values(Side).map(side => (
Outside {side} shadow
))}
); })}
); }; const shadowMap: Record> = { [Theme.Light]: boxShadows.light, [Theme.Dark]: boxShadows.dark, }; const excludeKeys: Array = ['overflow']; export const Shadows = () => (
{Object.entries(shadowMap).map(([theme, shadows]) => (

{theme}

{Object.entries(shadows).map( ([key, value]) => !excludeKeys.includes(key as keyof typeof boxShadows.light) && (
{key}
), )}
))}
); export const Spacing = () => (

Spacing

{Object.keys(spacing) .filter(num => Number(num) === 0 || Number(num) > 25) .map(space => ( ))}
); export const TypeScales = () => { return (

Typescales

{Object.keys(typeScales).map((_scale: string) => { const scale = _scale as TypeScale; return (
{scale}
); })}
); }; export const FontFamilies = () => (

Font Families

{Object.keys(fontFamilies).map((_family: string) => { const family = _family as FontFamily; return (
{family}
); })}
); const generateTable = (theme: Theme) => { const isDarkMode = !!(theme === Theme.Dark); return (

{theme} Mode

{Object.keys(color[theme]).map(type => ( {/* @ts-expect-error */} {Object.keys(color[theme][type]).map(variant => ( {/* @ts-expect-error */} {Object.keys(color[theme][type][variant]).map(state => ( ))} ))}
{type} default hover focus
{variant}
))}
); }; export const Colors = { render: () => { return (

Color Tokens

{Object.values(Theme).map(theme => generateTable(theme))}
); }, parameters: { chromatic: { disableSnapshot: true, }, }, }; export const Scrollbars: StoryObj = { parameters: { chromatic: { // TODO: skipping for now until we can get Chromatic to snapshot the scrollbars // https://github.com/storybookjs/storybook/discussions/31691#discussion-8425494 disableSnapshot: true, }, }, render: () => { return (
{Object.values(Theme).map((theme: Theme) => { const isDarkMode = theme === Theme.Dark; return [Variant.Primary, Variant.Secondary].map(variant => { const thumbColor = scrollbarColor[theme].thumb[variant].default; const trackColor = scrollbarColor[theme].track[variant].default; return (

{theme} Mode

{variant}

); }); })}
); }, play: async ({ canvasElement }) => { const cards = within(canvasElement).getAllByTestId('demo-card'); cards.forEach(card => { const scrollable = within(card).getByTestId('scrollable'); scrollable.scrollTo({ top: 12, left: 12, behavior: 'smooth', }); }); }, }; export const InteractionRings = () => { const invertTheme = (theme: Theme): Theme => theme === 'dark' ? 'light' : 'dark'; const themeWrapper = (theme: Theme) => css` display: flex; gap: ${spacing[200]}px; color: ${theme === 'dark' ? palette.white : palette.black}; background-color: ${theme === 'dark' ? palette.black : palette.white}; border: 1px solid ${theme === 'dark' ? palette.gray.light3 : palette.gray.dark3}; border-radius: ${spacing[400]}px; padding: ${spacing[600]}px; margin: ${spacing[400]}px 0; `; const buttonBase = css` font-family: ${fontFamilies.default}; font-size: ${typeScales.body2.fontSize}px; outline: none; background-color: unset; border: unset; padding: ${spacing[200]}px; border-radius: ${spacing[100]}px; cursor: pointer; transition: box-shadow ${transitionDuration.faster}ms ease-in-out; `; return (

Interaction States

{Object.values(Theme).map((theme: Theme) => (
{Object.keys(hoverRing[theme]).map(_color => { const color = _color as HoverRingColor; return ( ); })}
))}
); }; InteractionRings.parameters = { chromatic: { disableSnapshot: true, }, };