https://github.com/chanzuckerberg/sci-components
2021 Science Design System Component Library
https://github.com/chanzuckerberg/sci-components
css design-system react theme
Last synced: 5 months ago
JSON representation
2021 Science Design System Component Library
- Host: GitHub
- URL: https://github.com/chanzuckerberg/sci-components
- Owner: chanzuckerberg
- License: mit
- Created: 2021-03-08T20:37:00.000Z (over 5 years ago)
- Default Branch: main
- Last Pushed: 2026-02-05T19:28:01.000Z (5 months ago)
- Last Synced: 2026-02-06T04:19:47.182Z (5 months ago)
- Topics: css, design-system, react, theme
- Language: TypeScript
- Homepage: https://chanzuckerberg.github.io/sci-components/
- Size: 71.9 MB
- Stars: 32
- Watchers: 10
- Forks: 7
- Open Issues: 110
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Security: SECURITY.md
Awesome Lists containing this project
README
# Purpose
The Science Design System (SDS) brings consistency and universal standards to CZI’s science products by offering a library of high quality, reusable components that deliver predictable, accessible and easy to learn experiences. Our goal is to democratize access to tools and technologies for scientists.
## Design System Documentation
`@czi-sds/components` implements the Science Design System as documented in [Zeroheight](https://sds.czi.design/). As a result, it's very useful to get familiar with the available **theme variables**, such as `colors`, `spaces`, `typography`, etc., so you can leverage the theme properly in your application.

## Installation
[NPM Package](https://www.npmjs.com/package/czi-sds/components)
**Currently SDS uses Material UI v5**
NOTE: Since most of the czi-sds components are built on top of Material UI's equivalent, it's also super useful to use their [API documentation](https://mui.com/) to learn about what you can do with the components. Many czi-sds components are style wrappers that pass props through to the MUI component without modifying them.
`@czi-sds/components` installs without direct dependencies to prevent version errors. Please ensure the following peer dependencies are also installed:
```
"@emotion/css"
"@emotion/react"
"@emotion/styled"
"@mui/base"
"@mui/icons-material"
"@mui/lab"
"@mui/material"
"react"
"react-dom"
```
To install @czi-sds/components and the dependencies:
```
// with npm
npm i @czi-sds/components @emotion/css @emotion/react @emotion/styled @mui/base @mui/material @mui/icons-material @mui/lab react react-dom
// with yarn
yarn add @czi-sds/components @emotion/css @emotion/react @emotion/styled @mui/base @mui/material @mui/icons-material @mui/lab react react-dom
```
## Yarn scripts
Common yarn scrips have been moved to the monorepo root. The -- syntax can be used to pass parameters to the underlying yarn scripts. For instance, to update the snapshots, use `lerna run test -- -u` instead of running all tests on both packages with `yarn test`.
- `yarn start`: Starts storybook on the local machine
- `yarn build-storybook`: Builds the storybook in the docs-build folder
- `yarn test-storybook`: Tests current running instance of storybook
- `yarn storybook:axe`: Builds the storybook and runs accessibility tests
- `yarn storybook:axeOnly`: Runs accessibility tests on the latest build of the storybook inside the docs-build folder
- `yarn test`: Runs `jest` tests
- `yarn namespace-check`: Runs typescript type checking on namespace files to ensure that there are no duplicated exports
- `yarn lint`: Runs linter
- `yarn build`: Build the packages
- `yarn ci`: Executes `yarn install --frozen-lockfile` in both packages
- `yarn evaluate:code `: Evaluates a single component file for SDS compliance
- `yarn evaluate:batch `: Evaluates all .tsx/.ts files in a directory
- _To execute any script in the inner package, one can simply use the command `lerna run script --scope=`. For instance, to run the linter only on the sci-components package, use the command `lerna run lint --scope=@czi-sds/components`._
## Usage
`@czi-sds/components` comes with five main exports that help you build your app:
1. Components - Accessible and reusable components
```javascript
import React from "react";
import { Button } from "@czi-sds/components";
{text}
;
```
2. Mixins - Grouped styles defined by the design system
```javascript
import { styled } from '@emotion/styled';
import { Typography } from "@mui/material";
import { fontHeaderXL } from "@czi-sds/components";
export const Title - styled(Typography)`
${fontHeaderXl}
// which compiles to:
font-size: 22px;
font-weight: 600;
letter-spacing: 0.3px;
line-height: 30px;
`;
```
3. Selectors - Helper functions that return theme variables baased on passed props
```ts
import { css, SerializedStyles } from "@emotion/react";
import styled from "@emotion/styled";
import { getColors, getCorners } from "@czi-sds/components";
export const Tag = styled("div")`
// This is a callback function that returns more CSS rules, but the only way
// to access the custom theme object
${(props) => {
// getColors() is a selector that picks out colors from the theme object
const colors = getColors(props);
// getSpaces() is a selector that picks out spaces from the theme object
const spaces = getSpaces(props);
return `
background-color: ${colors?.gray[500]};
padding-bottom: ${spaces?.m}px;
margin-bottom: ${spaces?.xxl}px;
`;
}}
`;
```
4. CSS & SCSS Variables - Variables for the `defaultTheme` to use if your app doesn't support `@emotion/styled`
```scss
// with SCSS variables
@import "~@czi-sds/components/dist/variables";
.button-primary {
background-color: $sds-color-primary-400;
padding: $sds-spaces-xxs;
}
// with CSS variables
.button-primary {
background-color: var(--sds-color-primary-400);
padding: var(--sds-spaces-xxs);
}
```
5. Tailwind - Tailwind compliant configuration for the `defaultTheme` to use if your app uses Tailwind
First you need to import the SDS config into your application's Tailwind config:
```js
// tailwind.config.js
const sds = require("@czi-sds/components/dist/tailwind.json");
module.exports = {
mode: "jit",
content: ["./src/**/*.{tsx,scss}"],
theme: {
extend: sds,
},
};
```
If you have existing styles that you'd like to maintain, you can pick and choose
different parts of the SDS config:
```js
// tailwind.config.js
const sds = require("@czi-sds/components/dist/tailwind.json");
module.exports = {
mode: "jit",
content: ["./src/**/*.{tsx,scss}"],
theme: {
extend: {
...sds,
width: {
...sds.width,
"app-modal-width": "500px",
},
height: {
...sds.width,
"app-modal-height": "200px",
},
},
},
};
```
After that, you should be able to use SDS Tailwind classes in your app:
```tsx
export function Hello() {
return (
Hello, World!
);
}
```
### Theme System
SDS provides comprehensive light/dark theme support. To use the theme system in your React application, complete the following:
1. Add the following HTML to your `index.html` at the `` section:
```html
// installs the sds font from google fonts
```
2. Import and use SDS themes in Material UI's ``:
**Using the default light theme:**
```javascript
import { ThemeProvider as EmotionThemeProvider } from "@emotion/react";
import { StyledEngineProvider, ThemeProvider } from "@mui/material/styles";
import { defaultTheme } from "@czi-sds/components";
;
```
**Using programmatic theme switching:**
```javascript
import { ThemeProvider as EmotionThemeProvider } from "@emotion/react";
import { StyledEngineProvider, ThemeProvider } from "@mui/material/styles";
import { SDSChooseTheme } from "@czi-sds/components";
function App() {
const [isDarkMode, setIsDarkMode] = useState(false);
const currentTheme = SDSChooseTheme(isDarkMode ? "dark" : "light");
return (
);
}
```
**Creating custom themes:**
If you want to create a custom theme with your own color palette, use the `makeSdsSemanticAppTheme` function:
```tsx
import { ThemeProvider as EmotionThemeProvider } from "@emotion/react";
import { makeSdsSemanticAppTheme, makeThemeOptions } from "@czi-sds/components";
import { StyledEngineProvider, ThemeProvider } from "@mui/material/styles";
import createTheme from "@mui/material/styles/createTheme";
// Define your custom color palette following SDS color structure
const myCustomColors = {
blue: {
/* your blue color scale */
},
gray: {
/* your gray color scale */
},
// ... other colors
};
// Create a custom SDS theme
const customSdsTheme = makeSdsSemanticAppTheme(myCustomColors, false); // false = light mode
// Generate Material UI theme
const appTheme = makeThemeOptions(customSdsTheme);
const theme = createTheme(appTheme);
;
```
**Legacy theme override (deprecated):**
⚠️ **Note:** `defaultAppTheme` is deprecated. Use `SDSLightAppTheme` or create custom themes with `makeSdsSemanticAppTheme` instead.
```tsx
// DEPRECATED - Use makeSdsSemanticAppTheme instead
import { defaultAppTheme, makeThemeOptions } from "@czi-sds/components";
const customTheme = {
/* custom properties */
};
const appTheme = makeThemeOptions({ ...defaultAppTheme, ...customTheme });
const theme = createTheme(appTheme);
```
💡 CZGE example available [here](https://github.com/chanzuckerberg/czgenepi/blob/trunk/src/frontend/src/common/styles/theme.ts).
💡 Material UI docs for custom theming available [here](https://mui.com/material-ui/customization/theming/).
## Q&A
1. Why wrapping a component with `styled()` doesn't style the root element as expected?
This is likely because the component is **NOT** forwarding the css class name that `styled()` generates to the intended root element. So we likely need to update the `czif` component to make it work
For example, if a `czif` component `Foo` has the following implementation, `styled(Foo)` won't style the wrapper `
` as expected:
```tsx
function Foo() {
return (
);
}
```
The fix is:
```tsx
function Foo({ className }) {
return (
);
}
```
1. To style a sub-component of a `@czi-sds/components` component, typically we export the sub-component for the call site to import and style via `styled`, and then you will be able to pass back the styled sub-component to the `@czi-sds/components` component through prop
For example, `ComplexFilter` exports `ComplexFilterInputDropdown` sub-component, so if you want to style it, you can do the following:
```tsx
import {
ComplexFilter,
ComplexFilterInputDropdown,
} from "@czi-sds/components";
import styled from "@emotion/styled";
const StyledComplexFilterInputDropdown = styled(ComplexFilterInputDropdown)`
color: pink;
`;
function Foo() {
return (
);
}
```
## Code Evaluation
We provide a comprehensive evaluation script to assess LLM-generated UI components for SDS compliance and best practices.
### Quick Evaluation
```bash
# Evaluate a single component
yarn evaluate:code ./my-component.tsx
# Evaluate all components in a directory
yarn evaluate:batch ./generated-components/
```
### What It Evaluates
- ✅ **TypeScript compilation** - Ensures code compiles without errors
- ✅ **ESLint compliance** - Checks code quality and style
- ✅ **SDS component usage** - Verifies proper use of design system components
- ✅ **Import statements** - Ensures SDS components are properly imported
- ✅ **Design tokens** - Checks for consistent design token usage
- ✅ **Accessibility** - Verifies accessibility attributes and patterns
For detailed usage instructions and examples, see [scripts/README.md](scripts/README.md).
## Project status
This project is under **active development**. Contributions and ideas are welcome! If you would like to contribute, check out the [contribution guidelines](docs/contribution.md) or open an issue.
This project is governed under the [Contributor Covenant](https://www.contributor-covenant.org/) code of conduct.
## Reporting Security Issues
Please note: If you believe you have found a security issue, please responsibly disclose by contacting us at security@chanzuckerberg.com. More information is in our [Security Readme](docs/SECURITY.md)
## Code of Conduct
This project adheres to the Contributor Covenant [code of conduct](https://github.com/chanzuckerberg/.github/blob/master/CODE_OF_CONDUCT.md).
By participating, you are expected to uphold this code.
Please report unacceptable behavior to [opensource@chanzuckerberg.com](mailto:opensource@chanzuckerberg.com).