@enveritas/design-system v0.0.2-0
Enveritas Design System
This project is a library that provides a consistent design language for Enveritas' internal and external projects.
Installation
npm install @enveritas/design-systemUsage
Static Assets (Fonts)
This library includes some statically hostable assets (namely fonts). It does not however include any out-of-the-box CSS that references those assets because it does not know where a given application will be hosting them. An application can provide its own directives referencing static assets and resolve them relative to its node_modules, e.g.
@font-face {
font-family: "Inter";
src: local("Inter"),
url("~@enveritas/design-system/dist/fonts/Inter-VariableFont_slnt,wght.ttf");
font-display: swap;
}
@font-face {
font-family: "Lora";
src: local("Lora"),
url("~@enveritas/design-system/dist/fonts/Lora-VariableFont_wght.ttf");
font-display: swap;
}Alternatively, there is a init($assetPath) SASS mixin that will inject the relevant directives for you. In most webpack configurations (including CRA and Next.js) it can be called without any arguments, e.g.
@use "@enveritas/design-system";
@include design-system.init; Alternatively if the library's static assets are hosted in a way preventing this from working, the mixin can be included with a path to where they are hosted
@use "@enveritas/design-system";
@include design-system.init("static/vendor/@enveritas/design-system"); As a SASS Library
This library includes a number of SASS primitives (variables, mixins, and functions) that can be used inside an application's SASS stylesheets. The exported SASS module strictly includes SASS primitives and does not include any CSS selectors.
@use "@enveritas/design-system";
.title {
@include design-system.font-display-01;
}As a React Component Library
Additionally, this library includes a number of React Components.
import { Button } from "@enveritas/design-system";
export const MyComponent = () => {
return <Button>Click Me</Button>
}All React components encapsulate their presentation using CSS modules, and are exported as ES Modules to enable tree-shaking of unused components and styles.
Global Styles
Importing this library in Javascript has the side effect of injecting base global styles into the of a page. The global styles are small, generic, and aimed at providing a foundation for developing more specific designs. In particular, they include:
@css-tools/normalize.cssnormalization styles aimed at improving cross-browser consistency:rootCustom CSS properties, such asvar(--color-blue-100)such that any application-specific styles can reference and override the foundational elements of the design library- Broad, low-specificity, semantic selectors, such as
bodyor:focus
Development Scripts
In the project directory you can run:
npm start
Starts Storybook.\ Open http://localhost:6006 to view it in the browser.
Storybook can be used to display individual components and design patterns. It acts as a way to interact with the library in a browser during development, and as living documentation of the design system in production.
npm run ci
Runs all checks that must pass during CI, including linting, formatting, and testing
npm run build
Builds Storybook as static for production to the build folder.
npm run prepare
Prepares the library for distribution on npm. This happens automatically before npm pack and npm publish. Useful for examining the dist folder without packing or publishing.
npm pack
Creates a tarball for the library. This can be useful for testing the package in other applications without publishing it:
npm pack
cd path/to/some/app
npm install path/to/library/enveritas-design-system-<semver>.tgzGuidelines
Folder Organization
- 1 file per component: Every React component gets its own
.tsxfile. Single-use components can live in a module directory alongside the components that import them. - No application code in module index files: When using a directory to define a module,
index.tsfiles should only containexportstatements from files within that directory. All code should be defined in its own single-responsibility file. - Every file name is descriptive: every file name should describe its contents and a developer should be able to infer its responsibility from its name independent of its folder. This makes searching for code by file name easier. For example,
MyComponent/List.tsxcan be made easier to search for by renaming itMyComponent/MyComponentList.tsx. - No upwards imports: Never import
from "../". This makes it a lot easier to reorganize directories. Any file that is not in the tree relative to where it is being imported to can be imported using an absolute path beginning withsrc, e.g.import OtherComponent from "src/components/OtherComponent"
TypeScript
- Avoid
anytypes: While they may not be completely avoidable,anytypes are unchecked and have a nasty tendency to leak type safety issues to places in the code other than where theanyis.
React
- Favor functional components: Use functional components and hooks over class-based components.
- Presentational components: Components exported by this library should be purely presentational, and should minimize state and side-effects. They definitely should not be fetching data.
- Compositional components: Components exported by this library should be highly composable and where possible should extend native DOM elements rather than replace them.
HTML
- Semantic flexibility: Many library components do not correspond to fixed semantic elements, and will depend on the application using them. Where possible allow applications to provide their own underlying HTML elements.
Styling
- Use CSS Modules: Whenever possible use
.module.scssfiles to encapsulate styles for a component. Use CSS modules to write low-specificity class-based selectors. Keep it flat and avoid nesting. - Keep global styles generic: Global styles in
src/styles/globalshould define custom properties, resets, and semantic selectors. They should not contain any class or ID selectors, and should not contain styles for specific components. - Keep library styles pure: Library styles in
src/styles/libshould only define SASS variables, mixins, and functions. They should not include any selectors and importing them should have no global side effects.