Files
twenty/packages/twenty-ui
Thomas des Francs 9870d1e6a9 Fix source icon SVG ID collisions (#22177)
## Summary

Fixes the Gmail and Google Calendar source icons by replacing
document-global generic SVG IDs (`a`, `b`, `c`, etc.) with icon-specific
IDs. This prevents inline SVG gradients, masks, and filters from
resolving against another icon instance when the icons render together
in the record table actor/source column.

## Root cause

The Gmail and Google Calendar SVG assets both used generic IDs. Browser
SVG fragment references are document-global for inline SVG, so whichever
icon appears first can hijack the other icon's `url(#...)` references.
That made the Calendar icon pick up Gmail gradients, and could also
affect Gmail depending on DOM order.

## Before

<img width="1280" height="720" alt="Before icon collision screenshot"
src="https://github.com/user-attachments/assets/82ce20a8-47c7-4b70-8af2-e134cf88c0b8"
/>

## After

<img width="1280" height="720" alt="After icon collision screenshot"
src="https://github.com/user-attachments/assets/240120a6-b84e-4682-a116-0ccb48192543"
/>

## Validation

- Rendered Gmail + Calendar in both DOM orders via a local browser
fixture.
- Verified the before fixture had 14 generic SVG IDs and the after
fixture had 0.
- Verified 4 SVGs rendered, no cross-icon URL reference problems, and no
browser console warnings/errors.
- Ran `xmllint --noout packages/twenty-ui/src/assets/icons/gmail.svg
packages/twenty-ui/src/assets/icons/google-calendar.svg`.
- Ran `rg -n
"id=\"[a-z]\"|url\(#[a-z]\)|mask=\"url\(#[a-z]\)\"|filter=\"url\(#[a-z]\)\""
packages/twenty-ui/src/assets/icons -S` and confirmed no matches.

`yarn nx build twenty-ui` could not run in this worktree because
`node_modules` is missing, and Yarn reports: `Couldn't find the
node_modules state file`.
2026-06-25 14:22:17 +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.