Some checks failed
App Prod-Parity E2E Dispatch / dispatch (push) Failing after 10s
CD Storybook UI / build (push) Failing after 3m25s
CD Storybook UI / dispatch (push) Has been skipped
CD deploy main / website-changed-files (push) Successful in 18m8s
CI Agent Skills / changed-files-check (push) Successful in 18m9s
CI Create App E2E minimal / changed-files-check (push) Successful in 24s
CI Create App / changed-files-check (push) Successful in 26s
CI Docs / changed-files-check (push) Successful in 26s
CI Emails / changed-files-check (push) Successful in 28s
CI Example App Hello World / changed-files-check (push) Successful in 23s
CI Front / changed-files-check (push) Has been skipped
CI Example App Postcard / changed-files-check (push) Successful in 27s
CI UI / changed-files-check (push) Has been skipped
CI Utils Test / changed-files-check (push) Successful in 45s
CI Twenty Apps / discover (push) Successful in 1m3s
CD deploy main / deploy-main (push) Failing after 3s
CI Agent Skills / agent-skills-validate (push) Has been skipped
CI Create App / create-app-test (lint) (push) Has been skipped
CI Emails / emails-test (push) Has been skipped
CI Front / front-task (lingui:compile) (push) Has been skipped
CI Front / front-task (lint) (push) Has been skipped
CI Example App Postcard / example-app-postcard (push) Has been skipped
CI UI / ui-task (lint) (push) Has been skipped
CI UI / ui-task (pack-size) (push) Has been skipped
CI UI / ui-task (size) (push) Has been skipped
CI UI / ui-task (test) (push) Has been skipped
CI UI / ui-task (typecheck) (push) Has been skipped
CI Utils Test / utils-test (push) Has been skipped
CI Twenty Apps / ${{ matrix.app.name }} (push) Has been skipped
CI Emails / ci-emails-status-check (push) Successful in 2s
CI Example App Hello World / ci-example-app-hello-world-status-check (push) Successful in 2s
CI Example App Postcard / ci-example-app-postcard-status-check (push) Successful in 3s
CI UI / ui-sb-test (push) Has been skipped
CI Utils Test / ci-utils-test-status-check (push) Successful in 2s
CI Twenty Apps / ci-twenty-apps-status-check (push) Successful in 2s
CI UI / ci-ui-status-check (push) Successful in 2s
CI Desktop / desktop (push) Failing after 1m8s
Push docs to Crowdin / Push documentation to Crowdin (push) Failing after 55s
Push translations to Crowdin / Extract and upload translations (push) Failing after 5s
Push website translations to Crowdin / Extract and upload website translations (push) Failing after 5s
CI Create App / create-app-test (test) (push) Has been skipped
CI Create App / create-app-test (typecheck) (push) Has been skipped
CI Docs / docs-lint (push) Has been skipped
CI Example App Hello World / example-app-hello-world (push) Has been skipped
CI Front / front-task (lingui:extract) (push) Has been skipped
CI Front / front-task (test) (push) Has been skipped
CI Front / front-task (typecheck) (push) Has been skipped
CI UI / ui-sb-build (push) Failing after 1m32s
CI Twenty Apps / ${{ matrix.app.name }} (${{ matrix.server-source }}) (push) Has been skipped
CI Agent Skills / agent-skills-publish (push) Has been skipped
CI Create App / ci-create-app-status-check (push) Successful in 2s
CI Agent Skills / agent-skills-remote-source (push) Has been skipped
CI Create App E2E minimal / create-app-e2e-minimal (push) Has been cancelled
CI E2E Main / e2e-test (push) Has been cancelled
CI Front / front-sb-build (push) Has been cancelled
CI Front / front-build (push) Has been cancelled
CI Create App E2E minimal / ci-create-app-e2e-minimal-status-check (push) Has been cancelled
CI E2E Main / ci-e2e-main-status-check (push) Has been cancelled
CI E2E Main / notify-main-ci-failure (push) Has been cancelled
CI E2E Main / qa-scout-comment (push) Has been cancelled
CI Front / front-sb-test (push) Has been cancelled
CI Front / front-sb-screenshots (push) Has been cancelled
CI Front / ci-front-status-check (push) Has been cancelled
DPA Sub-Processor Sync / sync-subprocessors (push) Failing after 3s
AI Catalog Sync / sync-catalog (push) Failing after 2s
106 lines
6.1 KiB
Markdown
106 lines
6.1 KiB
Markdown
<p align="center">
|
|
<img src="https://raw.githubusercontent.com/twentyhq/twenty/main/packages/twenty-ui/logo.png" width="136" height="136" alt="twenty-ui logo" />
|
|
</p>
|
|
|
|
# twenty-ui
|
|
|
|
Twenty's open-source React UI component library: components, icons, and design tokens built on a zero-runtime, CSS-variable styling layer.
|
|
|
|
Read the [twenty-ui documentation](https://docs.twenty.com/ui/getting-started) for setup, theming, and component guides.
|
|
|
|
> **Alpha:** `twenty-ui` is still in alpha. Its version number follows the Twenty SDK release cycle. APIs and component behavior may change between releases.
|
|
|
|
# Installation
|
|
|
|
For a standalone React application, install the library and its peer dependencies. React 19 is required.
|
|
|
|
```bash
|
|
npm install twenty-ui monaco-editor react@^19 react-dom@^19
|
|
```
|
|
|
|
Install `monaco-editor` even if you never render a code editor: the `twenty-ui/primitives/input`, `twenty-ui/primitives/feedback`, and `twenty-ui/primitives/navigation` entry points reference it, and bundlers fail to resolve it otherwise.
|
|
|
|
For Twenty apps, follow [Using Twenty UI components](https://docs.twenty.com/developers/extend/apps/layout/front-components#using-twenty-ui-components). The front component renderer supplies the workspace theme. Keep `twenty-ui`, `twenty-sdk`, and `twenty-client-sdk` on the same version.
|
|
|
|
# Usage
|
|
|
|
For a standalone React application, import the base styles once, pick a theme stylesheet, and wrap your app in `ThemeProvider`:
|
|
|
|
```tsx
|
|
import { ThemeProvider } from 'twenty-ui/theme-constants';
|
|
import { Button } from 'twenty-ui/primitives/input';
|
|
|
|
import 'twenty-ui/style.css';
|
|
import 'twenty-ui/theme-light.css';
|
|
|
|
export const App = () => (
|
|
<ThemeProvider colorScheme="light">
|
|
<Button>Click me</Button>
|
|
</ThemeProvider>
|
|
);
|
|
```
|
|
|
|
Prefer the matching subpath for better tree-shaking. Imports from the `twenty-ui` root entry point are also supported.
|
|
|
|
```tsx
|
|
import { Button } from 'twenty-ui/primitives/input';
|
|
```
|
|
|
|
# Entry points
|
|
|
|
| Subpath | Contents |
|
|
| --- | --- |
|
|
| `twenty-ui` | All components, icons, theme tokens, and utilities |
|
|
| `twenty-ui/assets` | Logos and static assets |
|
|
| `twenty-ui/components` | Shared design presets and reusable app building blocks |
|
|
| `twenty-ui/icon` | Icon components and the icon provider |
|
|
| `twenty-ui/primitives` | Foundational UI controls and compound controls |
|
|
| `twenty-ui/primitives/accessibility` | Hidden elements and keyboard interaction helpers |
|
|
| `twenty-ui/primitives/data-display` | Avatars, chips, tags, status indicators, and display helpers |
|
|
| `twenty-ui/primitives/feedback` | Toasts, banners, progress bars, and loaders |
|
|
| `twenty-ui/primitives/input` | Buttons, form controls, pickers, and code editors |
|
|
| `twenty-ui/primitives/json-visualizer` | JSON tree viewer |
|
|
| `twenty-ui/primitives/layout` | Layout, animation, resizing, and section components |
|
|
| `twenty-ui/primitives/navigation` | Links, list items, menus, and tabs |
|
|
| `twenty-ui/primitives/surfaces` | Cards, dialogs, menus, popovers, and tooltips |
|
|
| `twenty-ui/primitives/typography` | Text, headings, labels, and typography helpers |
|
|
| `twenty-ui/testing` | Storybook and test decorators |
|
|
| `twenty-ui/theme` | Theme types and helpers |
|
|
| `twenty-ui/theme-constants` | Design tokens, `ThemeProvider`, and `useTheme` |
|
|
| `twenty-ui/utilities` | Hooks and shared utilities |
|
|
|
|
# Theming
|
|
|
|
- `twenty-ui/style.css` ships the base reset and component styles. Import it once.
|
|
- `twenty-ui/theme-light.css` and `twenty-ui/theme-dark.css` define the design-token CSS variables for each color scheme.
|
|
- `ThemeProvider` exposes the active theme through `useTheme()` and applies the `light` / `dark` class. Pass `applyToRoot={false}` with `overrides` to scope a theme to a subtree instead of the document root.
|
|
|
|
# Development
|
|
|
|
Primitive guides belong in `packages/twenty-docs/ui/primitives`. Shared component guides belong in `packages/twenty-docs/ui/components`. For each stateful API that supports both modes, include separate **Uncontrolled state** and **Controlled state** examples with the same scenario, labels, and initial state. Keep each example complete, with public imports and one exported example component.
|
|
|
|
Explain state ownership before advanced behavior such as indeterminate selection or manual tab activation. Document independent states, such as selection and popup visibility, separately. For components that delegate state to a parent or group, explain that ownership and link to the relevant examples.
|
|
|
|
For compound components, include an anatomy tree and identify required parts, optional parts, and elements supplied internally. Show supported composition with complete examples, use Twenty UI components for supporting controls, and explain how custom wrappers preserve props and refs. Use `text` fences for structural diagrams and `tsx` fences for runnable examples so the documentation checker validates the examples.
|
|
|
|
## Internal state
|
|
|
|
twenty-ui uses Base UI's store for notification state. Each `ToastProvider` creates its own store, and the toaster subscribes to the toast list. Queue rules and rendering remain owned by twenty-ui. Consumers use `useToast()` without configuring a state library.
|
|
|
|
The store factory and subscription hook are internal to the toast module. `@base-ui/utils` is a direct dependency pinned to the version used by `@base-ui/react`, and the library build keeps it external. Review its store API changes when upgrading the dependency.
|
|
|
|
## Testing
|
|
|
|
Component interaction and behavior tests belong in Storybook stories (`*.stories.tsx`) using `play` functions. Component unit tests are reserved for conformance (native props, refs, class names, rendering, and prop types). Keep non-interactive utility, hook, and token tests in the Vitest unit project; avoid duplicating story coverage there.
|
|
|
|
```bash
|
|
npx nx build twenty-ui # Build the library (dual ESM/CJS + types)
|
|
npx nx storybook:serve:dev twenty-ui # Run Storybook
|
|
npx nx test twenty-ui # Run unit tests
|
|
npx vitest run --root packages/twenty-ui --project unit <file> # Run a single test file
|
|
```
|
|
|
|
# License
|
|
|
|
twenty-ui is released under the [MIT](https://github.com/twentyhq/twenty/blob/main/packages/twenty-ui/LICENSE) license.
|