Design System
Source of truth: https://zeroheight.com/239aea73f
Installation
In order to get the design system on your app fully functional you need to
- Install it
npm i --save -E @stordata/design-system - Add the style in your
<App>->import '@stordata/design-system/style.css'; - Add a
<DSProvider>over you<App>-><DSProvider><App /></DSProvider> - Optionally add a theme to your
<DSProvider>to overload default properties - Now you're ready to enjoy the beauty and strength of our powerful DS components !
Optional
If you want to use DSDataGrid, a styled MaterialUI DataGrid component, please also install the following dependencies
npm i --save -E @mui/material @mui/x-data-grid-premium @emotion/react @emotion/styled
Using the design system
DSProvider
Before you can use any design system component, you need to render your application inside a <DSProvider> component.
This component provides the theme to all design system components, as well as a few other utility functions like localization, responsiveness, etc.
import DSProvider from '@stordata/design-system/DSProvider';
export default function App() {
return (
<DSProvider>
<YourApp />
</DSProvider>
);
}
The provider accepts a locale prop that is used by a few components that render localized text. It also accepts a theme prop
that you can use to customize how design system components look and behave. See below for more details.
Theming
The DSProvider component can be given a Theme object to customize
- Default properties for all components
- Color mode, color palettes, semantic tokens, typography, etc.
- Animation durations and easing functions
- Responsive breakpoints, spacing, and a few other layout-related settings
Default styling
To change default styles for a specific component, include a stylesheet in your application targeting the component:
.ds.ds-stack {
flex-direction: row;
}
The convention for classnames is
- All design system stuff have the
dsclass - All design system components have the
ds-componentclass - Every specific component has a
ds-<name>class, where<name>is the name of the component in lower, snake case
:bulb: It is recommended to always use the .ds class, just in case.
On-the-fly styling
All components support the sx prop, which is an enhanced style prop adding some features:
- Responsiveness support for all properties. See below for an example.
- The
modeproperty that can be used to override the color mode for a single component (e.g.: rendering a neutral button on a dark surface)
Responsiveness is supported through an object notation where keys are the breakpoints and values are the property value to use
when the corresponding breakpoint is active. Breakpoints are applied from smallest to largest, in a mobile-first fashion.
The example below would change the text color based on the screen size:
<DSStack
sx={{
color: {
xs: 'red',
sm: 'blue',
md: 'green',
lg: 'yellow',
xl: 'purple'
}
}}
>
Responsive text color
</DSStack>
<DSButton sx{{ mode: 'dark' }}>
This button renders in dark mode
</DSButton>
Conventions
Implementation
A component should either
- Render a native HTML element, or
- Render a component provided by BaseUI
All components support the render prop from BaseUI. This prop is either forwarded to the root component, when rendering a
BaseUI component, or used through the useRender hook when rendering a native HTML element, allowing further customization.
All components support a set of common properties:
- id
- className
- style
- ref (a React ref)
When implementing a new component, you should
- Write a TypeScript interface for the component props, extending the common properties and
HTMLAttributes<T>(or a sub-interface) to inherit default HTML props. - Use the
useMergePropsto merge default properties coming from the theme with the properties passed to the component. - Add a section to the
Themeinterface for the default props of your new component, and choose default values.
Props
Except for component-specific props (like variant, size, etc.), all components should support spread props on the root element.
This is automatically handled by useRender when rendering a native HTML element, but needs to be manually done for BaseUI components.
This allows all native HTML props (like style, onClick, etc.) to be forwarded.
Refs
All components accept a ref that should always be used. Either
- Forwarded to a BaseUI component (all of them accept refs), or
- Given to
useRenderhook when rendering a native HTML element. See https://base-ui.com/react/utils/use-render#merging-refs
Styling
Styling is done using a CSS module per component.
All CSS modules should always start with a root class, typically .<component name> that is applied to the root element of the component.
When typing common styling properties, such as color or size, please always define a TypeScript type for the property,
and use it in the component props interface. If the same set of values as the common ones is supported, you can use a type alias.
For instance
export type DSMyComponentSize = ComponentSize;
Sizing
When applicable, components should support a size property that can be set to small, medium or large. The default size is medium.
In the component's CSS module, .small, .medium and .large classes should be defined to apply the appropriate styles for each size.
When rendering the component, use the classNames utility to apply the appropriate size class based on the size property.
:bulb: It's OK to only support a subset of the available sizes.
Variants
When applicable, components should support a variant property that can be set to primary, secondary or tertiary. The default variant is primary.
In the component's CSS module, .primary, .secondary and .tertiary classes should be defined to apply the appropriate styles for each variant.
When rendering the component, use the classNames utility to apply the appropriate variant class based on the variant property.
:bulb: It's OK to only support a subset of the available variants.
Line height
As a general rule, don't override the line-height CSS property. It makes vertical alignment difficult, especially with icons next to text.
Whenever required, use an override in DSTypography to set a custom line-height on a variant.
Testing
To run the tests, make sure you have Docker installed first.
Run docker compose up -d to start the required containers, and then npm test to run the Vitest tests.
Coverage
Run npm run coverage to run the tests once with code coverage (V8). It prints a summary and writes an HTML report in coverage/.
In the CI, the coverage must not decrease compared to the main branch, whose coverage reports can be browsed online at https://coverage.stordata.dev/stordata/design-system/
Update Chromium container to match vitest playwright version
Pull the browserless image
docker pull ghcr.io/browserless/chrome:v2.xx.x
Tag it to our registry
docker tag ghcr.io/browserless/chrome:v2.xx.x docker.stordata.fr/docker.io/chrome:v2.xx.x
Pull it from our registry to test locally if everything is now fixed
docker push docker.stordata.fr/docker.io/chrome:v2.xx.x