Skip to content

chore(demo): refactor storybook #1265

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 80 commits into from
Jan 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
7fbcf73
Refactor `new` script
jzempel Nov 20, 2021
2d976e7
Update template stories
jzempel Nov 22, 2021
3ec686e
Update template element components
jzempel Nov 22, 2021
2bb693c
Add template subcomponent
jzempel Nov 24, 2021
3ff6e39
Update template tests
jzempel Nov 24, 2021
3ef3ee9
Merge branch 'main' into jzempel/enhance-new
jzempel Nov 24, 2021
5882deb
Fix prettier format check
jzempel Nov 24, 2021
d2c722b
Merge branch 'jzempel/enhance-new' into jzempel/refactor-storybook
jzempel Nov 24, 2021
f700179
Configure storybook to process package "demo" folders
jzempel Nov 24, 2021
aa976f0
Initial accordion stories
jzempel Nov 25, 2021
d0a6735
Refactor accordion and stepper stories
jzempel Nov 25, 2021
75b8d9c
Refactor timeline story demo
jzempel Nov 25, 2021
0272d63
Update template
jzempel Nov 27, 2021
34a94f6
Update template
jzempel Nov 27, 2021
a440d4c
Update formatting/linting
jzempel Nov 27, 2021
59eb499
Refactor tooltip demo stories
jzempel Nov 27, 2021
5e82f6b
Remove refactored stories
jzempel Nov 27, 2021
7207114
Refactor breadcrumb demo stories
jzempel Nov 27, 2021
39611ba
Categorize stories under "Packages"
jzempel Nov 27, 2021
fe8038f
Fix invalid role applied to component SVGs
jzempel Nov 27, 2021
62c529c
Refactor button demo stories
jzempel Nov 27, 2021
9460c0b
Fix import
jzempel Nov 27, 2021
d35afcf
Switch from useState to useArgs for controlled examples
jzempel Nov 29, 2021
8583cf3
Refactor colorpicker demo stories
jzempel Nov 29, 2021
b383e89
Refactor datepicker demo stories
jzempel Nov 29, 2021
f7ffa97
Fix readme sort order
jzempel Nov 29, 2021
acfa3ec
Initial refactor for typography demo stories
jzempel Nov 30, 2021
03a95fe
Refine template mdx
jzempel Nov 30, 2021
bb31a6e
Finesse story automation
jzempel Nov 30, 2021
b2948e1
Refactor blockquote demo story
jzempel Nov 30, 2021
8cb9dd0
Merge branch 'main' into jzempel/refactor-storybook
jzempel Nov 30, 2021
3018456
Update size snapshots
jzempel Dec 1, 2021
0ee13b4
Remove unwanted merge files
jzempel Dec 1, 2021
ed5bee9
Expose typography interfaces
jzempel Dec 1, 2021
7d7d066
Refactor typography demo stories
jzempel Dec 1, 2021
1d4a276
Refactor notification demo stories
jzempel Dec 2, 2021
fcc693e
Merge branch 'main' into jzempel/refactor-storybook
jzempel Dec 2, 2021
56680fa
Initial refactor of loaders demo stories
jzempel Dec 3, 2021
1f3b3d9
Fix tsc
jzempel Dec 3, 2021
1d5bdd4
Add control for number of skelton loaders
jzempel Dec 3, 2021
cc8c11c
Refactor avatar demo stories
jzempel Dec 3, 2021
89e9afc
Add avatar-chrome pattern controls
jzempel Dec 3, 2021
d594ac5
Add background color story control
jzempel Dec 4, 2021
745a915
Refactor menu demo stories
jzempel Dec 4, 2021
ef2604f
Refactor dropdown select demo stories
jzempel Dec 5, 2021
86dc841
Refactor modal demo story
jzempel Dec 7, 2021
fd45036
Refactor DrawerModal demo stories
jzempel Dec 7, 2021
0177083
Upgrade to latest storybook
jzempel Dec 7, 2021
3444e04
Add figma designs to storybook
jzempel Dec 9, 2021
0b76896
Refactor tooltip modal demo story
jzempel Dec 9, 2021
9b59c75
Refactor loader demo stories
jzempel Dec 9, 2021
c5d63f1
Refactor tags demo stories
jzempel Dec 10, 2021
47dc87a
Refactor pagination demo stories
jzempel Dec 10, 2021
0a3401f
Refactor tabs demo stories
jzempel Dec 10, 2021
53c325e
Refactor table demo stories
jzempel Dec 12, 2021
32f4637
Refactor chrome demo stories
jzempel Dec 15, 2021
51d6ba7
Add CollapsibleSubNavItem demo stories
jzempel Dec 15, 2021
82d5d0d
Demonstrate Sheet.Footer isCompact
jzempel Dec 15, 2021
03324ce
Refactor grid demo stories
jzempel Dec 17, 2021
48021b8
Grid demo refinements
jzempel Dec 17, 2021
8d9fac3
Initial refactor of forms demo stories
jzempel Dec 18, 2021
4eb3298
Continued forms demo stories refactor
jzempel Dec 19, 2021
ce256ea
Continued refactor form demo stories; reconfigure "patterns" stories
jzempel Dec 20, 2021
6dc9a45
Refactor InpuGroup demo stories
jzempel Dec 20, 2021
79393bb
Remove refactored forms stories
jzempel Dec 20, 2021
763d293
Resolve storybook static-dirs deprecation
jzempel Dec 20, 2021
8a3f3de
Abstract dropdown demo stories
jzempel Dec 21, 2021
82561ad
Refactor dropdowns demo stories
jzempel Dec 22, 2021
6cc5490
Fix type
jzempel Dec 22, 2021
1f07566
Refactor theming demo stories
jzempel Dec 23, 2021
2670c93
Add demo documenation
jzempel Dec 27, 2021
b66a606
Merge branch 'main' into jzempel/refactor-storybook
jzempel Dec 27, 2021
f9e0a64
Fix lint error
jzempel Dec 27, 2021
fe49dd3
Fix svgo configuration
jzempel Dec 28, 2021
595e2d3
Update size snapshots based on SVGO changes
jzempel Dec 28, 2021
c7cfb32
Zero out padding to make box-sizing differences more obvious
jzempel Jan 3, 2022
fa8baab
Address comments from @Francois-Esquire
jzempel Jan 4, 2022
862e979
Remove unused static images
jzempel Jan 4, 2022
c31bae4
Recategorize Sheet controls
jzempel Jan 4, 2022
6bcf661
Restore missing `isPrimary` control
jzempel Jan 5, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
},
{
"files": ["packages/**/*.{js,ts,tsx}"],
"excludedFiles": ["*.spec.*", "packages/**/stories/**/*"],
"excludedFiles": ["*.spec.*", "packages/*/demo/**/*"],
"plugins": ["garden-local"],
"rules": {
"garden-local/require-default-theme": "error"
Expand Down
2 changes: 1 addition & 1 deletion .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ on your system. After you clone this repo, run `yarn` to install
dependencies needed for development. After installation, the following
commands are available:

- `yarn start` to launch Styleguidist with live reload.
- `yarn start` to launch Storybook with live reload.
- `yarn test` to run Jest testing.
- `yarn lint` to enforce consistent JavaScript, CSS, and
markdown code conventions across all component packages. Note this is
Expand Down
2 changes: 1 addition & 1 deletion .lintstagedrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"jest --config=utils/test/jest.config.js --bail --findRelatedTests",
"prettier --write"
],
"!(*CHANGELOG).md": [
"!(*CHANGELOG).{md,mdx}": [
"markdownlint",
"prettier --write"
],
Expand Down
5 changes: 3 additions & 2 deletions .markdownlintrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
"default": true,
"first-line-h1": false,
"first-header-h1": false,
"MD013": {
"line-length": {
"line_length": 100,
"tables": false
}
},
"no-inline-html": false
}
4 changes: 2 additions & 2 deletions .storybook/babel.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@

const path = require('path');
const { readdirSync } = require('fs');
const babel = require('@storybook/core-common/dist/cjs/utils/babel');
const { getStorybookBabelConfig } = require('@storybook/core-common');

const config = babel.getStorybookBabelConfig();
const config = getStorybookBabelConfig();

const PACKAGE_NAMES = readdirSync(path.resolve(__dirname, '../packages')).filter(
name => name !== '.template'
Expand Down
15 changes: 9 additions & 6 deletions .storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,18 @@
*/

const webpack = require('webpack');
const externalConfig = require('../.svgo.config.js');
const svgoConfig = require('../.svgo.config.js');
const ESLintPlugin = require('eslint-webpack-plugin');
const docs = process.env.BROWSER ? process.env.BROWSER.toUpperCase() !== 'IE11' : true;

module.exports = {
stories: ['../packages/*/stories/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
addons: [{ name: '@storybook/addon-essentials', options: { docs } }, '@storybook/addon-a11y'],
stories: ['../packages/*/demo/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
staticDirs: ['./static'],
addons: [
{ name: '@storybook/addon-essentials', options: { docs } },
'@storybook/addon-a11y',
'storybook-addon-designs'
],
core: {
builder: 'webpack5'
},
Expand All @@ -26,9 +31,7 @@ module.exports = {
use: [
{
loader: '@svgr/webpack',
options: {
externalConfig
}
options: { svgoConfig }
}
]
});
Expand Down
1 change: 1 addition & 0 deletions .storybook/manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { addons } from '@storybook/addons';
import { DEFAULT_THEME } from '../packages/theming/src';

addons.setConfig({
panelPosition: 'right',
Copy link
Member Author

Choose a reason for hiding this comment

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

This default layout makes better UX sense for component-controls testing.

theme: create({
brandTitle: 'Zendesk Garden React Components',
brandUrl: 'https://github.com/zendeskgarden/react-components',
Expand Down
5 changes: 4 additions & 1 deletion .storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ export const parameters = {
grid: { disable: true }
},
controls: {
hideNoControlsWarning: true
hideNoControlsWarning: true,
sort: 'alpha'
},
docs: {
theme: create({
Expand All @@ -29,6 +30,8 @@ export const parameters = {
const GlobalPreviewStyling = createGlobalStyle`
body {
background-color: ${p => p.theme.colors.background};
/* stylelint-disable-next-line declaration-no-important */
padding: 0 !important;
font-family: ${p => p.theme.fonts.system};
}
`;
Expand Down
Binary file added .storybook/static/images/avatars/user.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion .svgo.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module.exports = {
focusable: false
},
{
role: 'presentation'
'aria-hidden': true
Copy link
Member Author

Choose a reason for hiding this comment

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

This clears out SVG errors seen in Storybook's a11y tab and applies the correct accessibility semantics for visually decorative Garden icons. See https://css-tricks.com/accessible-svgs/#example-2-standalone-icon-decorative for details.

}
]
}
Expand Down
222 changes: 222 additions & 0 deletions docs/demo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
# Garden demos

Garden leverages [Storybook](https://storybook.js.org/) for generating component
demos with story controls. Run `yarn start` to build and serve package demos in
development mode (with hot reloading).

The development goal for demos is to render components in isolation with the
least amount of structural scaffolding together with the greatest amount of
control for content and flexibility. Along with global toolbar items (preview
size, locale direction, CSS Bedrock, etc), controls should stress every aspect
of a component's layout and behavior.

## Best practice

The following list of dos and don'ts outline demo code expectations.

### Do this

- Expose controls for all essentials – inherent props, conditional subcomponent
renders, child content
- Allow natural component layout – full width for block, partial width for inline
- Use the Garden `Grid` to manage layout for components that respond to
placement values (start, end, top, bottom, etc)
- Rely on `useArgs` from Storybook's client API in order to keep component state
connected with it's associated Storybook control

### Not this

- Avoid `styled-components`. The addition of demo CSS is an indicator that the
underlying component may not offer comprehensive styling.
- Refrain from adding component documentation. The Storybook demos are not a
substitute for the [garden.zendesk.com](https://garden.zendesk.com/) website.
The website is the source of truth for component documenation.
- Avoid `useState`; prefer Storybook `useArgs` instead
- Do not write "Default" vs "Advanced" stories. A well-written component story
will render as expected with defaults and offer controls to push into advanced
component capabilities. See the [patterns](#patterns) section below for cases
that extend beyond the consideration of an isolated component.
- Do not use numeric file naming. By following the [naming](#naming) conventions
listed below, component stories will be naturally sorted alphabetically.

## Conventions

Stick to the following conventions for authoring demo stories that are
consistent with the existing codebase. You may find that running `yarn new` is
helpful for auto-generating component demo scaffolding.

### Structure

- Place MDX stories under the package `demo` directory.
- All `Story` TSX files are placed under a `demo/stories` directory.
- Move all boilerplate data constants (i.e. control data for a component's
`children`) into `demo/stories/data.ts`
- Capture all types and interfaces specific to story data under
`demo/stories/types.ts`
- If a package has patterns (see [section](#patterns) below), tuck all pattern
demo code under a `demo/~patterns` directory – repeating the directory structure
as needed for `Story` TSX, `data.ts`, and `types.ts` files noted above. Prefix
with a tilde to ensure these stories are ordered last.

### Meta

Story meta appears in the MDX file with the following structure:

```mdx
<Meta
title="Packages/Package/Component"
component={Component}
subcomponents={{...}} />
```

- The `Component` is the element-level component that this story is focused on
- Use the optional `subcomponents` object whenever subcomponents exist in
support of the main element component. Keep this list in alphabetical order.

### ArgsTable

The next simple section of MDX generates prop tables for the component and
subcomponents identied by the story meta. These tables can be viewed under the
Storybook "Docs" tab.

```mdx
# API

<ArgsTable />
```

### Canvas story (or stories)

The canvas story specifies a name, args, argTypes, parameters, and the rendered
story itself. In its most basic form:

```mdx
# Demo

<Canvas>
<Story name="Component">{args => <Component {...args} />}</Story>
</Canvas>
```

Often a single story is enough to fulfill the development goal for an isolated
and flexible component demo. But sometimes, in the case of uncontrolled vs.
controlled, there is a need to render multiple stories. In this case, the basic
MDX form is modified to be:

```mdx
# Demo

## Uncontrolled

<Canvas>
<Story name="Uncontrolled">{args => <ComponentStory {...args} />}</Story>
</Canvas>

## Controlled

<Canvas>
<Story name="Controlled">
{args => {
const updateArgs = useArgs()[1];
const handleEvent = argName => updateArgs({ argName });
return <ComponentStory {...args} onEvent={handleEvent} />;
}}
</Story>
</Canvas>
```

Note how the `ComponentStory` is reused for both canvas stories. See
[Story](#story) below for additional details. Be sure to move common `args`,
`argTypes`, and `parameters` under the MDX `<Meta>` rather than repeating these
under each story.

#### Story `args`

- Storybook automatically provides main component props as `args`. Usually there
is no need to specify these values (double-check for missing prop controls). One
notable exception is for Garden boolean prop values that default to `true`. In
this case, the `args` should be specified to match.
- Select smart defaults for the remaining subcomponent or "Story" `args`.
Sometimes the best choice is to leave an arg undefined.

#### Story `argTypes`

Standard convention for `argTypes` exists across dozens of existing stories.
Study demo code for details. Most importantly, main component props that are
_not_ auto-generated must be properly categorized. The two acceptable story
categories are:

- Subcomponent. All subcomponent props (including `children`) are specified
under the associated subcomponent name.
- "Story". This category includes all ancillary controls that are needed to
stress the full flexibility of the rendered component(s).

#### Story `parameters`

Currently, story `parameters` are used to link to the Figma page(s) or frame(s)
that best exhibits associated component designs. Note that the parameter URLs
are internal-only and point to designs that exist in the main Garden Figma
branch. Therefore, `parameters` may need to be added as a follow-on for new
components.

### Story

A `Story` type component is the best way to develop demo code for non-trivial
Garden components. Doing so removes complexity of coding in MDX, placing
component rendering and application of story args into TypeScript where code can
be properly maintained. In its basic form, a `Story` looks like this:

```tsx
import React from 'react';
import { Story } from '@storybook/react';
import { Component, IComponentProps } from '@zendeskgarden/react-package';

interface IArgs extends IComponentProps {
/* Subcomponent and "Story" arg definitions go here */
}

export const ComponentStory: Story<IArgs> = args => <Component {...args} />;
```

Take time to ensure Story `args` and `argTypes` are defined well. Often you will
find that the majority of demo development time is spent on `args` and
`argTypes` and the `Story` itself essentially falls out of the goal to
demonstrate component flexibility in isolation.

## Naming

- Follow the existing Storybook naming hierarcy:
`Packages/{{PackageName}}/{{ComponentName}}`
- The first story in every package demo should be a `#readme.stories.mdx` file
that renders the package's README.md. Prefix with a hashtag to ensure this story
is ordered first.
- Subsequent component story files are named `componentName.stories.mdx`
(camelCase)
- Use Garden's standard prop naming for story args (i.e. isXxx/hasXxx for
boolean args), but use `argTypes` to rename with subcomponent notation. For
example:

```js
args={{
hasHint: true
}}
argTypes={{
hasHint: { name: Hint, table: { category: 'Story' } }
}}
```

## Patterns

A pattern is a demo story that highlights a component's ability to work together
with other Garden components or in conjunction with external libraries.
Oftentimes, a pattern ends up violating the best practice of duplicating example
documentation that belongs on the website. However, due to component development
sequencing or a need to persist a visual test, a pattern can be a helpful tool
for (temporarily) demonstrating component layout or behavior that supercedes the
isolation of the component itself.

Follow [structure](#structure) conventions to keep patterns collected in a
(potentially) short-lived location. It is the component developer's
responsibility to track example pattern movement to the website and subsequently
remove the pattern from Storybook – keeping the website as the focal source of
truth.
25 changes: 7 additions & 18 deletions docs/development.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Garden Development
# Garden development

You're here because you want to get into the codebase. That's great. This
guide will help you dig in. If you haven't already, please see the
Expand All @@ -25,7 +25,7 @@ All packages follow this basic structure (.e.g. under `/packages/test`):

<!-- markdownlint-disable -->

- `β”œβ”€β”€ examples/` – visual component examples and generated documentation
- `β”œβ”€β”€ demo/` – visual component demos
- `β”œβ”€β”€ src/` – component source code and spec tests<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`β”œβ”€β”€ elements/` – high abstraction components that wrap interaction behavior and visual styling<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`β”œβ”€β”€ styled/` – view-level [styled-components](https://styled-components.com/) that contain theme based CSS<br>
Expand All @@ -40,23 +40,12 @@ The Garden React codebase is statically type-checked using
documentation for in-depth treatment of Garden's Container-View-Element
architecture, along with rules that apply to each component type.

## Package examples
## Package demos

Package example documentation is generated via [React
Styleguidist](https://react-styleguidist.js.org/). Run `yarn start` to build
and serve package documentation in development mode (with hot reloading). The
[global configuration](/utils/styleguide/styleguide.base.config.js) is
extended by a package-local `styleguide.config.js` which determines section
structure and content for each package page.

In general, an example page includes:

- the package README
- a "knobs" style example that toggles various visual component states
- API prop sheets for all public element exports

Include additional example files to demonstrate complex component behaviors
or common interactions with other Garden components.
Package demo code is generated via [Storybook](https://storybook.js.org/). Run
`yarn start` to build and serve package documentation in development mode (with
hot reloading). See [demo documentation](/docs/demo.md) for development
information.

## Package testing

Expand Down
Loading