A UI component library based on the design system of the canton of zurich.
This package is still in alpha state. It is not recommended to use it in production yet.
Node.js > v18.0.0
npm i @statistikzh/leu
In order for the components to work, you need to load the theme styles and the font definitions globally.
The theme file is part of the package (dist/theme.css
).
The fonts on the other hand have to be licensed and are therefore not included in the package.
If you have an environment that resolves bare module imports, you can use the library like this:
<link rel="stylesheet" href="https://github.com/statistikZH/leu/blob/main/@statistikzh/leu/theme.css" />
<script type="module">
import "@statistikzh/leu/leu-input.js"
</script>
<leu-input></leu-input>
Browsers can't resolve bare module imports without import maps. But we can use a CDN to resolve the imports for us. This is useful if you're just using plain HTML and JavaScript without any build or transformation steps. Also this is applicable in an environment like Observable.
<link
rel="stylesheet"
href="https://esm.run/@statistikzh/leu@0.1/dist/theme.css"
/>
<script type="module">
import "https://esm.run/@statistikzh/leu@0.1/dist/leu-input.js"
</script>
<leu-input></leu-input>
To scan the project for linting and formatting errors, run
npm run lint
To automatically fix linting and formatting errors, run
npm run format
To execute a single test run:
npm run test
To run the tests in interactive watch mode run:
npm run test:watch
To run a local instance of Storybook for your component, run
npm run storybook
To build a production version of Storybook, run
npm run storybook:build
To create a starting point for a new component, run
./scripts/generate-component/generate.js
Running it with --help
will show you all available options.
A few rules are necessary when developing a component library. The following conventions and guidelines should be followed when new features are implemented.
At the same time they're not set in stone. If the there is a good reason to change them open a pull request.
Every element, class or custom property that will be globally available has to be prefixed with leu
.
/* Custom elements */
class LeuRadio extends LitElement {
...
}
window.customElements.define("leu-input", LeuInput)
/* CSS class */
.leu-radio-group {
...;
}
/* CSS custom property */
:root {
--leu-color-black-0: #000;
}
All CSS declarations should, whenever possible, always live inside a custom element. This way we ensure that the styles won't interfere with the environment they're loaded into.
The only exceptions are @font-face
statements and custom property declarations.
Styles that are shared between components should be defined as global custom properties inside the styles/custom-properties.css
.
When a global custom property is used inside a component it should always be assigned to a local custom property in the :host
declaration block.
:host {
--radio-color-disabled: var(--leu-color-black-20);
}
All custom elements that contain a value of some sort have to implement a value
property.
Everytime the value of the value
property changes a input
event has to be dispatched.
This behaviour matches the way Observable handles and observes changes of values that are contained in arbitrary elements. We decided to take over this pattern as it is usable in every other environment too.
In case of a custom event that is meant to be catched by an other component of this library, the name of this event has to be prefixed too.
this.dispatchEvent(new Event("leu:select", { bubbles: true, composed: true }))
Use as little dependencies as possible and as many as needed.
Thanks to the following people who have contributed to this project
Dan Büschlen
dan.bueschlen@statistik.ji.zh.ch
This project uses the following license:
We welcome contributions. Please see our CONTRIBUTING.md file for detailed guidelines of how to contribute.
Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.