Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v22.12.0
56 changes: 56 additions & 0 deletions src/tokens/colors/color.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import type { Meta, StoryObj } from '@storybook/react';
import tokens from '../transformed.tokens.json';
import ColorTokens from './color';

const meta = {
title: 'Tokens/Colors',
component: ColorTokens,
} satisfies Meta<typeof ColorTokens>;

export default meta;
type Story = StoryObj<typeof meta>;
export const Colors: Story = {
args: {
colors: Object.keys(tokens.color).map((name) => {
const colorGroup = tokens.color[name];

// If it's a direct color token (no further nesting)
if (colorGroup.value) {
return {
name,
variants: [
{
name: null,
value: colorGroup.value,
type: colorGroup.type,
description: colorGroup.description,
},
],
};
}

// Handle nested structures (recursively flatten)
const processVariants = (data: any, parentKey = ""): any[] => {
return Object.entries(data).flatMap(([key, value]) => {
const currentKey = parentKey ? `${parentKey}-${key}` : key;

if ((value as any).value) {
return {
name: currentKey,
value: (value as any).value,
type: (value as any).type,
description: (value as any).description,
};
} else {
return processVariants(value, currentKey);
}
});
};

return {
name,
variants: processVariants(colorGroup),
};
}),
},
};
61 changes: 61 additions & 0 deletions src/tokens/colors/color.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React from 'react';
// Utility classes for token display components.
import clBase from '../../foundation/utility/cl-base.module.scss';

type ColorToken = {
name?: string;
value: string;
type: string;
description?: string;
};

type ColorTokensProps = {
colors: {
name: string;
variants: ColorToken[];
}[];
};
export default function ColorTokens({
colors,
}: ColorTokensProps) {
return (
<div>
<h2 className={clBase['sb-title']}>Colors</h2>
{colors.map((colorGroup) => (
<div key={colorGroup.name}>
<h2 className={clBase['sb-subtitle']}>{colorGroup.name}</h2>
<ul className={clBase['sb-list']}>
{colorGroup.variants.map((variant) => (
<li
className={`${clBase['sb-list__item']} token-card`}
key={`${colorGroup.name}-${variant.name}`}
>
<span className={clBase['sb-list__label']}>{variant.name ?? colorGroup.name }</span>
<span className={clBase['sb-list__value']}>{variant.value}</span>
<span className={clBase['sb-list__custom-property']}>
<code className={clBase['sb-custom-property-name']}>
var(--color-{colorGroup.name
.toLowerCase()
.replace("emulsifyblue", "emulsify-blue")}{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we do this replacement in the story instead of the component? Ideally the component should get a clean list of values and only display them.

variant.name ? `-${variant.name}` : ""
})
</code>
</span>
<span
className={clBase['sb-list__visualization']}
style={{
backgroundColor: `var(--color-${colorGroup.name
.toLowerCase()
.replace("emulsifyblue", "emulsify-blue")}${
variant.name ? `-${variant.name}` : ""
})`,
}}
></span>
</li>
))}
</ul>
</div>
))}
</div>
);
}