Files
twenty/packages/twenty-ui/src/display/index.ts
T
Charles Bochet d2f8352cb8 Start Jotai Migration (#17893)
## Recoil → Jotai progressive migration: infrastructure +
ChipFieldDisplay

### Benchmark

In the beginning, there was no hope:
<img width="1180" height="948" alt="image"
src="https://github.com/user-attachments/assets/f8635991-52e6-4958-8240-6ba7214132b2"
/>

Then the hope was reborn
<img width="2070" height="948" alt="image"
src="https://github.com/user-attachments/assets/be1182b9-1c8d-4fdc-ab4c-1484ad74449d"
/>



### Approach

We introduce a **V2 state management layer** backed by Jotai that
mirrors the existing Recoil API, enabling component-by-component
migration without a big-bang rewrite.

#### V2 API (Jotai-backed, Recoil-ergonomic)

- `createStateV2` / `createFamilyStateV2` — drop-in replacements for
`createState` / `createFamilyState`, returning wrapper types over Jotai
atoms
- `useRecoilValueV2`, `useRecoilStateV2`, `useFamilyRecoilValueV2`, etc.
— thin wrappers around Jotai's `useAtomValue` / `useAtom` / `useSetAtom`
- A shared `jotaiStore` (via `createStore()`) passed to a
`<JotaiProvider>` wrapping `<RecoilRoot>`, also accessible imperatively
for dual-writes

#### Dual-write bridge for progressive migration

For state shared between migrated and non-migrated components, we use
**dual-write**: writers update both the Recoil atom and the Jotai V2
atom (via `jotaiStore.set()`). This avoids sync components or extra
subscriptions.

Write sites updated: `useUpsertRecordsInStore`, `useSetRecordTableData`,
`ListenRecordUpdatesEffect`, `RecordShowEffect`,
`useLoadRecordIndexStates`, `useUpdateObjectViewOptions`.

#### First migration: ChipFieldDisplay render path

- `useChipFieldDisplay` → reads `recordStoreFamilyStateV2` via
`useFamilyRecoilValueV2` (was `useRecoilValue(recordStoreFamilyState)`)
- `RecordChip` → reads `recordIndexOpenRecordInStateV2` via
`useRecoilValueV2` (was `useRecoilValue(recordIndexOpenRecordInState)`)
- `Avatar` (twenty-ui) and event handlers (`useOpenRecordInCommandMenu`)
left on Recoil — not on the render path / in a different package

#### Pattern for migrating additional state

1. Create V2 atom: `createStateV2` or `createFamilyStateV2`
2. Add `jotaiStore.set(v2Atom, value)` at each write site
3. Switch readers to `useRecoilValueV2(v2Atom)`
4. Once all readers are migrated, remove the Recoil atom and dual-writes

#### Why not jotai-recoil-adapter?

Evaluated
[jotai-recoil-adapter](https://github.com/clockelliptic/jotai-recoil-adapter)
— not production-ready (21 open issues, no React 19, forces providerless
mode, missing types). We built a purpose-built thin layer instead.
2026-02-12 16:05:38 +01:00

547 lines
17 KiB
TypeScript

/*
* _____ _
*|_ _|_ _____ _ __ | |_ _ _
* | | \ \ /\ / / _ \ '_ \| __| | | | Auto-generated file
* | | \ V V / __/ | | | |_| |_| | Any edits to this will be overridden
* |_| \_/\_/ \___|_| |_|\__|\__, |
* |___/
*/
export type { AvatarProps } from './avatar/components/Avatar';
export { Avatar } from './avatar/components/Avatar';
export type { AvatarGroupProps } from './avatar/components/AvatarGroup';
export { AvatarGroup } from './avatar/components/AvatarGroup';
export { invalidAvatarUrlsAtomV2 } from './avatar/components/states/invalidAvatarUrlsAtomV2';
export { invalidAvatarUrlsState } from './avatar/components/states/isInvalidAvatarUrlState';
export { AVATAR_PROPERTIES_BY_SIZE } from './avatar/constants/AvatarPropertiesBySize';
export type { AvatarSize } from './avatar/types/AvatarSize';
export type { AvatarType } from './avatar/types/AvatarType';
export type { BannerVariant, BannerProps } from './banner/components/Banner';
export { Banner } from './banner/components/Banner';
export type { SidePanelInformationBannerProps } from './banner/components/SidePanelInformationBanner';
export { SidePanelInformationBanner } from './banner/components/SidePanelInformationBanner';
export type { CalloutVariant, CalloutProps } from './callout/Callout';
export { Callout } from './callout/Callout';
export type { AnimatedCheckmarkProps } from './checkmark/components/AnimatedCheckmark';
export { AnimatedCheckmark } from './checkmark/components/AnimatedCheckmark';
export type { CheckmarkProps } from './checkmark/components/Checkmark';
export { Checkmark } from './checkmark/components/Checkmark';
export type {
ColorSampleVariant,
ColorSampleProps,
} from './color/components/ColorSample';
export { ColorSample } from './color/components/ColorSample';
export type { CommandBlockProps } from './command-block/components/CommandBlock';
export { CommandBlock } from './command-block/components/CommandBlock';
export type { IconProps } from './icon/components/Icon';
export { Icon } from './icon/components/Icon';
export type { IconAddressBookProps } from './icon/components/IconAddressBook';
export { IconAddressBook } from './icon/components/IconAddressBook';
export type { IconChartBarHorizontalProps } from './icon/components/IconChartBarHorizontal';
export { IconChartBarHorizontal } from './icon/components/IconChartBarHorizontal';
export type { IconGmailProps } from './icon/components/IconGmail';
export { IconGmail } from './icon/components/IconGmail';
export type { IconGoogleProps } from './icon/components/IconGoogle';
export { IconGoogle } from './icon/components/IconGoogle';
export type { IconGoogleCalendarProps } from './icon/components/IconGoogleCalendar';
export { IconGoogleCalendar } from './icon/components/IconGoogleCalendar';
export type { IconLockCustomProps } from './icon/components/IconLock';
export { IconLockCustom } from './icon/components/IconLock';
export type { IconMicrosoftProps } from './icon/components/IconMicrosoft';
export { IconMicrosoft } from './icon/components/IconMicrosoft';
export type { IconMicrosoftCalendarProps } from './icon/components/IconMicrosoftCalendar';
export { IconMicrosoftCalendar } from './icon/components/IconMicrosoftCalendar';
export type { IconMicrosoftOutlookProps } from './icon/components/IconMicrosoftOutlook';
export { IconMicrosoftOutlook } from './icon/components/IconMicrosoftOutlook';
export type { IconRelationManyToOneProps } from './icon/components/IconRelationManyToOne';
export { IconRelationManyToOne } from './icon/components/IconRelationManyToOne';
export type { IconTrashXOffProps } from './icon/components/IconTrashXOff';
export { IconTrashXOff } from './icon/components/IconTrashXOff';
export type { IconTwentyStarProps } from './icon/components/IconTwentyStar';
export { IconTwentyStar } from './icon/components/IconTwentyStar';
export type { IconTwentyStarFilledProps } from './icon/components/IconTwentyStarFilled';
export { IconTwentyStarFilled } from './icon/components/IconTwentyStarFilled';
export type { IllustrationIconArrayProps } from './icon/components/IllustrationIconArray';
export { IllustrationIconArray } from './icon/components/IllustrationIconArray';
export type { IllustrationIconCalendarEventProps } from './icon/components/IllustrationIconCalendarEvent';
export { IllustrationIconCalendarEvent } from './icon/components/IllustrationIconCalendarEvent';
export type { IllustrationIconCalendarTimeProps } from './icon/components/IllustrationIconCalendarTime';
export { IllustrationIconCalendarTime } from './icon/components/IllustrationIconCalendarTime';
export type { IllustrationIconCurrencyProps } from './icon/components/IllustrationIconCurrency';
export { IllustrationIconCurrency } from './icon/components/IllustrationIconCurrency';
export type { IllustrationIconFileProps } from './icon/components/IllustrationIconFile';
export { IllustrationIconFile } from './icon/components/IllustrationIconFile';
export type { IllustrationIconJsonProps } from './icon/components/IllustrationIconJson';
export { IllustrationIconJson } from './icon/components/IllustrationIconJson';
export type { IllustrationIconLinkProps } from './icon/components/IllustrationIconLink';
export { IllustrationIconLink } from './icon/components/IllustrationIconLink';
export type { IllustrationIconMailProps } from './icon/components/IllustrationIconMail';
export { IllustrationIconMail } from './icon/components/IllustrationIconMail';
export type { IllustrationIconManyToManyProps } from './icon/components/IllustrationIconManyToMany';
export { IllustrationIconManyToMany } from './icon/components/IllustrationIconManyToMany';
export type { IllustrationIconMapProps } from './icon/components/IllustrationIconMap';
export { IllustrationIconMap } from './icon/components/IllustrationIconMap';
export type { IllustrationIconNumbersProps } from './icon/components/IllustrationIconNumbers';
export { IllustrationIconNumbers } from './icon/components/IllustrationIconNumbers';
export type { IllustrationIconOneToManyProps } from './icon/components/IllustrationIconOneToMany';
export { IllustrationIconOneToMany } from './icon/components/IllustrationIconOneToMany';
export type { IllustrationIconOneToOneProps } from './icon/components/IllustrationIconOneToOne';
export { IllustrationIconOneToOne } from './icon/components/IllustrationIconOneToOne';
export type { IllustrationIconPhoneProps } from './icon/components/IllustrationIconPhone';
export { IllustrationIconPhone } from './icon/components/IllustrationIconPhone';
export type { IllustrationIconSettingProps } from './icon/components/IllustrationIconSetting';
export { IllustrationIconSetting } from './icon/components/IllustrationIconSetting';
export type { IllustrationIconStarProps } from './icon/components/IllustrationIconStar';
export { IllustrationIconStar } from './icon/components/IllustrationIconStar';
export type { IllustrationIconTagProps } from './icon/components/IllustrationIconTag';
export { IllustrationIconTag } from './icon/components/IllustrationIconTag';
export type { IllustrationIconTagsProps } from './icon/components/IllustrationIconTags';
export { IllustrationIconTags } from './icon/components/IllustrationIconTags';
export type { IllustrationIconTextProps } from './icon/components/IllustrationIconText';
export { IllustrationIconText } from './icon/components/IllustrationIconText';
export type { IllustrationIconToggleProps } from './icon/components/IllustrationIconToggle';
export { IllustrationIconToggle } from './icon/components/IllustrationIconToggle';
export type { IllustrationIconUidProps } from './icon/components/IllustrationIconUid';
export { IllustrationIconUid } from './icon/components/IllustrationIconUid';
export type { IllustrationIconUserProps } from './icon/components/IllustrationIconUser';
export { IllustrationIconUser } from './icon/components/IllustrationIconUser';
export { IllustrationIconWrapper } from './icon/components/IllustrationIconWrapper';
export type { TablerIconsProps } from './icon/components/TablerIcons';
export {
Icon123,
IconAlertCircle,
IconAlertTriangle,
IconAlignBoxLeftTop,
IconAlignCenter,
IconAlignLeft,
IconAlignRight,
IconApi,
IconApps,
IconAppWindow,
IconArchive,
IconArchiveOff,
IconArrowBackUp,
IconArrowDown,
IconArrowLeft,
IconArrowMerge,
IconArrowRight,
IconArrowsDiagonal,
IconArrowsSort,
IconArrowsVertical,
IconArrowUp,
IconArrowUpRight,
IconAt,
IconAxisX,
IconAxisY,
IconBadge2k,
IconBaselineDensitySmall,
IconBell,
IconBlockquote,
IconBold,
IconBolt,
IconBook2,
IconBookmark,
IconBookmarkPlus,
IconBox,
IconBoxMultiple,
IconBrackets,
IconBracketsAngle,
IconBracketsContain,
IconBrain,
IconBrandDaysCounter,
IconBrandGithub,
IconBrandGoogle,
IconBrandGraphql,
IconBrandLinkedin,
IconBrandX,
IconBriefcase,
IconBroadcast,
IconBrowserMaximize,
IconBuildingSkyscraper,
IconCalendar,
IconCalendarDue,
IconCalendarEvent,
IconCalendarMonth,
IconCalendarRepeat,
IconCalendarTime,
IconCalendarWeek,
IconCalendarX,
IconCancel,
IconCaretLeft,
IconCaretRight,
IconChartBar,
IconChartBarPopular,
IconChartCandle,
IconChartDots3,
IconChartLine,
IconChartPie,
IconCheck,
IconCheckbox,
IconChevronDown,
IconChevronLeft,
IconChevronRight,
IconChevronRightPipe,
IconChevronsRight,
IconChevronUp,
IconCircle,
IconCircleDashed,
IconCircleDot,
IconCircleOff,
IconCirclePlus,
IconCircleX,
IconClick,
IconClockHour8,
IconClockPlay,
IconClockShare,
IconCode,
IconCodeCircle,
IconCoins,
IconColorSwatch,
IconColumns,
IconCommand,
IconComment,
IconCopy,
IconCopyPlus,
IconCpu,
IconCreativeCommonsSa,
IconCreditCard,
IconCsv,
IconCube,
IconCurrencyAfghani,
IconCurrencyBahraini,
IconCurrencyBaht,
IconCurrencyDinar,
IconCurrencyDirham,
IconCurrencyDollar,
IconCurrencyDollarAustralian,
IconCurrencyDollarBrunei,
IconCurrencyDollarCanadian,
IconCurrencyDollarGuyanese,
IconCurrencyDollarSingapore,
IconCurrencyDong,
IconCurrencyDram,
IconCurrencyEuro,
IconCurrencyFlorin,
IconCurrencyForint,
IconCurrencyFrank,
IconCurrencyGuarani,
IconCurrencyHryvnia,
IconCurrencyIranianRial,
IconCurrencyKip,
IconCurrencyKroneCzech,
IconCurrencyKroneDanish,
IconCurrencyKroneSwedish,
IconCurrencyLari,
IconCurrencyLeu,
IconCurrencyLira,
IconCurrencyLyd,
IconCurrencyManat,
IconCurrencyNaira,
IconCurrencyPaanga,
IconCurrencyPeso,
IconCurrencyPound,
IconCurrencyQuetzal,
IconCurrencyReal,
IconCurrencyRenminbi,
IconCurrencyRiyal,
IconCurrencyRubel,
IconCurrencyRufiyaa,
IconCurrencyRupee,
IconCurrencyRupeeNepalese,
IconCurrencyShekel,
IconCurrencySom,
IconCurrencyTaka,
IconCurrencyTenge,
IconCurrencyTugrik,
IconCurrencyWon,
IconCurrencyYen,
IconCurrencyYuan,
IconCurrencyZloty,
IconDatabase,
IconDatabaseExport,
IconDecimal,
IconDeviceFloppy,
IconDoorEnter,
IconDotsVertical,
IconDownload,
IconEdit,
IconEditCircle,
IconEraser,
IconExclamationCircle,
IconExternalLink,
IconEye,
IconEyeOff,
IconEyeShare,
IconFile,
IconFileCheck,
IconFileExport,
IconFileImport,
IconFileInfo,
IconFilePencil,
IconFileText,
IconFileUpload,
IconFileZip,
IconFilter,
IconFilterCog,
IconFilterOff,
IconFilterPlus,
IconFilters,
IconFilterX,
IconFlag,
IconFlask,
IconFocusCentered,
IconFolder,
IconFolderOpen,
IconFolderPlus,
IconFolderRoot,
IconFolderSymlink,
IconForbid,
IconFrame,
IconFunction,
IconGauge,
IconGitBranchDeleted,
IconGitCommit,
IconGizmo,
IconGripVertical,
IconH1,
IconH2,
IconH3,
IconHandClick,
IconHandMove,
IconHeadphones,
IconHeart,
IconHeartOff,
IconHeartRateMonitor,
IconHelp,
IconHelpCircle,
IconHierarchy,
IconHierarchy2,
IconHistory,
IconHistoryToggle,
IconHome,
IconHourglassHigh,
IconHours24,
IconHttpGet,
IconHttpPost,
IconId,
IconInbox,
IconInfoCircle,
IconItalic,
IconJson,
IconKey,
IconLanguage,
IconLayersLinked,
IconLayout,
IconLayoutDashboard,
IconLayoutGrid,
IconLayoutKanban,
IconLayoutList,
IconLayoutNavbar,
IconLayoutSidebarLeftCollapse,
IconLayoutSidebarRight,
IconLayoutSidebarRightCollapse,
IconLayoutSidebarRightExpand,
IconLetterK,
IconLibraryPlus,
IconLifebuoy,
IconLink,
IconLinkOff,
IconLinkPlus,
IconList,
IconListCheck,
IconListDetails,
IconListNumbers,
IconLoader,
IconLock,
IconLockOpen,
IconLogin2,
IconLogout,
IconMail,
IconMailCog,
IconMailX,
IconMap,
IconMathMax,
IconMathMin,
IconMathXy,
IconMaximize,
IconMessage,
IconMessageCirclePlus,
IconMinus,
IconMoneybag,
IconMoodSmile,
IconMoon,
IconMouse2,
IconNorthStar,
IconNoteOff,
IconNotes,
IconNumber,
IconNumber123,
IconNumber9,
IconNumbers,
IconPaperclip,
IconPassword,
IconPencil,
IconPencilOff,
IconPercentage,
IconPhone,
IconPhoto,
IconPhotoUp,
IconPilcrow,
IconPinned,
IconPinnedOff,
IconPlayerPause,
IconPlayerPlay,
IconPlayerStop,
IconPlaylistAdd,
IconPlaystationSquare,
IconPlug,
IconPlus,
IconPoint,
IconPower,
IconPresentation,
IconPrinter,
IconProgressCheck,
IconPuzzle,
IconPuzzle2,
IconQuestionMark,
IconRadiusBottomLeft,
IconRadiusBottomRight,
IconRadiusTopLeft,
IconRadiusTopRight,
IconRefresh,
IconRefreshAlert,
IconRefreshDot,
IconRelationManyToMany,
IconRelationOneToMany,
IconRelationOneToOne,
IconReload,
IconReorder,
IconRepeat,
IconRowInsertBottom,
IconRowInsertTop,
IconRestore,
IconRobot,
IconRocket,
IconRotate,
IconRotate2,
IconSearch,
IconSend,
IconServer,
IconServer2,
IconSettings,
IconSettings2,
IconSettingsAutomation,
IconShare,
IconShield,
IconSitemap,
IconSlash,
IconSortAscending,
IconSortAscendingLetters,
IconSortAscendingNumbers,
IconSortAZ,
IconSortDescending,
IconSortDescendingLetters,
IconSortDescendingNumbers,
IconSortZA,
IconSparkles,
IconSpy,
IconSql,
IconSquare,
IconSquareKey,
IconSquareNumber1,
IconSquareNumber2,
IconSquareNumber3,
IconSquareNumber4,
IconSquareNumber5,
IconSquareNumber6,
IconSquareNumber7,
IconSquareNumber8,
IconSquareNumber9,
IconSquareRoundedCheck,
IconSquareRoundedX,
IconStack2,
IconStatusChange,
IconStepInto,
IconStrikethrough,
IconSum,
IconSun,
IconSunMoon,
IconSwitchHorizontal,
IconTable,
IconTag,
IconTags,
IconTarget,
IconTargetArrow,
IconTerminal,
IconTestPipe,
IconTextCaption,
IconTextSize,
IconTextWrap,
IconTimeDuration30,
IconTimeDuration60,
IconTimelineEvent,
IconTool,
IconTransform,
IconTrash,
IconTrashOff,
IconTrashX,
IconTrendingDown,
IconTrendingUp,
IconTypography,
IconUnderline,
IconUnlink,
IconUpload,
IconUser,
IconUserCircle,
IconUserCog,
IconUserPin,
IconUserPlus,
IconUsers,
IconVariable,
IconVariablePlus,
IconVersions,
IconVersionsOff,
IconVideo,
IconWand,
IconWebhook,
IconWorld,
IconX,
} from './icon/components/TablerIcons';
export { useIcons } from './icon/hooks/useIcons';
export type { IconsProviderProps } from './icon/providers/IconsProvider';
export { IconsProvider } from './icon/providers/IconsProvider';
export { iconsState } from './icon/states/iconsState';
export type {
IconComponentProps,
IconComponent,
} from './icon/types/IconComponent';
export type { InfoAccent, InfoProps } from './info/components/Info';
export { Info } from './info/components/Info';
export type { StatusProps } from './status/components/Status';
export { Status } from './status/components/Status';
export type { HorizontalSeparatorProps } from './text/components/HorizontalSeparator';
export { HorizontalSeparator } from './text/components/HorizontalSeparator';
export { SeparatorLineText } from './text/components/SeparatorLineText';
export type { AppTooltipProps } from './tooltip/AppTooltip';
export {
TooltipPosition,
TooltipDelay,
AppTooltip,
} from './tooltip/AppTooltip';
export type { OverflowingTextWithTooltipProps } from './tooltip/OverflowingTextWithTooltip';
export { OverflowingTextWithTooltip } from './tooltip/OverflowingTextWithTooltip';
export type { H1TitleProps } from './typography/components/H1Title';
export { H1TitleFontColor, H1Title } from './typography/components/H1Title';
export type { H2TitleProps } from './typography/components/H2Title';
export { H2Title } from './typography/components/H2Title';
export type { H3TitleProps } from './typography/components/H3Title';
export { H3Title } from './typography/components/H3Title';
export type { LabelVariant } from './typography/components/Label';
export { Label } from './typography/components/Label';
export type { StyledTextProps } from './typography/components/StyledText';
export {
StyledTextContent,
StyledTextWrapper,
StyledText,
} from './typography/components/StyledText';