Complete linaria migration (#18361)

## Summary

Completes the migration of the frontend styling system from **Emotion**
(`@emotion/styled`, `@emotion/react`) to **Linaria** (`@linaria/react`,
`@linaria/core`), a zero-runtime CSS-in-JS library where styles are
extracted at build time.

This is the final step of the migration — all ~494 files across
`twenty-front`, `twenty-ui`, `twenty-website`, and `twenty-sdk` are now
fully converted.

## Changes

### Styling Migration (across ~480 component files)
- Replaced all `@emotion/styled` imports with `@linaria/react`
- Converted runtime theme access patterns (`({ theme }) => theme.x.y`)
to build-time `themeCssVariables` CSS custom properties
- Replaced `useTheme()` hook (from Emotion) with
`useContext(ThemeContext)` where runtime theme values are still needed
(e.g., passing colors to non-CSS props like icon components)
- Removed `@emotion/react` `css` helper usages in favor of Linaria
template literals

### Dependency & Configuration Changes
- **Removed**: `@emotion/react`, `@emotion/styled` from root
`package.json`
- **Added**: `@wyw-in-js/babel-preset`, `next-with-linaria` (for
twenty-website SSR support)
- Updated Nx generator defaults from `@emotion/styled` to
`@linaria/react` in `nx.json`
- Simplified `vite.config.ts` (removed Emotion-specific configuration)
- Updated `twenty-website/next.config.js` to use `next-with-linaria` for
SSR Linaria support

### Storybook & Testing
- Removed `ThemeProvider` from Emotion in Storybook previews
(`twenty-front`, `twenty-sdk`)
- Now relies solely on `ThemeContextProvider` for theme injection

### Documentation
- Removed the temporary `docs/emotion-to-linaria-migration-plan.md`
(migration complete)
- Updated `CLAUDE.md` and `README.md` to reflect Linaria as the styling
stack
- Updated frontend style guide docs across all locales

## How it works

Linaria extracts styles at build time via the `@wyw-in-js/vite` plugin.
All expressions in `styled` template literals must be **statically
evaluable** — no runtime theme objects or closures over component state.

- **Static styles** use `themeCssVariables` which map to CSS custom
properties (`var(--theme-color-x)`)
- **Runtime theme access** (for non-CSS use cases like icon `color`
props) uses `useContext(ThemeContext)` instead of Emotion's `useTheme()`
This commit is contained in:
Charles Bochet
2026-03-04 00:50:06 +01:00
committed by GitHub
parent 8a3b96d911
commit 7a2e397ad1
540 changed files with 3654 additions and 4156 deletions
@@ -1,10 +1,11 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledColumn = styled.div`
display: flex;
flex-direction: column;
width: 100%;
gap: ${({ theme }) => theme.spacing(1)};
gap: ${themeCssVariables.spacing[1]};
`;
export const AdvancedFilterCommandMenuColumn = StyledColumn;
@@ -9,20 +9,21 @@ import { rootLevelRecordFilterGroupComponentSelector } from '@/object-record/adv
import { isRecordFilterGroupChildARecordFilterGroup } from '@/object-record/advanced-filter/utils/isRecordFilterGroupChildARecordFilterGroup';
import { type VariablePickerComponent } from '@/object-record/record-field/ui/form-types/types/VariablePickerComponent';
import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { isDefined } from 'twenty-shared/utils';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledContainer = styled.div`
align-items: start;
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(2)};
gap: ${themeCssVariables.spacing[2]};
`;
const StyledChildContainer = styled.div`
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(6)};
gap: ${themeCssVariables.spacing[6]};
width: 100%;
`;
@@ -6,23 +6,24 @@ import { type RecordFilterGroup } from '@/object-record/record-filter-group/type
import { Select } from '@/ui/input/components/Select';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { useContext } from 'react';
import { capitalize } from 'twenty-shared/utils';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledText = styled.div`
align-items: center;
color: ${({ theme }) => theme.font.color.primary};
color: ${themeCssVariables.font.color.primary};
display: flex;
height: ${({ theme }) => theme.spacing(8)};
height: ${themeCssVariables.spacing[8]};
`;
const StyledContainer = styled.div`
align-items: start;
display: flex;
min-width: ${({ theme }) => theme.spacing(20)};
color: ${({ theme }) => theme.font.color.tertiary};
min-width: ${themeCssVariables.spacing[20]};
color: ${themeCssVariables.font.color.tertiary};
`;
type AdvancedFilterCommandMenuLogicalOperatorCellProps = {
@@ -11,14 +11,15 @@ import { getAdvancedFilterObjectFilterDropdownComponentInstanceId } from '@/obje
import { ObjectFilterDropdownComponentInstanceContext } from '@/object-record/object-filter-dropdown/states/contexts/ObjectFilterDropdownComponentInstanceContext';
import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup';
import { type RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { useContext } from 'react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledContainer = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
gap: ${({ theme }) => theme.spacing(1)};
gap: ${themeCssVariables.spacing[1]};
`;
type AdvancedFilterCommandMenuRecordFilterColumnProps = {
@@ -3,21 +3,24 @@ import { AdvancedFilterAddFilterRuleSelect } from '@/object-record/advanced-filt
import { useChildRecordFiltersAndRecordFilterGroups } from '@/object-record/advanced-filter/hooks/useChildRecordFiltersAndRecordFilterGroups';
import { AdvancedFilterContext } from '@/object-record/advanced-filter/states/context/AdvancedFilterContext';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { useContext } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledContainer = styled.div<{ isGrayBackground?: boolean }>`
align-items: start;
background-color: ${({ theme, isGrayBackground }) =>
isGrayBackground ? theme.background.transparent.lighter : 'transparent'};
border: ${({ theme }) => `1px solid ${theme.border.color.medium}`};
border-radius: ${({ theme }) => theme.border.radius.md};
background-color: ${({ isGrayBackground }) =>
isGrayBackground
? themeCssVariables.background.transparent.lighter
: 'transparent'};
border: 1px solid ${themeCssVariables.border.color.medium};
border-radius: ${themeCssVariables.border.radius.md};
display: flex;
flex: 1;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(6)};
padding: ${({ theme }) => theme.spacing(2)};
gap: ${themeCssVariables.spacing[6]};
padding: ${themeCssVariables.spacing[2]};
`;
type AdvancedFilterCommandMenuRecordFilterGroupChildrenProps = {
@@ -5,14 +5,15 @@ import { AdvancedFilterRecordFilterGroupOptionsDropdown } from '@/object-record/
import { AdvancedFilterContext } from '@/object-record/advanced-filter/states/context/AdvancedFilterContext';
import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { useContext } from 'react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledContainer = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
gap: ${({ theme }) => theme.spacing(1)};
gap: ${themeCssVariables.spacing[1]};
`;
export const AdvancedFilterCommandMenuRecordFilterGroupColumn = ({
@@ -1,9 +1,10 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledRow = styled.div`
display: flex;
width: 100%;
gap: ${({ theme }) => theme.spacing(1)};
gap: ${themeCssVariables.spacing[1]};
`;
export const AdvancedFilterDropdownRow = StyledRow;
@@ -4,7 +4,7 @@ import { DEFAULT_ADVANCED_FILTER_DROPDOWN_OFFSET } from '@/object-record/advance
import { useAdvancedFilterFieldSelectDropdown } from '@/object-record/advanced-filter/hooks/useAdvancedFilterFieldSelectDropdown';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
const StyledContainer = styled.div`
flex: 2;
@@ -1,23 +1,24 @@
import { objectFilterDropdownSearchInputComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSearchInputComponentState';
import { useAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentState';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { themeCssVariables } from 'twenty-ui/theme-constants';
export const StyledInput = styled.input`
background: transparent;
border: none;
border-top: none;
border-bottom: 1px solid ${({ theme }) => theme.border.color.light};
border-bottom: 1px solid ${themeCssVariables.border.color.light};
border-radius: 0;
border-top-left-radius: ${({ theme }) => theme.border.radius.md};
border-top-right-radius: ${({ theme }) => theme.border.radius.md};
color: ${({ theme }) => theme.font.color.primary};
border-top-left-radius: ${themeCssVariables.border.radius.md};
border-top-right-radius: ${themeCssVariables.border.radius.md};
color: ${themeCssVariables.font.color.primary};
margin: 0;
outline: none;
padding: ${({ theme }) => theme.spacing(2)};
padding: ${themeCssVariables.spacing[2]};
min-height: 19px;
font-family: inherit;
font-size: ${({ theme }) => theme.font.size.sm};
font-size: ${themeCssVariables.font.size.sm};
font-weight: inherit;
max-width: 100%;
@@ -25,7 +26,7 @@ export const StyledInput = styled.input`
text-decoration: none;
&::placeholder {
color: ${({ theme }) => theme.font.color.light};
color: ${themeCssVariables.font.color.light};
}
`;
@@ -1,23 +1,24 @@
import { AdvancedFilterLogicalOperatorDropdown } from '@/object-record/advanced-filter/components/AdvancedFilterLogicalOperatorDropdown';
import { type RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { capitalize } from 'twenty-shared/utils';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledText = styled.div`
height: ${({ theme }) => theme.spacing(8)};
height: ${themeCssVariables.spacing[8]};
display: flex;
align-items: center;
padding-left: ${({ theme }) => theme.spacing(2.25)};
padding-left: 9px;
`;
const StyledContainer = styled.div`
align-items: start;
display: flex;
min-width: ${({ theme }) => theme.spacing(20)};
color: ${({ theme }) => theme.font.color.tertiary};
min-width: ${themeCssVariables.spacing[20]};
color: ${themeCssVariables.font.color.tertiary};
`;
type AdvancedFilterLogicalOperatorCellProps = {
@@ -2,20 +2,23 @@ import { AdvancedFilterAddFilterRuleSelect } from '@/object-record/advanced-filt
import { AdvancedFilterRecordFilterRow } from '@/object-record/advanced-filter/components/AdvancedFilterRecordFilterRow';
import { useChildRecordFiltersAndRecordFilterGroups } from '@/object-record/advanced-filter/hooks/useChildRecordFiltersAndRecordFilterGroups';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { isDefined } from 'twenty-shared/utils';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledContainer = styled.div<{ isGrayBackground?: boolean }>`
align-items: start;
background-color: ${({ theme, isGrayBackground }) =>
isGrayBackground ? theme.background.transparent.lighter : 'transparent'};
border: ${({ theme }) => `1px solid ${theme.border.color.medium}`};
border-radius: ${({ theme }) => theme.border.radius.md};
background-color: ${({ isGrayBackground }) =>
isGrayBackground
? themeCssVariables.background.transparent.lighter
: 'transparent'};
border: 1px solid ${themeCssVariables.border.color.medium};
border-radius: ${themeCssVariables.border.radius.md};
display: flex;
flex: 1;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(2)};
padding: ${({ theme }) => theme.spacing(2)};
gap: ${themeCssVariables.spacing[2]};
padding: ${themeCssVariables.spacing[2]};
`;
type AdvancedFilterRecordFilterGroupChildrenProps = {
@@ -6,7 +6,7 @@ import { getRecordFilterOperands } from '@/object-record/record-filter/utils/get
import { useUserTimezone } from '@/ui/input/components/internal/date/hooks/useUserTimezone';
import { SelectControl } from '@/ui/input/components/SelectControl';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { isDefined } from 'twenty-shared/utils';
@@ -11,16 +11,17 @@ import { isRecordFilterGroupChildARecordFilterGroup } from '@/object-record/adva
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { isDefined } from 'twenty-shared/utils';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledContainer = styled.div`
align-items: start;
display: flex;
flex: 1;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(2)};
padding: ${({ theme }) => theme.spacing(2)};
gap: ${themeCssVariables.spacing[2]};
padding: ${themeCssVariables.spacing[2]};
`;
export const AdvancedFilterRootRecordFilterGroup = () => {
@@ -14,7 +14,7 @@ import { type DropdownOffset } from '@/ui/layout/dropdown/types/DropdownOffset';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { useSetAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useSetAtomComponentState';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { isDefined } from 'twenty-shared/utils';
const StyledValueDropdownContainer = styled.div`
@@ -5,26 +5,27 @@ import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/use
import { isNonEmptyString } from '@sniptt/guards';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { useFieldMetadataItemById } from '@/object-metadata/hooks/useFieldMetadataItemById';
import { useGetRecordFilterDisplayValue } from '@/object-record/record-filter/hooks/useGetRecordFilterDisplayValue';
import { t } from '@lingui/core/macro';
import { isDefined } from 'twenty-shared/utils';
import { themeCssVariables } from 'twenty-ui/theme-constants';
// TODO: factorize this with https://github.com/twentyhq/core-team-issues/issues/752
const StyledControlContainer = styled.div`
display: flex;
align-items: center;
gap: ${({ theme }) => theme.spacing(1)};
gap: ${themeCssVariables.spacing[1]};
box-sizing: border-box;
height: ${({ theme }) => theme.spacing(8)};
height: ${themeCssVariables.spacing[8]};
max-width: 100%;
padding: 0 ${({ theme }) => theme.spacing(2)};
background-color: ${({ theme }) => theme.background.transparent.lighter};
border: 1px solid ${({ theme }) => theme.border.color.medium};
border-radius: ${({ theme }) => theme.border.radius.sm};
color: ${({ theme }) => theme.font.color.primary};
padding: 0 ${themeCssVariables.spacing[2]};
background-color: ${themeCssVariables.background.transparent.lighter};
border: 1px solid ${themeCssVariables.border.color.medium};
border-radius: ${themeCssVariables.border.radius.sm};
color: ${themeCssVariables.font.color.primary};
cursor: pointer;
text-align: left;
`;
@@ -2,9 +2,10 @@ import { CommandMenuForMobile } from '@/command-menu/components/CommandMenuForMo
import { CommandMenuSidePanelForDesktop } from '@/command-menu/components/CommandMenuSidePanelForDesktop';
import { useCommandMenuHotKeys } from '@/command-menu/hooks/useCommandMenuHotKeys';
import { PageBody } from '@/ui/layout/page/components/PageBody';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { type ReactNode } from 'react';
import { useIsMobile } from 'twenty-ui/utilities';
import { themeCssVariables } from 'twenty-ui/theme-constants';
type MainContainerLayoutWithCommandMenuProps = {
children: ReactNode;
@@ -14,8 +15,8 @@ const StyledMainContainerLayoutForDesktop = styled.div`
display: flex;
flex: 1;
min-height: 0;
padding-bottom: ${({ theme }) => theme.spacing(3)};
padding-right: ${({ theme }) => theme.spacing(3)};
padding-bottom: ${themeCssVariables.spacing[3]};
padding-right: ${themeCssVariables.spacing[3]};
`;
const StyledPageBodyForDesktop = styled(PageBody)`
@@ -35,9 +36,9 @@ const StyledMainContainerLayoutForMobile = styled.div`
const StyledPageBodyForMobile = styled(PageBody)`
padding-bottom: 0;
padding-left: ${({ theme }) => theme.spacing(1)};
padding-left: ${themeCssVariables.spacing[1]};
padding-right: ${({ theme }) => theme.spacing(1.5)};
padding-right: ${themeCssVariables.spacing['1.5']};
`;
export const MainContainerLayoutWithCommandMenu = ({
@@ -1,6 +1,8 @@
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { useContext } from 'react';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { useApplyObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue';
import { useObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useObjectFilterDropdownFilterValue';
@@ -16,12 +18,12 @@ const StyledBooleanSelectContainer = styled.div<{ selected?: boolean }>`
align-items: center;
cursor: pointer;
display: flex;
padding: ${({ theme }) =>
`${theme.spacing(2)} ${theme.spacing(2)} ${theme.spacing(2)} ${theme.spacing(1)}`};
border-radius: ${({ theme }) => theme.border.radius.sm};
color: ${({ theme }) => theme.font.color.primary};
padding: ${themeCssVariables.spacing[2]} ${themeCssVariables.spacing[2]}
${themeCssVariables.spacing[2]} ${themeCssVariables.spacing[1]};
border-radius: ${themeCssVariables.border.radius.sm};
color: ${themeCssVariables.font.color.primary};
&:hover {
background: ${({ theme }) => theme.background.transparent.light};
background: ${themeCssVariables.background.transparent.light};
}
`;
@@ -32,7 +34,7 @@ const StyledIconCheckContainer = styled.div`
`;
export const ObjectFilterDropdownBooleanSelect = () => {
const theme = useTheme();
const { theme } = useContext(ThemeContext);
const options = [true, false];
const { objectFilterDropdownFilterValue } =
@@ -1,13 +1,14 @@
import { useApplyObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue';
import { useObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useObjectFilterDropdownFilterValue';
import { RatingInput } from '@/ui/field/input/components/RatingInput';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { RATING_VALUES } from 'twenty-shared/constants';
import { type FieldRatingValue } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledRatingInputContainer = styled.div`
padding: ${({ theme }) => theme.spacing(2)};
padding: ${themeCssVariables.spacing[2]};
`;
const convertFieldRatingValueToNumber = (
@@ -1,12 +1,13 @@
import { type SelectableItem } from '@/object-record/select/types/SelectableItem';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { Avatar } from 'twenty-ui/display';
import { MenuItemMultiSelectAvatar } from 'twenty-ui/navigation';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledPinnedItemsContainer = styled.div`
display: flex;
flex-direction: column;
padding: ${({ theme }) => theme.spacing(1)};
padding: ${themeCssVariables.spacing[1]};
`;
export const ObjectFilterDropdownRecordPinnedItems = (props: {
@@ -12,11 +12,12 @@ import { useUpdateViewFromCurrentState } from '@/views/view-picker/hooks/useUpda
import { viewPickerIsDirtyComponentState } from '@/views/view-picker/states/viewPickerIsDirtyComponentState';
import { viewPickerIsPersistingComponentState } from '@/views/view-picker/states/viewPickerIsPersistingComponentState';
import { viewPickerSelectedIconComponentState } from '@/views/view-picker/states/viewPickerSelectedIconComponentState';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useEffect, useRef, useState } from 'react';
import { styled } from '@linaria/react';
import { useContext, useEffect, useRef, useState } from 'react';
import { Key } from 'ts-key-enum';
import { OverflowingTextWithTooltip, useIcons } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { useDebouncedCallback } from 'use-debounce';
const StyledDropdownMenuIconAndNameContainer = styled.div`
@@ -24,27 +25,27 @@ const StyledDropdownMenuIconAndNameContainer = styled.div`
display: flex;
margin-left: 0;
margin-right: 0;
gap: ${({ theme }) => theme.spacing(1)};
gap: ${themeCssVariables.spacing[1]};
`;
const StyledMenuTitleContainer = styled.div`
align-items: center;
display: flex;
gap: ${({ theme }) => theme.spacing(1)};
padding: ${({ theme }) => theme.spacing(1)};
gap: ${themeCssVariables.spacing[1]};
padding: ${themeCssVariables.spacing[1]};
`;
const StyledMenuIconContainer = styled.div`
color: ${({ theme }) => theme.font.color.primary};
color: ${themeCssVariables.font.color.primary};
align-items: center;
display: flex;
height: ${({ theme }) => theme.spacing(6)};
height: ${themeCssVariables.spacing[6]};
justify-content: center;
width: ${({ theme }) => theme.spacing(6)};
width: ${themeCssVariables.spacing[6]};
`;
const StyledMainText = styled.div`
color: ${({ theme }) => theme.font.color.primary};
color: ${themeCssVariables.font.color.primary};
flex-shrink: 0;
overflow: hidden;
text-overflow: ellipsis;
@@ -110,7 +111,7 @@ export const ObjectOptionsDropdownMenuViewName = ({
}
}, [currentView?.key]);
const theme = useTheme();
const { theme } = useContext(ThemeContext);
const { getIcon } = useIcons();
const MainIcon = getIcon(currentView?.icon);
@@ -1,6 +1,7 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { useContext, useRef } from 'react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { RecordBoardColumns } from '@/object-record/record-board/components/RecordBoardColumns';
import { RecordBoardDragDropContext } from '@/object-record/record-board/components/RecordBoardDragDropContext';
@@ -22,7 +23,7 @@ const StyledContainer = styled.div`
const StyledContainerContainer = styled.div`
display: flex;
flex-direction: column;
min-height: calc(100% - ${({ theme }) => theme.spacing(2)});
min-height: calc(100% - ${themeCssVariables.spacing[2]});
height: min-content;
`;
@@ -2,13 +2,14 @@ import { RecordBoardColumn } from '@/object-record/record-board/record-board-col
import { visibleRecordGroupIdsComponentFamilySelector } from '@/object-record/record-group/states/selectors/visibleRecordGroupIdsComponentFamilySelector';
import { useAtomComponentFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilySelectorValue';
import { ViewType } from '@/views/types/ViewType';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledColumnContainer = styled.div`
display: flex;
& > *:not(:first-of-type) {
border-left: 1px solid ${({ theme }) => theme.border.color.light};
border-left: 1px solid ${themeCssVariables.border.color.light};
}
`;
@@ -1,4 +1,4 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { useEffect } from 'react';
import { useInView } from 'react-intersection-observer';
@@ -4,7 +4,8 @@ import { visibleRecordGroupIdsComponentFamilySelector } from '@/object-record/re
import { RecordIndexGroupAggregatesDataLoader } from '@/object-record/record-index/components/RecordIndexGroupAggregatesDataLoader';
import { useAtomComponentFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilySelectorValue';
import { ViewType } from '@/views/types/ViewType';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledHeaderContainer = styled.div`
display: flex;
@@ -21,7 +22,7 @@ const StyledHeaderContainer = styled.div`
}
& > *:not(:first-of-type) {
border-left: 1px solid ${({ theme }) => theme.border.color.light};
border-left: 1px solid ${themeCssVariables.border.color.light};
}
`;
@@ -30,23 +30,21 @@ import { useAtomComponentFamilyStateValue } from '@/ui/utilities/state/jotai/hoo
import { useAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentState';
import { useSetAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useSetAtomComponentState';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { useContext } from 'react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { AnimatedEaseInOut } from 'twenty-ui/utilities';
import { useDebouncedCallback } from 'use-debounce';
const StyledCardContainer = styled.div<{ isPrimaryMultiDrag?: boolean }>`
position: relative;
${({ isPrimaryMultiDrag }) =>
isPrimaryMultiDrag &&
`
transform: scale(1.02);
z-index: 10;
`}
transform: ${({ isPrimaryMultiDrag }) =>
isPrimaryMultiDrag ? 'scale(1.02)' : 'none'};
z-index: ${({ isPrimaryMultiDrag }) => (isPrimaryMultiDrag ? '10' : 'auto')};
`;
const StyledBoardCardWrapper = styled.div`
padding-bottom: ${({ theme }) => theme.spacing(2)};
padding-bottom: ${themeCssVariables.spacing[2]};
width: 100%;
`;
@@ -1,4 +1,4 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { Draggable } from '@hello-pangea/dnd';
import { useContext } from 'react';
@@ -18,8 +18,9 @@ import { useAtomFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAto
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { useContext } from 'react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { isDefined } from 'twenty-shared/utils';
import { ChipVariant } from 'twenty-ui/components';
import { IconEye, IconEyeOff } from 'twenty-ui/display';
@@ -29,7 +30,7 @@ const StyledCompactIconContainer = styled.div`
align-items: center;
display: flex;
justify-content: center;
margin-left: ${({ theme }) => theme.spacing(1)};
margin-left: ${themeCssVariables.spacing[1]};
`;
const StyledCheckboxContainer = styled.div`
@@ -1,6 +1,6 @@
import { originalDragSelectionComponentState } from '@/object-record/record-drag/states/originalDragSelectionComponentState';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { NotificationCounter } from 'twenty-ui/navigation';
const StyledNotificationCounter = styled(NotificationCounter)`
@@ -1,6 +1,7 @@
import { originalDragSelectionComponentState } from '@/object-record/record-drag/states/originalDragSelectionComponentState';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledRecordBoardCardStackCard = styled.div<{ offset: number }>`
position: absolute;
@@ -8,9 +9,9 @@ const StyledRecordBoardCardStackCard = styled.div<{ offset: number }>`
left: 0;
right: 0;
height: 100%;
background-color: ${({ theme }) => theme.accent.tertiary};
border: 1px solid ${({ theme }) => theme.border.color.medium};
border-radius: ${({ theme }) => theme.border.radius.sm};
background-color: ${themeCssVariables.accent.tertiary};
border: 1px solid ${themeCssVariables.border.color.medium};
border-radius: ${themeCssVariables.border.radius.sm};
z-index: ${({ offset }) => -offset};
`;
@@ -1,4 +1,4 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { type ReactNode } from 'react';
const StyledFieldContainer = styled.div`
@@ -1,5 +1,6 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { Droppable } from '@hello-pangea/dnd';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { RecordBoardColumnCardsContainer } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnCardsContainer';
import { RecordBoardColumnContext } from '@/object-record/record-board/record-board-column/contexts/RecordBoardColumnContext';
@@ -12,14 +13,14 @@ import { useAtomComponentFamilyStateValue } from '@/ui/utilities/state/jotai/hoo
import { isDefined } from 'twenty-shared/utils';
const StyledColumn = styled.div`
background-color: ${({ theme }) => theme.background.primary};
background-color: ${themeCssVariables.background.primary};
display: flex;
flex-direction: column;
max-width: 200px;
min-width: 200px;
min-height: 100%;
flex: 1;
padding: ${({ theme }) => theme.spacing(2)};
padding: ${themeCssVariables.spacing[2]};
padding-top: 0px;
position: relative;
height: 100%;
@@ -1,6 +1,8 @@
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { useContext } from 'react';
import { SkeletonTheme } from 'react-loading-skeleton';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader';
import { RecordCardBodyContainer } from '@/object-record/record-card/components/RecordCardBodyContainer';
@@ -11,31 +13,31 @@ import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
const StyledSkeletonIconAndText = styled.div`
display: flex;
gap: ${({ theme }) => theme.spacing(1)};
gap: ${themeCssVariables.spacing[1]};
`;
const StyledSkeletonTitle = styled.div`
padding-left: ${({ theme }) => theme.spacing(1)};
padding-left: ${themeCssVariables.spacing[1]};
`;
const StyledBodyContainer = styled.div`
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(0.5)};
gap: ${themeCssVariables.spacing['0.5']};
padding-top: 4px;
padding-bottom: 4px;
`;
const StyledStaticCellSkeleton = styled.div<{ width: number; height: number }>`
background-color: ${({ theme }) => theme.background.tertiary};
border-radius: ${({ theme }) => theme.border.radius.sm};
background-color: ${themeCssVariables.background.tertiary};
border-radius: ${themeCssVariables.border.radius.sm};
width: ${({ width }) => width}px;
height: ${({ height }) => height}px;
`;
export const RecordBoardColumnCardContainerSkeletonLoader = () => {
const theme = useTheme();
const { theme } = useContext(ThemeContext);
const { currentView } = useGetCurrentViewOnly();
@@ -1,6 +1,7 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { Draggable, type DroppableProvided } from '@hello-pangea/dnd';
import { useContext } from 'react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { RecordBoardCardDraggableContainer } from '@/object-record/record-board/record-board-card/components/RecordBoardCardDraggableContainer';
@@ -19,7 +20,7 @@ const StyledColumnCardsContainer = styled.div`
`;
const StyledNewButtonContainer = styled.div`
padding-bottom: ${({ theme }) => theme.spacing(4)};
padding-bottom: ${themeCssVariables.spacing[4]};
`;
type RecordBoardColumnCardsContainerProps = {
@@ -1,5 +1,6 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { useContext, useState } from 'react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { useObjectPermissionsForObject } from '@/object-record/hooks/useObjectPermissionsForObject';
import { RecordBoardContext } from '@/object-record/record-board/contexts/RecordBoardContext';
@@ -38,7 +39,7 @@ const StyledHeaderActions = styled.div`
`;
const StyledHeaderContainer = styled.div`
background: ${({ theme }) => theme.background.primary};
background: ${themeCssVariables.background.primary};
display: flex;
justify-content: space-between;
width: 100%;
@@ -46,7 +47,7 @@ const StyledHeaderContainer = styled.div`
const StyledLeftContainer = styled.div`
align-items: center;
display: flex;
gap: ${({ theme }) => theme.spacing(1)};
gap: ${themeCssVariables.spacing[1]};
overflow: hidden;
`;
@@ -56,13 +57,13 @@ const StyledRightContainer = styled.div`
`;
const StyledColumn = styled.div`
background-color: ${({ theme }) => theme.background.primary};
background-color: ${themeCssVariables.background.primary};
display: flex;
flex-direction: column;
max-width: ${RECORD_BOARD_COLUMN_WIDTH}px;
min-width: ${RECORD_BOARD_COLUMN_WIDTH}px;
padding: ${({ theme }) => theme.spacing(2)};
padding: ${themeCssVariables.spacing[2]};
position: relative;
`;
@@ -7,7 +7,7 @@ import { RecordBoardColumnHeaderAggregateDropdownContext } from '@/object-record
import { type RecordBoardColumnHeaderAggregateContentId } from '@/object-record/record-board/types/RecordBoardColumnHeaderAggregateContentId';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DROPDOWN_OFFSET_Y } from '@/ui/layout/dropdown/constants/DropdownOffsetY';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { type Nullable } from 'twenty-shared/types';
type RecordBoardColumnHeaderAggregateDropdownProps = {
@@ -1,7 +1,7 @@
import { StyledHeaderDropdownButton } from '@/ui/layout/dropdown/components/StyledHeaderDropdownButton';
import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { type Nullable } from 'twenty-shared/types';
import { Tag } from 'twenty-ui/components';
import { AppTooltip, TooltipDelay } from 'twenty-ui/display';
@@ -1,16 +1,17 @@
import { RECORD_BOARD_QUERY_PAGE_SIZE } from '@/object-record/record-board/constants/RecordBoardQueryPageSize';
import { RecordBoardColumnCardContainerSkeletonLoader } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnCardContainerSkeletonLoader';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledSkeletonCardContainer = styled.div`
background-color: ${({ theme }) => theme.background.secondary};
border: 1px solid ${({ theme }) => theme.background.quaternary};
border-radius: ${({ theme }) => theme.border.radius.sm};
background-color: ${themeCssVariables.background.secondary};
border: 1px solid ${themeCssVariables.background.quaternary};
border-radius: ${themeCssVariables.border.radius.sm};
box-shadow:
0px 4px 8px 0px ${({ theme }) => theme.color.gray2},
0px 0px 4px 0px ${({ theme }) => theme.color.gray2};
color: ${({ theme }) => theme.font.color.primary};
margin-bottom: ${({ theme }) => theme.spacing(2)};
0px 4px 8px 0px ${themeCssVariables.color.gray2},
0px 0px 4px 0px ${themeCssVariables.color.gray2};
color: ${themeCssVariables.font.color.primary};
margin-bottom: ${themeCssVariables.spacing[2]};
`;
export const RecordBoardColumnLoadingSkeletonCards = () => {
@@ -4,31 +4,32 @@ import { RecordBoardColumnContext } from '@/object-record/record-board/record-bo
import { hasAnySoftDeleteFilterOnViewComponentSelector } from '@/object-record/record-filter/states/hasAnySoftDeleteFilterOnView';
import { useCreateNewIndexRecord } from '@/object-record/record-table/hooks/useCreateNewIndexRecord';
import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { useContext } from 'react';
import { IconPlus } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledNewButton = styled.button`
align-items: center;
align-self: baseline;
background-color: ${({ theme }) => theme.background.primary};
background-color: ${themeCssVariables.background.primary};
border: none;
border-radius: ${({ theme }) => theme.border.radius.sm};
color: ${({ theme }) => theme.font.color.tertiary};
border-radius: ${themeCssVariables.border.radius.sm};
color: ${themeCssVariables.font.color.tertiary};
cursor: pointer;
display: flex;
gap: ${({ theme }) => theme.spacing(1)};
padding: ${({ theme }) => theme.spacing(1)};
gap: ${themeCssVariables.spacing[1]};
padding: ${themeCssVariables.spacing[1]};
&:hover {
background-color: ${({ theme }) => theme.background.tertiary};
background-color: ${themeCssVariables.background.tertiary};
}
`;
export const RecordBoardColumnNewRecordButton = () => {
const theme = useTheme();
const { theme } = useContext(ThemeContext);
const { objectMetadataItem, selectFieldMetadataItem } =
useContext(RecordBoardContext);
@@ -1,4 +1,4 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { ACTION_MENU_DROPDOWN_CLICK_OUTSIDE_ID } from '@/action-menu/constants/ActionMenuDropdownClickOutsideId';
import { COMMAND_MENU_CLICK_OUTSIDE_ID } from '@/command-menu/constants/CommandMenuClickOutsideId';
@@ -14,14 +14,15 @@ import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useLis
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { LINK_CHIP_CLICK_OUTSIDE_ID } from 'twenty-ui/components';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledContainerContainer = styled.div`
display: flex;
flex-direction: column;
height: inherit;
gap: ${({ theme }) => theme.spacing(2)};
padding: ${({ theme }) => theme.spacing(2)};
padding-left: ${({ theme }) => theme.spacing(1)};
gap: ${themeCssVariables.spacing[2]};
padding: ${themeCssVariables.spacing[2]};
padding-left: ${themeCssVariables.spacing[1]};
`;
export const RecordCalendar = () => {
@@ -7,14 +7,16 @@ import { useCreateNewIndexRecord } from '@/object-record/record-table/hooks/useC
import { useUserTimezone } from '@/ui/input/components/internal/date/hooks/useUserTimezone';
import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue';
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { useContext } from 'react';
import { type Temporal } from 'temporal-polyfill';
import { IconPlus } from 'twenty-ui/display';
import { Button } from 'twenty-ui/input';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledButton = styled(Button)`
padding: ${({ theme }) => theme.spacing(0.5)};
padding: ${themeCssVariables.spacing['0.5']};
min-width: unset;
height: auto;
`;
@@ -28,7 +30,7 @@ export const RecordCalendarAddNew = ({
}: RecordCalendarAddNewProps) => {
const { userTimezone } = useUserTimezone();
const { objectMetadataItem } = useRecordCalendarContextOrThrow();
const theme = useTheme();
const { theme } = useContext(ThemeContext);
const { createNewIndexRecord } = useCreateNewIndexRecord({
objectMetadataItem,
@@ -9,7 +9,7 @@ import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { type DropdownOffset } from '@/ui/layout/dropdown/types/DropdownOffset';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentState';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { format } from 'date-fns';
import { Temporal } from 'temporal-polyfill';
@@ -20,6 +20,7 @@ import {
} from 'twenty-shared/utils';
import { IconChevronLeft, IconChevronRight } from 'twenty-ui/display';
import { Button } from 'twenty-ui/input';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledContainer = styled.div`
align-items: center;
@@ -30,19 +31,19 @@ const StyledContainer = styled.div`
`;
const StyledNavigationButton = styled(Button)`
padding: ${({ theme }) => theme.spacing(1)};
padding: ${themeCssVariables.spacing[1]};
`;
const StyledLeftSection = styled.div`
display: flex;
align-items: center;
gap: ${({ theme }) => theme.spacing(2)};
gap: ${themeCssVariables.spacing[2]};
`;
const StyledNavigationSection = styled.div`
display: flex;
align-items: center;
gap: ${({ theme }) => theme.spacing(1)};
gap: ${themeCssVariables.spacing[1]};
justify-content: flex-end;
`;
@@ -7,7 +7,7 @@ import { useEndRecordDrag } from '@/object-record/record-drag/hooks/useEndRecord
import { useProcessCalendarCardDrop } from '@/object-record/record-drag/hooks/useProcessCalendarCardDrop';
import { useStartRecordDrag } from '@/object-record/record-drag/hooks/useStartRecordDrag';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import {
DragDropContext,
type DragStart,
@@ -1,12 +1,13 @@
import { RecordCalendarMonthBodyWeek } from '@/object-record/record-calendar/month/components/RecordCalendarMonthBodyWeek';
import { useRecordCalendarMonthContextOrThrow } from '@/object-record/record-calendar/month/contexts/RecordCalendarMonthContext';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledContainer = styled.div`
display: flex;
flex-direction: column;
flex: 1;
border: 1px solid ${({ theme }) => theme.border.color.light};
border: 1px solid ${themeCssVariables.border.color.light};
border-radius: 4px;
overflow: hidden;
`;
@@ -4,8 +4,7 @@ import { calendarDayRecordIdsComponentFamilySelector } from '@/object-record/rec
import { useUserTimezone } from '@/ui/input/components/internal/date/hooks/useUserTimezone';
import { useAtomComponentFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilySelectorValue';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { css } from '@emotion/react';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { Droppable } from '@hello-pangea/dnd';
import { useState } from 'react';
import { Temporal } from 'temporal-polyfill';
@@ -16,6 +15,7 @@ import {
isSamePlainDate,
} from 'twenty-shared/utils';
import { RecordCalendarAddNew } from '@/object-record/record-calendar/components/RecordCalendarAddNew';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledContainer = styled.div<{
isOtherMonth: boolean;
@@ -25,27 +25,20 @@ const StyledContainer = styled.div<{
width: calc(100% / 7);
flex-direction: column;
min-height: 122px;
padding: ${({ theme }) => theme.spacing(1)};
background: ${({ theme }) => theme.background.primary};
padding: ${themeCssVariables.spacing[1]};
min-width: 0;
color: ${({ theme }) => theme.font.color.primary};
background: ${({ isOtherMonth, isDayOfWeekend }) =>
isOtherMonth || isDayOfWeekend
? themeCssVariables.background.secondary
: themeCssVariables.background.primary};
color: ${({ isOtherMonth }) =>
isOtherMonth
? themeCssVariables.font.color.light
: themeCssVariables.font.color.primary};
&:not(:last-child) {
border-right: 1px solid ${({ theme }) => theme.border.color.light};
border-right: 1px solid ${themeCssVariables.border.color.light};
}
${({ isOtherMonth, theme }) =>
isOtherMonth &&
css`
background: ${theme.background.secondary};
color: ${theme.font.color.light};
`}
${({ isDayOfWeekend, theme }) =>
isDayOfWeekend &&
css`
background: ${theme.background.secondary};
`}
`;
const StyledDayHeader = styled.div`
@@ -61,42 +54,44 @@ const StyledDayHeader = styled.div`
const StyledDayHeaderDayContainer = styled.div`
display: flex;
margin-left: auto;
padding: ${({ theme }) => theme.spacing(0.5, 0.5)};
padding: ${themeCssVariables.spacing['0.5']}
${themeCssVariables.spacing['0.5']};
`;
const StyledDayHeaderDay = styled.span<{ isToday: boolean }>`
align-items: center;
display: flex;
font-size: ${({ theme }) => theme.font.size.sm};
font-size: ${themeCssVariables.font.size.sm};
justify-content: center;
line-height: 140%;
width: 20px;
${({ isToday, theme }) =>
isToday &&
css`
border-radius: 4px;
background: ${theme.color.blue};
color: ${theme.font.color.inverted};
font-weight: ${theme.font.weight.medium};
`}
border-radius: ${({ isToday }) => (isToday ? '4px' : '0')};
background: ${({ isToday }) =>
isToday ? themeCssVariables.color.blue : 'transparent'};
color: ${({ isToday }) =>
isToday
? themeCssVariables.font.color.inverted
: themeCssVariables.font.color.primary};
font-weight: ${({ isToday }) =>
isToday ? themeCssVariables.font.weight.medium : 'normal'};
`;
const StyledCardsContainer = styled.div<{ isDraggedOver?: boolean }>`
background: ${({ isDraggedOver }) =>
isDraggedOver
? themeCssVariables.background.transparent.lighter
: 'transparent'};
border: ${({ isDraggedOver }) =>
isDraggedOver
? `1px dashed ${themeCssVariables.border.color.medium}`
: 'none'};
border-radius: ${themeCssVariables.border.radius.sm};
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(0.5)};
flex: 1;
flex-direction: column;
gap: ${themeCssVariables.spacing['0.5']};
min-height: 60px;
border-radius: ${({ theme }) => theme.border.radius.sm};
transition: background-color 0.1s ease;
${({ isDraggedOver, theme }) =>
isDraggedOver &&
css`
background: ${theme.background.transparent.lighter};
border: 1px dashed ${theme.border.color.medium};
`}
`;
type RecordCalendarMonthBodyDayProps = {
@@ -1,6 +1,7 @@
import { RecordCalendarMonthBodyDay } from '@/object-record/record-calendar/month/components/RecordCalendarMonthBodyDay';
import { useRecordCalendarMonthContextOrThrow } from '@/object-record/record-calendar/month/contexts/RecordCalendarMonthContext';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { eachDayOfInterval, endOfWeek } from 'date-fns';
import { type Temporal } from 'temporal-polyfill';
import {
@@ -14,7 +15,7 @@ const StyledContainer = styled.div`
flex: 1;
&:not(:last-of-type) {
border-bottom: 1px solid ${({ theme }) => theme.border.color.light};
border-bottom: 1px solid ${themeCssVariables.border.color.light};
}
`;
@@ -1,6 +1,6 @@
import { RecordCalendarMonthHeaderDay } from '@/object-record/record-calendar/month/components/RecordCalendarMonthHeaderDay';
import { useRecordCalendarMonthContextOrThrow } from '@/object-record/record-calendar/month/contexts/RecordCalendarMonthContext';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
const StyledContainer = styled.div`
display: flex;
@@ -1,16 +1,17 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
type RecordCalendarMonthHeaderDayProps = {
label: string;
};
const StyledLabel = styled.div`
color: ${({ theme }) => theme.font.color.light};
color: ${themeCssVariables.font.color.light};
display: flex;
font-size: ${({ theme }) => theme.font.size.sm};
font-size: ${themeCssVariables.font.size.sm};
height: 24px;
justify-content: flex-end;
padding: ${({ theme }) => theme.spacing(0, 1)};
padding: ${themeCssVariables.spacing[0]} ${themeCssVariables.spacing[1]};
width: calc(100% / 7);
`;
@@ -17,7 +17,7 @@ import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/com
import { useAtomComponentFamilyState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyState';
import { useSetAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useSetAtomComponentState';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { AnimatedEaseInOut } from 'twenty-ui/utilities';
const StyledContainer = styled.div`
@@ -17,10 +17,11 @@ import { RecordInlineCell } from '@/object-record/record-inline-cell/components/
import { getRecordFieldInputInstanceId } from '@/object-record/utils/getRecordFieldInputId';
import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue';
import { useSetAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useSetAtomComponentState';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledRecordCardBodyContainer = styled(RecordCardBodyContainer)`
padding: ${({ theme }) => theme.spacing(1)};
padding: ${themeCssVariables.spacing[1]};
`;
type RecordCalendarCardBodyProps = {
@@ -1,4 +1,4 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { Draggable } from '@hello-pangea/dnd';
import { useObjectPermissionsForObject } from '@/object-record/hooks/useObjectPermissionsForObject';
@@ -8,7 +8,8 @@ import { recordStoreFamilyState } from '@/object-record/record-store/states/reco
import { useAtomComponentFamilyState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyState';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { useAtomFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilyStateValue';
import { isDefined } from 'twenty-shared/utils';
import { ChipVariant } from 'twenty-ui/components';
@@ -23,11 +24,11 @@ const StyledRecordChipContainer = styled.div`
display: flex;
flex: 1 1 auto;
overflow: hidden;
padding: ${({ theme }) => theme.spacing(1)};
padding: ${themeCssVariables.spacing[1]};
`;
const StyledRecordCardHeaderContainer = styled(RecordCardHeaderContainer)`
padding: ${({ theme }) => theme.spacing(1)};
padding: ${themeCssVariables.spacing[1]};
`;
type RecordCalendarCardHeaderProps = {
@@ -1,41 +1,38 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledBoardCard = styled.div<{
isDragging?: boolean;
isSecondaryDragged?: boolean;
isPrimaryMultiDrag?: boolean;
}>`
background-color: ${({ theme }) => theme.background.secondary};
border: 1px solid ${({ theme }) => theme.border.color.medium};
border-radius: ${({ theme }) => theme.border.radius.sm};
color: ${({ theme }) => theme.font.color.primary};
background-color: ${themeCssVariables.background.secondary};
border: 1px solid ${themeCssVariables.border.color.medium};
border-radius: ${themeCssVariables.border.radius.sm};
color: ${themeCssVariables.font.color.primary};
cursor: pointer;
width: 100%;
${({ isSecondaryDragged }) =>
isSecondaryDragged &&
`
opacity: 0.3;
`}
opacity: ${({ isSecondaryDragged }) => (isSecondaryDragged ? '0.3' : '1')};
&[data-selected='true'] {
background-color: ${({ theme }) => theme.accent.quaternary};
background-color: ${themeCssVariables.accent.quaternary};
}
&[data-focused='true'] {
background-color: ${({ theme }) => theme.background.tertiary};
background-color: ${themeCssVariables.background.tertiary};
}
&[data-active='true'] {
background-color: ${({ theme }) => theme.accent.quaternary};
border: 1px solid ${({ theme }) => theme.color.blue7};
background-color: ${themeCssVariables.accent.quaternary};
border: 1px solid ${themeCssVariables.color.blue7};
}
&:hover {
border: 1px solid ${({ theme }) => theme.border.color.strong};
border: 1px solid ${themeCssVariables.border.color.strong};
&[data-active='true'] {
border: 1px solid ${({ theme }) => theme.color.blue7};
border: 1px solid ${themeCssVariables.color.blue7};
}
}
@@ -1,19 +1,20 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledCardBodyContainer = styled.div`
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(0.5)};
padding-bottom: ${({ theme }) => theme.spacing(2)};
gap: ${themeCssVariables.spacing['0.5']};
padding-bottom: ${themeCssVariables.spacing[2]};
padding-left: 10px;
padding-right: ${({ theme }) => theme.spacing(2)};
padding-right: ${themeCssVariables.spacing[2]};
span {
align-items: center;
display: flex;
flex-direction: row;
svg {
color: ${({ theme }) => theme.font.color.tertiary};
margin-right: ${({ theme }) => theme.spacing(2)};
color: ${themeCssVariables.font.color.tertiary};
margin-right: ${themeCssVariables.spacing[2]};
}
}
`;
@@ -1,4 +1,5 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
export const StyledBoardCardHeaderContainer = styled.div<{
isCompact: boolean;
@@ -7,18 +8,19 @@ export const StyledBoardCardHeaderContainer = styled.div<{
display: flex;
flex-direction: row;
justify-content: space-between;
font-weight: ${({ theme }) => theme.font.weight.medium};
font-weight: ${themeCssVariables.font.weight.medium};
height: 24px;
padding-bottom: ${({ theme, isCompact }) => theme.spacing(isCompact ? 2 : 1)};
padding-left: ${({ theme }) => theme.spacing(2)};
padding-right: ${({ theme }) => theme.spacing(2)};
padding-top: ${({ theme }) => theme.spacing(2)};
padding-bottom: ${({ isCompact }) =>
isCompact ? themeCssVariables.spacing[2] : themeCssVariables.spacing[1]};
padding-left: ${themeCssVariables.spacing[2]};
padding-right: ${themeCssVariables.spacing[2]};
padding-top: ${themeCssVariables.spacing[2]};
transition: padding ease-in-out 160ms;
img {
height: ${({ theme }) => theme.icon.size.md}px;
height: ${themeCssVariables.icon.size.md}px;
object-fit: cover;
width: ${({ theme }) => theme.icon.size.md}px;
width: ${themeCssVariables.icon.size.md}px;
}
`;
@@ -1,7 +1,8 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledRecordsList = styled.div`
color: ${({ theme }) => theme.font.color.secondary};
color: ${themeCssVariables.font.color.secondary};
`;
export { StyledRecordsList as RecordDetailRecordsListContainer };
@@ -1,31 +1,46 @@
import { useLayoutRenderingContext } from '@/ui/layout/contexts/LayoutRenderingContext';
import isPropValid from '@emotion/is-prop-valid';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { PageLayoutType } from '~/generated-metadata/graphql';
const StyledListItem = styled('div', {
shouldForwardProp: (prop) =>
isPropValid(prop) && prop !== 'noHorizontalPadding',
})<{ noHorizontalPadding?: boolean }>`
const StyledListItem = styled.div<{
noHorizontalPadding?: boolean;
isDropdownOpen?: boolean;
}>`
align-items: center;
justify-content: space-between;
gap: ${({ theme }) => theme.spacing(1)};
gap: ${themeCssVariables.spacing[1]};
display: flex;
height: ${({ theme }) => theme.spacing(10)};
padding-left: ${({ theme, noHorizontalPadding }) =>
noHorizontalPadding ? 0 : theme.spacing(3)};
padding-right: ${({ theme, noHorizontalPadding }) =>
noHorizontalPadding ? 0 : theme.spacing(2)};
height: ${themeCssVariables.spacing[10]};
padding-left: ${({ noHorizontalPadding }) =>
noHorizontalPadding ? 0 : themeCssVariables.spacing[3]};
padding-right: ${({ noHorizontalPadding }) =>
noHorizontalPadding ? 0 : themeCssVariables.spacing[2]};
.displayOnHover {
opacity: ${({ isDropdownOpen }) => (isDropdownOpen ? 1 : 0)};
pointer-events: ${({ isDropdownOpen }) =>
isDropdownOpen ? 'auto' : 'none'};
transition: opacity
calc(${themeCssVariables.animation.duration.instant} * 1s) ease;
}
&:hover .displayOnHover {
opacity: 1;
pointer-events: auto;
}
`;
type RecordDetailRecordsListItemContainerProps = {
children: React.ReactNode;
className?: string;
isDropdownOpen?: boolean;
};
export const RecordDetailRecordsListItemContainer = ({
children,
className,
isDropdownOpen,
}: RecordDetailRecordsListItemContainerProps) => {
const layoutRenderingContext = useLayoutRenderingContext();
@@ -36,6 +51,7 @@ export const RecordDetailRecordsListItemContainer = ({
<StyledListItem
className={className}
noHorizontalPadding={isInRecordPageLayout}
isDropdownOpen={isDropdownOpen}
>
{children}
</StyledListItem>
@@ -1,12 +1,13 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { useState } from 'react';
import { Link } from 'react-router-dom';
import { Section } from 'twenty-ui/layout';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledRecordDetailSectionContainer = styled(Section)`
border-top: 1px solid ${({ theme }) => theme.border.color.light};
padding-top: ${({ theme }) => theme.spacing(3)};
padding-bottom: ${({ theme }) => theme.spacing(3)};
border-top: 1px solid ${themeCssVariables.border.color.light};
padding-top: ${themeCssVariables.spacing[3]};
padding-bottom: ${themeCssVariables.spacing[3]};
width: auto;
`;
@@ -19,29 +20,29 @@ const StyledHeader = styled.header<{
display: flex;
height: 24px;
justify-content: space-between;
margin-bottom: ${({ theme, areRecordsAvailable }) =>
areRecordsAvailable && theme.spacing(2)};
padding-left: ${({ theme }) => theme.spacing(3)};
padding-right: ${({ theme }) => theme.spacing(2)};
margin-bottom: ${({ areRecordsAvailable }) =>
areRecordsAvailable ? themeCssVariables.spacing[2] : '0'};
padding-left: ${themeCssVariables.spacing[3]};
padding-right: ${themeCssVariables.spacing[2]};
`;
const StyledTitle = styled.div`
align-items: flex-end;
display: flex;
gap: ${({ theme }) => theme.spacing(1)};
gap: ${themeCssVariables.spacing[1]};
`;
const StyledTitleLabel = styled.div`
font-weight: ${({ theme }) => theme.font.weight.medium};
font-weight: ${themeCssVariables.font.weight.medium};
`;
const StyledLink = styled(Link)`
color: ${({ theme }) => theme.font.color.light};
color: ${themeCssVariables.font.color.light};
text-decoration: none;
font-size: ${({ theme }) => theme.font.size.sm};
font-size: ${themeCssVariables.font.size.sm};
:hover {
color: ${({ theme }) => theme.font.color.secondary};
color: ${themeCssVariables.font.color.secondary};
}
`;
@@ -1,5 +1,4 @@
import { css } from '@emotion/react';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { motion } from 'framer-motion';
import { useCallback, useContext } from 'react';
@@ -49,27 +48,6 @@ import { MenuItem } from 'twenty-ui/navigation';
import { AnimatedEaseInOut } from 'twenty-ui/utilities';
import { FieldMetadataType, RelationType } from '~/generated-metadata/graphql';
const StyledListItem = styled(RecordDetailRecordsListItemContainer)<{
isDropdownOpen?: boolean;
}>`
${({ isDropdownOpen, theme }) =>
!isDropdownOpen &&
css`
.displayOnHover {
opacity: 0;
pointer-events: none;
transition: opacity ${theme.animation.duration.instant}s ease;
}
`}
&:hover {
.displayOnHover {
opacity: 1;
pointer-events: auto;
}
}
`;
const StyledClickableZone = styled.div`
align-items: center;
cursor: pointer;
@@ -238,7 +216,7 @@ export const RecordDetailRelationRecordsListItem = ({
return (
<>
<StyledListItem
<RecordDetailRecordsListItemContainer
isDropdownOpen={isDropdownOpen}
data-testid="record-detail-records-list-item"
>
@@ -286,7 +264,7 @@ export const RecordDetailRelationRecordsListItem = ({
}
/>
)}
</StyledListItem>
</RecordDetailRecordsListItemContainer>
<AnimatedEaseInOut isOpen={isExpanded}>
<RecordFieldList
instanceId={`${scopeInstanceId}-relation-${relationRecord.id}`}
@@ -1,11 +1,12 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { useLingui } from '@lingui/react/macro';
import { IconCopy } from 'twenty-ui/display';
import { LightIconButton } from 'twenty-ui/input';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { useCopyToClipboard } from '~/hooks/useCopyToClipboard';
const StyledButtonContainer = styled.div`
padding: 0 ${({ theme }) => theme.spacing(1)};
padding: 0 ${themeCssVariables.spacing[1]};
`;
export type LightCopyIconButtonProps = {
@@ -1,14 +1,16 @@
import { css, useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { useContext } from 'react';
import { IconX } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledChip = styled.div<{ deletable: boolean; danger: boolean }>`
background-color: ${({ theme, danger }) =>
danger ? theme.color.red3 : theme.color.blue3};
background-color: ${({ danger }) =>
danger ? themeCssVariables.color.red3 : themeCssVariables.color.blue3};
border-width: 1px;
border-style: solid;
border-color: ${({ theme, danger }) =>
danger ? theme.color.red5 : theme.color.blue5};
border-color: ${({ danger }) =>
danger ? themeCssVariables.color.red5 : themeCssVariables.color.blue5};
border-radius: 4px;
height: 20px;
box-sizing: border-box;
@@ -16,24 +18,19 @@ const StyledChip = styled.div<{ deletable: boolean; danger: boolean }>`
align-items: center;
flex-direction: row;
flex-shrink: 0;
column-gap: ${({ theme }) => theme.spacing(1)};
padding-left: ${({ theme }) => theme.spacing(1)};
column-gap: ${themeCssVariables.spacing[1]};
padding-left: ${themeCssVariables.spacing[1]};
user-select: none;
white-space: nowrap;
${({ theme, deletable }) =>
!deletable
? css`
padding-right: ${theme.spacing(1)};
`
: css`
cursor: pointer;
`}
cursor: ${({ deletable }) => (deletable ? 'pointer' : 'default')};
padding-right: ${({ deletable }) =>
deletable ? '0' : themeCssVariables.spacing[1]};
`;
const StyledLabel = styled.span<{ danger: boolean }>`
color: ${({ theme, danger }) =>
danger ? theme.color.red : theme.color.blue};
color: ${({ danger }) =>
danger ? themeCssVariables.color.red : themeCssVariables.color.blue};
line-height: 140%;
`;
@@ -45,20 +42,20 @@ const StyledDelete = styled.button<{ danger: boolean }>`
justify-content: center;
align-items: center;
cursor: pointer;
font-size: ${({ theme }) => theme.font.size.sm};
font-size: ${themeCssVariables.font.size.sm};
user-select: none;
padding: 0;
margin: 0;
background: none;
border: none;
color: ${({ theme, danger }) =>
danger ? theme.color.red : theme.color.blue};
border-top-right-radius: ${({ theme }) => theme.border.radius.sm};
border-bottom-right-radius: ${({ theme }) => theme.border.radius.sm};
color: ${({ danger }) =>
danger ? themeCssVariables.color.red : themeCssVariables.color.blue};
border-top-right-radius: ${themeCssVariables.border.radius.sm};
border-bottom-right-radius: ${themeCssVariables.border.radius.sm};
&:hover {
background-color: ${({ theme, danger }) =>
danger ? theme.color.red5 : theme.color.blue5};
background-color: ${({ danger }) =>
danger ? themeCssVariables.color.red5 : themeCssVariables.color.blue5};
}
`;
@@ -79,7 +76,7 @@ export const BaseChip = ({
danger = false,
leftIcon,
}: BaseChipProps) => {
const theme = useTheme();
const { theme } = useContext(ThemeContext);
const isDeletable = onRemove !== undefined;
return (
@@ -14,12 +14,13 @@ import { type BreadcrumbProps } from '@/ui/navigation/bread-crumb/components/Bre
import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack';
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { useLingui } from '@lingui/react/macro';
import { useId, useState } from 'react';
import { useContext, useId, useState } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { IconMaximize } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { useIsMobile } from 'twenty-ui/utilities';
const StyledAdvancedTextFieldContainer = styled(FormFieldInputContainer)`
@@ -30,15 +31,15 @@ const StyledAdvancedTextFieldFieldContainer = styled.div`
position: relative;
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(2)};
gap: ${themeCssVariables.spacing[2]};
flex-grow: 1;
`;
const StyledAdvancedTextFieldInnerContainer = styled.div`
flex-grow: 1;
background-color: ${({ theme }) => theme.background.transparent.lighter};
border: 1px solid ${({ theme }) => theme.border.color.medium};
border-radius: ${({ theme }) => theme.border.radius.sm};
background-color: ${themeCssVariables.background.transparent.lighter};
border: 1px solid ${themeCssVariables.border.color.medium};
border-radius: ${themeCssVariables.border.radius.sm};
box-sizing: border-box;
display: flex;
@@ -48,29 +49,29 @@ const StyledAdvancedTextFieldInnerContainer = styled.div`
const StyledEditorActionButtonContainer = styled.div`
position: absolute;
top: ${({ theme }) => theme.spacing(0)};
right: ${({ theme }) => theme.spacing(7.5)};
top: ${themeCssVariables.spacing[0]};
right: 30px;
z-index: 1;
`;
const StyledFullScreenEditorContainer = styled.div`
background-color: ${({ theme }) => theme.background.secondary};
border: 1px solid ${({ theme }) => theme.border.color.medium};
border-radius: ${({ theme }) => theme.border.radius.sm};
background-color: ${themeCssVariables.background.secondary};
border: 1px solid ${themeCssVariables.border.color.medium};
border-radius: ${themeCssVariables.border.radius.sm};
flex: 1;
min-height: 0;
padding: ${({ theme }) => theme.spacing(2)};
padding: ${themeCssVariables.spacing[2]};
overflow-y: auto;
`;
const StyledFullScreenButtonContainer = styled(StyledDropdownButtonContainer)`
background-color: transparent;
color: ${({ theme }) => theme.font.color.tertiary};
padding: ${({ theme }) => theme.spacing(2)};
color: ${themeCssVariables.font.color.tertiary};
padding: ${themeCssVariables.spacing[2]};
:hover {
cursor: pointer;
background-color: ${({ theme }) => theme.background.transparent.light};
background-color: ${themeCssVariables.background.transparent.light};
}
`;
@@ -112,7 +113,7 @@ export const FormAdvancedTextFieldInput = ({
const instanceId = useId();
const isMobile = useIsMobile();
const [isFullScreen, setIsFullScreen] = useState(false);
const theme = useTheme();
const { theme } = useContext(ThemeContext);
const { t } = useLingui();
const { pushFocusItemToFocusStack } = usePushFocusItemToFocusStack();
@@ -127,7 +128,6 @@ export const FormAdvancedTextFieldInput = ({
contentType,
onUpdate: (editor) => {
if (contentType === 'markdown') {
// For markdown mode, output the HTML which preserves formatting
onChange(editor.getHTML());
} else {
const jsonContent = editor.getJSON();
@@ -22,13 +22,14 @@ import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { isStandaloneVariableString } from '@/workflow/utils/isStandaloneVariableString';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { useLingui } from '@lingui/react/macro';
import { isNonEmptyArray } from '@sniptt/guards';
import { useId, useRef, useState } from 'react';
import { useContext, useId, useRef, useState } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { IconPlus } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { MenuItem } from 'twenty-ui/navigation';
import { toSpliced } from '~/utils/array/toSpliced';
@@ -48,7 +49,7 @@ const StyledDisplayModeReadonlyContainer = styled.div`
border: none;
display: flex;
font-family: inherit;
padding-inline: ${({ theme }) => theme.spacing(2)};
padding-inline: ${themeCssVariables.spacing[2]};
width: 100%;
`;
@@ -59,12 +60,12 @@ const StyledDisplayModeContainer = styled(StyledDisplayModeReadonlyContainer)`
&:hover,
&[data-open='true'] {
background-color: ${({ theme }) => theme.background.transparent.lighter};
background-color: ${themeCssVariables.background.transparent.lighter};
}
`;
const StyledInput = styled(TextInput)`
padding: ${({ theme }) => `${theme.spacing(1)} ${theme.spacing(2)}`};
padding: ${themeCssVariables.spacing[1]} ${themeCssVariables.spacing[2]};
`;
const StyledPlaceholder = styled(FormFieldPlaceholder)`
@@ -85,7 +86,7 @@ export const FormArrayFieldInput = ({
testId,
}: FormArrayFieldInputProps) => {
const { t } = useLingui();
const theme = useTheme();
const { theme } = useContext(ThemeContext);
const instanceId = useId();
@@ -8,11 +8,11 @@ import { Select } from '@/ui/input/components/Select';
import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/GenericDropdownContentWidth';
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
import { isStandaloneVariableString } from '@/workflow/utils/isStandaloneVariableString';
import { useTheme } from '@emotion/react';
import { useLingui } from '@lingui/react/macro';
import { useId, useState } from 'react';
import { useContext, useId, useState } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { IconCheck, IconCircleOff, IconX } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
type FormBooleanFieldInputProps = {
label?: string;
@@ -45,7 +45,7 @@ export const FormBooleanFieldInput = ({
readonly,
VariablePicker,
}: FormBooleanFieldInputProps) => {
const theme = useTheme();
const { theme } = useContext(ThemeContext);
const { t } = useLingui();
const instanceId = useId();
@@ -3,9 +3,10 @@ import { FormFieldInputInnerContainer } from '@/object-record/record-field/ui/fo
import { FormFieldInputRowContainer } from '@/object-record/record-field/ui/form-types/components/FormFieldInputRowContainer';
import { InputHint } from '@/ui/input/components/InputHint';
import { InputLabel } from '@/ui/input/components/InputLabel';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { useId } from 'react';
import { Toggle } from 'twenty-ui/input';
import { themeCssVariables } from 'twenty-ui/theme-constants';
type FormBooleanFieldToggleInputProps = {
label?: string;
@@ -18,10 +19,10 @@ type FormBooleanFieldToggleInputProps = {
const StyledDescription = styled.span`
align-items: center;
color: ${({ theme }) => theme.font.color.secondary};
color: ${themeCssVariables.font.color.secondary};
display: flex;
font-size: ${({ theme }) => theme.font.size.md};
padding-left: ${({ theme }) => theme.spacing(2)};
font-size: ${themeCssVariables.font.size.md};
padding-left: ${themeCssVariables.spacing[2]};
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
@@ -29,14 +30,14 @@ const StyledDescription = styled.span`
const StyledToggleContainer = styled.div`
align-items: center;
background-color: ${({ theme }) => theme.background.transparent.lighter};
border-top: 1px solid ${({ theme }) => theme.border.color.medium};
border-bottom: 1px solid ${({ theme }) => theme.border.color.medium};
border-right: 1px solid ${({ theme }) => theme.border.color.medium};
border-bottom-right-radius: ${({ theme }) => theme.border.radius.sm};
border-top-right-radius: ${({ theme }) => theme.border.radius.sm};
background-color: ${themeCssVariables.background.transparent.lighter};
border-top: 1px solid ${themeCssVariables.border.color.medium};
border-bottom: 1px solid ${themeCssVariables.border.color.medium};
border-right: 1px solid ${themeCssVariables.border.color.medium};
border-bottom-right-radius: ${themeCssVariables.border.radius.sm};
border-top-right-radius: ${themeCssVariables.border.radius.sm};
display: flex;
padding-right: ${({ theme }) => theme.spacing(2)};
padding-right: ${themeCssVariables.spacing[2]};
`;
export const FormBooleanFieldToggleInput = ({
@@ -18,8 +18,7 @@ import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContaine
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { isStandaloneVariableString } from '@/workflow/utils/isStandaloneVariableString';
import { css } from '@emotion/react';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { isNonEmptyString } from '@sniptt/guards';
import {
useId,
@@ -30,7 +29,7 @@ import {
} from 'react';
import { Key } from 'ts-key-enum';
import { isDefined } from 'twenty-shared/utils';
import { TEXT_INPUT_STYLE } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { type Nullable } from 'twenty-ui/utilities';
import { getDateFormatStringForDatePickerInputMask } from '~/utils/date-utils';
@@ -44,21 +43,34 @@ const StyledInputContainer = styled(FormFieldInputInnerContainer)`
const StyledDateInputAbsoluteContainer = styled.div`
position: absolute;
top: ${({ theme }) => theme.spacing(1)};
top: ${themeCssVariables.spacing[1]};
`;
const StyledDateInput = styled.input<{ hasError?: boolean }>`
${TEXT_INPUT_STYLE}
background-color: transparent;
border: none;
color: ${themeCssVariables.font.color.primary};
font-family: ${themeCssVariables.font.family};
font-size: inherit;
font-weight: inherit;
outline: none;
padding: ${themeCssVariables.spacing[0]} ${themeCssVariables.spacing[2]};
&:disabled {
color: ${({ theme }) => theme.font.color.tertiary};
&::placeholder,
&::-webkit-input-placeholder {
color: ${themeCssVariables.font.color.light};
font-family: ${themeCssVariables.font.family};
font-weight: ${themeCssVariables.font.weight.medium};
}
${({ hasError, theme }) =>
hasError &&
css`
color: ${theme.color.red};
`};
&:disabled {
color: ${themeCssVariables.font.color.tertiary};
}
color: ${({ hasError }) =>
hasError
? themeCssVariables.color.red
: themeCssVariables.font.color.primary};
`;
const StyledDateInputContainer = styled.div`
@@ -18,11 +18,12 @@ import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotke
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
import { isStandaloneVariableString } from '@/workflow/utils/isStandaloneVariableString';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { useId, useRef, useState } from 'react';
import { Temporal } from 'temporal-polyfill';
import { Key } from 'ts-key-enum';
import { isDefined } from 'twenty-shared/utils';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { type Nullable } from 'twenty-ui/utilities';
const StyledInputContainer = styled(FormFieldInputInnerContainer)`
@@ -35,7 +36,7 @@ const StyledInputContainer = styled(FormFieldInputInnerContainer)`
const StyledDateInputAbsoluteContainer = styled.div`
position: absolute;
top: ${({ theme }) => theme.spacing(1)};
top: ${themeCssVariables.spacing[1]};
`;
const StyledDateInputTextContainer = styled.div`
@@ -1,4 +1,4 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
const StyledFormFieldInputContainer = styled.div`
display: flex;
@@ -1,9 +1,9 @@
import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack';
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
import { css } from '@emotion/react';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { forwardRef, type HTMLAttributes, type Ref } from 'react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
type FormFieldInputInnerContainerProps = {
hasRightElement: boolean;
@@ -16,24 +16,17 @@ type FormFieldInputInnerContainerProps = {
const StyledFormFieldInputInnerContainer = styled.div<
Omit<FormFieldInputInnerContainerProps, 'formFieldInputInstanceId'>
>`
background-color: ${({ theme }) => theme.background.transparent.lighter};
border: 1px solid ${({ theme }) => theme.border.color.medium};
border-top-left-radius: ${({ theme }) => theme.border.radius.sm};
border-bottom-left-radius: ${({ theme }) => theme.border.radius.sm};
${({ multiline, hasRightElement, theme }) =>
multiline || !hasRightElement
? css`
border-right: auto;
border-bottom-right-radius: ${theme.border.radius.sm};
border-top-right-radius: ${theme.border.radius.sm};
`
: css`
border-right: none;
border-bottom-right-radius: 0;
border-top-right-radius: 0;
`}
background-color: ${themeCssVariables.background.transparent.lighter};
border: 1px solid ${themeCssVariables.border.color.medium};
border-top-left-radius: ${themeCssVariables.border.radius.sm};
border-bottom-left-radius: ${themeCssVariables.border.radius.sm};
border-bottom-right-radius: ${({ multiline, hasRightElement }) =>
multiline || !hasRightElement ? themeCssVariables.border.radius.sm : '0'};
border-right: ${({ multiline, hasRightElement }) =>
multiline || !hasRightElement ? 'auto' : 'none'};
border-top-right-radius: ${({ multiline, hasRightElement }) =>
multiline || !hasRightElement ? themeCssVariables.border.radius.sm : '0'};
box-sizing: border-box;
display: flex;
overflow-x: auto;
@@ -1,5 +1,4 @@
import { css } from '@emotion/react';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
export const LINE_HEIGHT = 24;
@@ -11,16 +10,13 @@ const StyledFormFieldInputRowContainer = styled.div<{
flex-direction: row;
position: relative;
${({ multiline, maxHeight }) =>
multiline
? css`
line-height: ${LINE_HEIGHT}px;
min-height: ${3 * LINE_HEIGHT}px;
max-height: ${maxHeight ?? 5 * LINE_HEIGHT}px;
`
: css`
height: 32px;
`}
height: ${({ multiline }) => (multiline ? 'auto' : '32px')};
line-height: ${({ multiline }) =>
multiline ? `${LINE_HEIGHT}px` : 'normal'};
max-height: ${({ multiline, maxHeight }) =>
multiline ? `${maxHeight ?? 5 * LINE_HEIGHT}px` : 'none'};
min-height: ${({ multiline }) =>
multiline ? `${3 * LINE_HEIGHT}px` : 'auto'};
`;
export const FormFieldInputRowContainer = StyledFormFieldInputRowContainer;
@@ -1,5 +1,5 @@
import { FORM_FIELD_PLACEHOLDER_STYLES } from '@/object-record/record-field/ui/form-types/constants/FormFieldPlaceholderStyles';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
const StyledPlaceholder = styled.div`
${FORM_FIELD_PLACEHOLDER_STYLES}
@@ -1,4 +1,4 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { FormFieldInputContainer } from '@/object-record/record-field/ui/form-types/components/FormFieldInputContainer';
@@ -19,13 +19,14 @@ import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePush
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType';
import { isStandaloneVariableString } from '@/workflow/utils/isStandaloneVariableString';
import { useTheme } from '@emotion/react';
import { isArray } from '@sniptt/guards';
import { useId, useState } from 'react';
import { useContext, useId, useState } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { VisibilityHidden } from 'twenty-ui/accessibility';
import { IconChevronDown } from 'twenty-ui/display';
import { type SelectOption } from 'twenty-ui/input';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
type FormMultiSelectFieldInputProps = {
label?: string;
@@ -46,7 +47,7 @@ const StyledDisplayModeReadonlyContainer = styled.div`
border: none;
display: flex;
font-family: inherit;
padding-inline: ${({ theme }) => theme.spacing(2)};
padding-inline: ${themeCssVariables.spacing[2]};
width: 100%;
`;
@@ -55,14 +56,14 @@ const StyledDisplayModeContainer = styled(StyledDisplayModeReadonlyContainer)`
&:hover,
&[data-open='true'] {
background-color: ${({ theme }) => theme.background.transparent.lighter};
background-color: ${themeCssVariables.background.transparent.lighter};
}
`;
const StyledSelectInputContainer = styled.div`
position: absolute;
z-index: 1;
top: ${({ theme }) => theme.spacing(9)};
top: ${themeCssVariables.spacing[9]};
`;
const StyledPlaceholder = styled(FormFieldPlaceholder)`
@@ -90,7 +91,7 @@ export const FormMultiSelectFieldInput = ({
dropdownWidth,
}: FormMultiSelectFieldInputProps) => {
const instanceId = useId();
const theme = useTheme();
const { theme } = useContext(ThemeContext);
const { pushFocusItemToFocusStack } = usePushFocusItemToFocusStack();
const { removeFocusItemFromFocusStackById } =
@@ -1,13 +1,14 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledFormNestedFieldInputContainer = styled.div`
display: flex;
flex-direction: column;
background: ${({ theme }) => theme.background.secondary};
border: 1px solid ${({ theme }) => theme.border.color.medium};
border-radius: ${({ theme }) => theme.border.radius.sm};
gap: ${({ theme }) => theme.spacing(2)};
padding: ${({ theme }) => theme.spacing(2)};
background: ${themeCssVariables.background.secondary};
border: 1px solid ${themeCssVariables.border.color.medium};
border-radius: ${themeCssVariables.border.radius.sm};
gap: ${themeCssVariables.spacing[2]};
padding: ${themeCssVariables.spacing[2]};
`;
export const FormNestedFieldInputContainer =
@@ -11,12 +11,12 @@ import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/Gene
import { useRemoveFocusItemFromFocusStackById } from '@/ui/utilities/focus/hooks/useRemoveFocusItemFromFocusStackById';
import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement';
import { isStandaloneVariableString } from '@/workflow/utils/isStandaloneVariableString';
import { useTheme } from '@emotion/react';
import { useId, useState } from 'react';
import { useContext, useId, useState } from 'react';
import { Key } from 'ts-key-enum';
import { isDefined } from 'twenty-shared/utils';
import { IconCircleOff } from 'twenty-ui/display';
import { type SelectOption } from 'twenty-ui/input';
import { ThemeContext } from 'twenty-ui/theme';
type FormSelectFieldInputProps = {
label?: string;
@@ -37,7 +37,7 @@ export const FormSelectFieldInput = ({
options,
readonly,
}: FormSelectFieldInputProps) => {
const theme = useTheme();
const { theme } = useContext(ThemeContext);
const instanceId = useId();
@@ -7,15 +7,16 @@ import {
import { VariableChipStandalone } from '@/object-record/record-field/ui/form-types/components/VariableChipStandalone';
import { type ObjectRecord } from '@/object-record/types/ObjectRecord';
import { isStandaloneVariableString } from '@/workflow/utils/isStandaloneVariableString';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledRecordChip = styled(RecordChip)`
margin: ${({ theme }) => theme.spacing(2)};
margin: ${themeCssVariables.spacing[2]};
`;
const StyledPlaceholder = styled(FormFieldPlaceholder)`
margin: ${({ theme }) => theme.spacing(2)};
margin: ${themeCssVariables.spacing[2]};
`;
type FormSingleRecordFieldChipProps = {
@@ -14,13 +14,14 @@ import { GenericDropdownContentWidth } from '@/ui/layout/dropdown/constants/Gene
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
import { useSetAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useSetAtomComponentState';
import { isStandaloneVariableString } from '@/workflow/utils/isStandaloneVariableString';
import { css, useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { isNonEmptyString } from '@sniptt/guards';
import { useCallback, useId } from 'react';
import { useCallback, useContext, useId } from 'react';
import { CustomError, isDefined, isValidUuid } from 'twenty-shared/utils';
import { IconChevronDown, IconForbid } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledFormSelectContainer = styled(FormFieldInputInnerContainer)<{
readonly?: boolean;
@@ -28,18 +29,17 @@ const StyledFormSelectContainer = styled(FormFieldInputInnerContainer)<{
align-items: center;
height: 32px;
justify-content: space-between;
padding-right: ${({ theme }) => theme.spacing(2)};
padding-right: ${themeCssVariables.spacing[2]};
${({ readonly, theme }) =>
!readonly &&
css`
&:hover,
&[data-open='true'] {
background-color: ${theme.background.transparent.light};
}
cursor: ${({ readonly }) => (readonly ? 'default' : 'pointer')};
cursor: pointer;
`}
&:hover,
&[data-open='true'] {
background-color: ${({ readonly }) =>
readonly
? 'transparent'
: themeCssVariables.background.transparent.light};
}
`;
const StyledIconButton = styled.div`
@@ -80,7 +80,7 @@ export const FormSingleRecordPicker = ({
testId,
VariablePicker,
}: FormSingleRecordPickerProps) => {
const theme = useTheme();
const { theme } = useContext(ThemeContext);
const draftValue: FormSingleRecordPickerValue = isStandaloneVariableString(
defaultValue,
)
@@ -143,7 +143,6 @@ export const FormSingleRecordPicker = ({
};
const handleUnlinkVariable = (event?: React.MouseEvent<HTMLDivElement>) => {
// Prevents the dropdown to open when clicking on the chip
event?.stopPropagation();
onClear?.();
};
@@ -1,6 +1,7 @@
import { FORM_FIELD_PLACEHOLDER_STYLES } from '@/object-record/record-field/ui/form-types/constants/FormFieldPlaceholderStyles';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { EditorContent, type Editor } from '@tiptap/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledEditor = styled.div<{
multiline?: boolean;
@@ -9,15 +10,15 @@ const StyledEditor = styled.div<{
width: 100%;
display: flex;
box-sizing: border-box;
padding-right: ${({ multiline, theme }) =>
multiline ? theme.spacing(4) : undefined};
padding-right: ${({ multiline }) =>
multiline ? themeCssVariables.spacing[4] : '0'};
.editor-content {
width: 100%;
}
.tiptap {
padding: ${({ theme }) => `${theme.spacing(1)} ${theme.spacing(2)}`};
padding: ${themeCssVariables.spacing[1]} ${themeCssVariables.spacing[2]};
box-sizing: border-box;
display: flex;
height: 100%;
@@ -27,10 +28,12 @@ const StyledEditor = styled.div<{
&::-webkit-scrollbar {
display: none;
}
color: ${({ theme, readonly }) =>
readonly ? theme.font.color.light : theme.font.color.primary};
font-family: ${({ theme }) => theme.font.family};
font-weight: ${({ theme }) => theme.font.weight.regular};
color: ${({ readonly }) =>
readonly
? themeCssVariables.font.color.light
: themeCssVariables.font.color.primary};
font-family: ${themeCssVariables.font.family};
font-weight: ${themeCssVariables.font.weight.regular};
border: none !important;
align-items: ${({ multiline }) => (multiline ? 'top' : 'center')};
white-space: ${({ multiline }) => (multiline ? 'pre' : 'nowrap')};
@@ -48,17 +51,17 @@ const StyledEditor = styled.div<{
}
.variable-tag {
background-color: ${({ theme }) => theme.color.blue3};
border-radius: ${({ theme }) => theme.border.radius.sm};
color: ${({ theme }) => theme.color.blue};
padding: ${({ theme }) => theme.spacing(1)};
background-color: ${themeCssVariables.color.blue3};
border-radius: ${themeCssVariables.border.radius.sm};
color: ${themeCssVariables.color.blue};
padding: ${themeCssVariables.spacing[1]};
}
.text-tag {
background-color: ${({ theme }) => theme.color.blue3};
border-radius: ${({ theme }) => theme.border.radius.sm};
color: ${({ theme }) => theme.color.blue};
padding: ${({ theme }) => theme.spacing(1)};
background-color: ${themeCssVariables.color.blue3};
border-radius: ${themeCssVariables.border.radius.sm};
color: ${themeCssVariables.color.blue};
padding: ${themeCssVariables.spacing[1]};
}
}
@@ -1,10 +1,11 @@
import { BaseChip } from '@/object-record/record-field/ui/form-types/components/BaseChip';
import { useSearchVariable } from '@/workflow/workflow-variables/hooks/useSearchVariable';
import { useTheme } from '@emotion/react';
import { useLingui } from '@lingui/react/macro';
import { useContext } from 'react';
import { isDefined } from 'twenty-shared/utils';
import { extractRawVariableNamePart } from 'twenty-shared/workflow';
import { IconAlertTriangle } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
type VariableChipProps = {
rawVariableName: string;
@@ -17,7 +18,7 @@ export const VariableChip = ({
onRemove,
isFullRecord = false,
}: VariableChipProps) => {
const theme = useTheme();
const { theme } = useContext(ThemeContext);
const { t } = useLingui();
const { variableLabel, variablePathLabel } = useSearchVariable({
@@ -1,10 +1,11 @@
import { VariableChip } from '@/object-record/record-field/ui/form-types/components/VariableChip';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledContainer = styled.div`
align-items: center;
display: flex;
margin-left: ${({ theme }) => theme.spacing(2)};
margin-left: ${themeCssVariables.spacing[2]};
`;
type VariableChipStandaloneProps = {
@@ -1,27 +1,29 @@
import { type Theme, useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { Trans } from '@lingui/react/macro';
import { useContext } from 'react';
import { IconLock } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledContainer = styled.div<{ theme: Theme }>`
const StyledContainer = styled.div`
align-items: center;
display: inline-flex;
background: ${({ theme }) => theme.background.transparent.light};
color: ${({ theme }) => theme.font.color.tertiary};
font-weight: ${({ theme }) => theme.font.weight.regular};
font-size: ${({ theme }) => theme.font.size.md};
padding: ${({ theme }) => theme.spacing(1)};
gap: ${({ theme }) => theme.spacing(1)};
background: ${themeCssVariables.background.transparent.light};
color: ${themeCssVariables.font.color.tertiary};
font-weight: ${themeCssVariables.font.weight.regular};
font-size: ${themeCssVariables.font.size.md};
padding: ${themeCssVariables.spacing[1]};
gap: ${themeCssVariables.spacing[1]};
border-radius: 4px;
`;
export const ForbiddenFieldDisplay = () => {
const theme = useTheme();
const { theme } = useContext(ThemeContext);
return (
<StyledContainer theme={theme}>
<StyledContainer>
<IconLock size={theme.icon.size.sm} />
<Trans>Not shared</Trans>
</StyledContainer>
@@ -16,14 +16,15 @@ import { getJunctionConfig } from '@/object-record/record-field/ui/utils/junctio
import { hasJunctionConfig } from '@/object-record/record-field/ui/utils/junction/hasJunctionConfig';
import { ExpandableList } from '@/ui/layout/expandable-list/components/ExpandableList';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { isArray } from '@sniptt/guards';
import { isDefined } from 'twenty-shared/utils';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledContainer = styled.div`
align-items: center;
display: flex;
gap: ${({ theme }) => theme.spacing(1)};
gap: ${themeCssVariables.spacing[1]};
justify-content: flex-start;
max-width: 100%;
overflow: hidden;
@@ -1,5 +1,4 @@
import { css } from '@emotion/react';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import {
forwardRef,
useRef,
@@ -8,7 +7,7 @@ import {
} from 'react';
import { useRegisterInputEvents } from '@/object-record/record-field/ui/meta-types/input/hooks/useRegisterInputEvents';
import { TEXT_INPUT_STYLE } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { useCombinedRefs } from '~/hooks/useCombinedRefs';
const StyledInput = styled.input<{
@@ -16,34 +15,39 @@ const StyledInput = styled.input<{
hasError?: boolean;
hasItem: boolean;
}>`
${TEXT_INPUT_STYLE}
background-color: transparent;
border: none;
color: ${themeCssVariables.font.color.primary};
font-family: ${themeCssVariables.font.family};
font-size: inherit;
font-weight: inherit;
outline: none;
padding: ${themeCssVariables.spacing[0]} ${themeCssVariables.spacing[2]};
${({ hasItem, theme }) =>
hasItem &&
css`
background-color: ${theme.background.transparent.lighter};
border-radius: 4px;
border: 1px solid ${theme.border.color.medium};
`}
${({ hasError, hasItem, theme }) =>
hasError &&
hasItem &&
css`
border: 1px solid ${theme.border.color.danger};
`}
&::placeholder,
&::-webkit-input-placeholder {
color: ${themeCssVariables.font.color.light};
font-family: ${themeCssVariables.font.family};
font-weight: ${themeCssVariables.font.weight.medium};
}
background-color: ${({ hasItem }) =>
hasItem ? themeCssVariables.background.transparent.lighter : 'transparent'};
border: ${({ hasItem, hasError }) =>
hasItem
? hasError
? `1px solid ${themeCssVariables.border.color.danger}`
: `1px solid ${themeCssVariables.border.color.medium}`
: 'none'};
border-radius: ${({ hasItem }) => (hasItem ? '4px' : '0')};
box-sizing: border-box;
font-weight: ${({ theme }) => theme.font.weight.medium};
font-weight: ${themeCssVariables.font.weight.medium};
height: 32px;
position: relative;
width: 100%;
${({ withRightComponent }) =>
withRightComponent &&
css`
padding-right: 32px;
`}
padding-right: ${({ withRightComponent }) =>
withRightComponent ? '32px' : '0'};
`;
const StyledInputContainer = styled.div`
@@ -53,20 +57,20 @@ const StyledInputContainer = styled.div`
width: 100%;
&:not(:first-of-type) {
padding: ${({ theme }) => theme.spacing(1)};
padding: ${themeCssVariables.spacing[1]};
}
`;
const StyledRightContainer = styled.div`
position: absolute;
right: ${({ theme }) => theme.spacing(2)};
right: ${themeCssVariables.spacing[2]};
top: 50%;
transform: translateY(-50%);
`;
const StyledErrorDiv = styled.div`
color: ${({ theme }) => theme.color.red};
padding: 0 ${({ theme }) => theme.spacing(2)};
color: ${themeCssVariables.color.red};
padding: 0 ${themeCssVariables.spacing[2]};
`;
type HTMLInputProps = InputHTMLAttributes<HTMLInputElement>;
@@ -4,7 +4,7 @@ import { PhonesFieldMenuItem } from '@/object-record/record-field/ui/meta-types/
import { recordFieldInputIsFieldInErrorComponentState } from '@/object-record/record-field/ui/states/recordFieldInputIsFieldInErrorComponentState';
import { phoneSchema } from '@/object-record/record-field/ui/validation-schemas/phoneSchema';
import { useSetAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useSetAtomComponentState';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { parsePhoneNumber, type E164Number } from 'libphonenumber-js';
import ReactPhoneNumberInput from 'react-phone-number-input';
import 'react-phone-number-input/style.css';
@@ -20,11 +20,10 @@ import {
} from '@/object-record/record-field/ui/types/FieldMetadata';
import { phonesSchema } from '@/object-record/record-field/ui/types/guards/isFieldPhonesValue';
import { PhoneCountryPickerDropdownButton } from '@/ui/input/components/internal/phone/components/PhoneCountryPickerDropdownButton';
import { css } from '@emotion/react';
import { useContext } from 'react';
import { MULTI_ITEM_FIELD_DEFAULT_MAX_VALUES } from 'twenty-shared/constants';
import { isDefined } from 'twenty-shared/utils';
import { TEXT_INPUT_STYLE } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { FieldMetadataType } from '~/generated-metadata/graphql';
import { stripSimpleQuotesFromString } from '~/utils/string/stripSimpleQuotesFromString';
@@ -32,39 +31,47 @@ const StyledCustomPhoneInputContainer = styled.div<{
hasItem: boolean;
hasError?: boolean;
}>`
${({ hasItem, theme }) =>
hasItem &&
css`
background-color: ${theme.background.transparent.lighter};
border-radius: 4px;
border: 1px solid ${theme.border.color.medium};
height: 30px;
`}
${({ hasError, hasItem, theme }) =>
hasError &&
hasItem &&
css`
border: 1px solid ${theme.border.color.danger};
`}
background-color: ${({ hasItem }) =>
hasItem ? themeCssVariables.background.transparent.lighter : 'transparent'};
border: ${({ hasItem, hasError }) =>
hasItem
? hasError
? `1px solid ${themeCssVariables.border.color.danger}`
: `1px solid ${themeCssVariables.border.color.medium}`
: 'none'};
border-radius: ${({ hasItem }) => (hasItem ? '4px' : '0')};
height: ${({ hasItem }) => (hasItem ? '30px' : 'auto')};
`;
const StyledCustomPhoneInput = styled(ReactPhoneNumberInput)`
${TEXT_INPUT_STYLE}
background-color: transparent;
border: none;
color: ${themeCssVariables.font.color.primary};
font-family: ${themeCssVariables.font.family};
font-size: inherit;
font-weight: inherit;
outline: none;
padding: 0;
&::placeholder,
&::-webkit-input-placeholder {
color: ${themeCssVariables.font.color.light};
font-family: ${themeCssVariables.font.family};
font-weight: ${themeCssVariables.font.weight.medium};
}
height: 100%;
.PhoneInputInput {
background: none;
border: none;
color: ${({ theme }) => theme.font.color.primary};
margin-left: ${({ theme }) => theme.spacing(2)};
color: ${themeCssVariables.font.color.primary};
margin-left: ${themeCssVariables.spacing[2]};
&::placeholder,
&::-webkit-input-placeholder {
color: ${({ theme }) => theme.font.color.light};
font-family: ${({ theme }) => theme.font.family};
font-weight: ${({ theme }) => theme.font.weight.medium};
color: ${themeCssVariables.font.color.light};
font-family: ${themeCssVariables.font.family};
font-weight: ${themeCssVariables.font.weight.medium};
}
:focus {
@@ -73,10 +80,10 @@ const StyledCustomPhoneInput = styled(ReactPhoneNumberInput)`
}
& svg {
border-radius: ${({ theme }) => theme.border.radius.xs};
border-radius: ${themeCssVariables.border.radius.xs};
height: 12px;
}
width: calc(100% - ${({ theme }) => theme.spacing(8)});
width: calc(100% - ${themeCssVariables.spacing[8]});
`;
export const PhonesFieldInput = () => {
@@ -1,4 +1,4 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { FieldInputEventContext } from '@/object-record/record-field/ui/contexts/FieldInputEventContext';
import { RecordFieldComponentInstanceContext } from '@/object-record/record-field/ui/states/contexts/RecordFieldComponentInstanceContext';
@@ -12,6 +12,7 @@ import { Key } from 'ts-key-enum';
import { IconPencil } from 'twenty-ui/display';
import { CodeEditor, FloatingIconButton } from 'twenty-ui/input';
import { JsonTree, isTwoFirstDepths } from 'twenty-ui/json-visualizer';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { useCopyToClipboard } from '~/hooks/useCopyToClipboard';
import { useJsonField } from '@/object-record/record-field/ui/meta-types/hooks/useJsonField';
@@ -27,16 +28,16 @@ const StyledContainer = styled.div`
const StyledSwitchModeButtonContainer = styled.div`
position: fixed;
top: ${({ theme }) => theme.spacing(1)};
right: ${({ theme }) => theme.spacing(1)};
top: ${themeCssVariables.spacing[1]};
right: ${themeCssVariables.spacing[1]};
`;
const StyledCodeEditorContainer = styled.div`
padding: ${({ theme }) => theme.spacing(1)};
padding: ${themeCssVariables.spacing[1]};
`;
const StyledJsonTreeContainer = styled.div`
padding: ${({ theme }) => theme.spacing(2)};
padding: ${themeCssVariables.spacing[2]};
width: min-content;
`;
@@ -9,12 +9,13 @@ import { FieldInputEventContext } from '@/object-record/record-field/ui/contexts
import { type FieldRichTextV2Metadata } from '@/object-record/record-field/ui/types/FieldMetadata';
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { Suspense, lazy, useContext, useRef } from 'react';
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import { IconLayoutSidebarLeftCollapse } from 'twenty-ui/display';
import { FloatingIconButton } from 'twenty-ui/input';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const ActivityRichTextEditor = lazy(() =>
import('@/activities/components/ActivityRichTextEditor').then((module) => ({
@@ -23,25 +24,25 @@ const ActivityRichTextEditor = lazy(() =>
);
const StyledContainer = styled.div`
background-color: ${({ theme }) => theme.background.primary};
background-color: ${themeCssVariables.background.primary};
width: 480px;
padding: ${({ theme }) => theme.spacing(2)} ${({ theme }) => theme.spacing(2)}
${({ theme }) => theme.spacing(2)} ${({ theme }) => theme.spacing(12)};
margin: 0 0 0 ${({ theme }) => theme.spacing(-5)};
padding: ${themeCssVariables.spacing[2]} ${themeCssVariables.spacing[2]}
${themeCssVariables.spacing[2]} ${themeCssVariables.spacing[12]};
margin: 0 0 0 calc(-1 * ${themeCssVariables.spacing[5]});
display: flex;
box-sizing: border-box;
position: relative;
`;
const StyledCollapseButton = styled.div`
border-radius: ${({ theme }) => theme.border.radius.md};
color: ${({ theme }) => theme.font.color.light};
border-radius: ${themeCssVariables.border.radius.md};
color: ${themeCssVariables.font.color.light};
cursor: pointer;
display: flex;
`;
const LoadingSkeleton = () => {
const theme = useTheme();
const { theme } = useContext(ThemeContext);
return (
<SkeletonTheme
@@ -1,4 +1,5 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ObjectOptionsDropdown } from '@/object-record/object-options-dropdown/components/ObjectOptionsDropdown';
import { RecordBoardContainer } from '@/object-record/record-board/components/RecordBoardContainer';
@@ -27,8 +28,8 @@ const StyledContainer = styled.div`
const StyledContainerWithPadding = styled.div`
box-sizing: border-box;
height: calc(100% - ${({ theme }) => theme.spacing(10)});
margin-left: ${({ theme }) => theme.spacing(2)};
height: calc(100% - ${themeCssVariables.spacing[10]});
margin-left: ${themeCssVariables.spacing[2]};
`;
export const RecordIndexContainer = () => {
@@ -17,7 +17,7 @@ import { useRecordIndexIdFromCurrentContextStore } from '@/object-record/record-
import { RECORD_INDEX_DRAG_SELECT_BOUNDARY_CLASS } from '@/ui/utilities/drag-select/constants/RecordIndecDragSelectBoundaryClass';
import { PageTitle } from '@/ui/utilities/page-title/components/PageTitle';
import { ViewComponentInstanceContext } from '@/views/states/contexts/ViewComponentInstanceContext';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { useCallback } from 'react';
import { NotFound } from '~/pages/not-found/NotFound';
import { useStore } from 'jotai';
@@ -8,24 +8,25 @@ import { useRecordIndexContextOrThrow } from '@/object-record/record-index/conte
import { PageHeaderToggleCommandMenuButton } from '@/ui/layout/page-header/components/PageHeaderToggleCommandMenuButton';
import { PageHeader } from '@/ui/layout/page/components/PageHeader';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { t } from '@lingui/core/macro';
import { isDefined } from 'twenty-shared/utils';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledTitleWithSelectedRecords = styled.div`
display: flex;
flex-direction: row;
gap: ${({ theme }) => theme.spacing(1)};
gap: ${themeCssVariables.spacing[1]};
`;
const StyledTitle = styled.div`
color: ${({ theme }) => theme.font.color.primary};
padding-right: ${({ theme }) => theme.spacing(0.5)};
color: ${themeCssVariables.font.color.primary};
padding-right: ${themeCssVariables.spacing['0.5']};
`;
const StyledSelectedRecordsCount = styled.div`
color: ${({ theme }) => theme.font.color.tertiary};
padding-left: ${({ theme }) => theme.spacing(0.5)};
color: ${themeCssVariables.font.color.tertiary};
padding-left: ${themeCssVariables.spacing['0.5']};
`;
export const RecordIndexPageHeader = () => {
@@ -1,4 +1,5 @@
import { isNonEmptyString } from '@sniptt/guards';
import { useContext } from 'react';
import { NavigationMenuItemStyleIcon } from '@/navigation-menu-item/components/NavigationMenuItemStyleIcon';
import { usePrefetchedNavigationMenuItemsData } from '@/navigation-menu-item/hooks/usePrefetchedNavigationMenuItemsData';
@@ -7,9 +8,9 @@ import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataI
import { useAtomFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilySelectorValue';
import { coreIndexViewIdFromObjectMetadataItemFamilySelector } from '@/views/states/selectors/coreIndexViewIdFromObjectMetadataItemFamilySelector';
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
import { useTheme } from '@emotion/react';
import { isDefined } from 'twenty-shared/utils';
import { useIcons } from 'twenty-ui/display';
import { ThemeContext } from 'twenty-ui/theme';
import { FeatureFlagKey } from '~/generated-metadata/graphql';
export const RecordIndexPageHeaderIcon = ({
@@ -17,7 +18,7 @@ export const RecordIndexPageHeaderIcon = ({
}: {
objectMetadataItem?: ObjectMetadataItem;
}) => {
const theme = useTheme();
const { theme } = useContext(ThemeContext);
const isNavigationMenuItemEditingEnabled = useIsFeatureEnabled(
FeatureFlagKey.IS_NAVIGATION_MENU_ITEM_EDITING_ENABLED,
);
@@ -1,7 +1,7 @@
import { recordGroupDefinitionFamilyState } from '@/object-record/record-group/states/recordGroupDefinitionFamilyState';
import { RecordGroupDefinitionType } from '@/object-record/record-group/types/RecordGroupDefinition';
import { useAtomFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilyStateValue';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { isDefined } from 'twenty-shared/utils';
import { MenuItem } from 'twenty-ui/navigation';
import { Tag } from 'twenty-ui/components';
@@ -1,6 +1,7 @@
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { useContext } from 'react';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { FieldContext } from '@/object-record/record-field/ui/contexts/FieldContext';
import { useFieldFocus } from '@/object-record/record-field/ui/hooks/useFieldFocus';
@@ -19,7 +20,7 @@ import { useRecordInlineCellContext } from './RecordInlineCellContext';
const StyledIconContainer = styled.div`
align-items: center;
color: ${({ theme }) => theme.font.color.tertiary};
color: ${themeCssVariables.font.color.tertiary};
display: flex;
width: 16px;
@@ -35,9 +36,9 @@ const StyledIconContainer = styled.div`
const StyledLabelAndIconContainer = styled.div`
align-items: center;
align-self: flex-start;
color: ${({ theme }) => theme.font.color.tertiary};
color: ${themeCssVariables.font.color.tertiary};
display: flex;
gap: ${({ theme }) => theme.spacing(1)};
gap: ${themeCssVariables.spacing[1]};
height: 24px;
`;
@@ -49,9 +50,9 @@ const StyledValueContainer = styled.div<{ readonly: boolean }>`
`;
const StyledLabelContainer = styled.div<{ width?: number }>`
color: ${({ theme }) => theme.font.color.tertiary};
font-size: ${({ theme }) => theme.font.size.sm};
width: ${({ width }) => width}px;
color: ${themeCssVariables.font.color.tertiary};
font-size: ${themeCssVariables.font.size.sm};
width: ${({ width }) => (width !== undefined ? `${width}px` : 'auto')};
`;
const StyledInlineCellBaseContainer = styled.div<{ readonly: boolean }>`
@@ -59,7 +60,7 @@ const StyledInlineCellBaseContainer = styled.div<{ readonly: boolean }>`
width: 100%;
display: flex;
height: fit-content;
gap: ${({ theme }) => theme.spacing(1)};
gap: ${themeCssVariables.spacing[1]};
user-select: none;
align-items: center;
cursor: ${({ readonly }) => (readonly ? 'default' : 'pointer')};
@@ -96,7 +97,7 @@ export const RecordInlineCellContainer = () => {
onMouseLeave?.();
};
const theme = useTheme();
const { theme } = useContext(ThemeContext);
const labelId = `label-${getRecordFieldInputInstanceId({
recordId,
fieldName: fieldDefinition?.metadata?.fieldName,
@@ -1,4 +1,4 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { FieldContext } from '@/object-record/record-field/ui/contexts/FieldContext';
import { useIsFieldEmpty } from '@/object-record/record-field/ui/hooks/useIsFieldEmpty';
@@ -8,9 +8,9 @@ import {
type RecordInlineCellContextProps,
} from '@/object-record/record-inline-cell/components/RecordInlineCellContext';
import { RecordInlineCellButton } from '@/object-record/record-inline-cell/components/RecordInlineCellEditButton';
import { css } from '@emotion/react';
import { useLingui } from '@lingui/react/macro';
import { useContext } from 'react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledRecordInlineCellNormalModeOuterContainer = styled.div<
Pick<
@@ -19,34 +19,31 @@ const StyledRecordInlineCellNormalModeOuterContainer = styled.div<
> & { isHovered?: boolean }
>`
outline: 1px solid
${({ theme, isHovered, readonly }) =>
isHovered && readonly ? theme.border.color.medium : 'transparent'};
${({ isHovered, readonly }) =>
isHovered && readonly
? themeCssVariables.border.color.medium
: 'transparent'};
align-items: center;
border-radius: ${({ theme }) => theme.border.radius.sm};
border-radius: ${themeCssVariables.border.radius.sm};
display: flex;
height: ${({ isDisplayModeFixHeight }) =>
isDisplayModeFixHeight ? '16px' : 'auto'};
min-height: 16px;
overflow: hidden;
padding-right: ${({ theme }) => theme.spacing(1)};
padding-left: ${({ theme }) => theme.spacing(1)};
${(props) => {
if (props.isHovered === true && !props.readonly) {
return css`
background-color: ${!props.disableHoverEffect
? props.theme.background.transparent.light
: 'transparent'};
cursor: pointer;
`;
}
}}
padding-right: ${themeCssVariables.spacing[1]};
padding-left: ${themeCssVariables.spacing[1]};
background-color: ${({ isHovered, readonly, disableHoverEffect }) =>
isHovered && !readonly && !disableHoverEffect
? themeCssVariables.background.transparent.light
: 'transparent'};
cursor: ${({ isHovered, readonly }) =>
isHovered && !readonly ? 'pointer' : 'default'};
`;
const StyledRecordInlineCellNormalModeInnerContainer = styled.div`
align-content: center;
align-items: center;
color: ${({ theme }) => theme.font.color.primary};
color: ${themeCssVariables.font.color.primary};
height: fit-content;
overflow: hidden;
@@ -59,7 +56,7 @@ const StyledRecordInlineCellNormalModeInnerContainer = styled.div`
const StyledEmptyField = styled.div`
align-items: center;
color: ${({ theme }) => theme.font.color.light};
color: ${themeCssVariables.font.color.light};
display: flex;
height: 20px;
`;
@@ -1,4 +1,4 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { type IconComponent } from 'twenty-ui/display';
import { FloatingIconButton } from 'twenty-ui/input';
import { AnimatedContainer } from 'twenty-ui/utilities';
@@ -7,7 +7,7 @@ import { OverlayContainer } from '@/ui/layout/overlay/components/OverlayContaine
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
import { useSetAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useSetAtomComponentState';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import {
autoUpdate,
flip,
@@ -1,4 +1,4 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
const StyledRecordTableCellHoveredPortal = styled.div`
height: 100%;
@@ -1,5 +1,6 @@
import { RecordInlineCellHoveredPortal } from '@/object-record/record-inline-cell/components/RecordInlineCellHoveredPortal';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledRecordTableCellHoveredPortalContent = styled.div<{
readonly?: boolean;
@@ -7,14 +8,11 @@ const StyledRecordTableCellHoveredPortalContent = styled.div<{
}>`
align-items: center;
display: flex;
gap: ${({ theme }) => theme.spacing(1)};
gap: ${themeCssVariables.spacing[1]};
width: 100%;
${({ isCentered }) =>
isCentered === true &&
`
justify-content: center;
`};
justify-content: ${({ isCentered }) =>
isCentered === true ? 'center' : 'normal'};
`;
const StyledInlineCellBaseContainer = styled.div<{ readonly: boolean }>`
@@ -22,7 +20,7 @@ const StyledInlineCellBaseContainer = styled.div<{ readonly: boolean }>`
width: 100%;
display: flex;
height: fit-content;
gap: ${({ theme }) => theme.spacing(1)};
gap: ${themeCssVariables.spacing[1]};
user-select: none;
align-items: center;
`;
@@ -1,11 +1,12 @@
import { useTheme } from '@emotion/react';
import { useContext } from 'react';
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import { ThemeContext } from 'twenty-ui/theme';
import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader';
import { StyledSkeletonDiv } from './RecordInlineCellContainer';
export const RecordInlineCellSkeletonLoader = () => {
const theme = useTheme();
const { theme } = useContext(ThemeContext);
return (
<SkeletonTheme
@@ -1,11 +1,11 @@
import { css } from '@emotion/react';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { FieldDisplay } from '@/object-record/record-field/ui/components/FieldDisplay';
import { useFieldFocus } from '@/object-record/record-field/ui/hooks/useFieldFocus';
import { useRecordInlineCellContext } from '@/object-record/record-inline-cell/components/RecordInlineCellContext';
import { RecordInlineCellDisplayMode } from '@/object-record/record-inline-cell/components/RecordInlineCellDisplayMode';
import { RecordInlineCellSkeletonLoader } from '@/object-record/record-inline-cell/components/RecordInlineCellSkeletonLoader';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledClickableContainer = styled.div<{
readonly?: boolean;
@@ -13,20 +13,12 @@ const StyledClickableContainer = styled.div<{
}>`
align-items: center;
display: flex;
gap: ${({ theme }) => theme.spacing(1)};
gap: ${themeCssVariables.spacing[1]};
width: 100%;
${({ isCentered }) =>
isCentered === true &&
`
justify-content: center;
`};
${({ readonly }) =>
!readonly &&
css`
cursor: pointer;
`};
justify-content: ${({ isCentered }) =>
isCentered === true ? 'center' : 'normal'};
cursor: ${({ readonly }) => (readonly ? 'default' : 'pointer')};
`;
export const RecordInlineCellValue = () => {
@@ -1,6 +1,6 @@
import { useLayoutRenderingContext } from '@/ui/layout/contexts/LayoutRenderingContext';
import isPropValid from '@emotion/is-prop-valid';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { PageLayoutType } from '~/generated-metadata/graphql';
interface PropertyBoxProps {
@@ -9,21 +9,20 @@ interface PropertyBoxProps {
dataTestId?: string;
}
const StyledPropertyBoxContainer = styled('div', {
shouldForwardProp: (prop) =>
isPropValid(prop) && prop !== 'noHorizontalPadding',
})<{ noHorizontalPadding?: boolean }>`
const StyledPropertyBoxContainer = styled.div<{
noHorizontalPadding?: boolean;
}>`
align-self: stretch;
border-radius: ${({ theme }) => theme.border.radius.sm};
border-radius: ${themeCssVariables.border.radius.sm};
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(2)};
padding-top: ${({ theme }) => theme.spacing(3)};
padding-bottom: ${({ theme }) => theme.spacing(3)};
padding-left: ${({ theme, noHorizontalPadding }) =>
noHorizontalPadding ? 0 : theme.spacing(3)};
padding-right: ${({ theme, noHorizontalPadding }) =>
noHorizontalPadding ? 0 : theme.spacing(2)};
gap: ${themeCssVariables.spacing[2]};
padding-top: ${themeCssVariables.spacing[3]};
padding-bottom: ${themeCssVariables.spacing[3]};
padding-left: ${({ noHorizontalPadding }) =>
noHorizontalPadding ? 0 : themeCssVariables.spacing[3]};
padding-right: ${({ noHorizontalPadding }) =>
noHorizontalPadding ? 0 : themeCssVariables.spacing[2]};
`;
export const PropertyBox = ({
@@ -1,17 +1,19 @@
import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLoader';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { useContext } from 'react';
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import { ThemeContext } from 'twenty-ui/theme';
import { themeCssVariables } from 'twenty-ui/theme-constants';
const StyledSkeletonDiv = styled.div`
align-items: center;
display: flex;
gap: ${({ theme }) => theme.spacing(1)};
gap: ${themeCssVariables.spacing[1]};
width: 100%;
height: 24px;
`;
export const PropertyBoxSkeletonLoader = () => {
const theme = useTheme();
const { theme } = useContext(ThemeContext);
const skeletonItems = Array.from({ length: 4 }).map((_, index) => ({
id: `skeleton-item-${index}`,
}));
@@ -1,4 +1,5 @@
import styled from '@emotion/styled';
import { styled } from '@linaria/react';
import { themeCssVariables } from 'twenty-ui/theme-constants';
import { ShowPageContainer } from '@/ui/layout/page/components/ShowPageContainer';
import { RightDrawerProvider } from '@/ui/layout/right-drawer/contexts/RightDrawerContext';
@@ -27,15 +28,15 @@ const StyledShowPageRightContainer = styled.div`
`;
const StyledTabList = styled(TabList)`
background-color: ${({ theme }) => theme.background.secondary};
padding-left: ${({ theme }) => theme.spacing(2)};
background-color: ${themeCssVariables.background.secondary};
padding-left: ${themeCssVariables.spacing[2]};
`;
const StyledContentContainer = styled.div`
flex: 1;
overflow-y: auto;
background: ${({ theme }) => theme.background.primary};
padding-bottom: ${({ theme }) => theme.spacing(16)};
background: ${themeCssVariables.background.primary};
padding-bottom: ${themeCssVariables.spacing[16]};
`;
type MergeRecordsContainerProps = {

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