Reorganize twenty-ui into best-practice component domains and per-component folders (#21745)

Reorganizes `twenty-ui`'s component organization to follow how the best
UI libraries (MUI, Mantine, Base UI, Polaris) structure their source,
now that the package has stabilized.

**Taxonomy** — dissolves the meaningless `components/` junk-drawer and
the 107-file `display/` mega-category. New domains/subpaths:
`data-display`, `typography`, `icon`, `surfaces`; `feedback` and
`layout` absorb the rest (banners/callout/info + placeholders →
feedback; modal/card → surfaces; motion + separators → layout).

**Per-component layout** — every component is now
`<domain>/<ComponentName>/<ComponentName>.tsx` with colocated
styles/stories/types, `internal/` for private helpers and `parts/` for
re-exported compound sub-parts. The redundant inner `/components/` is
gone. `icon` and `json-visualizer` are kept as cohesive subsystems.

**Also:** adds a tree-shakeable root barrel (`import { Button } from
'twenty-ui'`), the generator now owns `individual-entry.ts`, and a real
barrel-leak bug is fixed (private `internals/` parts were leaking into
the public API).

Consumer imports (~1.2k files) and the `twenty-sdk` UI aggregator were
updated by codemod. The change is **export-neutral** except 16
intentionally-removed private internals symbols (all verified
unconsumed). Gates green: typecheck, lint, build, size-limit, storybook.


<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/21745?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. -->
This commit is contained in:
Raphaël Bosi
2026-06-18 10:31:29 +02:00
committed by GitHub
parent 640a8e6ca6
commit 8034c7725f
1580 changed files with 2382 additions and 2404 deletions
@@ -2,7 +2,7 @@ import { styled } from '@linaria/react';
import { motion } from 'framer-motion';
import Linkify from 'linkify-react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { AnimatedEaseInOut } from 'twenty-ui/utilities';
import { AnimatedEaseInOut } from 'twenty-ui/layout';
const StyledTextBody = styled(motion.div)`
color: ${themeCssVariables.font.color.primary};
@@ -11,12 +11,12 @@ import {
} from 'react';
import { isDefined } from 'twenty-shared/utils';
import {
HorizontalSeparator,
IconAlertTriangle,
IconInfoCircle,
IconSquareRoundedCheck,
IconX,
} from 'twenty-ui/display';
} from 'twenty-ui/icon';
import { HorizontalSeparator } from 'twenty-ui/layout';
import { ProgressBar, useProgressAnimation } from 'twenty-ui/feedback';
import { LightButton, LightIconButton } from 'twenty-ui/input';
import { UndecoratedLink } from 'twenty-ui/navigation';
@@ -2,7 +2,7 @@ import { type FieldActorValue } from '@/object-record/record-field/ui/types/Fiel
import { t } from '@lingui/core/macro';
import { ConnectedAccountProvider } from 'twenty-shared/types';
import { AvatarOrIcon, Chip, ChipVariant } from 'twenty-ui/components';
import { AvatarOrIcon, Chip, ChipVariant } from 'twenty-ui/data-display';
import {
IconApi,
IconCalendar,
@@ -17,7 +17,7 @@ import {
IconUpload,
IconWebhook,
type IconComponent,
} from 'twenty-ui/display';
} from 'twenty-ui/icon';
type ActorDisplayProps = Partial<FieldActorValue> & {
avatarUrl?: string | null;
@@ -1,7 +1,7 @@
import { type FieldArrayValue } from '@/object-record/record-field/ui/types/FieldMetadata';
import { ExpandableList } from '@/ui/layout/expandable-list/components/ExpandableList';
import { t } from '@lingui/core/macro';
import { Chip, ChipVariant } from 'twenty-ui/components';
import { Chip, ChipVariant } from 'twenty-ui/data-display';
type ArrayDisplayProps = {
value: FieldArrayValue;
@@ -1,6 +1,6 @@
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { IconCheck, IconX } from 'twenty-ui/display';
import { IconCheck, IconX } from 'twenty-ui/icon';
const iconSizeSm = 14;
const StyledBooleanFieldValue = styled.div`
@@ -1,7 +1,7 @@
import { useContext, useId, useState } from 'react';
import { createPortal } from 'react-dom';
import { styled } from '@linaria/react';
import { AppTooltip, TooltipDelay, TooltipPosition } from 'twenty-ui/display';
import { AppTooltip, TooltipDelay, TooltipPosition } from 'twenty-ui/surfaces';
import { ThemeContext } from 'twenty-ui/theme-constants';
import { isDefined, formatToShortNumber } from 'twenty-shared/utils';
@@ -5,7 +5,7 @@ import { isNonEmptyString } from '@sniptt/guards';
import { FileIcon } from '@/file/components/FileIcon';
import { type FieldFilesValue } from '@/object-record/record-field/ui/types/FieldMetadata';
import { getFileCategoryFromExtension } from '@/object-record/record-field/ui/utils/getFileCategoryFromExtension';
import { Chip, ChipVariant } from 'twenty-ui/components';
import { Chip, ChipVariant } from 'twenty-ui/data-display';
const MAX_WIDTH = 120;
@@ -9,7 +9,7 @@ import { useLingui } from '@lingui/react/macro';
import { type JSX, lazy, Suspense, useEffect } from 'react';
import { createPortal } from 'react-dom';
import { isDefined } from 'twenty-shared/utils';
import { IconDownload, IconX } from 'twenty-ui/display';
import { IconDownload, IconX } from 'twenty-ui/icon';
import { IconButton } from 'twenty-ui/input';
import { themeCssVariables } from 'twenty-ui/theme-constants';
@@ -1,7 +1,7 @@
import { type FieldMultiSelectValue } from '@/object-record/record-field/ui/types/FieldMetadata';
import { isDefined } from 'twenty-shared/utils';
import { styled } from '@linaria/react';
import { Tag } from 'twenty-ui/components';
import { Tag } from 'twenty-ui/data-display';
import { type SelectOption } from 'twenty-ui/input';
const StyledContainer = styled.div`
@@ -1,5 +1,5 @@
import { type IconComponent } from 'twenty-ui/display';
import { Tag } from 'twenty-ui/components';
import { type IconComponent } from 'twenty-ui/icon';
import { Tag } from 'twenty-ui/data-display';
import { type ThemeColor } from 'twenty-ui/theme';
type SelectDisplayProps = {
@@ -1,6 +1,6 @@
import { styled } from '@linaria/react';
import { isUndefined } from '@sniptt/guards';
import { OverflowingTextWithTooltip } from 'twenty-ui/display';
import { OverflowingTextWithTooltip } from 'twenty-ui/surfaces';
type TextDisplayProps = {
text: string;
@@ -1,6 +1,6 @@
import { styled } from '@linaria/react';
import { useContext } from 'react';
import { IconArrowUp } from 'twenty-ui/display';
import { IconArrowUp } from 'twenty-ui/icon';
import { Loader } from 'twenty-ui/feedback';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
@@ -8,7 +8,7 @@ import { CURRENCIES } from '@/settings/data-model/constants/Currencies';
import { CurrencyPickerDropdownButton } from '@/ui/input/components/internal/currency/components/CurrencyPickerDropdownButton';
import { type Currency } from '@/ui/input/components/internal/types/Currency';
import { IMaskInput } from 'react-imask';
import { type IconComponent } from 'twenty-ui/display';
import { type IconComponent } from 'twenty-ui/icon';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { getSeparatorsForNumberFormat } from '~/utils/format/getSeparatorsForNumberFormat';
@@ -5,7 +5,7 @@ import { useContext, useState } from 'react';
import { useClearField } from '@/object-record/record-field/ui/hooks/useClearField';
import { RATING_VALUES } from 'twenty-shared/constants';
import { type FieldRatingValue } from 'twenty-shared/types';
import { IconTwentyStarFilled } from 'twenty-ui/display';
import { IconTwentyStarFilled } from 'twenty-ui/icon';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledContainer = styled.div`
@@ -15,7 +15,7 @@ import {
IconRocket,
IconTag,
IconTarget,
} from 'twenty-ui/display';
} from 'twenty-ui/icon';
import { type SelectOption } from 'twenty-ui/input';
import { ComponentDecorator } from 'twenty-ui/testing';
@@ -10,12 +10,8 @@ import React, {
useState,
} from 'react';
import { isDefined } from 'twenty-shared/utils';
import {
ColorSample,
IconApps,
type IconComponent,
useIcons,
} from 'twenty-ui/display';
import { ColorSample } from 'twenty-ui/data-display';
import { IconApps, type IconComponent, useIcons } from 'twenty-ui/icon';
import {
IconButton,
type IconButtonSize,
@@ -4,7 +4,7 @@ import { Trans, useLingui } from '@lingui/react/macro';
import { isNonEmptyString } from '@sniptt/guards';
import React, { useContext, useState } from 'react';
import { getImageAbsoluteURI, isDefined } from 'twenty-shared/utils';
import { IconPhotoUp, IconTrash, IconUpload, IconX } from 'twenty-ui/display';
import { IconPhotoUp, IconTrash, IconUpload, IconX } from 'twenty-ui/icon';
import { Button } from 'twenty-ui/input';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { REACT_APP_SERVER_BASE_URL } from '~/config';
@@ -5,12 +5,9 @@ import {
import { styled } from '@linaria/react';
import React, { useContext } from 'react';
import { isDefined } from 'twenty-shared/utils';
import {
IconChevronDown,
type IconComponent,
OverflowingTextWithTooltip,
TintedIconTile,
} from 'twenty-ui/display';
import { TintedIconTile } from 'twenty-ui/data-display';
import { IconChevronDown, type IconComponent } from 'twenty-ui/icon';
import { OverflowingTextWithTooltip } from 'twenty-ui/surfaces';
import { type ThemeColor } from 'twenty-ui/theme';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
@@ -19,7 +19,7 @@ import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { isNonEmptyArray, isNonEmptyString } from '@sniptt/guards';
import { isDefined } from 'twenty-shared/utils';
import { type IconComponent } from 'twenty-ui/display';
import { type IconComponent } from 'twenty-ui/icon';
import { type SelectOption } from 'twenty-ui/input';
import { MenuItem, MenuItemSelect } from 'twenty-ui/navigation';
import { themeCssVariables } from 'twenty-ui/theme-constants';
@@ -2,11 +2,9 @@ import { type SelectSizeVariant } from '@/ui/input/components/Select';
import { styled } from '@linaria/react';
import { useContext } from 'react';
import { isDefined } from 'twenty-shared/utils';
import {
IconChevronDown,
OverflowingTextWithTooltip,
TintedIconTile,
} from 'twenty-ui/display';
import { TintedIconTile } from 'twenty-ui/data-display';
import { IconChevronDown } from 'twenty-ui/icon';
import { OverflowingTextWithTooltip } from 'twenty-ui/surfaces';
import { type SelectOption } from 'twenty-ui/input';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
@@ -12,7 +12,7 @@ import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/use
import { useEffect, useMemo, useRef, useState } from 'react';
import { t } from '@lingui/core/macro';
import { isDefined } from 'twenty-shared/utils';
import { type TagColor } from 'twenty-ui/components';
import { type TagColor } from 'twenty-ui/data-display';
import { type SelectOption } from 'twenty-ui/input';
import { MenuItemSelectTag } from 'twenty-ui/navigation';
import { normalizeSearchText } from '~/utils/normalizeSearchText';
@@ -14,8 +14,8 @@ import React, {
useRef,
useState,
} from 'react';
import { type IconComponent, IconEye, IconEyeOff } from 'twenty-ui/display';
import { AutogrowWrapper } from 'twenty-ui/utilities';
import { type IconComponent, IconEye, IconEyeOff } from 'twenty-ui/icon';
import { AutogrowWrapper } from 'twenty-ui/layout';
import { useCombinedRefs } from '~/hooks/useCombinedRefs';
import { turnIntoEmptyStringIfWhitespacesOnly } from '~/utils/string/turnIntoEmptyStringIfWhitespacesOnly';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
@@ -8,7 +8,7 @@ import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePush
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
import { styled } from '@linaria/react';
import { OverflowingTextWithTooltip } from 'twenty-ui/display';
import { OverflowingTextWithTooltip } from 'twenty-ui/surfaces';
import { themeCssVariables } from 'twenty-ui/theme-constants';
type InputProps = {
@@ -3,7 +3,7 @@ import { useState } from 'react';
import { userEvent, within } from 'storybook/test';
import { Select, type SelectProps } from '@/ui/input/components/Select';
import { IconPlus } from 'twenty-ui/display';
import { IconPlus } from 'twenty-ui/icon';
import { ComponentDecorator } from 'twenty-ui/testing';
type RenderProps = SelectProps<string | number | boolean | null>;
@@ -4,7 +4,7 @@ import { useMemo } from 'react';
import { SELECT_COUNTRY_DROPDOWN_ID } from '@/ui/input/components/internal/country/constants/SelectCountryDropdownId';
import { useCountries } from '@/ui/input/components/internal/hooks/useCountries';
import { Select } from '@/ui/input/components/Select';
import { IconCircleOff, type IconComponentProps } from 'twenty-ui/display';
import { IconCircleOff, type IconComponentProps } from 'twenty-ui/icon';
import { type SelectOption } from 'twenty-ui/input';
export const CountrySelect = ({
@@ -7,7 +7,7 @@ import { CURRENCIES } from '@/settings/data-model/constants/Currencies';
import { type Currency } from '@/ui/input/components/internal/types/Currency';
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useContext } from 'react';
import { IconChevronDown } from 'twenty-ui/display';
import { IconChevronDown } from 'twenty-ui/icon';
import { CurrencyPickerDropdownSelect } from './CurrencyPickerDropdownSelect';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledDropdownButtonContainer = styled.div`
@@ -24,7 +24,7 @@ import {
turnJSDateToPlainDate,
type RelativeDateFilter,
} from 'twenty-shared/utils';
import { IconCalendarX } from 'twenty-ui/display';
import { IconCalendarX } from 'twenty-ui/icon';
import { MenuItemLeftContent } from 'twenty-ui/navigation';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
@@ -5,7 +5,7 @@ import { Select } from '@/ui/input/components/Select';
import { DatePickerInput } from '@/ui/input/components/internal/date/components/DatePickerInput';
import { getMonthSelectOptions } from '@/ui/input/components/internal/date/utils/getMonthSelectOptions';
import { ClickOutsideListenerContext } from '@/ui/utilities/pointer-event/contexts/ClickOutsideListenerContext';
import { IconChevronLeft, IconChevronRight } from 'twenty-ui/display';
import { IconChevronLeft, IconChevronRight } from 'twenty-ui/icon';
import { LightIconButton } from 'twenty-ui/input';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
@@ -20,7 +20,7 @@ import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import 'react-datepicker/dist/react-datepicker.css';
import { IconCalendarX } from 'twenty-ui/display';
import { IconCalendarX } from 'twenty-ui/icon';
import { MenuItemLeftContent } from 'twenty-ui/navigation';
import { useGetShiftedDateToSystemTimeZone } from '@/ui/input/components/internal/date/hooks/useGetShiftedDateToSystemTimeZone';
@@ -23,7 +23,7 @@ import {
IconChevronLeft,
IconChevronRight,
IconClock,
} from 'twenty-ui/display';
} from 'twenty-ui/icon';
import { LightIconButton } from 'twenty-ui/input';
import { themeCssVariables } from 'twenty-ui/theme-constants';
@@ -12,7 +12,7 @@ import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDrop
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import 'react-phone-number-input/style.css';
import { isDefined } from 'twenty-shared/utils';
import { IconChevronDown, IconWorld } from 'twenty-ui/display';
import { IconChevronDown, IconWorld } from 'twenty-ui/icon';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
type StyledDropdownButtonProps = {
@@ -2,7 +2,7 @@ import { renderHook } from '@testing-library/react';
import { act } from 'react';
import { useIconPicker } from '@/ui/input/hooks/useIconPicker';
import { Icon123, IconApps } from 'twenty-ui/display';
import { Icon123, IconApps } from 'twenty-ui/icon';
describe('useIconPicker', () => {
it('should return correct iconPickerState', async () => {
@@ -1,5 +1,5 @@
import { createAtomState } from '@/ui/utilities/state/jotai/utils/createAtomState';
import { IconApps, type IconComponent } from 'twenty-ui/display';
import { IconApps, type IconComponent } from 'twenty-ui/icon';
type IconPickerState = {
Icon: IconComponent;
@@ -3,7 +3,7 @@ import { type Meta, type StoryObj } from '@storybook/react-vite';
import { fn } from 'storybook/test';
import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableItem';
import { IconBell } from 'twenty-ui/display';
import { IconBell } from 'twenty-ui/icon';
import { MenuItemDraggable } from 'twenty-ui/navigation';
import { ComponentDecorator } from 'twenty-ui/testing';
@@ -2,7 +2,7 @@ import { DraggableItem } from '@/ui/layout/draggable-list/components/DraggableIt
import { DraggableList } from '@/ui/layout/draggable-list/components/DraggableList';
import { type Meta, type StoryObj } from '@storybook/react-vite';
import { action } from 'storybook/actions';
import { IconBell } from 'twenty-ui/display';
import { IconBell } from 'twenty-ui/icon';
import { MenuItemDraggable } from 'twenty-ui/navigation';
import { ComponentDecorator } from 'twenty-ui/testing';
@@ -1,10 +1,7 @@
import { type MouseEvent, type ReactElement, useContext } from 'react';
import { styled } from '@linaria/react';
import {
type Avatar,
type AvatarProps,
type IconComponent,
} from 'twenty-ui/display';
import { type Avatar, type AvatarProps } from 'twenty-ui/data-display';
import { type IconComponent } from 'twenty-ui/icon';
import { LightIconButton } from 'twenty-ui/input';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
@@ -5,7 +5,7 @@ import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { styled } from '@linaria/react';
import { useContext } from 'react';
import { IconChevronDown } from 'twenty-ui/display';
import { IconChevronDown } from 'twenty-ui/icon';
import { type SelectOption } from 'twenty-ui/input';
import { MenuItemSelect } from 'twenty-ui/navigation';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
@@ -1,6 +1,6 @@
import { styled } from '@linaria/react';
import { type ReactNode } from 'react';
import { Label } from 'twenty-ui/display';
import { Label } from 'twenty-ui/typography';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledDropdownMenuSubheaderContainer = styled.div`
@@ -23,11 +23,7 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { StyledDropdownMenuSubheader } from '@/ui/layout/dropdown/components/StyledDropdownMenuSubheader';
import {
// TEMP_DISABLED_TEST: Commented out unused import
// Avatar,
IconChevronLeft,
} from 'twenty-ui/display';
import { IconChevronLeft } from 'twenty-ui/icon';
import { Button } from 'twenty-ui/input';
import { MenuItem } from 'twenty-ui/navigation';
import { ComponentDecorator } from 'twenty-ui/testing';
@@ -5,12 +5,8 @@ import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent
import { DropdownMenuHeader } from '@/ui/layout/dropdown/components/DropdownMenuHeader/DropdownMenuHeader';
import { DropdownMenuHeaderLeftComponent } from '@/ui/layout/dropdown/components/DropdownMenuHeader/internal/DropdownMenuHeaderLeftComponent';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import {
Avatar,
IconChevronLeft,
IconChevronRight,
IconPlus,
} from 'twenty-ui/display';
import { Avatar } from 'twenty-ui/data-display';
import { IconChevronLeft, IconChevronRight, IconPlus } from 'twenty-ui/icon';
import { MenuItem } from 'twenty-ui/navigation';
import { AVATAR_URL_MOCK, ComponentDecorator } from 'twenty-ui/testing';
@@ -10,9 +10,9 @@ import {
import { ExpandedListDropdown } from '@/ui/layout/expandable-list/components/ExpandedListDropdown';
import { isFirstOverflowingChildElement } from '@/ui/layout/expandable-list/utils/isFirstOverflowingChildElement';
import { isDefined } from 'twenty-shared/utils';
import { ChipSize } from 'twenty-ui/components';
import { OverflowingTextWithTooltip } from 'twenty-ui/display';
import { AnimatedContainer } from 'twenty-ui/utilities';
import { ChipSize } from 'twenty-ui/data-display';
import { OverflowingTextWithTooltip } from 'twenty-ui/surfaces';
import { AnimatedContainer } from 'twenty-ui/layout';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledContainer = styled.div`
@@ -2,7 +2,7 @@ import { type Meta, type StoryObj } from '@storybook/react-vite';
import { expect, userEvent, within } from 'storybook/test';
import { ExpandableList } from '@/ui/layout/expandable-list/components/ExpandableList';
import { Tag } from 'twenty-ui/components';
import { Tag } from 'twenty-ui/data-display';
import { ComponentDecorator } from 'twenty-ui/testing';
import { MAIN_COLOR_NAMES } from 'twenty-ui/theme';
@@ -1,6 +1,6 @@
import { styled } from '@linaria/react';
import { useContext } from 'react';
import { IconPlayerPlay } from 'twenty-ui/display';
import { IconPlayerPlay } from 'twenty-ui/icon';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
type HeroPlayButtonProps = {
@@ -8,14 +8,10 @@ import { ModalStatefulWrapper } from '@/ui/layout/modal/components/ModalStateful
import { useModal } from '@/ui/layout/modal/hooks/useModal';
import { msg } from '@lingui/core/macro';
import { useLingui } from '@lingui/react/macro';
import { H1Title, H1TitleFontColor } from 'twenty-ui/display';
import { H1Title, H1TitleFontColor } from 'twenty-ui/typography';
import { Button, type ButtonAccent } from 'twenty-ui/input';
import {
Section,
SectionAlignment,
SectionFontColor,
type ModalOverlay,
} from 'twenty-ui/layout';
import { Section, SectionAlignment, SectionFontColor } from 'twenty-ui/layout';
import { type ModalOverlay } from 'twenty-ui/surfaces';
import { themeCssVariables } from 'twenty-ui/theme-constants';
export type ConfirmationModalProps = {
@@ -12,7 +12,7 @@ import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { useRef } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { Modal } from 'twenty-ui/layout';
import { Modal } from 'twenty-ui/surfaces';
export const ModalStatefulWrapper = ({
modalInstanceId,
@@ -10,7 +10,7 @@ import { isModalOpenedComponentState } from '@/ui/layout/modal/states/isModalOpe
import { focusStackState } from '@/ui/utilities/focus/states/focusStackState';
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
import { jotaiStore } from '@/ui/utilities/state/jotai/jotaiStore';
import { ModalContent, ModalFooter, ModalHeader } from 'twenty-ui/layout';
import { ModalContent, ModalFooter, ModalHeader } from 'twenty-ui/surfaces';
import { ComponentDecorator } from 'twenty-ui/testing';
import { RootDecorator } from '~/testing/decorators/RootDecorator';
import { sleep } from '~/utils/sleep';
@@ -1,5 +1,5 @@
import type React from 'react';
import { type ModalProps } from 'twenty-ui/layout';
import { type ModalProps } from 'twenty-ui/surfaces';
export type ModalStatefulWrapperProps = Pick<
ModalProps,
@@ -10,11 +10,8 @@ import { PAGE_BAR_MIN_HEIGHT } from '@/ui/layout/page/constants/PageBarMinHeight
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { AnimatePresence } from 'framer-motion';
import { isDefined } from 'twenty-shared/utils';
import {
type IconComponent,
IconX,
OverflowingTextWithTooltip,
} from 'twenty-ui/display';
import { type IconComponent, IconX } from 'twenty-ui/icon';
import { OverflowingTextWithTooltip } from 'twenty-ui/surfaces';
import { LightIconButton } from 'twenty-ui/input';
import {
MOBILE_VIEWPORT,
@@ -4,12 +4,9 @@ import { Trans } from '@lingui/react/macro';
import { type ChangeEvent, type ReactNode, useContext, useRef } from 'react';
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import { isDefined } from 'twenty-shared/utils';
import {
AppTooltip,
Avatar,
type AvatarType,
type IconComponent,
} from 'twenty-ui/display';
import { Avatar, type AvatarType } from 'twenty-ui/data-display';
import { type IconComponent } from 'twenty-ui/icon';
import { AppTooltip } from 'twenty-ui/surfaces';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { v4 as uuidV4 } from 'uuid';
@@ -1,4 +1,4 @@
import { type IconComponent } from 'twenty-ui/display';
import { type IconComponent } from 'twenty-ui/icon';
export type SidePanelFooterCommandMenuItem = {
id: string;
@@ -1,7 +1,7 @@
import { type SingleTabProps } from '@/ui/layout/tab-list/types/SingleTabProps';
import { useContext } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { Avatar } from 'twenty-ui/display';
import { Avatar } from 'twenty-ui/data-display';
import { ThemeContext } from 'twenty-ui/theme-constants';
export const TabAvatar = ({ tab }: { tab: SingleTabProps }) => {
@@ -4,7 +4,7 @@ import { TAB_LIST_GAP } from '@/ui/layout/tab-list/constants/TabListGap';
import { type SingleTabProps } from '@/ui/layout/tab-list/types/SingleTabProps';
import { NodeDimension } from '@/ui/utilities/dimensions/components/NodeDimension';
import { styled } from '@linaria/react';
import { IconPlus } from 'twenty-ui/display';
import { IconPlus } from 'twenty-ui/icon';
import { TabButton } from 'twenty-ui/input';
import { type TabListDimensions } from '@/ui/layout/tab-list/types/TabListDimension';
@@ -1,6 +1,6 @@
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { IconChevronDown } from 'twenty-ui/display';
import { IconChevronDown } from 'twenty-ui/icon';
import { TabButton } from 'twenty-ui/input';
import { TAB_LIST_HEIGHT } from '@/ui/layout/tab-list/constants/TabListHeight';
@@ -9,7 +9,7 @@ import {
IconMail,
IconPhone,
IconUser,
} from 'twenty-ui/display';
} from 'twenty-ui/icon';
import {
AVATAR_URL_MOCK,
ComponentWithRouterDecorator,
@@ -1,4 +1,4 @@
import { type IconComponent } from 'twenty-ui/display';
import { type IconComponent } from 'twenty-ui/icon';
export type SingleTabProps<T extends string = string> = {
title: string;
@@ -4,11 +4,7 @@ import { sortedFieldByTableFamilyState } from '@/ui/layout/table/states/sortedFi
import { type TableSortValue } from '@/ui/layout/table/types/TableSortValue';
import { useAtomFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilyStateValue';
import { useSetAtomFamilyState } from '@/ui/utilities/state/jotai/hooks/useSetAtomFamilyState';
import {
IconArrowDown,
IconArrowUp,
type IconComponent,
} from 'twenty-ui/display';
import { IconArrowDown, IconArrowUp, type IconComponent } from 'twenty-ui/icon';
export const SortableTableHeader = ({
tableId,
@@ -1,7 +1,8 @@
import { styled } from '@linaria/react';
import { type ReactNode, useContext, useState } from 'react';
import { TableBody } from './TableBody';
import { IconChevronDown, IconChevronUp, Label } from 'twenty-ui/display';
import { IconChevronDown, IconChevronUp } from 'twenty-ui/icon';
import { Label } from 'twenty-ui/typography';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
type TableSectionProps = {
@@ -1,5 +1,5 @@
import { type MessageDescriptor } from '@lingui/core';
import { type IconComponent } from 'twenty-ui/display';
import { type IconComponent } from 'twenty-ui/icon';
export type TableFieldMetadata<ItemType> = {
fieldLabel: MessageDescriptor;
@@ -4,7 +4,7 @@ import { styled } from '@linaria/react';
import { isNonEmptyString } from '@sniptt/guards';
import { type ReactNode, useContext } from 'react';
import { Link } from 'react-router-dom';
import { IconChevronLeft } from 'twenty-ui/display';
import { IconChevronLeft } from 'twenty-ui/icon';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
export type MobileBreadcrumbProps = {
@@ -11,7 +11,7 @@ import {
IconChevronRight,
type IconComponent,
IconDotsVertical,
} from 'twenty-ui/display';
} from 'twenty-ui/icon';
import { LightIconButton, type LightIconButtonProps } from 'twenty-ui/input';
import {
type MenuItemAccent,
@@ -5,7 +5,7 @@ import {
IconList,
IconSearch,
IconSettings,
} from 'twenty-ui/display';
} from 'twenty-ui/icon';
import { NavigationBar } from 'twenty-ui/navigation';
import { ComponentDecorator } from 'twenty-ui/testing';
import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator';
@@ -10,7 +10,7 @@ import { DEFAULT_WORKSPACE_LOGO } from '@/ui/navigation/navigation-drawer/consta
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { useContext } from 'react';
import { Avatar } from 'twenty-ui/display';
import { Avatar } from 'twenty-ui/data-display';
import { ThemeContext } from 'twenty-ui/theme-constants';
type MultiWorkspaceDropdownClickableComponentProps = {
@@ -28,8 +28,8 @@ import { themeCssVariables } from 'twenty-ui/theme-constants';
import { isNonEmptyString } from '@sniptt/guards';
import { AppPath, SettingsPath } from 'twenty-shared/types';
import { getSettingsPath } from 'twenty-shared/utils';
import { Avatar } from 'twenty-ui/data-display';
import {
Avatar,
IconDotsVertical,
IconLogout,
IconMessage,
@@ -37,7 +37,7 @@ import {
IconSettings,
IconSwitchHorizontal,
IconUserPlus,
} from 'twenty-ui/display';
} from 'twenty-ui/icon';
import { LightIconButton } from 'twenty-ui/input';
import {
MenuItem,
@@ -6,7 +6,7 @@ import { multiWorkspaceDropdownState } from '@/ui/navigation/navigation-drawer/s
import { useColorScheme } from '@/ui/theme/hooks/useColorScheme';
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
import { useLingui } from '@lingui/react/macro';
import { IconCheck, IconChevronLeft } from 'twenty-ui/display';
import { IconCheck, IconChevronLeft } from 'twenty-ui/icon';
import { MenuItem } from 'twenty-ui/navigation';
export const MultiWorkspaceDropdownThemesComponents = () => {
@@ -8,7 +8,7 @@ import { useLingui } from '@lingui/react/macro';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
import { useState } from 'react';
import { IconChevronLeft } from 'twenty-ui/display';
import { IconChevronLeft } from 'twenty-ui/icon';
import { WorkspacesForSignIn } from './components/WorkspacesForSignIn';
import { WorkspacesForSignUp } from './components/WorkspacesForSignUp';
@@ -1,5 +1,5 @@
import { styled } from '@linaria/react';
import { IconChevronDown } from 'twenty-ui/display';
import { IconChevronDown } from 'twenty-ui/icon';
import { themeCssVariables } from 'twenty-ui/theme-constants';
export const StyledContainer = styled.div<{
@@ -1,4 +1,4 @@
import { Avatar } from 'twenty-ui/display';
import { Avatar } from 'twenty-ui/data-display';
import { MenuItemSelectAvatar, UndecoratedLink } from 'twenty-ui/navigation';
import { DEFAULT_WORKSPACE_LOGO } from '@/ui/navigation/navigation-drawer/constants/DefaultWorkspaceLogo';
import { type AvailableWorkspace } from '~/generated-metadata/graphql';
@@ -9,7 +9,7 @@ import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomStat
import { useIsWorkspaceActivationStatusEqualsTo } from '@/workspace/hooks/useIsWorkspaceActivationStatusEqualsTo';
import { WorkspaceActivationStatus } from 'twenty-shared/workspace';
import { useContext } from 'react';
import { IconX } from 'twenty-ui/display';
import { IconX } from 'twenty-ui/icon';
import { UndecoratedLink } from 'twenty-ui/navigation';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
@@ -7,7 +7,7 @@ import { styled } from '@linaria/react';
import {
IconLayoutSidebarLeftCollapse,
IconLayoutSidebarRightCollapse,
} from 'twenty-ui/display';
} from 'twenty-ui/icon';
import { LightIconButton } from 'twenty-ui/input';
import { themeCssVariables } from 'twenty-ui/theme-constants';
@@ -1,6 +1,6 @@
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { IconSearch } from 'twenty-ui/display';
import { IconSearch } from 'twenty-ui/icon';
import { LightIconButton } from 'twenty-ui/input';
import { MOBILE_VIEWPORT, themeCssVariables } from 'twenty-ui/theme-constants';
@@ -7,7 +7,7 @@ import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useLis
import { type JSX, type FocusEvent, useRef } from 'react';
import { Key } from 'ts-key-enum';
import { isDefined } from 'twenty-shared/utils';
import { type IconComponent, type TablerIconsProps } from 'twenty-ui/display';
import { type IconComponent, type TablerIconsProps } from 'twenty-ui/icon';
type NavigationDrawerInputProps = {
className?: string;
@@ -13,17 +13,15 @@ import { isNonEmptyString } from '@sniptt/guards';
import { type JSX, type ReactNode, useContext } from 'react';
import { Link } from 'react-router-dom';
import { isDefined } from 'twenty-shared/utils';
import { Pill } from 'twenty-ui/components';
import { Pill, TintedIconTile } from 'twenty-ui/data-display';
import { type IconComponent, type TablerIconsProps } from 'twenty-ui/icon';
import {
AppTooltip,
type IconComponent,
Label,
OverflowingTextWithTooltip,
type TablerIconsProps,
TintedIconTile,
TooltipDelay,
TooltipPosition,
} from 'twenty-ui/display';
} from 'twenty-ui/surfaces';
import { Label } from 'twenty-ui/typography';
import {
MOBILE_VIEWPORT,
ThemeContext,
@@ -6,7 +6,8 @@ import { styled } from '@linaria/react';
import { motion } from 'framer-motion';
import React, { useContext } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { IconChevronRight, Label } from 'twenty-ui/display';
import { IconChevronRight } from 'twenty-ui/icon';
import { Label } from 'twenty-ui/typography';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledTitle = styled.div`
@@ -33,8 +33,8 @@ import {
IconUser,
IconUserCircle,
IconUsers,
} from 'twenty-ui/display';
import { AdvancedSettingsToggle } from 'twenty-ui/navigation';
} from 'twenty-ui/icon';
import { AdvancedSettingsToggle } from 'twenty-ui/input';
import { getOsControlSymbol } from 'twenty-ui/utilities';
import { NavigationDrawer } from '@/ui/navigation/navigation-drawer/components/NavigationDrawer';
@@ -2,7 +2,7 @@ import { styled } from '@linaria/react';
import { type Meta, type StoryObj } from '@storybook/react-vite';
import { NavigationDrawerItem } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerItem';
import { IconSearch } from 'twenty-ui/display';
import { IconSearch } from 'twenty-ui/icon';
import { CatalogDecorator, type CatalogStory } from 'twenty-ui/testing';
import { getOsControlSymbol } from 'twenty-ui/utilities';
import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWithRouterDecorator';
@@ -3,7 +3,7 @@ import { motion } from 'framer-motion';
import { useContext } from 'react';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { AnimatedCheckmark } from 'twenty-ui/display';
import { AnimatedCheckmark } from 'twenty-ui/data-display';
import {
MOBILE_VIEWPORT,
ThemeContext,
@@ -10,7 +10,7 @@ import {
IconMoon,
IconSun,
IconSunMoon,
} from 'twenty-ui/display';
} from 'twenty-ui/icon';
export const useColorScheme = () => {
const [currentWorkspaceMember, setCurrentWorkspaceMember] = useAtomState(