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

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