As this design system will be used among multiple products and multiple teams, we prefer consistency above all. So the best way to know how to do something new is to look around.
Before writing a Component you must know what problem it is supposed to solve and in what context to use it. Before adding a new Component, please see if the Component does not already exist, or the problem is not already solved by another Component. As a general advice, you should ask the assigned designer what to do and make sure you have everything you need to start implementing your new Component.
- Create a branch (
git checkout -b branch_name
) - Use the included Component generator
- Start Storybook in dev mode
$ front/akeneo-design-system/bin/dsm generate ComponentName
$ npm --prefix front/akeneo-design-system run storybook:start
# Or with Docker
$ docker compose run --rm -p 6006:6006 node npm --prefix front/akeneo-design-system run storybook:start
- Then implement your Component logic in the newly created file
src/components/ComponentName/ComponentName.tsx
- First of all define all properties that your Component requires, using TypeScript to type them the most strongly possible
- For closed choice property, prefer type union ('primary' | 'secondary' | 'danger') instead of Enum
- If you have a doubt, don't hesitate to ask on #pim-frontend
- Add JSDoc on all your properties (these comments will be used as descriptor in Storybook)
- Style your Component with styled-components
- If necessary, add icons in the folder
src/icons/
(color & size should be configurable) - Make sure
forwardRef
management works properly on your Component (https://reactjs.org/docs/forwarding-refs.html) (should be automatically done by the generator) - Make sure you forward ...props to your Component (should be automatically done by the generator)
- Make your Component accessible (https://developer.mozilla.org/en-US/docs/Web/Accessibility)
- Your component should react to keyboard events if relevant
- Your component should be describable (
aria-label
,alt
, etc) and readable by screen readers - Your component should be focusable if relevant.
- First of all define all properties that your Component requires, using TypeScript to type them the most strongly possible
- Write the related Story of your Component
src/components/ComponentName/ComponentName.stories.tsx
(should be automatically generated by the generator)- Copy and paste
Usage introduction
andGeneral guidance
paragraph from the notion design system page - Define all
argTypes
- Use
control
when your property expects a value (string, number, boolean, enum ...), you can retrieve full list of control types here. - Use
action
when your property expects a callback relative to an action on the Component (https://storybook.js.org/docs/react/essentials/actions)
- Use
- Define
arg
when you want a specific default value - Write all variations of your Component
- Be careful, on the notion page, the variation are not always relevant and some should not be implemented this way.
- Variations should only vary on one prop at a time
- Copy and paste
- Complete the unit test file generated earlier
src/components/ComponentName/ComponentName.unit.tsx
- Add unit tests to validate all Component behaviours
- Commit and push your change
- Open a pull request (Github Action will be automatically launched)
- Github Action will assign you a pull request to alert you that new stories found, review it and merge it when it looks good for you
- Github Action will deploy a new version of the storybook give the url to designer for review
If you update the style of one Component, the visual test will fail. Github Action will assign you a pull request to alert you that Component changed, review it and merge it when it looks good for you.
Github Action will deploy a new version of the storybook give the url to designer for review.
- Component should be strongly typed with TypeScript
- All properties should be documented
- Simple components should be stateless
- Coding style should follow rules defined in .eslintrc (
npm run lint:check
) - Component should manage forwardRef and ...props
- Component should provide aria attributes if necessary
- Components should be keyboard accessible
- Component should not have hardcoded color, it should use color in theme
- Component should use CSS-in-JS with styled-components
- Components should follow the compound components pattern.
- All stories should be in MDX format
- Story should describe when the Component should be used
- All properties should be editable by the user
- Story should display all possible variations
- Variations should describe itself through value label when it's possible
import {Meta, Story, ArgsTable, Canvas} from '@storybook/addon-docs';
import {ComponentName} from './ComponentName';
<Meta
title="Components/ComponentName"
component={ComponentName}
argTypes={{
arg1: {control: {type: 'select', options: ['default', 'small']}},
arg2: {control: {type: 'boolean'}},
onArg3: {action: 'Click on the button'},
}}
args={{
arg1: 'default',
}}
/>
# Name of the Component
## Usage
_Describe what problem the Component is supposed to solve_
### General guidance
_Describe when the Component should be used_
_Describe each element on the component_
## Playground
<Canvas>
<Story name="Standard">
{args => {
return <ComponentName {...args} />;
}}
</Story>
</Canvas>
## Variation through arg1
_Show all possible variations that allow user to have a better overview of the Component capabilities_
<Canvas>
<Story name="Variation through arg1">
{args => {
return (
<>
<ComponentName {...args} arg1="default">
Default
</ComponentName>
<ComponentName {...args} arg1="small">
Small
</ComponentName>
</>
);
}}
</Story>
</Canvas>
## Variation through arg2
<Canvas>
<Story name="Variation through arg2">
{args => {
return (
<>
<ComponentName {...args} arg2={false}>
Default
</ComponentName>
<ComponentName {...args} arg2={true}>
Arg2 activated
</ComponentName>
</>
);
}}
</Story>
</Canvas>
- Test should use Jest
- Test should use React Testing Library