Deprecate runtime theme objects in favor of CSS variables (#18402)

## Summary

- **Eliminate `ICON_SIZES` / `ICON_STROKES` constants**: all icon
dimensions are now resolved at runtime via
`resolveThemeVariableAsNumber(themeCssVariables.icon.size.X)`, ensuring
values always come from computed CSS variables
- **No more consumer imports from `twenty-ui/theme`**: moved
`ColorSchemeContext`, `ColorSchemeProvider`, `ThemeColor`,
`MAIN_COLOR_NAMES`, `getNextThemeColor`, `AnimationDuration` to
`twenty-ui/theme-constants`
- **Remove `ThemeContext` / `ThemeContextProvider` / `ThemeProvider` /
`ThemeType`**: replaced across ~300 files with `themeCssVariables` (for
CSS contexts) or `resolveThemeVariable` / `resolveThemeVariableAsNumber`
(for JS runtime values)
- **Simplify provider chain**: only `ColorSchemeProvider` remains — it
toggles `light`/`dark` class on `document.documentElement` and provides
`colorScheme` via React context
- **Fix pre-existing test failures**: `useIcons.test.ts`
(non-configurable ES module spy) and
`turnRecordFilterGroupIntoGqlOperationFilter.test.ts`
(`Omit<RecordFilter, 'id'>` type mismatch)

### Theme access pattern (before → after)

| Context | Before | After |
|---------|--------|-------|
| CSS (Linaria) | `${({ theme }) => theme.font.color.primary}` |
`${themeCssVariables.font.color.primary}` |
| JS runtime (icon size, animation) | `theme.icon.size.md` /
`ICON_SIZES.md` |
`resolveThemeVariableAsNumber(themeCssVariables.icon.size.md)` |
| Color scheme check | `theme.name === 'dark'` |
`useContext(ColorSchemeContext).colorScheme === 'dark'` |
This commit is contained in:
Charles Bochet
2026-03-05 14:39:01 +01:00
committed by GitHub
parent 7293d4c1f8
commit 647c32ff3e
432 changed files with 1243 additions and 1433 deletions
@@ -1,7 +1,6 @@
import { defineLogicFunction, RoutePayload } from "twenty-sdk";
import { MetadataApiClient } from 'twenty-sdk/generated';
export const OAUTH_TOKEN_PAIRS_PATH = '/oauth/token-pairs';
type ApolloTokenResponse = {
@@ -53,16 +52,8 @@ const handler = async (event: RoutePayload): Promise<any> => {
const apolloClientSecret = process.env.APOLLO_CLIENT_SECRET ?? '';
const applicationId = process.env.APPLICATION_ID ?? '';
const metadataClient = new MetadataApiClient({});
const tokenPairs = await getAuthenticationTokenPairs(
code,
apolloClientId,
@@ -5,8 +5,6 @@ import {
} from 'twenty-sdk';
import { CoreApiClient } from 'twenty-sdk/generated';
type CompanyRecord = {
id: string;
name?: string;
@@ -38,8 +36,6 @@ type ApolloEnrichResponse = {
organization?: ApolloOrganization;
};
const extractDomain = (
domainName?: CompanyRecord['domainName'],
): string | undefined => {
@@ -172,7 +168,6 @@ const updateCompanyInTwenty = async (
}
};
type CompanyUpdateEvent = DatabaseEventPayload<
ObjectRecordUpdateEvent<CompanyRecord>
>;
@@ -181,7 +176,6 @@ const handler = async (
event: CompanyUpdateEvent,
): Promise<object | undefined> => {
const { recordId, properties } = event;
const { after: companyAfter } = properties;
@@ -206,7 +200,6 @@ const handler = async (
return { skipped: true, reason: 'no enrichment data to apply' };
}
await updateCompanyInTwenty(recordId, updateData);
const result = {
@@ -219,4 +219,3 @@ main().catch((error) => {
process.exit(1);
});
@@ -81,4 +81,3 @@ describe('HistoricalImporter', () => {
});
});
@@ -158,4 +158,3 @@ export class HistoricalImporter {
}
}
@@ -1,3 +1,2 @@
export { Meeting } from './meeting';
@@ -330,7 +330,6 @@ export class WebhookHandler {
}
}
private async createFailedMeetingRecord(params: unknown, error: string): Promise<void> {
try {
const twentyApiKey = process.env.TWENTY_API_KEY || '';
@@ -43,7 +43,6 @@ export default defineContentScript({
},
});
ctx.addEventListener(window, 'wxt:locationchange', ({newUrl, }) => {
const injectedBtn = document.querySelector('[data-id="twenty-btn"]');
if(personPattern.includes(newUrl) && !injectedBtn) ui.mount();
@@ -8,7 +8,6 @@ const StyledButton = styled.button`
--text-color: #0a66c2;
--bg-color: #00000000;
font-size: ${({theme}) => theme.spacing(3.5)};
font-weight: ${({theme}) => theme.font.weight.semiBold};
font-family: ${({theme}) => theme.font.family};
@@ -26,7 +25,6 @@ const StyledButton = styled.button`
transition-timing-function: cubic-bezier(.4, 0, .2, 1);
transition-duration: 167ms;
&:hover {
background-color: var(--hover-bg-color);
color: var(--hover-color);
@@ -1,6 +1,5 @@
import { ThemeProvider } from '@emotion/react';
import type React from 'react';
import { THEME_DARK, ThemeContextProvider } from 'twenty-ui/theme';
import { ColorSchemeProvider } from 'twenty-ui/theme-constants';
type ThemeContextProps = {
children: React.ReactNode;
@@ -8,10 +7,6 @@ type ThemeContextProps = {
export const ThemeContext = ({ children }: ThemeContextProps) => {
return (
<ThemeProvider theme={THEME_DARK}>
<ThemeContextProvider theme={THEME_DARK}>
{children}
</ThemeContextProvider>
</ThemeProvider>
<ColorSchemeProvider colorScheme="dark">{children}</ColorSchemeProvider>
);
};
@@ -1,5 +0,0 @@
import type { ThemeType } from 'twenty-ui/theme';
declare module '@emotion/react' {
export interface Theme extends ThemeType {}
}
+5 -13
View File
@@ -2,9 +2,7 @@ import { i18n } from '@lingui/core';
import { I18nProvider } from '@lingui/react';
import { type Preview } from '@storybook/react-vite';
import { initialize, mswLoader } from 'msw-storybook-addon';
import { useEffect } from 'react';
import { SOURCE_LOCALE } from 'twenty-shared/translations';
//import { useDarkMode } from 'storybook-dark-mode';
// eslint-disable-next-line no-restricted-imports
import { RootDecorator } from '../src/testing/decorators/RootDecorator';
@@ -13,7 +11,9 @@ import { resetJotaiStore } from '../src/modules/ui/utilities/state/jotai/jotaiSt
import 'react-loading-skeleton/dist/skeleton.css';
import 'twenty-ui/style.css';
import { THEME_LIGHT, ThemeContextProvider } from 'twenty-ui/theme';
import 'twenty-ui/theme-light.css';
import 'twenty-ui/theme-dark.css';
import { ThemeProvider } from 'twenty-ui/theme-constants';
// eslint-disable-next-line no-restricted-imports
import { messages as enMessages } from '../src/locales/generated/en';
@@ -60,23 +60,15 @@ initialize({
const preview: Preview = {
decorators: [
(Story) => {
// const theme = useDarkMode() ? THEME_DARK : THEME_LIGHT;
const theme = THEME_LIGHT;
useEffect(() => {
document.documentElement.className =
theme.name === 'dark' ? 'dark' : 'light';
}, [theme]);
return (
<I18nProvider i18n={i18n}>
<ThemeContextProvider theme={theme}>
<ThemeProvider colorScheme="light">
<ClickOutsideListenerContext.Provider
value={{ excludedClickOutsideId: undefined }}
>
<Story />
</ClickOutsideListenerContext.Provider>
</ThemeContextProvider>
</ThemeProvider>
</I18nProvider>
);
},
@@ -2,8 +2,7 @@ import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { useLingui } from '@lingui/react/macro';
import { IconCopy, IconExclamationCircle } from 'twenty-ui/display';
import { useContext } from 'react';
import { ThemeContext } from 'twenty-ui/theme';
import { ThemeContext } from 'twenty-ui/theme-constants';
export const useCopyToClipboard = () => {
const { theme } = useContext(ThemeContext);
const { enqueueSuccessSnackBar, enqueueErrorSnackBar } = useSnackBar();
@@ -5,9 +5,9 @@ import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader';
import { NAVIGATION_DRAWER_CONSTRAINTS } from '@/ui/layout/resizable-panel/constants/NavigationDrawerConstraints';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { useContext } from 'react';
import { ANIMATION, ThemeContext } from 'twenty-ui/theme';
import { MainNavigationDrawerItemsSkeletonLoader } from '~/loading/components/MainNavigationDrawerItemsSkeletonLoader';
import { useContext } from 'react';
import { ThemeContext } from 'twenty-ui/theme-constants';
const StyledAnimatedContainer = styled(motion.div)`
align-items: center;
@@ -47,9 +47,8 @@ const StyledSkeletonTitleContainer = styled.div`
`;
export const LeftPanelSkeletonLoader = () => {
const isMobile = useIsMobile();
const { theme } = useContext(ThemeContext);
const isMobile = useIsMobile();
return (
<StyledAnimatedContainer
initial={false}
@@ -57,7 +56,9 @@ export const LeftPanelSkeletonLoader = () => {
width: isMobile ? 0 : NAVIGATION_DRAWER_CONSTRAINTS.default,
opacity: isMobile ? 0 : 1,
}}
transition={{ duration: ANIMATION.duration.fast }}
transition={{
duration: theme.animation.duration.fast,
}}
>
<StyledItemsContainer>
<StyledSkeletonTitleContainer>
@@ -2,7 +2,7 @@ import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLo
import { styled } from '@linaria/react';
import { useContext } from 'react';
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import { ThemeContext } from 'twenty-ui/theme';
import { ThemeContext } from 'twenty-ui/theme-constants';
const StyledSkeletonContainer = styled.div`
align-items: flex-start;
@@ -22,7 +22,6 @@ export const MainNavigationDrawerItemsSkeletonLoader = ({
length: number;
}) => {
const { theme } = useContext(ThemeContext);
return (
<StyledSkeletonContainer>
<SkeletonTheme
@@ -2,8 +2,7 @@ import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLo
import { styled } from '@linaria/react';
import { useContext } from 'react';
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledRightDrawerContainer = styled.div`
display: flex;
@@ -14,7 +13,6 @@ const StyledRightDrawerContainer = styled.div`
const StyledSkeletonLoader = () => {
const { theme } = useContext(ThemeContext);
return (
<SkeletonTheme
baseColor={theme.background.tertiary}
@@ -2,8 +2,11 @@ import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLo
import { styled } from '@linaria/react';
import { useContext } from 'react';
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import { ThemeContext } from 'twenty-ui/theme';
import { MOBILE_VIEWPORT, themeCssVariables } from 'twenty-ui/theme-constants';
import {
MOBILE_VIEWPORT,
ThemeContext,
themeCssVariables,
} from 'twenty-ui/theme-constants';
const StyledMainContainer = styled.div`
background: ${themeCssVariables.background.noisy};
@@ -51,7 +54,6 @@ const StyledRightPanelFlexContainer = styled.div`
const StyledSkeletonHeaderLoader = () => {
const { theme } = useContext(ThemeContext);
return (
<StyledHeaderContainer>
<SkeletonTheme
@@ -70,7 +72,6 @@ const StyledSkeletonHeaderLoader = () => {
const StyledSkeletonAddLoader = () => {
const { theme } = useContext(ThemeContext);
return (
<SkeletonTheme
baseColor={theme.background.tertiary}
@@ -3,7 +3,7 @@ import { ActionMenuContext } from '@/action-menu/contexts/ActionMenuContext';
import { styled } from '@linaria/react';
import { motion } from 'framer-motion';
import { useContext } from 'react';
import { ThemeContext } from 'twenty-ui/theme';
import { ThemeContext } from 'twenty-ui/theme-constants';
const StyledActionContainer = styled(motion.div)`
display: flex;
@@ -12,9 +12,8 @@ const StyledActionContainer = styled(motion.div)`
`;
export const PageHeaderActionMenuButtons = () => {
const { actions } = useContext(ActionMenuContext);
const { theme } = useContext(ThemeContext);
const { actions } = useContext(ActionMenuContext);
const pinnedActions = actions.filter((entry) => entry.isPinned).toReversed();
const actionsWithPositionForAnimation = pinnedActions.map(
@@ -1,12 +1,11 @@
import { useContext } from 'react';
import { styled } from '@linaria/react';
import { differenceInSeconds, endOfDay, format } from 'date-fns';
import { useContext } from 'react';
import { CalendarEventRow } from '@/activities/calendar/components/CalendarEventRow';
import { getCalendarEventStartDate } from '@/activities/calendar/utils/getCalendarEventStartDate';
import { CardContent } from 'twenty-ui/layout';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { type TimelineCalendarEvent } from '~/generated/graphql';
type CalendarDayCardContentProps = {
@@ -54,7 +53,6 @@ export const CalendarDayCardContent = ({
divider,
}: CalendarDayCardContentProps) => {
const { theme } = useContext(ThemeContext);
const endOfDayDate = endOfDay(getCalendarEventStartDate(calendarEvents[0]));
const dayEndsIn = differenceInSeconds(endOfDayDate, Date.now());
@@ -63,7 +61,9 @@ export const CalendarDayCardContent = ({
const upcomingDayCardContentVariants = {
upcoming: {},
ended: { backgroundColor: theme.background.primary },
ended: {
backgroundColor: theme.background.primary,
},
};
return (
@@ -1,10 +1,9 @@
import { useContext } from 'react';
import { styled } from '@linaria/react';
import { Trans } from '@lingui/react/macro';
import { useContext } from 'react';
import { IconLock } from 'twenty-ui/display';
import { Card, CardContent } from 'twenty-ui/layout';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledVisibilityCard = styled(Card)`
color: ${themeCssVariables.font.color.light};
@@ -7,8 +7,7 @@ import { ParticipantChip } from '@/activities/components/ParticipantChip';
import { EllipsisDisplay } from '@/ui/field/display/components/EllipsisDisplay';
import { ExpandableList } from '@/ui/layout/expandable-list/components/ExpandableList';
import { IconCheck, IconQuestionMark, IconX } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledInlineCellBaseContainer = styled.div`
align-items: center;
@@ -1,4 +1,3 @@
import { useContext } from 'react';
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { format } from 'date-fns';
@@ -15,9 +14,9 @@ import { getCalendarEventStartDate } from '@/activities/calendar/utils/getCalend
import { hasCalendarEventEnded } from '@/activities/calendar/utils/hasCalendarEventEnded';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { useOpenCalendarEventInCommandMenu } from '@/command-menu/hooks/useOpenCalendarEventInCommandMenu';
import { useContext } from 'react';
import { IconArrowRight } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
type CalendarEventRowProps = {
calendarEvent: TimelineCalendarEvent;
@@ -1,8 +1,7 @@
import { useContext } from 'react';
import { styled } from '@linaria/react';
import { useContext } from 'react';
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledSkeletonContainer = styled.div`
align-items: center;
@@ -44,7 +43,6 @@ export const SKELETON_LOADER_HEIGHT_SIZES = {
const SkeletonColumnLoader = ({ height }: { height: number }) => {
const { theme } = useContext(ThemeContext);
return (
<SkeletonTheme
baseColor={theme.background.tertiary}
@@ -1,9 +1,8 @@
import { useContext } from 'react';
import { styled } from '@linaria/react';
import { useLingui } from '@lingui/react/macro';
import { useContext } from 'react';
import { AppTooltip, IconLock, TooltipDelay } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { MessageChannelVisibility } from '~/generated/graphql';
const StyledContainer = styled.div<{ isCompact?: boolean }>`
@@ -34,8 +33,8 @@ type EmailThreadNotSharedProps = {
export const EmailThreadNotShared = ({
visibility,
}: EmailThreadNotSharedProps) => {
const { t } = useLingui();
const { theme } = useContext(ThemeContext);
const { t } = useLingui();
const containerId = 'email-thread-not-shared';
const isCompact = visibility === MessageChannelVisibility.SUBJECT;
@@ -1,12 +1,12 @@
import { useContext } from 'react';
import { styled } from '@linaria/react';
import { ActivityRow } from '@/activities/components/ActivityRow';
import { EmailThreadNotShared } from '@/activities/emails/components/EmailThreadNotShared';
import { useOpenEmailThreadInCommandMenu } from '@/command-menu/hooks/useOpenEmailThreadInCommandMenu';
import { useContext } from 'react';
import { Avatar } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import {
MessageChannelVisibility,
type TimelineThread,
@@ -75,6 +75,7 @@ type EmailThreadPreviewProps = {
};
export const EmailThreadPreview = ({ thread }: EmailThreadPreviewProps) => {
const { theme } = useContext(ThemeContext);
const { openEmailThreadInCommandMenu } = useOpenEmailThreadInCommandMenu();
const visibility = thread.visibility;
@@ -107,8 +108,6 @@ export const EmailThreadPreview = ({ thread }: EmailThreadPreviewProps) => {
};
const isDisabled = visibility !== MessageChannelVisibility.SHARE_EVERYTHING;
const { theme } = useContext(ThemeContext);
return (
<ActivityRow onClick={handleThreadClick} disabled={isDisabled}>
<StyledHeading unread={!thread.read}>
@@ -10,7 +10,7 @@ import {
import { getFileCategoryFromExtension } from '@/object-record/record-field/ui/utils/getFileCategoryFromExtension';
import { SettingsTextInput } from '@/ui/input/components/SettingsTextInput';
import { styled } from '@linaria/react';
import { useContext, useState } from 'react';
import { useState, useContext } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { type AttachmentWithFile } from '@/activities/files/utils/filterAttachmentsWithFile';
@@ -18,8 +18,7 @@ import { FileIcon } from '@/file/components/FileIcon';
import { useHasPermissionFlag } from '@/settings/roles/hooks/useHasPermissionFlag';
import { CoreObjectNameSingular } from 'twenty-shared/types';
import { IconCalendar, OverflowingTextWithTooltip } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { isNavigationModifierPressed } from 'twenty-ui/utilities';
import { PermissionFlagType } from '~/generated-metadata/graphql';
import { formatToHumanReadableDate } from '~/utils/date-utils';
@@ -13,8 +13,7 @@ import { useContext, useEffect, useState } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { IconDownload } from 'twenty-ui/display';
import { Button } from 'twenty-ui/input';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { getFileNameAndExtension } from '~/utils/file/getFileNameAndExtension';
const MS_OFFICE_EXTENSIONS = [
@@ -200,8 +199,8 @@ export const DocumentViewer = ({
documentUrl,
documentExtension,
}: DocumentViewerProps) => {
const { t } = useLingui();
const { theme } = useContext(ThemeContext);
const { t } = useLingui();
const [csvPreview, setCsvPreview] = useState<CsvPreviewData | undefined>(
undefined,
);
@@ -1,12 +1,11 @@
import { useContext } from 'react';
import { styled } from '@linaria/react';
import { useLingui } from '@lingui/react/macro';
import { useContext } from 'react';
import { useDropzone } from 'react-dropzone';
import { useSpreadsheetImportInternal } from '@/spreadsheet-import/hooks/useSpreadsheetImportInternal';
import { IconUpload } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledContainer = styled.div`
align-items: center;
@@ -49,8 +48,8 @@ export const DropZone = ({
setIsDraggingFile,
onUploadFiles,
}: DropZoneProps) => {
const { t } = useLingui();
const { theme } = useContext(ThemeContext);
const { t } = useLingui();
const { maxFileSize } = useSpreadsheetImportInternal();
const { getRootProps, getInputProps, isDragActive } = useDropzone({
@@ -1,4 +1,3 @@
import { useContext } from 'react';
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
@@ -14,10 +13,10 @@ import { CoreObjectNameSingular } from 'twenty-shared/types';
import { StopPropagationContainer } from '@/object-record/record-board/record-board-card/components/StopPropagationContainer';
import { RecordFieldsScopeContextProvider } from '@/object-record/record-field-list/contexts/RecordFieldsScopeContext';
import { FieldContextProvider } from '@/object-record/record-field/ui/components/FieldContextProvider';
import { useContext } from 'react';
import { IconCalendar, OverflowingTextWithTooltip } from 'twenty-ui/display';
import { Checkbox, CheckboxShape } from 'twenty-ui/input';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { useCompleteTask } from '@/activities/tasks/hooks/useCompleteTask';
const StyledTaskBody = styled.div`
@@ -9,8 +9,7 @@ import { type Editor } from '@tiptap/react';
import { useContext, useId } from 'react';
import { IconPilcrow } from 'twenty-ui/display';
import { MenuItem } from 'twenty-ui/navigation';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledMenuItem = styled.button`
align-items: center;
@@ -45,7 +44,6 @@ export const TurnIntoBlockDropdown = ({
editor,
}: TurnIntoBlockDropdownProps) => {
const { theme } = useContext(ThemeContext);
const instanceId = useId();
const dropdownId = `turn-into-block-dropdown-${instanceId}`;
const { toggleDropdown } = useToggleDropdown();
@@ -84,7 +82,7 @@ export const TurnIntoBlockDropdown = ({
</StyledMenuItem>
}
dropdownOffset={{
y: parseInt(theme.spacing(1), 10),
y: parseInt(theme.spacing[1], 10),
}}
/>
);
@@ -6,8 +6,7 @@ import { useContext } from 'react';
import { type WorkflowAttachment } from 'twenty-shared/workflow';
import { AvatarOrIcon } from 'twenty-ui/components';
import { IconX } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
type WorkflowAttachmentChipProps = {
file: WorkflowAttachment;
@@ -65,8 +64,8 @@ export const WorkflowAttachmentChip = ({
onRemove,
readonly = false,
}: WorkflowAttachmentChipProps) => {
const iconColors = useFileCategoryColors();
const { theme } = useContext(ThemeContext);
const iconColors = useFileCategoryColors();
return (
<StyledChip data-chip deletable={!readonly}>
@@ -8,8 +8,7 @@ import { type ChangeEvent, useContext, useRef } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { type WorkflowAttachment } from 'twenty-shared/workflow';
import { IconUpload } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
type WorkflowSendEmailAttachmentsProps = {
files: WorkflowAttachment[];
@@ -67,11 +66,10 @@ export const WorkflowSendEmailAttachments = ({
label,
onChange,
}: WorkflowSendEmailAttachmentsProps) => {
const { theme } = useContext(ThemeContext);
const fileInputRef = useRef<HTMLInputElement>(null);
const { uploadWorkflowFile } = useUploadWorkflowFile();
const { t } = useLingui();
const { theme } = useContext(ThemeContext);
const handleAddFileClick = (e: React.MouseEvent) => {
const target = e.target as HTMLElement;
@@ -7,11 +7,10 @@ import { LazyMarkdownRenderer } from '@/ai/components/LazyMarkdownRenderer';
import { ToolStepRenderer } from '@/ai/components/ToolStepRenderer';
import { groupContiguousThinkingStepParts } from '@/ai/utils/groupContiguousThinkingStepParts';
import { styled } from '@linaria/react';
import { useContext } from 'react';
import { isToolUIPart, type ToolUIPart } from 'ai';
import { type ExtendedUIMessagePart } from 'twenty-shared/ai';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { useContext } from 'react';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledMessagePartsContainer = styled.div`
display: flex;
@@ -4,11 +4,10 @@ import { dispatchBrowserEvent } from '@/browser-event/utils/dispatchBrowserEvent
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { useContext } from 'react';
import { IconAlertCircle, IconRefresh } from 'twenty-ui/display';
import { Button } from 'twenty-ui/input';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { useContext } from 'react';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledErrorContainer = styled.div`
align-items: center;
@@ -1,10 +1,9 @@
import { useAIChatThreadClick } from '@/ai/hooks/useAIChatThreadClick';
import { styled } from '@linaria/react';
import { useContext } from 'react';
import { useLingui } from '@lingui/react/macro';
import { useContext } from 'react';
import { IconSparkles } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { type AgentChatThread } from '~/generated-metadata/graphql';
const StyledThreadsList = styled.div`
@@ -73,8 +72,8 @@ export const AIChatThreadGroup = ({
threads: AgentChatThread[];
title: string;
}) => {
const { t } = useLingui();
const { theme } = useContext(ThemeContext);
const { t } = useLingui();
const { handleThreadClick } = useAIChatThreadClick();
if (threads.length === 0) {
@@ -15,8 +15,7 @@ import {
} from 'twenty-ui/display';
import { CodeEditor, LightIconButton } from 'twenty-ui/input';
import { AnimatedExpandableContainer } from 'twenty-ui/layout';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { useCopyToClipboard } from '~/hooks/useCopyToClipboard';
const StyledContainer = styled.div`
@@ -202,8 +201,8 @@ export const CodeExecutionDisplay = ({
files = [],
isRunning = false,
}: CodeExecutionDisplayProps) => {
const { t } = useLingui();
const { theme } = useContext(ThemeContext);
const { t } = useLingui();
const { copyToClipboard } = useCopyToClipboard();
const [isCodeExpanded, setIsCodeExpanded] = useState(false);
const [isOutputExpanded, setIsOutputExpanded] = useState(true);
@@ -13,7 +13,7 @@ import {
import { lazy, Suspense, useContext } from 'react';
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import { isDefined } from 'twenty-shared/utils';
import { ThemeContext } from 'twenty-ui/theme';
import { ThemeContext } from 'twenty-ui/theme-constants';
const TextWithRecordLinks = ({ text }: { text: string }) => {
const parts: React.ReactNode[] = [];
@@ -132,7 +132,6 @@ const MarkdownRenderer = lazy(async () => {
const LoadingSkeleton = () => {
const { theme } = useContext(ThemeContext);
return (
<SkeletonTheme
baseColor={theme.background.tertiary}
@@ -3,8 +3,7 @@ import { useContext, useState } from 'react';
import { IconBrain, IconChevronDown, IconChevronUp } from 'twenty-ui/display';
import { AnimatedExpandableContainer } from 'twenty-ui/layout';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { ShimmeringText } from '@/ai/components/ShimmeringText';
import { t } from '@lingui/core/macro';
@@ -4,8 +4,7 @@ import { useContext, useState } from 'react';
import { IconChevronDown, IconChevronUp } from 'twenty-ui/display';
import { JsonTree } from 'twenty-ui/json-visualizer';
import { AnimatedExpandableContainer } from 'twenty-ui/layout';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { useLingui } from '@lingui/react/macro';
import { type DataMessagePart } from 'twenty-shared/ai';
@@ -323,8 +322,8 @@ type RoutingDebugDisplayProps = {
};
export const RoutingDebugDisplay = ({ debug }: RoutingDebugDisplayProps) => {
const { t } = useLingui();
const { theme } = useContext(ThemeContext);
const { t } = useLingui();
const { copyToClipboard } = useCopyToClipboard();
const [isExpanded, setIsExpanded] = useState(false);
const [activeTab, setActiveTab] = useState<TabType>('timing');
@@ -5,8 +5,7 @@ import { useContext, useState } from 'react';
import { type DataMessagePart } from 'twenty-shared/ai';
import { IconChevronDown, IconChevronUp, IconCpu } from 'twenty-ui/display';
import { AnimatedExpandableContainer } from 'twenty-ui/layout';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledContainer = styled.div`
display: flex;
@@ -4,8 +4,7 @@ import { useContext, useState } from 'react';
import { IconChevronDown, IconChevronUp } from 'twenty-ui/display';
import { JsonTree } from 'twenty-ui/json-visualizer';
import { AnimatedExpandableContainer } from 'twenty-ui/layout';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { CodeExecutionDisplay } from '@/ai/components/CodeExecutionDisplay';
import { ShimmeringText } from '@/ai/components/ShimmeringText';
@@ -137,8 +136,8 @@ export const ToolStepRenderer = ({
toolPart: ToolUIPart;
isStreaming: boolean;
}) => {
const { t } = useLingui();
const { theme } = useContext(ThemeContext);
const { t } = useLingui();
const { copyToClipboard } = useCopyToClipboard();
const [isExpanded, setIsExpanded] = useState(false);
const [activeTab, setActiveTab] = useState<TabType>('output');
@@ -1,5 +1,5 @@
import { render, screen } from '@testing-library/react';
import { THEME_LIGHT, ThemeContextProvider } from 'twenty-ui/theme';
import { ThemeProvider } from 'twenty-ui/theme-constants';
import { type ExtendedUIMessagePart } from 'twenty-shared/ai';
import { AIChatAssistantMessageRenderer } from '@/ai/components/AIChatAssistantMessageRenderer';
@@ -42,12 +42,12 @@ jest.mock('@/ai/components/CodeExecutionDisplay', () => ({
const renderAssistantRenderer = (messageParts: ExtendedUIMessagePart[]) => {
return render(
<ThemeContextProvider theme={THEME_LIGHT}>
<ThemeProvider colorScheme="light">
<AIChatAssistantMessageRenderer
messageParts={messageParts}
isLastMessageStreaming={false}
/>
</ThemeContextProvider>,
</ThemeProvider>,
);
};
@@ -1,6 +1,6 @@
import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { THEME_LIGHT, ThemeContextProvider } from 'twenty-ui/theme';
import { ThemeProvider } from 'twenty-ui/theme-constants';
import { ThinkingStepsDisplay } from '@/ai/components/ThinkingStepsDisplay';
import { type ThinkingStepPart } from '@/ai/utils/thinkingStepPart';
@@ -80,13 +80,13 @@ const renderThinkingStepsDisplay = ({
hasAssistantTextResponseStarted?: boolean;
}) => {
return render(
<ThemeContextProvider theme={THEME_LIGHT}>
<ThemeProvider colorScheme="light">
<ThinkingStepsDisplay
parts={parts}
isLastMessageStreaming={isLastMessageStreaming}
hasAssistantTextResponseStarted={hasAssistantTextResponseStarted}
/>
</ThemeContextProvider>,
</ThemeProvider>,
);
};
@@ -1,11 +1,10 @@
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { useLingui } from '@lingui/react/macro';
import { useContext, useState } from 'react';
import { useState } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { HorizontalSeparator } from 'twenty-ui/display';
import { ProgressBar } from 'twenty-ui/feedback';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ContextUsageProgressRing } from '@/ai/components/internal/ContextUsageProgressRing';
@@ -116,7 +115,6 @@ const getCachedLabel = (lastMessage: AgentChatLastMessageUsage): string => {
export const AIChatContextUsageButton = () => {
const { t } = useLingui();
const { theme } = useContext(ThemeContext);
const [isHovered, setIsHovered] = useState(false);
const agentChatUsage = useAtomStateValue(agentChatUsageState);
@@ -175,19 +173,22 @@ export const AIChatContextUsageButton = () => {
value={percentage}
barColor={
percentage > 80
? theme.color.red
? themeCssVariables.color.red
: percentage > 60
? theme.color.orange
: theme.color.blue
? themeCssVariables.color.orange
: themeCssVariables.color.blue
}
backgroundColor={theme.background.tertiary}
backgroundColor={themeCssVariables.background.tertiary}
withBorderRadius
/>
</StyledSection>
{isDefined(lastMessage) && (
<>
<HorizontalSeparator noMargin color={theme.background.tertiary} />
<HorizontalSeparator
noMargin
color={themeCssVariables.background.tertiary}
/>
<StyledSection>
<StyledSectionTitle>{t`Last message`}</StyledSectionTitle>
<SettingsBillingLabelValueItem
@@ -206,7 +207,10 @@ export const AIChatContextUsageButton = () => {
</>
)}
<HorizontalSeparator noMargin color={theme.background.tertiary} />
<HorizontalSeparator
noMargin
color={themeCssVariables.background.tertiary}
/>
<StyledSection>
<StyledSectionTitle>{t`Conversation`}</StyledSectionTitle>
<SettingsBillingLabelValueItem
@@ -5,8 +5,7 @@ import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomState
import { styled } from '@linaria/react';
import { useContext } from 'react';
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledSkeletonContainer = styled.div`
display: flex;
@@ -13,7 +13,7 @@ import { isDefined } from 'twenty-shared/utils';
import { AvatarOrIcon, Chip, ChipVariant } from 'twenty-ui/components';
import { type IconComponent, IconX } from 'twenty-ui/display';
import { Loader } from 'twenty-ui/feedback';
import { ThemeContext } from 'twenty-ui/theme';
import { ThemeContext } from 'twenty-ui/theme-constants';
const StyledClickableContainer = styled.div<{ clickable: boolean }>`
cursor: ${({ clickable }: { clickable: boolean }) =>
@@ -1,6 +1,4 @@
import { styled } from '@linaria/react';
import { useContext } from 'react';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
type ContextUsageProgressRingProps = {
@@ -32,8 +30,6 @@ export const ContextUsageProgressRing = ({
size = 16,
strokeWidth = 2,
}: ContextUsageProgressRingProps) => {
const { theme } = useContext(ThemeContext);
const normalizedPercentage = Math.min(Math.max(percentage, 0), 100);
const radius = (size - strokeWidth) / 2;
const circumference = 2 * Math.PI * radius;
@@ -42,10 +38,10 @@ export const ContextUsageProgressRing = ({
const progressColor =
normalizedPercentage > 80
? theme.color.red
? themeCssVariables.color.red
: normalizedPercentage > 60
? theme.color.orange
: theme.color.blue;
? themeCssVariables.color.orange
: themeCssVariables.color.blue;
return (
<StyledSvg width={size} height={size}>
@@ -60,7 +56,7 @@ export const ContextUsageProgressRing = ({
cy={size / 2}
r={radius}
strokeWidth={strokeWidth}
stroke={progressColor}
style={{ stroke: progressColor }}
strokeDasharray={circumference}
strokeDashoffset={strokeDashoffset}
strokeLinecap="round"
@@ -30,8 +30,7 @@ import {
IconChevronRight,
IconPlus,
} from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { type AvailableWorkspace } from '~/generated-metadata/graphql';
import { getWorkspaceUrl } from '~/utils/getWorkspaceUrl';
@@ -135,11 +134,11 @@ const StyledForgotPasswordLinkContainer = styled.div`
`;
export const SignInUpGlobalScopeForm = () => {
const { theme } = useContext(ThemeContext);
const authProviders = useAtomStateValue(authProvidersState);
const signInUpStep = useAtomStateValue(signInUpStepState);
const { buildWorkspaceUrl } = useBuildWorkspaceUrl();
const { signOut } = useAuth();
const { theme } = useContext(ThemeContext);
const { createWorkspace } = useSignUpInNewWorkspace();
const availableWorkspaces = useAtomStateValue(availableWorkspacesState);
@@ -3,11 +3,7 @@ import { I18nProvider } from '@lingui/react';
import { fireEvent, render, screen } from '@testing-library/react';
import { Provider as JotaiProvider } from 'jotai';
import { SOURCE_LOCALE } from 'twenty-shared/translations';
import {
THEME_LIGHT,
ThemeContextProvider,
ThemeProvider,
} from 'twenty-ui/theme';
import { ThemeProvider } from 'twenty-ui/theme-constants';
import { SignInUpGlobalScopeForm } from '@/auth/sign-in-up/components/SignInUpGlobalScopeForm';
import {
@@ -98,12 +94,10 @@ describe('SignInUpGlobalScopeForm', () => {
render(
<JotaiProvider store={jotaiStore}>
<ThemeProvider theme={THEME_LIGHT}>
<ThemeContextProvider theme={THEME_LIGHT}>
<I18nProvider i18n={i18n}>
<SignInUpGlobalScopeForm />
</I18nProvider>
</ThemeContextProvider>
<ThemeProvider colorScheme="light">
<I18nProvider i18n={i18n}>
<SignInUpGlobalScopeForm />
</I18nProvider>
</ThemeProvider>
</JotaiProvider>,
);
@@ -7,8 +7,7 @@ import { motion } from 'framer-motion';
import { useContext } from 'react';
import { Controller, useFormContext } from 'react-hook-form';
import { StyledText } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledFullWidthMotionDiv = styled(motion.div)`
width: 100%;
@@ -25,8 +24,8 @@ export const SignInUpPasswordField = ({
showErrors: boolean;
signInUpMode: SignInUpMode;
}) => {
const { t } = useLingui();
const { theme } = useContext(ThemeContext);
const { t } = useLingui();
const form = useFormContext<Form>();
return (
@@ -7,14 +7,13 @@ import {
import { extractSecretFromOtpUri } from '@/settings/two-factor-authentication/utils/extractSecretFromOtpUri';
import { styled } from '@linaria/react';
import { Trans, useLingui } from '@lingui/react/macro';
import { useContext } from 'react';
import QRCode from 'react-qr-code';
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
import { IconCopy } from 'twenty-ui/display';
import { Loader } from 'twenty-ui/feedback';
import { MainButton } from 'twenty-ui/input';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { useContext } from 'react';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { useCopyToClipboard } from '~/hooks/useCopyToClipboard';
@@ -69,8 +68,8 @@ const StyledCopySetupKeyLink = styled.button`
`;
export const SignInUpTwoFactorAuthenticationProvision = () => {
const { t } = useLingui();
const { theme } = useContext(ThemeContext);
const { t } = useLingui();
const { copyToClipboard } = useCopyToClipboard();
const qrCode = useAtomStateValue(qrCodeState);
const setSignInUpStep = useSetAtomState(signInUpStepState);
@@ -11,12 +11,11 @@ import { useLingui } from '@lingui/react/macro';
import { memo, useContext } from 'react';
import { HorizontalSeparator, IconGoogle } from 'twenty-ui/display';
import { MainButton } from 'twenty-ui/input';
import { ThemeContext } from 'twenty-ui/theme';
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { LastUsedPill } from './LastUsedPill';
import { StyledSSOButtonContainer } from './SignInUpSSOButtonStyles';
import { ThemeContext } from 'twenty-ui/theme-constants';
const GoogleIcon = memo(() => {
const { theme } = useContext(ThemeContext);
return <IconGoogle size={theme.icon.size.md} />;
@@ -11,11 +11,11 @@ import { useLingui } from '@lingui/react/macro';
import { useContext } from 'react';
import { HorizontalSeparator, IconMicrosoft } from 'twenty-ui/display';
import { MainButton } from 'twenty-ui/input';
import { ThemeContext } from 'twenty-ui/theme';
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { LastUsedPill } from './LastUsedPill';
import { StyledSSOButtonContainer } from './SignInUpSSOButtonStyles';
import { ThemeContext } from 'twenty-ui/theme-constants';
export const SignInUpWithMicrosoft = ({
action,
@@ -11,13 +11,13 @@ import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomState
import { useAtomState } from '@/ui/utilities/state/jotai/hooks/useAtomState';
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
import { useLingui } from '@lingui/react/macro';
import { useContext } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { HorizontalSeparator, IconLock } from 'twenty-ui/display';
import { MainButton } from 'twenty-ui/input';
import { ThemeContext } from 'twenty-ui/theme';
import { LastUsedPill } from './LastUsedPill';
import { StyledSSOButtonContainer } from './SignInUpSSOButtonStyles';
import { useContext } from 'react';
import { ThemeContext } from 'twenty-ui/theme-constants';
export const SignInUpWithSSO = () => {
const { theme } = useContext(ThemeContext);
@@ -14,7 +14,7 @@ import { formatToShortNumber } from 'twenty-shared/utils';
import { H2Title, HorizontalSeparator } from 'twenty-ui/display';
import { ProgressBar } from 'twenty-ui/feedback';
import { Section } from 'twenty-ui/layout';
import { ThemeContext } from 'twenty-ui/theme';
import { ThemeContext } from 'twenty-ui/theme-constants';
import { SubscriptionStatus } from '~/generated-metadata/graphql';
export const SettingsBillingCreditsSection = ({
@@ -24,6 +24,7 @@ export const SettingsBillingCreditsSection = ({
CurrentWorkspace['currentBillingSubscription']
>;
}) => {
const { theme } = useContext(ThemeContext);
const subscriptionStatus = useSubscriptionStatus();
const { formatNumber } = useNumberFormat();
@@ -60,8 +61,6 @@ export const SettingsBillingCreditsSection = ({
currentBillingSubscription.interval,
);
const { theme } = useContext(ThemeContext);
return (
<>
<Section>
@@ -1,8 +1,7 @@
import { styled } from '@linaria/react';
import React, { useContext } from 'react';
import { IconCheck } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledBenefitContainer = styled.div`
color: ${themeCssVariables.font.color.secondary};
@@ -25,6 +24,7 @@ type SubscriptionBenefitProps = {
};
export const SubscriptionBenefit = ({ children }: SubscriptionBenefitProps) => {
const { theme } = useContext(ThemeContext);
return (
<StyledBenefitContainer>
<StyledCheckContainer>
@@ -2,8 +2,7 @@ import { type IconComponent } from 'twenty-ui/display';
import React, { useContext } from 'react';
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
type SubscriptionInfoRowContainerProps = {
Icon: IconComponent;
@@ -56,6 +55,7 @@ export const SubscriptionInfoRowContainer = ({
nextValue,
}: SubscriptionInfoRowContainerProps) => {
const { theme } = useContext(ThemeContext);
return (
<StyledContainer>
<StyledIconLabelContainer>
@@ -3,9 +3,6 @@ import { BlockNoteView } from '@blocknote/mantine';
import { SuggestionMenuController } from '@blocknote/react';
import { styled } from '@linaria/react';
import { type ClipboardEvent, useContext } from 'react';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { type BLOCK_SCHEMA } from '@/blocknote-editor/blocks/Schema';
import { getSlashMenu } from '@/blocknote-editor/utils/getSlashMenu';
import { CustomMentionMenu } from '@/blocknote-editor/components/CustomMentionMenu';
@@ -15,6 +12,7 @@ import {
type SuggestionItem,
} from '@/blocknote-editor/components/CustomSlashMenu';
import { useMentionMenu } from '@/mention/hooks/useMentionMenu';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
interface BlockEditorProps {
editor: typeof BLOCK_SCHEMA.BlockNoteEditor;
@@ -142,8 +140,9 @@ export const BlockEditor = ({
onPaste,
readonly,
}: BlockEditorProps) => {
const { theme } = useContext(ThemeContext);
const blockNoteTheme = theme.name === 'light' ? 'light' : 'dark';
const { colorScheme } = useContext(ThemeContext);
const blockNoteTheme = colorScheme === 'light' ? 'light' : 'dark';
const getMentionItems = useMentionMenu(editor);
const handleFocus = () => {
@@ -1,8 +1,7 @@
import { styled } from '@linaria/react';
import { useContext } from 'react';
import { type IconComponent } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledContainer = styled.div<{ Variant: Variants }>`
color: ${({ Variant }) =>
@@ -29,6 +28,7 @@ export const CustomSideMenuOptions = ({
text,
}: CustomSideMenuOptionsProps) => {
const { theme } = useContext(ThemeContext);
return (
<StyledContainer Variant={Variant}>
<LeftIcon
@@ -3,11 +3,9 @@ import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataI
import { useRecordChipData } from '@/object-record/hooks/useRecordChipData';
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
import { styled } from '@linaria/react';
import { Avatar } from 'twenty-ui/display';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { useContext } from 'react';
import { ThemeContext } from 'twenty-ui/theme';
import { Avatar } from 'twenty-ui/display';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledIconWrapper = styled.div<{ withIconBackground?: boolean }>`
background: ${({ withIconBackground }) =>
withIconBackground ? themeCssVariables.background.primary : 'unset'};
@@ -32,6 +30,7 @@ export const CommandMenuContextRecordChipAvatars = ({
objectMetadataItem: ObjectMetadataItem;
record: ObjectRecord;
}) => {
const { theme } = useContext(ThemeContext);
const { recordChipData } = useRecordChipData({
objectNameSingular: objectMetadataItem.nameSingular,
record,
@@ -39,9 +38,6 @@ export const CommandMenuContextRecordChipAvatars = ({
const { Icon, IconColor } = useGetStandardObjectIcon(
objectMetadataItem.nameSingular,
);
const { theme } = useContext(ThemeContext);
return (
<StyledIconWrapper
withIconBackground={recordChipData.avatarType !== 'rounded'}
@@ -5,7 +5,7 @@ import { CommandMenuPageInfoLayout } from '@/command-menu/components/CommandMenu
import { useFindManyRecordsSelectedInContextStore } from '@/context-store/hooks/useFindManyRecordsSelectedInContextStore';
import { t } from '@lingui/core/macro';
import { useContext } from 'react';
import { ThemeContext } from 'twenty-ui/theme';
import { ThemeContext } from 'twenty-ui/theme-constants';
type CommandMenuMultipleRecordsInfoProps = {
commandMenuPageInstanceId: string;
@@ -15,7 +15,6 @@ export const CommandMenuMultipleRecordsInfo = ({
commandMenuPageInstanceId,
}: CommandMenuMultipleRecordsInfoProps) => {
const { theme } = useContext(ThemeContext);
const { totalCount } = useFindManyRecordsSelectedInContextStore({
instanceId: commandMenuPageInstanceId,
limit: 1,
@@ -23,9 +23,7 @@ import { motion } from 'framer-motion';
import { useCallback, useContext, useRef } from 'react';
import { LINK_CHIP_CLICK_OUTSIDE_ID } from 'twenty-ui/components';
import { useIsMobile } from 'twenty-ui/utilities';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext } from 'twenty-ui/theme';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledCommandMenuBase = styled.div`
background: ${themeCssVariables.background.primary};
border-left: 1px solid ${themeCssVariables.border.color.medium};
@@ -46,14 +44,12 @@ const StyledCommandMenu = motion.create(StyledCommandMenuBase);
export const CommandMenuOpenContainer = ({
children,
}: React.PropsWithChildren) => {
const { theme } = useContext(ThemeContext);
const isMobile = useIsMobile();
const targetVariantForAnimation: CommandMenuAnimationVariant = isMobile
? 'fullScreen'
: 'normal';
const { theme } = useContext(ThemeContext);
const { closeCommandMenu } = useCommandMenu();
const commandMenuRef = useRef<HTMLDivElement>(null);
@@ -100,7 +96,9 @@ export const CommandMenuOpenContainer = ({
initial="closed"
exit="closed"
variants={COMMAND_MENU_ANIMATION_VARIANTS}
transition={{ duration: theme.animation.duration.normal }}
transition={{
duration: theme.animation.duration.normal,
}}
onAnimationStart={() => setIsSidePanelAnimating(true)}
onAnimationComplete={() => setIsSidePanelAnimating(false)}
>
@@ -20,11 +20,9 @@ import { selectedNavigationMenuItemInEditModeState } from '@/navigation-menu-ite
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { CommandMenuPages } from 'twenty-shared/types';
import { type CommandMenuContextChipProps } from './CommandMenuContextChip';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { useContext } from 'react';
import { ThemeContext } from 'twenty-ui/theme';
import { type CommandMenuContextChipProps } from './CommandMenuContextChip';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledPageTitle = styled.div`
color: ${themeCssVariables.font.color.primary};
font-size: ${themeCssVariables.font.size.sm};
@@ -18,8 +18,7 @@ import { CommandMenuPages } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { useIcons } from 'twenty-ui/display';
import { CommandMenuPageInfoLayout } from './CommandMenuPageInfoLayout';
import { ThemeContext } from 'twenty-ui/theme';
import { ThemeContext } from 'twenty-ui/theme-constants';
export const CommandMenuPageLayoutInfoContent = ({
pageLayoutId,
}: {
@@ -8,9 +8,9 @@ import { CommandMenuPageComponentInstanceContext } from '@/command-menu/states/c
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { styled } from '@linaria/react';
import { motion } from 'framer-motion';
import { isDefined } from 'twenty-shared/utils';
import { useContext } from 'react';
import { ThemeContext } from 'twenty-ui/theme';
import { isDefined } from 'twenty-shared/utils';
import { ThemeContext } from 'twenty-ui/theme-constants';
const StyledCommandMenuContent = styled.div`
flex: 1;
@@ -18,6 +18,7 @@ const StyledCommandMenuContent = styled.div`
`;
export const CommandMenuRouter = () => {
const { theme } = useContext(ThemeContext);
const commandMenuPage = useAtomStateValue(commandMenuPageState);
const commandMenuPageInfo = useAtomStateValue(commandMenuPageInfoState);
@@ -26,9 +27,6 @@ export const CommandMenuRouter = () => {
) : (
<></>
);
const { theme } = useContext(ThemeContext);
return (
<CommandMenuContainer>
<CommandMenuPageComponentInstanceContext.Provider
@@ -23,8 +23,7 @@ import { CommandMenuPages } from 'twenty-shared/types';
import { IconX } from 'twenty-ui/display';
import { IconButton } from 'twenty-ui/input';
import { useIsMobile } from 'twenty-ui/utilities';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledInputContainer = styled.div<{ isMobile: boolean }>`
align-items: center;
@@ -80,6 +79,7 @@ const StyledContentContainer = styled.div`
`;
export const CommandMenuTopBar = () => {
const { theme } = useContext(ThemeContext);
const [commandMenuSearch, setCommandMenuSearch] = useAtomState(
commandMenuSearchState,
);
@@ -101,8 +101,6 @@ export const CommandMenuTopBar = () => {
commandMenuNavigationStackState,
);
const { theme } = useContext(ThemeContext);
const { contextChips } = useCommandMenuContextChips();
const { pushFocusItemToFocusStack } = usePushFocusItemToFocusStack();
@@ -18,19 +18,20 @@ import { getActionIconColorOrThrow } from '@/workflow/workflow-steps/workflow-ac
import { getTriggerIcon } from '@/workflow/workflow-trigger/utils/getTriggerIcon';
import { getTriggerIconColor } from '@/workflow/workflow-trigger/utils/getTriggerIconColor';
import { t } from '@lingui/core/macro';
import { useState } from 'react';
import { useContext, useState } from 'react';
import { CommandMenuPages, CoreObjectNameSingular } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { TRIGGER_STEP_ID } from 'twenty-shared/workflow';
import { useIcons } from 'twenty-ui/display';
import { ICON_SIZES, ICON_STROKES } from 'twenty-ui/theme-constants';
import { CommandMenuPageInfoLayout } from './CommandMenuPageInfoLayout';
import { ThemeContext } from 'twenty-ui/theme-constants';
export const CommandMenuWorkflowStepInfo = ({
commandMenuPageInstanceId,
}: {
commandMenuPageInstanceId: string;
}) => {
const { theme } = useContext(ThemeContext);
const { getIcon } = useIcons();
const commandMenuPage = useAtomStateValue(commandMenuPageState);
@@ -169,7 +170,7 @@ export const CommandMenuWorkflowStepInfo = ({
<CommandMenuPageInfoLayout
icon={
headerIcon ? (
<Icon size={ICON_SIZES.md} stroke={ICON_STROKES.sm} />
<Icon size={theme.icon.size.md} stroke={theme.icon.stroke.sm} />
) : undefined
}
iconColor={headerIconColor}
@@ -13,8 +13,8 @@ import {
IconPlus,
type IconComponent,
} from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme-constants';
import { useContext } from 'react';
import { ThemeContext } from 'twenty-ui/theme';
type PageLayoutHeaderInfo = {
headerIcon: IconComponent | undefined;
@@ -1,4 +1,5 @@
import { THEME_COMMON } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
export const COMMAND_MENU_ANIMATION_VARIANTS = {
fullScreen: {
x: '0%',
@@ -9,14 +10,14 @@ export const COMMAND_MENU_ANIMATION_VARIANTS = {
},
normal: {
x: '0%',
width: THEME_COMMON.rightDrawerWidth,
width: themeCssVariables.rightDrawerWidth,
height: '100%',
bottom: '0',
top: '0',
},
closed: {
x: '100%',
width: THEME_COMMON.rightDrawerWidth,
width: themeCssVariables.rightDrawerWidth,
height: '100%',
bottom: '0',
top: 'auto',
@@ -12,9 +12,11 @@ import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomState
import { useContext, useMemo } from 'react';
import { CommandMenuPages } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { ThemeContext } from 'twenty-ui/theme';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
export const useCommandMenuContextChips = () => {
const { theme } = useContext(ThemeContext);
const iconSizeSm = theme.icon.size.sm;
const commandMenuNavigationStack = useAtomStateValue(
commandMenuNavigationStackState,
);
@@ -27,8 +29,6 @@ export const useCommandMenuContextChips = () => {
const { navigateCommandMenuHistory } = useCommandMenuHistory();
const { theme } = useContext(ThemeContext);
const commandMenuNavigationMorphItemsByPage = useAtomStateValue(
commandMenuNavigationMorphItemsByPageState,
);
@@ -111,16 +111,16 @@ export const useCommandMenuContextChips = () => {
return {
page,
Icons: isLastChip
? [<page.pageIcon size={theme.icon.size.sm} />]
? [<page.pageIcon size={iconSizeSm} />]
: [
<CommandMenuContextChipIconWrapper>
<page.pageIcon
size={theme.icon.size.sm}
size={iconSizeSm}
color={
isDefined(page.pageIconColor) &&
page.pageIconColor !== 'currentColor'
? page.pageIconColor
: theme.font.color.tertiary
: themeCssVariables.font.color.tertiary
}
/>
</CommandMenuContextChipIconWrapper>,
@@ -137,12 +137,11 @@ export const useCommandMenuContextChips = () => {
}, [
commandMenuNavigationMorphItemsByPage,
commandMenuNavigationStack,
iconSizeSm,
navigateCommandMenuHistory,
objectMetadataItems,
recordIdentifiers,
records,
theme.font.color.tertiary,
theme.icon.size.sm,
]);
return {
@@ -15,9 +15,8 @@ import {
DEFAULT_COLOR_LABELS,
MenuItemSelectColor,
} from 'twenty-ui/navigation';
import { MAIN_COLOR_NAMES, type ThemeColor } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { type ThemeColor, MAIN_COLOR_NAMES } from 'twenty-ui/theme';
const NAVIGATION_MENU_ITEM_COLOR_DROPDOWN_ID = 'navigation-menu-item-color';
const StyledMenuStyleText = styled.span`
@@ -19,7 +19,7 @@ import { NavigationMenuItemStyleIcon } from '@/navigation-menu-item/components/N
import { NavigationMenuItemType } from '@/navigation-menu-item/constants/NavigationMenuItemType';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { useContext } from 'react';
import { ThemeContext } from 'twenty-ui/theme';
import { ThemeContext } from 'twenty-ui/theme-constants';
type CommandMenuNewSidebarItemMainMenuProps = {
onSelectObject: () => void;
@@ -32,8 +32,8 @@ export const CommandMenuNewSidebarItemMainMenu = ({
onSelectView,
onSelectRecord,
}: CommandMenuNewSidebarItemMainMenuProps) => {
const { t } = useLingui();
const { theme } = useContext(ThemeContext);
const { t } = useLingui();
const { handleAddFolder } = useAddFolderToNavigationMenu();
const { handleAddLink } = useAddLinkToNavigationMenu();
@@ -5,9 +5,8 @@ import { SelectableListItem } from '@/ui/layout/selectable-list/components/Selec
import { styled } from '@linaria/react';
import { ColorSample } from 'twenty-ui/display';
import { MenuItemSelect } from 'twenty-ui/navigation';
import { type ThemeColor } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { type ThemeColor } from 'twenty-ui/theme';
type ChartColorGradientOptionProps = {
colorOption: {
id: string;
@@ -6,10 +6,9 @@ import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { ColorSample } from 'twenty-ui/display';
import { MenuItemSelect } from 'twenty-ui/navigation';
import { type ThemeColor } from 'twenty-ui/theme';
import { getMainColorNameFromPaletteColorName } from 'twenty-ui/utilities';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { type ThemeColor } from 'twenty-ui/theme';
type ChartColorPaletteOptionProps = {
selectedItemId: string | null;
currentColor: string | null | undefined;
@@ -17,7 +17,7 @@ import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/use
import { t } from '@lingui/core/macro';
import { useState } from 'react';
import { capitalize, isDefined } from 'twenty-shared/utils';
import { MAIN_COLOR_NAMES, type ThemeColor } from 'twenty-ui/theme';
import { type ThemeColor, MAIN_COLOR_NAMES } from 'twenty-ui/theme';
import { filterBySearchQuery } from '~/utils/filterBySearchQuery';
type ColorOption = {
@@ -5,8 +5,7 @@ import { styled } from '@linaria/react';
import { lazy, Suspense, useContext } from 'react';
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import { CoreObjectNameSingular } from 'twenty-shared/types';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const ActivityRichTextEditor = lazy(() =>
import('@/activities/components/ActivityRichTextEditor').then((module) => ({
@@ -23,7 +22,6 @@ const StyledContainer = styled.div`
const LoadingSkeleton = () => {
const { theme } = useContext(ThemeContext);
return (
<SkeletonTheme
baseColor={theme.background.tertiary}
@@ -18,11 +18,12 @@ import { t } from '@lingui/core/macro';
import { isDefined } from 'twenty-shared/utils';
import { TRIGGER_STEP_ID } from 'twenty-shared/workflow';
import { useIcons } from 'twenty-ui/display';
import { MenuItem } from 'twenty-ui/navigation';
import { useContext } from 'react';
import { ThemeContext } from 'twenty-ui/theme';
import { MenuItem } from 'twenty-ui/navigation';
import { ThemeContext } from 'twenty-ui/theme-constants';
export const CommandMenuWorkflowSelectTriggerTypeContent = () => {
const { theme } = useContext(ThemeContext);
const { getIcon } = useIcons();
const workflowId = useCommandMenuWorkflowIdOrThrow();
const { updateTrigger } = useUpdateWorkflowVersionTrigger();
@@ -73,8 +74,6 @@ export const CommandMenuWorkflowSelectTriggerTypeContent = () => {
};
};
const { theme } = useContext(ThemeContext);
return (
<RightDrawerStepListContainer>
<RightDrawerWorkflowSelectStepTitle>
@@ -1,8 +1,9 @@
import { type AppErrorDisplayProps } from '@/error-handler/types/AppErrorDisplayProps';
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { useContext } from 'react';
import { IconReload } from 'twenty-ui/display';
import { ICON_SIZES, themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
type AppRootErrorFallbackProps = AppErrorDisplayProps;
@@ -102,6 +103,8 @@ export const AppRootErrorFallback = ({
resetErrorBoundary,
title = t`Sorry, something went wrong`,
}: AppRootErrorFallbackProps) => {
const { theme } = useContext(ThemeContext);
return (
<StyledContainer>
<StyledPanel>
@@ -124,7 +127,7 @@ export const AppRootErrorFallback = ({
</StyledEmptyTextContainer>
<StyledButton onClick={resetErrorBoundary}>
<StyledIconContainer>
<IconReload size={ICON_SIZES.md} />
<IconReload size={theme.icon.size.md} />
</StyledIconContainer>
{t`Reload`}
</StyledButton>
@@ -2,7 +2,7 @@ import { type ProcessedFavorite } from '@/favorites/utils/sortFavorites';
import { useGetStandardObjectIcon } from '@/object-metadata/hooks/useGetStandardObjectIcon';
import { useContext } from 'react';
import { Avatar, useIcons } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { ThemeContext } from 'twenty-ui/theme-constants';
export const FavoriteIcon = ({ favorite }: { favorite: ProcessedFavorite }) => {
const { theme } = useContext(ThemeContext);
@@ -1,10 +1,9 @@
import { currentFavoriteFolderIdState } from '@/ui/navigation/navigation-drawer/states/currentFavoriteFolderIdState';
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
import { styled } from '@linaria/react';
import { useContext } from 'react';
import { IconX } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { useContext } from 'react';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledBackButton = styled.button`
display: flex;
@@ -2,8 +2,7 @@ import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLo
import { styled } from '@linaria/react';
import { useContext } from 'react';
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledSkeletonContainer = styled.div`
display: flex;
@@ -5,17 +5,17 @@ import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useNavigationSection } from '@/ui/navigation/navigation-drawer/hooks/useNavigationSection';
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
import { useContext } from 'react';
import { useLingui } from '@lingui/react/macro';
import { useContext } from 'react';
import { IconPlus } from 'twenty-ui/display';
import { MenuItem } from 'twenty-ui/navigation';
import { ThemeContext } from 'twenty-ui/theme';
import { ThemeContext } from 'twenty-ui/theme-constants';
export const FavoriteFolderPickerFooter = ({
dropdownId,
}: {
dropdownId: string;
}) => {
const { theme } = useContext(ThemeContext);
const { t } = useLingui();
const [, setIsFavoriteFolderCreating] = useAtomState(
isFavoriteFolderCreatingState,
@@ -24,7 +24,6 @@ export const FavoriteFolderPickerFooter = ({
isNavigationDrawerExpandedState,
);
const { openNavigationSection } = useNavigationSection('Favorites');
const { theme } = useContext(ThemeContext);
const { closeDropdown } = useCloseDropdown();
return (
@@ -2,11 +2,10 @@ import { type AttachmentFileCategory } from '@/activities/files/types/Attachment
import { useFileIconColors } from '@/file/hooks/useFileIconColors';
import { IconMapping } from '@/file/utils/fileIconMappings';
import { styled } from '@linaria/react';
import { useContext } from 'react';
import { type FileCategory } from 'twenty-shared/types';
import { AvatarOrIcon } from 'twenty-ui/components';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { useContext } from 'react';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
type FileIconSize = 'small' | 'medium';
@@ -3,13 +3,14 @@ import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadata
import { useContext } from 'react';
import { CoreObjectNameSingular } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { type ThemeColor, ThemeContext } from 'twenty-ui/theme';
import { ThemeContext } from 'twenty-ui/theme-constants';
import { type ThemeColor } from 'twenty-ui/theme';
export const useFileCategoryColors = (): Record<
AttachmentFileCategory,
string
> => {
const { theme } = useContext(ThemeContext);
const { objectMetadataItem } = useObjectMetadataItem({
objectNameSingular: CoreObjectNameSingular.Attachment,
});
@@ -36,9 +37,11 @@ export const useFileCategoryColors = (): Record<
if (
isDefined(category) &&
isDefined(color) &&
isDefined(theme.color[color])
isDefined((theme.color as unknown as Record<string, string>)[color])
) {
colorMap[category] = theme.color[color];
colorMap[category] = (theme.color as unknown as Record<string, string>)[
color
];
}
});
}
@@ -1,7 +1,7 @@
import { type AttachmentFileCategory } from '@/activities/files/types/AttachmentFileCategory';
import { useContext } from 'react';
import { type FileCategory } from 'twenty-shared/types';
import { ThemeContext } from 'twenty-ui/theme';
import { ThemeContext } from 'twenty-ui/theme-constants';
export const useFileIconColors = (): Record<
AttachmentFileCategory | FileCategory,
@@ -9,7 +9,7 @@ import { t } from '@lingui/core/macro';
import { useCallback, useContext } from 'react';
import { FrontComponentRenderer as SharedFrontComponentRenderer } from 'twenty-sdk/front-component-renderer';
import { isDefined } from 'twenty-shared/utils';
import { ThemeContext } from 'twenty-ui/theme';
import { ThemeContext } from 'twenty-ui/theme-constants';
import { REACT_APP_SERVER_BASE_URL } from '~/config';
import { useFindOneFrontComponentQuery } from '~/generated-metadata/graphql';
@@ -20,7 +20,7 @@ type FrontComponentRendererProps = {
export const FrontComponentRenderer = ({
frontComponentId,
}: FrontComponentRendererProps) => {
const { theme } = useContext(ThemeContext);
const { colorScheme } = useContext(ThemeContext);
const { enqueueErrorSnackBar } = useSnackBar();
const setFrontComponentApplicationTokenPair = useSetAtomComponentState(
@@ -81,7 +81,7 @@ export const FrontComponentRenderer = ({
return (
<FrontComponentRendererProvider frontComponentId={frontComponentId}>
<SharedFrontComponentRenderer
theme={theme}
colorScheme={colorScheme}
componentUrl={componentUrl}
applicationAccessToken={
applicationTokenPair.applicationAccessToken.token
@@ -3,8 +3,7 @@ import { isNonEmptyString } from '@sniptt/guards';
import { type ReactNode, useContext } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { IconGripVertical, type IconComponent } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { NavigationMenuItemStyleIcon } from '@/navigation-menu-item/components/NavigationMenuItemStyleIcon';
import { DEFAULT_NAVIGATION_MENU_ITEM_COLOR_FOLDER } from '@/navigation-menu-item/constants/NavigationMenuItemDefaultColorFolder';
@@ -15,8 +15,7 @@ import { useLingui } from '@lingui/react/macro';
import { useContext, useState } from 'react';
import { CommandMenuPages } from 'twenty-shared/types';
import { IconCheck, useIcons } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { FeatureFlagKey } from '~/generated-metadata/graphql';
const StyledContainer = styled.div`
@@ -1,8 +1,7 @@
import { styled } from '@linaria/react';
import { useContext } from 'react';
import { IconX } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { currentNavigationMenuItemFolderIdState } from '@/ui/navigation/navigation-drawer/states/currentNavigationMenuItemFolderIdState';
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
@@ -2,8 +2,7 @@ import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLo
import { styled } from '@linaria/react';
import { useContext } from 'react';
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledSkeletonContainer = styled.div`
display: flex;
@@ -1,8 +1,8 @@
import type { IconComponent } from 'twenty-ui/display';
import { ICON_SIZES, ICON_STROKES } from 'twenty-ui/theme-constants';
import { StyledNavigationMenuItemIconContainer } from '@/navigation-menu-item/components/NavigationMenuItemIconContainer';
import { getNavigationMenuItemIconStyleFromColor } from '@/navigation-menu-item/utils/get-navigation-menu-item-icon-style-from-color';
import { useContext } from 'react';
import { ThemeContext } from 'twenty-ui/theme-constants';
export type NavigationMenuItemStyleIconProps = {
Icon: IconComponent;
@@ -13,6 +13,7 @@ export const NavigationMenuItemStyleIcon = ({
Icon,
color,
}: NavigationMenuItemStyleIconProps) => {
const { theme } = useContext(ThemeContext);
const style = getNavigationMenuItemIconStyleFromColor(color);
return (
<StyledNavigationMenuItemIconContainer
@@ -20,8 +21,8 @@ export const NavigationMenuItemStyleIcon = ({
$borderColor={style.borderColor}
>
<Icon
size={ICON_SIZES.md}
stroke={ICON_STROKES.md}
size={theme.icon.size.md}
stroke={theme.icon.stroke.md}
color={style.iconColor}
/>
</StyledNavigationMenuItemIconContainer>
@@ -1,6 +1,7 @@
import { styled } from '@linaria/react';
import type { IconComponent } from 'twenty-ui/display';
import { ICON_STROKES, themeCssVariables } from 'twenty-ui/theme-constants';
import { useContext } from 'react';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { getNavigationMenuItemIconStyleFromColor } from '@/navigation-menu-item/utils/get-navigation-menu-item-icon-style-from-color';
@@ -56,6 +57,7 @@ export const ObjectIconWithViewOverlay = ({
ViewIcon,
objectColor,
}: ObjectIconWithViewOverlayProps) => {
const { theme } = useContext(ThemeContext);
const objectStyle = getNavigationMenuItemIconStyleFromColor(objectColor);
return (
@@ -66,14 +68,14 @@ export const ObjectIconWithViewOverlay = ({
>
<ObjectIcon
size="14px"
stroke={ICON_STROKES.md}
stroke={theme.icon.stroke.md}
color={objectStyle.iconColor}
/>
</StyledObjectIconWrapper>
<StyledViewOverlay $backgroundColor={themeCssVariables.grayScale.gray4}>
<ViewIcon
size="10px"
stroke={ICON_STROKES.lg}
stroke={theme.icon.stroke.lg}
color={themeCssVariables.grayScale.gray10}
/>
</StyledViewOverlay>
@@ -5,7 +5,7 @@ import {
} from '@hello-pangea/dnd';
import { useContext } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { ThemeContext } from 'twenty-ui/theme';
import { ThemeContext } from 'twenty-ui/theme-constants';
import { NavigationMenuItemIcon } from '@/navigation-menu-item/components/NavigationMenuItemIcon';
import { getNavigationMenuItemSecondaryLabel } from '@/navigation-menu-item/utils/getNavigationMenuItemSecondaryLabel';
@@ -11,8 +11,7 @@ import {
IconPlus,
useIcons,
} from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { useIsDropDisabledForSection } from '@/navigation-menu-item/hooks/useIsDropDisabledForSection';
import { useOpenAddItemToFolderPage } from '@/navigation-menu-item/hooks/useOpenAddItemToFolderPage';
@@ -1,5 +1,5 @@
import type { ThemeColor } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { type ThemeColor } from 'twenty-ui/theme';
export const getColorFromTheme = (
themeColor: ThemeColor,
@@ -1,15 +1,15 @@
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { useContext } from 'react';
import {
IconComment,
IconHome,
IconMessageCirclePlus,
} from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { useIsMobile } from 'twenty-ui/utilities';
import { useContext } from 'react';
import { useCreateNewAIChatThread } from '@/ai/hooks/useCreateNewAIChatThread';
import { NavigationDrawerAnimatedCollapseWrapper } from '@/ui/navigation/navigation-drawer/components/NavigationDrawerAnimatedCollapseWrapper';
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
@@ -2,8 +2,7 @@ import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLo
import { styled } from '@linaria/react';
import { useContext } from 'react';
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
const StyledSkeletonColumn = styled.div`
display: flex;
@@ -1,8 +1,7 @@
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { useContext } from 'react';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { useApplyObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue';
import { useObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useObjectFilterDropdownFilterValue';
@@ -16,8 +16,7 @@ import { styled } from '@linaria/react';
import { useContext, useEffect, useRef, useState } from 'react';
import { Key } from 'ts-key-enum';
import { OverflowingTextWithTooltip, useIcons } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { useDebouncedCallback } from 'use-debounce';
const StyledDropdownMenuIconAndNameContainer = styled.div`
@@ -60,6 +59,7 @@ type ObjectOptionsDropdownMenuViewNameProps = {
export const ObjectOptionsDropdownMenuViewName = ({
currentView,
}: ObjectOptionsDropdownMenuViewNameProps) => {
const { theme } = useContext(ThemeContext);
const [viewPickerSelectedIcon, setViewPickerSelectedIcon] =
useAtomComponentState(viewPickerSelectedIconComponentState);
@@ -111,7 +111,6 @@ export const ObjectOptionsDropdownMenuViewName = ({
}
}, [currentView?.key]);
const { theme } = useContext(ThemeContext);
const { getIcon } = useIcons();
const MainIcon = getIcon(currentView?.icon);
@@ -1,8 +1,7 @@
import { styled } from '@linaria/react';
import { useContext } from 'react';
import { SkeletonTheme } from 'react-loading-skeleton';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ThemeContext, themeCssVariables } from 'twenty-ui/theme-constants';
import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader';
import { RecordCardBodyContainer } from '@/object-record/record-card/components/RecordCardBodyContainer';
@@ -38,7 +37,6 @@ const StyledStaticCellSkeleton = styled.div<{ width: number; height: number }>`
export const RecordBoardColumnCardContainerSkeletonLoader = () => {
const { theme } = useContext(ThemeContext);
const { currentView } = useGetCurrentViewOnly();
const isCompactModeActive = currentView?.isCompact ?? false;

Some files were not shown because too many files have changed in this diff Show More