80fb91c033
## Context The List View toggle in Settings → Lab rendered without an icon: the front end kept a hardcoded `Partial<Record<FeatureFlagKey, IconComponent>>` map, so nothing caught a public feature flag added without an icon. ## What this PR does Moves the icon into the public feature flag metadata, next to `label` and `description`, as a **required** field — so a lab flag now registers in one place and can't be declared without an icon (server typecheck fails otherwise): - `twenty-server`: `FeatureFlagMetadata` gains required `icon: string`; each `PUBLIC_FEATURE_FLAGS` entry declares its icon (`IconList` for List View — the icon already used for the List view type). `PublicFeatureFlagMetadata` GraphQL entity exposes it. - `twenty-front`: `SettingsLabContent` renders `getIcon(flag.metadata.icon)` via `useIcons`, the same metadata-driven icon pattern used across the app; the hardcoded icon map is deleted. - `twenty-ui`: registers `IconCalendarWeek` in `AllIcons` — it was importable but not resolvable by name through `useIcons`, so it would have silently fallen back to the default icon. - Generated artifacts (`twenty-front/src/generated-metadata`, `twenty-client-sdk/src/metadata/generated`) updated for the new field. ## Verification - `nx run-many -t typecheck,lint -p twenty-front twenty-server twenty-shared twenty-client-sdk twenty-ui` passes (oxlint + oxfmt clean). - Negative case: removing `icon` from a `PUBLIC_FEATURE_FLAGS` entry fails `twenty-server:typecheck` with `TS2741: Property 'icon' is missing … but required in type 'FeatureFlagMetadata'`.
twenty-ui
Twenty's open-source React UI component library: components, icons, and design tokens built on a zero-runtime, CSS-variable styling layer.
Installation
npm install twenty-ui
react, react-dom, and monaco-editor are peer dependencies (install them in your app). monaco-editor is only required if you use the code editor components.
Usage
Import the base styles once, pick a theme stylesheet, and wrap your app in ThemeProvider:
import { ThemeProvider } from 'twenty-ui/theme-constants';
import { Button } from 'twenty-ui/input';
import 'twenty-ui/style.css';
import 'twenty-ui/theme-light.css';
export const App = () => (
<ThemeProvider colorScheme="light">
<Button title="Click me" />
</ThemeProvider>
);
Components are available from the root entry point or from a specific subpath for better tree-shaking:
import { Button } from 'twenty-ui';
import { Button } from 'twenty-ui/input';
Entry points
| Subpath | Contents |
|---|---|
twenty-ui |
All components, icons, theme tokens, and utilities |
twenty-ui/accessibility |
Accessibility helpers |
twenty-ui/assets |
Logos and static assets |
twenty-ui/data-display |
Avatars, chips, tags, and other display components |
twenty-ui/feedback |
Progress bars, loaders, and status feedback |
twenty-ui/icon |
Icon components and the icon provider |
twenty-ui/input |
Buttons, toggles, and form inputs |
twenty-ui/json-visualizer |
JSON tree viewer |
twenty-ui/layout |
Layout primitives |
twenty-ui/navigation |
Menus, links, and navigation components |
twenty-ui/surfaces |
Cards, tooltips, and surface components |
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/typography |
Text and typography components |
twenty-ui/utilities |
Hooks and shared utilities |
Theming
twenty-ui/style.cssships the base reset and component styles. Import it once.twenty-ui/theme-light.cssandtwenty-ui/theme-dark.cssdefine the design-token CSS variables for each color scheme.ThemeProviderexposes the active theme throughuseTheme()and applies thelight/darkclass. PassapplyToRoot={false}withoverridesto scope a theme to a subtree instead of the document root.
Development
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
License
twenty-ui is released under the MIT license.
