Files
twenty/packages/twenty-ui
martmull 7b682bced9 feat(shared): require defaultValue on non-nullable field manifests (#22419)
## Context

Follow-up to #22362, which made `isNullable` manifest changes actually
apply (including a nullable → non-nullable backfill). This models the
`isNullable` / `defaultValue` relationship directly in the
`FieldManifest` type.

## Rule

- A **non-nullable** field (`isNullable: false`) must declare a
`defaultValue`, so the column always has a value to fall back on (e.g.
for the backfill on the nullable → non-nullable transition).
- A **nullable** or **unspecified** field may omit `defaultValue`.

## Changes

- Split `RegularFieldManifest` into a base shape plus a discriminated
nullability union. The union keeps `isNullable` free once a
`defaultValue` is supplied, so helpers that always provide one can still
pass a dynamic `boolean` `isNullable`.
- `defaultValue` keeps its rich per-type `FieldMetadataDefaultValue<T>`
(POSITION → number, ACTOR → composite) rather than a bare `string`.
- `RelationFieldManifest` is rebased on the shared base and keeps
`isNullable` / `defaultValue` optional, since relation join columns are
always nullable by design.
- Narrowed `buildEstimateFieldManifest` in the manifest-update
integration test to satisfy the stricter type.

## Verification

Environment couldn't install the monorepo deps (registry connections
aborting), so `nx typecheck` wasn't run here. Validated the union
structure with standalone `tsc` synthetic tests mirroring every
construction pattern in the codebase:

-  nullable/no-default, no-`isNullable`, non-nullable with
string/number/composite defaults, dynamic-boolean-with-default, and the
`DistributiveOmit` path into `ObjectFieldManifest`
-  non-nullable **without** a default is correctly rejected with a
clear "defaultValue is missing but required" error

Recommend a full `nx typecheck twenty-shared twenty-sdk twenty-server`
in CI to confirm against full project resolution.

https://claude.ai/code/session_01VnbrgBB3kNGP876qaKPYDL

---
_Generated by [Claude
Code](https://claude.ai/code/session_01VnbrgBB3kNGP876qaKPYDL)_

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22419?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
2026-07-02 08:03:52 +00:00
..
2026-06-11 11:02:28 +02:00
2026-06-11 11:02:28 +02:00
2026-06-24 13:19:03 +00:00
2026-06-11 11:02:28 +02:00

twenty-ui logo

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.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

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 AGPL-3.0 license.