Skip to content

Commit

Permalink
Add additional Storybook v8 (#2865)
Browse files Browse the repository at this point in the history
* chore: make typescript aware of storybook-helper components

* chore: add build and cache directories to .gitignore

* chore: basic storybook repo setup

* chore: basic storybook setup & config

* feat: add components to storybook which allow demo'ing design tokens

* feat: add design token documentation to storybook

* chore: exclude storybook v8 source files from typecheck

* chore: exclude storybook v8 folder from es- & style-linting
  • Loading branch information
misama-ct authored Aug 2, 2024
1 parent 091c660 commit ea4a283
Show file tree
Hide file tree
Showing 58 changed files with 9,187 additions and 2 deletions.
1 change: 1 addition & 0 deletions jest.eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module.exports = {
'.cache',
'docs/.public',
'docs/public',
'storybook',
'dist',
],
testMatch: ['<rootDir>/**/*.js', '<rootDir>/**/*.ts', '<rootDir>/**/*.tsx'],
Expand Down
1 change: 1 addition & 0 deletions jest.stylelint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = {
modulePathIgnorePatterns: [
'dist',
'docs/public',
'storybook',
'.spec.js',
'.visualspec.js',
'.visualroute.js',
Expand Down
4 changes: 4 additions & 0 deletions storybook/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules/
.yarn/
.swc/
storybook-static/
76 changes: 76 additions & 0 deletions storybook/.storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import type { StorybookConfig } from '@storybook/react-vite';
import react from '@vitejs/plugin-react-swc';
import ViteYaml from '@modyfi/vite-plugin-yaml';
import remarkGfm from 'remark-gfm';
import { join, dirname, resolve } from 'path';

/**
* This function is used to resolve the absolute path of a package.
* It is needed in projects that use Yarn PnP or are set up within a monorepo.
*/
function getAbsolutePath(value: string) {
return dirname(require.resolve(join(value, 'package.json')));
}

const config: StorybookConfig = {
stories: [
'../src/docs/**/**.mdx',
'../../packages/components/**/*.stories.@(js|jsx|mjs|ts|tsx)',
'../../packages/components/**/*.mdx',
],
addons: [
//getAbsolutePath('@storybook/addon-webpack5-compiler-swc'),
getAbsolutePath('@storybook/addon-links'),
getAbsolutePath('@storybook/addon-a11y'),
getAbsolutePath('@storybook/addon-essentials'),
getAbsolutePath('@storybook/addon-interactions'),
{
name: '@storybook/addon-docs',
options: {
mdxPluginOptions: {
mdxCompileOptions: {
remarkPlugins: [remarkGfm],
},
},
},
},
],

framework: {
name: '@storybook/react-vite',
options: {},
},
docs: {
autodocs: 'tag',
defaultName: 'Props',
},

core: {
disableTelemetry: true,
},

staticDirs: ['../src/static'],

viteFinal: async (config, _options) => {
config.resolve = config.resolve || {};

// Our custom alias for better import statements
config.resolve.alias = {
...config.resolve.alias,
'@/storybook-helpers': resolve(__dirname, './../src/helpers'),
};

config.plugins?.push(
react({
jsxImportSource: '@emotion/react',
plugins: [['@swc/plugin-emotion', {}]],
})
);

config.plugins?.push(ViteYaml());

return config;
},
};

export default config;
9 changes: 9 additions & 0 deletions storybook/.storybook/manager-head.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<link href="./fonts/index.css" rel="stylesheet">

<style>
.sidebar-header img {
width: 192px !important;
max-width: 192px !important;
position: relative;
}
</style>
6 changes: 6 additions & 0 deletions storybook/.storybook/manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { addons } from '@storybook/manager-api';
import { cocoTheme } from './theme';

addons.setConfig({
theme: cocoTheme,
});
22 changes: 22 additions & 0 deletions storybook/.storybook/preview-head.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<link href="./fonts/index.css" rel="stylesheet">
<style>

.sbdocs-content *:not(pre):not(code):not(.token):not(.prismjs > div):not(.prismjs > div > span) {
font-family: 'Inter', monospace !important;
}

/* fixes an issue with positioned: fixed elements */
.docs-story :not(.sb-story *) {
transform: none;
}

table code {
/** make sure that e.g. long lists of unions etc. in prop-tables don't break the layout */
white-space: pre-wrap !important;
}

/** remove a default-margin from the table element, when it's DataTable */
.sbdocs-content table[class*="TableGrid"] {
margin: 0;
}
</style>
63 changes: 63 additions & 0 deletions storybook/.storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import type { Preview } from '@storybook/react';

import intlGlobalType from './../src/global-types/intl-global';

import '../../design-system/materials/resets.css';
import { WithIntlDecorator } from '../src/decorators/intl-decorator';
import { withThemeDecorator } from '../src/decorators/theme-decorator';

const preview: Preview = {
globalTypes: {
locale: intlGlobalType,
},
parameters: {
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
matchers: {
//color: /(background|color)$/i,
//date: /Date$/,
},
},
options: {
storySort: {
method: 'alphabetical',
includeNames: true,
order: [
'home',
['Start', '*'],
'Foundation',
['Readme', 'Choices', '*'],
'Text & Media',
[
'Text',
['Readme', 'Props', '*'],
'Icons',
['Readme', 'All Icons', '*'],
'*',
['Readme', 'Props', '*', ['Readme', 'Props', '*']],
],
'layout',
['*', ['Readme', 'Props', '*', ['Readme', 'Props', '*']]],
'components',
['*', ['Readme', 'Props', '*', ['Readme', 'Props', '*']]],
'form',
['*', ['Readme', 'Props', '*', ['Readme', 'Props', '*']]],
'field',
['*', ['Readme', 'Props', '*', ['Readme', 'Props', '*']]],
'unported',
['*', ['Readme', 'Props', '*', ['Readme', 'Props', '*']]],
],
},
},
},
// argTypes: {
// onBlur: { action: 'onBlur' },
// onChange: { action: 'onChange' },
// onFocus: { action: 'onFocus' },
// onInputChange: { action: 'onInputChange' },
// },
decorators: [withThemeDecorator, WithIntlDecorator],
tags: ['autodocs'],
};

export default preview;
47 changes: 47 additions & 0 deletions storybook/.storybook/theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { create } from '@storybook/theming/create';

export const cocoTheme = create({
// Mode
base: 'light',

// Brand
brandTitle: 'commercetools ui-kit',
brandUrl: './',
brandImage:
'https://unpkg.com/@commercetools-frontend/assets/logos/commercetools_primary-logo_horizontal_RGB.png',
brandTarget: '_self',

// Typography
fontBase: '"Inter", serif',
fontCode: 'monospace',

//
// colorPrimary: '#3A10E5',
// colorSecondary: '#585C6D',

colorPrimary: 'hsl(240, 64%, 58%)',
colorSecondary: 'hsl(195, 70%, 50%)',

// UI
//appBg: '#ff0000',
//appContentBg: '#ffffff',
//appPreviewBg: '#ffffff',
//appBorderColor: '#585C6D',
//appBorderRadius: 4,

// Text colors
textColor: '#1a1a1a',
textInverseColor: '#ffffff',

// Toolbar default and active colors
//barTextColor: '#9E9E9E',
barSelectedColor: 'hsl(240, 64%, 58%)',
barHoverColor: 'hsl(240, 64%, 40%)',
//barBg: '#ffffff',

// Form colors
//inputBg: '#ffffff',
//inputBorder: '#10162F',
//inputTextColor: '#10162F',
//inputBorderRadius: 2,
});
39 changes: 39 additions & 0 deletions storybook/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Storybook

This repository contains all storybook related configuration.

## Development

Install all dependencies by running the following command in your terminal after entering the directory:

```
yarn
```

> You need to have `Node 18` and `yarn` installed on your system.
After all dependencies are installed you can start the development environment by running the following command:

```
yarn start
```

This will open storybook in your browser. You can now start adding new components or modifying existing ones.

## Creating a build

To create a storybook production-build, run the following command:

```
yarn run build
```

The build-files will end up in `./storybook-static` and can be served _as-is_.

## Testing the build locally

To serve a local production build you can run the following command, it will create the production build and serve it:

```
yarn run storybook-static
```
36 changes: 36 additions & 0 deletions storybook/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"name": "@commercetools-local/storybook",
"version": "0.0.0",
"private": true,
"devDependencies": {
"@chromatic-com/storybook": "^1.6.1",
"@emotion/css": "^11.10.5",
"@emotion/react": "^11.10.5",
"@emotion/styled": "^11.10.5",
"@modyfi/vite-plugin-yaml": "^1.1.0",
"@storybook/addon-a11y": "^8.2.6",
"@storybook/addon-essentials": "^8.2.6",
"@storybook/addon-interactions": "^8.2.6",
"@storybook/addon-links": "^8.2.6",
"@storybook/addon-onboarding": "^8.2.6",
"@storybook/addon-themes": "^8.2.6",
"@storybook/blocks": "^8.2.6",
"@storybook/react": "^8.2.6",
"@storybook/react-vite": "^8.2.6",
"@storybook/test": "^8.2.6",
"@swc/plugin-emotion": "^3.0.10",
"@vitejs/plugin-react-swc": "^3.7.0",
"prop-types": "15.8.1",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-intl": "^6.3.2",
"serve": "^14.2.3",
"storybook": "^8.2.6"
},
"scripts": {
"start": "storybook dev -p 6006",
"build-and-serve": "yarn build & yarn serve",
"build": "NODE_ENV=production storybook build",
"serve": "serve"
}
}
1 change: 1 addition & 0 deletions storybook/scripts/postinstall.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#!/usr/bin/env bash
6 changes: 6 additions & 0 deletions storybook/serve.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"public": "./storybook-static",
"cleanUrls": false,
"directoryListing": false,
"redirects": [{ "source": "/", "destination": "/index.html" }]
}
56 changes: 56 additions & 0 deletions storybook/src/components/decision-group.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// @ts-expect-error
import definition from './../../../design-system/materials/internals/definition.yaml';
import DataTable from '@commercetools-uikit/data-table';

function get(obj: object, path: string, defaultValue = undefined) {
const keys = path.split('.');
let result = obj;

for (let key of keys) {
if (result && result.hasOwnProperty(key)) {
// @ts-expect-error
result = result[key];
} else {
return defaultValue;
}
}

return result;
}

type TToken = Record<string, string>;

interface TTokenGroupProps {
path: string;
group:
| string
| {
label: string;
prefix: string;
choices: TToken[];
};
}
export const DecisionGroup = ({ path }: TTokenGroupProps) => {
// @ts-expect-error
const { decisions } = get(definition, path) || {};

if (!decisions) {
return <pre>{JSON.stringify(definition, null, 2)}</pre>;
}

const rows = Object.keys(decisions).map((choiceKey) => {
const { choice } = decisions[choiceKey];

return {
id: choiceKey,
value: choice,
};
});

const columns = [
{ key: 'id', label: 'Name' },
{ key: 'value', label: 'Value' },
];

return <DataTable rows={rows} columns={columns} footer={null} />;
};
Loading

0 comments on commit ea4a283

Please sign in to comment.