diff --git a/CLAUDE.md b/CLAUDE.md index 55b0f18119..070905e9e8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -90,7 +90,7 @@ npx nx run twenty-front:graphql:generate --configuration=metadata ## Architecture Overview ### Tech Stack -- **Frontend**: React 18, TypeScript, Jotai (state management), Emotion (styling), Vite +- **Frontend**: React 18, TypeScript, Jotai (state management), Linaria (styling), Vite - **Backend**: NestJS, TypeORM, PostgreSQL, Redis, GraphQL (with GraphQL Yoga) - **Monorepo**: Nx workspace managed with Yarn 4 @@ -175,7 +175,7 @@ IMPORTANT: Use Context7 for code generation, setup or configuration steps, or li 5. Run `graphql:generate` after any GraphQL schema changes ### Code Style Notes -- Use **Emotion** for styling with styled-components pattern +- Use **Linaria** for styling with zero-runtime CSS-in-JS (styled-components pattern) - Follow **Nx** workspace conventions for imports - Use **Lingui** for internationalization - Apply security first, then formatting (sanitize before format) diff --git a/README.md b/README.md index 9e3210454f..8f3f02bada 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,7 @@ Below are a few features we have implemented to date: - [TypeScript](https://www.typescriptlang.org/) - [Nx](https://nx.dev/) - [NestJS](https://nestjs.com/), with [BullMQ](https://bullmq.io/), [PostgreSQL](https://www.postgresql.org/), [Redis](https://redis.io/) -- [React](https://reactjs.org/), with [Jotai](https://jotai.org/), [Emotion](https://emotion.sh/) and [Lingui](https://lingui.dev/) +- [React](https://reactjs.org/), with [Jotai](https://jotai.org/), [Linaria](https://linaria.dev/) and [Lingui](https://lingui.dev/) diff --git a/docs/emotion-to-linaria-migration-plan.md b/docs/emotion-to-linaria-migration-plan.md deleted file mode 100644 index fa210863a8..0000000000 --- a/docs/emotion-to-linaria-migration-plan.md +++ /dev/null @@ -1,423 +0,0 @@ -# Emotion → Linaria Migration Plan: twenty-front - -## Overview - -Migrate all Emotion (`@emotion/styled`, `@emotion/react`) usages in -`packages/twenty-front/src` to Linaria (`@linaria/react`, `@linaria/core`), -following the same patterns already established in the `twenty-ui` package. - -Linaria is a **zero-runtime** CSS-in-JS library. Styles are extracted at -build time by [wyw-in-js](https://wyw-in-js.dev/) (the Vite plugin is -`@wyw-in-js/vite`, already configured in `twenty-front/vite.config.ts`). -This means every expression inside a `styled` or `css` template literal -must be statically evaluable at build time — no runtime theme objects, -no closures over component state, no side-effects. - -**Total files to migrate: ~998** - -| Category | Files | Description | -|---|---|---| -| styled-only | 694 | Import `@emotion/styled` but not `useTheme` | -| styled + useTheme | 224 | Import both `@emotion/styled` and `useTheme` | -| useTheme-only | 79 | Import `useTheme` but not `@emotion/styled` | -| css / Global only | 1 | Import `css` or `Global` from `@emotion/react` only | - -## Theme Architecture - -Two build-time utilities produce the theme system: - -- **`buildThemeReferencingRootCssVariables`** — walks the theme object and - builds a nested mirror where every leaf is a `var(--t-xxx)` string - (evaluated at build time by wyw-in-js) -- **`prepareThemeForRootCssVariableInjection`** — walks the runtime theme - and collects flat `[--css-variable-name, value]` pairs, injected onto - `document.documentElement` by `ThemeCssVariableInjectorEffect` - -`themeCssVariables` is the build-time object; every leaf resolves to a CSS -`var()` reference. It is safe to use inside `styled` and `css` templates -because wyw-in-js can evaluate it statically. - -## Migration Patterns - -### 1. `styled` import - -```diff -- import styled from '@emotion/styled'; -+ import { styled } from '@linaria/react'; -``` - -### 2. Theme access in styled components - -Replace Emotion's `({ theme }) =>` prop-function pattern with static -`themeCssVariables` references: - -```diff -+ import { themeCssVariables } from 'twenty-ui/theme'; - - const StyledTitle = styled.span` -- color: ${({ theme }) => theme.font.color.primary}; -- font-size: ${({ theme }) => theme.font.size.lg}; -+ color: ${themeCssVariables.font.color.primary}; -+ font-size: ${themeCssVariables.font.size.lg}; - `; -``` - -### 3. Spacing - -`theme.spacing(N)` is a function; in Linaria it becomes an indexed lookup: - -```diff -- margin-top: ${({ theme }) => theme.spacing(3)}; -+ margin-top: ${themeCssVariables.spacing[3]}; -``` - -For multi-arg spacing like `theme.spacing(2, 4)` → `"8px 16px"`: - -```diff -- padding: ${({ theme }) => theme.spacing(2, 4)}; -+ padding: ${themeCssVariables.spacing[2]} ${themeCssVariables.spacing[4]}; -``` - -The spacing scale covers integers 0–32 plus `0.5` and `1.5`. Any other -fractional values (`0.25`, `0.75`, `1.25`, `2.5`, `3.5`) must be replaced -with literal pixel values (e.g. `theme.spacing(2.5)` → `10px`). - -### 4. `useTheme` → `useContext(ThemeContext)` - -For runtime theme access (icon sizes, animation durations, conditional logic -outside of styled components): - -```diff -- import { useTheme } from '@emotion/react'; -+ import { useContext } from 'react'; -+ import { ThemeContext } from 'twenty-ui/theme'; - - const MyComponent = () => { -- const theme = useTheme(); -+ const { theme } = useContext(ThemeContext); - return ; - }; -``` - -### 5. `css` template literal - -Linaria's `css` (from `@linaria/core`) returns a **class name string**, not -a serialized style object like Emotion's `css`. This has two consequences: - -**Standalone usage** — apply via `className`, not the `css` prop: - -```diff -- import { css } from '@emotion/react'; -+ import { css } from '@linaria/core'; - - const myClass = css` - text-decoration: none; - `; - -- -+ -``` - -**Inside `styled` templates** — do NOT nest `css` tags. Linaria's `css` -returns a class name, not raw CSS text, so interpolating it inside `styled` -produces broken output. Use plain strings instead: - -```diff - // WRONG — css`` returns a class name, not CSS text - ${({ handle }) => - handle === 'left' -- ? css`left: ${themeCssVariables.spacing[1]};` -- : css`right: ${themeCssVariables.spacing[1]};`} -+ ? `left: ${themeCssVariables.spacing[1]};` -+ : `right: ${themeCssVariables.spacing[1]};`} -``` - -### 6. Interpolation return types - -wyw-in-js requires prop interpolation functions to return `string | number`. -They must **never** return `false`, `undefined`, or `null`. Replace -short-circuit `&&` with ternary expressions: - -```diff - // WRONG — returns false when condition is false -- ${({ isActive }) => isActive && `background: ${themeCssVariables.color.blue};`} - // CORRECT -+ ${({ isActive }) => isActive ? `background: ${themeCssVariables.color.blue};` : ''} -``` - -### 7. Block interpolations (multi-declaration returns) - -Linaria wraps each interpolation result in a single CSS custom property -(`var(--xxx)`). An interpolation that returns **multiple CSS declarations** -produces invalid CSS. Split into one interpolation per property: - -```diff - // WRONG — single interpolation returning multiple declarations -- ${({ divider, theme }) => { -- const border = `1px solid ${theme.border.color.light}`; -- return divider === 'left' ? `border-left: ${border}` : `border-right: ${border}`; -- }} - - // CORRECT — one interpolation per property -+ border-left: ${({ divider }) => -+ divider === 'left' ? `1px solid ${themeCssVariables.border.color.light}` : 'none'}; -+ border-right: ${({ divider }) => -+ divider === 'right' ? `1px solid ${themeCssVariables.border.color.light}` : 'none'}; -``` - -### 8. CSS var + unit concatenation - -CSS custom properties can't be concatenated with unit suffixes directly -(`var(--x)px` is invalid). Use `calc()` to attach units: - -```diff -- transition: background ${themeCssVariables.animation.duration.instant}s ease; -+ transition: background calc(${themeCssVariables.animation.duration.instant} * 1s) ease; -``` - -### 9. `styled(Component)` requires `className` - -Linaria's `styled(Component)` works by passing a generated `className` to -the wrapped component. The component **must** accept and forward a -`className` prop — otherwise the styles are silently lost. If the component -doesn't support it, either add `className` support or use a wrapper div. - -Linaria also does **not** support Emotion's `shouldForwardProp` option. -Custom props on HTML elements are automatically filtered by Linaria's -runtime (via `@emotion/is-prop-valid`). For custom components, all props are -forwarded — ensure the wrapped component ignores unknown props gracefully. - -### 10. `type Theme` → `type ThemeType` - -```diff -- import { type Theme } from '@emotion/react'; -+ import { type ThemeType } from 'twenty-ui/theme'; -``` - -### 11. Framer Motion integration - -Linaria doesn't support `styled(motion.div)` — wrapping a motion element -with `styled()` causes the component body to be stripped at build time by -wyw-in-js. Define the styled component first, then wrap with -`motion.create()`: - -```tsx -const StyledBarBase = styled.div` - background-color: ${themeCssVariables.font.color.primary}; - height: 100%; -`; - -const StyledBar = motion.create(StyledBarBase); -``` - -### 12. Dynamic styles via CSS variables - -When a component needs to compute styles from multiple props with complex -branching logic (e.g. combining `variant`, `accent`, `disabled`, `focus`), -Linaria's prop interpolations become unwieldy. Use a `computeDynamicStyles` -helper that returns a `CSSProperties` object injected via `style={}`, -referenced from the static CSS with `var()`: - -```tsx -const StyledButton = styled.button` - background: var(--btn-bg); - border-color: var(--btn-border-color); - &:hover { background: var(--btn-hover-bg); } -`; - -const dynamicStyles = useMemo(() => { - const s = computeButtonDynamicStyles(variant, accent, ...); - return { - '--btn-bg': s.background, - '--btn-hover-bg': s.hoverBackground, - } as CSSProperties; -}, [variant, accent, ...]); - -return ; -``` - -### 13. `Global` component - -Replace Emotion's `` with standard CSS or the -`ThemeCssVariableInjectorEffect` pattern from twenty-ui. - -### 14. `ThemeProvider` - -The `BaseThemeProvider` already wraps children with both Emotion's -`ThemeProvider` and Linaria's `ThemeContextProvider`. Once all Emotion usages -are gone, the Emotion `ThemeProvider` wrapper can be removed. - ---- - -## PR Breakdown - -Files are grouped to keep each PR around ~100 files with consistent review -surface. We start with the simplest, lowest-risk modules. - -### PR 1 (~97 files) — Small standalone modules - -Low-risk modules with mostly simple `styled`-only patterns. - -| Module | Files | -|---|---| -| spreadsheet-import | 28 | -| billing | 10 | -| views | 14 | -| navigation-menu-item | 14 | -| blocknote-editor | 7 | -| advanced-text-editor | 7 | -| favorites | 7 | -| navigation | 4 | -| information-banner | 3 | -| sign-in-background-mock | 3 | - -### PR 2 (~100 files) — Auth, tiny modules, loading, testing, pages (part 1) - -| Module | Files | -|---|---| -| auth | 19 | -| action-menu | 3 | -| object-metadata | 3 | -| onboarding | 2 | -| workspace | 2 | -| file | 2 | -| error-handler | 2 | -| front-components | 1 | -| geo-map | 1 | -| hooks | 1 | -| loading | 5 | -| testing | 5 | -| pages (first ~55 files) | ~55 | - -### PR 3 (~97 files) — Pages (remaining) + activities + AI - -| Module | Files | -|---|---| -| pages (remaining ~16 files) | ~16 | -| activities | 53 | -| ai | 28 | - -### PR 4 (~100 files) — Command-menu + workflow (part 1) - -| Module | Files | -|---|---| -| command-menu | 53 | -| workflow (first ~47 files) | ~47 | - -### PR 5 (~115 files) — Workflow (remaining) + page-layout - -| Module | Files | -|---|---| -| workflow (remaining ~32 files) | ~32 | -| page-layout | 83 | - -### PR 6 (~100 files) — UI module (part 1) - -| Module | Files | -|---|---| -| ui (first ~100 files) | ~100 | - -### PR 7 (~85 files) — UI module (remaining) + object-record (start) - -| Module | Files | -|---|---| -| ui (remaining ~23 files) | ~23 | -| object-record (first ~62 files) | ~62 | - -### PR 8 (~100 files) — Object-record (continued) - -| Module | Files | -|---|---| -| object-record (next ~100 files) | ~100 | - -### PR 9 (~100 files) — Settings (part 1) - -| Module | Files | -|---|---| -| settings (first ~100 files) | ~100 | - -### PR 10 (~102 files) — Settings (part 2) + final cleanup - -| Module | Files | -|---|---| -| settings (remaining ~102 files) | ~102 | -| css/Global-only file | 1 | - -### Post-migration PR — Remove Emotion - -Once all PRs are merged: - -- Remove `ThemeProvider` from `@emotion/react` in `BaseThemeProvider` -- Remove `@emotion/styled` and `@emotion/react` dependencies -- Remove `@styled/typescript-styled-plugin` from tsconfig -- Clean up any remaining Emotion-related configuration - ---- - -## Risk Assessment - -| Risk | Mitigation | -|---|---| -| wyw-in-js evaluates at build time; dynamic expressions may fail | Use `themeCssVariables` for static theme values; pass dynamic values as component props or via `style={}` CSS variables | -| `theme.spacing(N)` function → `themeCssVariables.spacing[N]` index | Pre-computed for integers 0–32 plus 0.5 and 1.5; other fractional values → literal pixel values | -| `useTheme` used for runtime logic (not just styles) | Replace with `useContext(ThemeContext)`, destructure `{ theme }` | -| Multi-arg `theme.spacing(a, b, c)` | Split into individual `themeCssVariables.spacing[N]` references | -| `css` tag inside `styled` templates | Linaria `css` returns class name, not CSS text; use plain strings inside `styled` | -| Interpolation returns `false` / `undefined` | wyw-in-js requires `string \| number`; use ternary `? : ''` instead of `&&` | -| Block interpolations (multiple declarations) | Split into one interpolation per CSS property | -| `var(--x)px` concatenation | Use `calc(var(--x) * 1px)` | -| `styled(motion.div)` stripped by wyw-in-js | Use `motion.create(StyledBase)` pattern | -| `styled(Component)` with no `className` prop | Add `className` support to wrapped component or use wrapper div | -| Complex multi-prop style branching | Use `computeDynamicStyles` + `style={}` + `var()` references | - ---- - -## Known Issues & TODOs - -### `styled(Component)` from `twenty-ui` — style overrides silently dropped - -When `twenty-front` uses `styled(SomeComponent)` to extend a pre-built -component from `twenty-ui` (e.g. `Card`, `CardContent`, `PropertyBox`, -`Chip`, `Pill`, `Avatar`, `StyledHoverableMenuItemBase`, `MenuItemLeftContent`, -`TabList`, `NavigationDrawerSection`), the style overrides are silently -ignored at runtime. This happens because `wyw-in-js` in `twenty-front` -cannot resolve the base class name of a component that was already compiled -in another package. - -**Current workaround:** Replace `styled(Component)` with a plain -`styled.div` (or wrapper div) that duplicates the needed base styles. -This fixes the visual regression but loses the component's built-in -behavior (e.g. `CardContent`'s framer-motion animation, `PropertyBox`'s -layout-context padding logic, `Card`'s border/overflow). - -**Proper fix (TODO):** Add customization props directly to the base -components so consumers can override styles without wrapping: - -- `Card` / `CardContent` — add `padding`, `backgroundColor`, `borderColor` props -- `PropertyBox` — add `padding`, `height`, `noPadding` props -- Other frequently extended components — audit and add props as needed - -**Affected files (using workaround today):** - -- `CalendarEventDetails.tsx` — `styled(PropertyBox)` → `styled.div`, `styled(Chip)` → wrapper -- `CalendarEventParticipantsResponseStatusField.tsx` — `styled(PropertyBox)` → `styled.div` -- `CalendarEventNotSharedContent.tsx` — `styled(Card)` / `styled(CardContent)` → `styled.div` -- `CalendarDayCardContent.tsx` — `styled(CardContent)` → `styled(motion.div)` -- `ActivityRow.tsx` — `styled(CardContent)` → `styled.div` -- `EmailThreadPreview.tsx` — `styled(Avatar)` → wrapper div -- `SignInAppNavigationDrawerMock.tsx` — `styled(NavigationDrawerSection)` → wrapper div -- `DefaultLayout.tsx` — `styled(SignInAppNavigationDrawerMock)` → wrapper div -- `LastUsedPill.tsx` — `styled(Pill)` → wrapper span -- `Logo.tsx` — dynamic `background-image` via inline `style` instead of prop -- `DatePicker.tsx` / `DateTimePicker.tsx` — `styled(StyledHoverableMenuItemBase)` / `styled(MenuItemLeftContent)` → `styled.div` -- `SelectControl.tsx` / `MultiSelectControl.tsx` — `styled(IconChevronDown)` → wrapper div - ---- - -## Validation Checklist (per PR) - -- [ ] `npx nx lint:diff-with-main twenty-front` passes -- [ ] `npx nx typecheck twenty-front` passes -- [ ] `npx nx test twenty-front` passes -- [ ] Visual spot-check of affected components in the app -- [ ] No remaining `@emotion/styled` or `@emotion/react` imports in migrated files diff --git a/nx.json b/nx.json index 552198c0ae..7519bf837d 100644 --- a/nx.json +++ b/nx.json @@ -276,7 +276,7 @@ "generators": { "@nx/react": { "application": { - "style": "@emotion/styled", + "style": "@linaria/react", "linter": "eslint", "bundler": "vite", "compiler": "swc", @@ -284,7 +284,7 @@ "projectNameAndRootFormat": "derived" }, "library": { - "style": "@emotion/styled", + "style": "@linaria/react", "linter": "eslint", "bundler": "vite", "compiler": "swc", @@ -292,7 +292,7 @@ "projectNameAndRootFormat": "derived" }, "component": { - "style": "@emotion/styled" + "style": "@linaria/react" } } }, diff --git a/package.json b/package.json index d241873387..65b9909fd0 100644 --- a/package.json +++ b/package.json @@ -2,14 +2,13 @@ "private": true, "dependencies": { "@apollo/client": "^3.7.17", - "@emotion/react": "^11.11.1", - "@emotion/styled": "^11.11.0", "@floating-ui/react": "^0.24.3", "@linaria/core": "^6.2.0", "@linaria/react": "^6.2.1", "@radix-ui/colors": "^3.0.0", "@sniptt/guards": "^0.2.0", "@tabler/icons-react": "^3.31.0", + "@wyw-in-js/babel-preset": "^1.0.6", "@wyw-in-js/vite": "^0.7.0", "archiver": "^7.0.1", "danger-plugin-todos": "^1.3.1", @@ -41,6 +40,7 @@ "lodash.snakecase": "^4.1.1", "lodash.upperfirst": "^4.3.1", "microdiff": "^1.3.2", + "next-with-linaria": "^1.3.0", "planer": "^1.2.0", "pluralize": "^8.0.0", "react": "^18.2.0", diff --git a/packages/twenty-docs/developers/contribute/capabilities/frontend-development/style-guide.mdx b/packages/twenty-docs/developers/contribute/capabilities/frontend-development/style-guide.mdx index 9fcd36f3e5..a67980ce76 100644 --- a/packages/twenty-docs/developers/contribute/capabilities/frontend-development/style-guide.mdx +++ b/packages/twenty-docs/developers/contribute/capabilities/frontend-development/style-guide.mdx @@ -194,7 +194,7 @@ setHotkeyScopeAndMemorizePreviousScope( ### Use StyledComponents -Style the components with [styled-components](https://emotion.sh/docs/styled). +Style the components with [Linaria styled](https://github.com/callstack/linaria). ```tsx // ❌ Bad diff --git a/packages/twenty-docs/developers/self-host/capabilities/troubleshooting.mdx b/packages/twenty-docs/developers/self-host/capabilities/troubleshooting.mdx index fff725daa7..62d67b7b6d 100644 --- a/packages/twenty-docs/developers/self-host/capabilities/troubleshooting.mdx +++ b/packages/twenty-docs/developers/self-host/capabilities/troubleshooting.mdx @@ -136,7 +136,7 @@ That's expected as user is unauthorized when logged out since its identity is no Comment out checker plugin in `packages/twenty-ui/vite-config.ts` like in example below ``` plugins: [ - react({ jsxImportSource: '@emotion/react' }), + react({ jsxImportSource: 'react' }), tsconfigPaths(), svgr(), dts(dtsConfig), diff --git a/packages/twenty-docs/l/ar/developers/contribute/capabilities/frontend-development/style-guide.mdx b/packages/twenty-docs/l/ar/developers/contribute/capabilities/frontend-development/style-guide.mdx index 4e467a549d..083e2aef08 100644 --- a/packages/twenty-docs/l/ar/developers/contribute/capabilities/frontend-development/style-guide.mdx +++ b/packages/twenty-docs/l/ar/developers/contribute/capabilities/frontend-development/style-guide.mdx @@ -194,7 +194,7 @@ setHotkeyScopeAndMemorizePreviousScope( ### استخدام مكونات منسقة -قم بتنسيق المكونات باستخدام [styled-components](https://emotion.sh/docs/styled). +قم بتنسيق المكونات باستخدام [Linaria styled](https://github.com/callstack/linaria). ```tsx // ❌ سيء diff --git a/packages/twenty-docs/l/ar/developers/self-host/capabilities/troubleshooting.mdx b/packages/twenty-docs/l/ar/developers/self-host/capabilities/troubleshooting.mdx index 8aa2ba3ef7..3bf00d4c35 100644 --- a/packages/twenty-docs/l/ar/developers/self-host/capabilities/troubleshooting.mdx +++ b/packages/twenty-docs/l/ar/developers/self-host/capabilities/troubleshooting.mdx @@ -145,7 +145,7 @@ npx nx worker twenty-server ``` plugins: [ - react({ jsxImportSource: '@emotion/react' }), + react({ jsxImportSource: 'react' }), tsconfigPaths(), svgr(), dts(dtsConfig), diff --git a/packages/twenty-docs/l/cs/developers/contribute/capabilities/frontend-development/style-guide.mdx b/packages/twenty-docs/l/cs/developers/contribute/capabilities/frontend-development/style-guide.mdx index 7f827be1d9..445015512a 100644 --- a/packages/twenty-docs/l/cs/developers/contribute/capabilities/frontend-development/style-guide.mdx +++ b/packages/twenty-docs/l/cs/developers/contribute/capabilities/frontend-development/style-guide.mdx @@ -67,11 +67,11 @@ const EmailField: React.FC<{ ``` ```tsx -/* ✅ - Dobré, explicitně definován samostatný typ (OwnProps) pro +/* ✅ - Dobré, explicitně definován samostatný typ (OwnProps) pro * rekvizity komponenty * - Tato metoda automaticky nezahrnuje rekvizitu children. Pokud * ji chcete zahrnout, musíte ji specifikovat v OwnProps. - */ + */ type EmailFieldProps = { value: string; }; @@ -96,7 +96,7 @@ const MyComponent = (props: OwnProps) => { ```tsx /* ✅ - Dobré, explicitně uvádí všechny rekvizity * - Zvyšuje čitelnost a udržovatelnost - */ + */ const MyComponent = ({ prop1, prop2, prop3 }: MyComponentProps) => { return ; }; @@ -123,7 +123,7 @@ const value = process.env.MY_VALUE ?? 'default'; ### Používejte volitelné zřetězení `?.` ```tsx -// ❌ Špatné +// ❌ Špatné onClick && onClick(); // ✅ Dobré @@ -194,7 +194,7 @@ setHotkeyScopeAndMemorizePreviousScope( ### Používejte StyledComponents -Styling komponenty s [styled-components](https://emotion.sh/docs/styled). +Styling komponenty s [Linaria styled](https://github.com/callstack/linaria). ```tsx // ❌ Špatné diff --git a/packages/twenty-docs/l/cs/developers/self-host/capabilities/troubleshooting.mdx b/packages/twenty-docs/l/cs/developers/self-host/capabilities/troubleshooting.mdx index 0f0f50f543..90da88d552 100644 --- a/packages/twenty-docs/l/cs/developers/self-host/capabilities/troubleshooting.mdx +++ b/packages/twenty-docs/l/cs/developers/self-host/capabilities/troubleshooting.mdx @@ -146,7 +146,7 @@ Zakomentujte plugin checker v `packages/twenty-ui/vite-config.ts` jako v příkl ``` plugins: [ - react({ jsxImportSource: '@emotion/react' }), + react({ jsxImportSource: 'react' }), tsconfigPaths(), svgr(), dts(dtsConfig), diff --git a/packages/twenty-docs/l/de/developers/contribute/capabilities/frontend-development/style-guide.mdx b/packages/twenty-docs/l/de/developers/contribute/capabilities/frontend-development/style-guide.mdx index 850e42d7c2..0e8b16643d 100644 --- a/packages/twenty-docs/l/de/developers/contribute/capabilities/frontend-development/style-guide.mdx +++ b/packages/twenty-docs/l/de/developers/contribute/capabilities/frontend-development/style-guide.mdx @@ -194,7 +194,7 @@ setHotkeyScopeAndMemorizePreviousScope( ### Verwenden Sie StyledComponents -Stylen Sie die Komponenten mit [styled-components](https://emotion.sh/docs/styled). +Stylen Sie die Komponenten mit [Linaria styled](https://github.com/callstack/linaria). ```tsx // ❌ Schlecht diff --git a/packages/twenty-docs/l/de/developers/self-host/capabilities/troubleshooting.mdx b/packages/twenty-docs/l/de/developers/self-host/capabilities/troubleshooting.mdx index d93d9cad51..8d011c7b5b 100644 --- a/packages/twenty-docs/l/de/developers/self-host/capabilities/troubleshooting.mdx +++ b/packages/twenty-docs/l/de/developers/self-host/capabilities/troubleshooting.mdx @@ -145,7 +145,7 @@ Kommentieren Sie das Checker-Plugin in `packages/twenty-ui/vite-config.ts` wie i ``` plugins: [ - react({ jsxImportSource: '@emotion/react' }), + react({ jsxImportSource: 'react' }), tsconfigPaths(), svgr(), dts(dtsConfig), diff --git a/packages/twenty-docs/l/es/developers/contribute/capabilities/frontend-development/style-guide.mdx b/packages/twenty-docs/l/es/developers/contribute/capabilities/frontend-development/style-guide.mdx index ea4c1651d0..07ed20717f 100644 --- a/packages/twenty-docs/l/es/developers/contribute/capabilities/frontend-development/style-guide.mdx +++ b/packages/twenty-docs/l/es/developers/contribute/capabilities/frontend-development/style-guide.mdx @@ -194,7 +194,7 @@ setHotkeyScopeAndMemorizePreviousScope( ### Usar StyledComponents -Estiliza los componentes con [styled-components](https://emotion.sh/docs/styled). +Estiliza los componentes con [Linaria styled](https://github.com/callstack/linaria). ```tsx // ❌ Bad diff --git a/packages/twenty-docs/l/es/developers/self-host/capabilities/troubleshooting.mdx b/packages/twenty-docs/l/es/developers/self-host/capabilities/troubleshooting.mdx index 887408ed52..6aa989676f 100644 --- a/packages/twenty-docs/l/es/developers/self-host/capabilities/troubleshooting.mdx +++ b/packages/twenty-docs/l/es/developers/self-host/capabilities/troubleshooting.mdx @@ -145,7 +145,7 @@ Comente el plugin checker en `packages/twenty-ui/vite-config.ts` como en el ejem ``` plugins: [ - react({ jsxImportSource: '@emotion/react' }), + react({ jsxImportSource: 'react' }), tsconfigPaths(), svgr(), dts(dtsConfig), diff --git a/packages/twenty-docs/l/fr/developers/contribute/capabilities/frontend-development/style-guide.mdx b/packages/twenty-docs/l/fr/developers/contribute/capabilities/frontend-development/style-guide.mdx index 54b3473c05..6c502fb1cf 100644 --- a/packages/twenty-docs/l/fr/developers/contribute/capabilities/frontend-development/style-guide.mdx +++ b/packages/twenty-docs/l/fr/developers/contribute/capabilities/frontend-development/style-guide.mdx @@ -194,7 +194,7 @@ setHotkeyScopeAndMemorizePreviousScope( ### Utilisez StyledComponents -Styliser les composants avec [styled-components](https://emotion.sh/docs/styled). +Styliser les composants avec [Linaria styled](https://github.com/callstack/linaria). ```tsx // ❌ Bad diff --git a/packages/twenty-docs/l/fr/developers/self-host/capabilities/troubleshooting.mdx b/packages/twenty-docs/l/fr/developers/self-host/capabilities/troubleshooting.mdx index b1f25938eb..5cf1d384e3 100644 --- a/packages/twenty-docs/l/fr/developers/self-host/capabilities/troubleshooting.mdx +++ b/packages/twenty-docs/l/fr/developers/self-host/capabilities/troubleshooting.mdx @@ -145,7 +145,7 @@ Commentez le plugin de vérification dans `packages/twenty-ui/vite-config.ts` co ``` plugins: [ - react({ jsxImportSource: '@emotion/react' }), + react({ jsxImportSource: 'react' }), tsconfigPaths(), svgr(), dts(dtsConfig), diff --git a/packages/twenty-docs/l/it/developers/contribute/capabilities/frontend-development/style-guide.mdx b/packages/twenty-docs/l/it/developers/contribute/capabilities/frontend-development/style-guide.mdx index 73383d5986..e13368660d 100644 --- a/packages/twenty-docs/l/it/developers/contribute/capabilities/frontend-development/style-guide.mdx +++ b/packages/twenty-docs/l/it/developers/contribute/capabilities/frontend-development/style-guide.mdx @@ -194,7 +194,7 @@ setHotkeyScopeAndMemorizePreviousScope( ### Usa StyledComponents -Stile i componenti con [styled-components](https://emotion.sh/docs/styled). +Stile i componenti con [Linaria styled](https://github.com/callstack/linaria). ```tsx // ❌ Male diff --git a/packages/twenty-docs/l/it/developers/self-host/capabilities/troubleshooting.mdx b/packages/twenty-docs/l/it/developers/self-host/capabilities/troubleshooting.mdx index 55fb1825d1..15e13ab08d 100644 --- a/packages/twenty-docs/l/it/developers/self-host/capabilities/troubleshooting.mdx +++ b/packages/twenty-docs/l/it/developers/self-host/capabilities/troubleshooting.mdx @@ -146,7 +146,7 @@ Commenta il plugin checker in `packages/twenty-ui/vite-config.ts` come mostrato ``` plugins: [ - react({ jsxImportSource: '@emotion/react' }), + react({ jsxImportSource: 'react' }), tsconfigPaths(), svgr(), dts(dtsConfig), diff --git a/packages/twenty-docs/l/ja/developers/contribute/capabilities/frontend-development/style-guide.mdx b/packages/twenty-docs/l/ja/developers/contribute/capabilities/frontend-development/style-guide.mdx index 39daabcda2..bf8e412718 100644 --- a/packages/twenty-docs/l/ja/developers/contribute/capabilities/frontend-development/style-guide.mdx +++ b/packages/twenty-docs/l/ja/developers/contribute/capabilities/frontend-development/style-guide.mdx @@ -194,7 +194,7 @@ setHotkeyScopeAndMemorizePreviousScope( ### StyledComponentsを使用する -コンポーネントを[styled-components](https://emotion.sh/docs/styled)でスタイル設定する。 +コンポーネントを[Linaria styled](https://github.com/callstack/linaria)でスタイル設定する。 ```tsx // ❌ Bad diff --git a/packages/twenty-docs/l/ja/developers/self-host/capabilities/troubleshooting.mdx b/packages/twenty-docs/l/ja/developers/self-host/capabilities/troubleshooting.mdx index 0e2a94959f..0cd20cdad8 100644 --- a/packages/twenty-docs/l/ja/developers/self-host/capabilities/troubleshooting.mdx +++ b/packages/twenty-docs/l/ja/developers/self-host/capabilities/troubleshooting.mdx @@ -152,7 +152,7 @@ npx nx worker twenty-server ``` plugins: [ - react({ jsxImportSource: '@emotion/react' }), + react({ jsxImportSource: 'react' }), tsconfigPaths(), svgr(), dts(dtsConfig), diff --git a/packages/twenty-docs/l/ko/developers/contribute/capabilities/frontend-development/style-guide.mdx b/packages/twenty-docs/l/ko/developers/contribute/capabilities/frontend-development/style-guide.mdx index 49b2328ec1..81acf92246 100644 --- a/packages/twenty-docs/l/ko/developers/contribute/capabilities/frontend-development/style-guide.mdx +++ b/packages/twenty-docs/l/ko/developers/contribute/capabilities/frontend-development/style-guide.mdx @@ -194,7 +194,7 @@ setHotkeyScopeAndMemorizePreviousScope( ### StyledComponents 사용 -[styled-components](https://emotion.sh/docs/styled)로 구성 요소를 스타일링하십시오. +[Linaria styled](https://github.com/callstack/linaria)로 구성 요소를 스타일링하십시오. ```tsx // ❌ Bad diff --git a/packages/twenty-docs/l/ko/developers/self-host/capabilities/troubleshooting.mdx b/packages/twenty-docs/l/ko/developers/self-host/capabilities/troubleshooting.mdx index 591bab724b..91608b308c 100644 --- a/packages/twenty-docs/l/ko/developers/self-host/capabilities/troubleshooting.mdx +++ b/packages/twenty-docs/l/ko/developers/self-host/capabilities/troubleshooting.mdx @@ -145,7 +145,7 @@ npx nx worker twenty-server ``` plugins: [ - react({ jsxImportSource: '@emotion/react' }), + react({ jsxImportSource: 'react' }), tsconfigPaths(), svgr(), dts(dtsConfig), diff --git a/packages/twenty-docs/l/pt/developers/contribute/capabilities/frontend-development/style-guide.mdx b/packages/twenty-docs/l/pt/developers/contribute/capabilities/frontend-development/style-guide.mdx index 48d4c509eb..7db8c34a7f 100644 --- a/packages/twenty-docs/l/pt/developers/contribute/capabilities/frontend-development/style-guide.mdx +++ b/packages/twenty-docs/l/pt/developers/contribute/capabilities/frontend-development/style-guide.mdx @@ -194,7 +194,7 @@ setHotkeyScopeAndMemorizePreviousScope( ### Use StyledComponents -Estilize os componentes com [styled-components](https://emotion.sh/docs/styled). +Estilize os componentes com [Linaria styled](https://github.com/callstack/linaria). ```tsx // ❌ Bad diff --git a/packages/twenty-docs/l/pt/developers/self-host/capabilities/troubleshooting.mdx b/packages/twenty-docs/l/pt/developers/self-host/capabilities/troubleshooting.mdx index 7ad56863ad..4f76404a50 100644 --- a/packages/twenty-docs/l/pt/developers/self-host/capabilities/troubleshooting.mdx +++ b/packages/twenty-docs/l/pt/developers/self-host/capabilities/troubleshooting.mdx @@ -145,7 +145,7 @@ Comente o plugin checker em `packages/twenty-ui/vite-config.ts` como no exemplo ``` plugins: [ - react({ jsxImportSource: '@emotion/react' }), + react({ jsxImportSource: 'react' }), tsconfigPaths(), svgr(), dts(dtsConfig), diff --git a/packages/twenty-docs/l/ro/developers/contribute/capabilities/frontend-development/style-guide.mdx b/packages/twenty-docs/l/ro/developers/contribute/capabilities/frontend-development/style-guide.mdx index 6949fb055e..1cbf9ba723 100644 --- a/packages/twenty-docs/l/ro/developers/contribute/capabilities/frontend-development/style-guide.mdx +++ b/packages/twenty-docs/l/ro/developers/contribute/capabilities/frontend-development/style-guide.mdx @@ -194,7 +194,7 @@ setHotkeyScopeAndMemorizePreviousScope( ### Folosește ComponentaStilizată -Stilizează componentele cu [styled-components](https://emotion.sh/docs/styled). +Stilizează componentele cu [Linaria styled](https://github.com/callstack/linaria). ```tsx // ❌ Rău diff --git a/packages/twenty-docs/l/ro/developers/self-host/capabilities/troubleshooting.mdx b/packages/twenty-docs/l/ro/developers/self-host/capabilities/troubleshooting.mdx index dda1e4a076..2c1a800ad7 100644 --- a/packages/twenty-docs/l/ro/developers/self-host/capabilities/troubleshooting.mdx +++ b/packages/twenty-docs/l/ro/developers/self-host/capabilities/troubleshooting.mdx @@ -146,7 +146,7 @@ Comentați pluginul checker în `packages/twenty-ui/vite-config.ts`, ca în exem ``` plugins: [ - react({ jsxImportSource: '@emotion/react' }), + react({ jsxImportSource: 'react' }), tsconfigPaths(), svgr(), dts(dtsConfig), diff --git a/packages/twenty-docs/l/ru/developers/contribute/capabilities/frontend-development/style-guide.mdx b/packages/twenty-docs/l/ru/developers/contribute/capabilities/frontend-development/style-guide.mdx index 60e37a40e6..f91d5dd9f1 100644 --- a/packages/twenty-docs/l/ru/developers/contribute/capabilities/frontend-development/style-guide.mdx +++ b/packages/twenty-docs/l/ru/developers/contribute/capabilities/frontend-development/style-guide.mdx @@ -194,7 +194,7 @@ setHotkeyScopeAndMemorizePreviousScope( ### Использование StyledComponents -Стилизуйте компоненты с помощью [styled-components](https://emotion.sh/docs/styled). +Стилизуйте компоненты с помощью [Linaria styled](https://github.com/callstack/linaria). ```tsx // ❌ Плохо diff --git a/packages/twenty-docs/l/ru/developers/self-host/capabilities/troubleshooting.mdx b/packages/twenty-docs/l/ru/developers/self-host/capabilities/troubleshooting.mdx index 81e2dedac5..41f3c1dc89 100644 --- a/packages/twenty-docs/l/ru/developers/self-host/capabilities/troubleshooting.mdx +++ b/packages/twenty-docs/l/ru/developers/self-host/capabilities/troubleshooting.mdx @@ -146,7 +146,7 @@ npx nx worker twenty-server ``` plugins: [ - react({ jsxImportSource: '@emotion/react' }), + react({ jsxImportSource: 'react' }), tsconfigPaths(), svgr(), dts(dtsConfig), diff --git a/packages/twenty-docs/l/tr/developers/contribute/capabilities/frontend-development/style-guide.mdx b/packages/twenty-docs/l/tr/developers/contribute/capabilities/frontend-development/style-guide.mdx index 142478bdf9..4345d4438f 100644 --- a/packages/twenty-docs/l/tr/developers/contribute/capabilities/frontend-development/style-guide.mdx +++ b/packages/twenty-docs/l/tr/developers/contribute/capabilities/frontend-development/style-guide.mdx @@ -68,7 +68,7 @@ const EmailField: React.FC<{ ```tsx /* ✅ - İyi, bileşenin prop'ları için ayrı bir tür (OwnProps) açıkça tanımlanmıştır - * - Bu yöntem çocuk prop'unu otomatik olarak içermez. + * - Bu yöntem çocuk prop'unu otomatik olarak içermez. * Onu dahil etmek istiyorsanız, OwnProps'ta belirtmeniz gerekir. */ type EmailFieldProps = { @@ -193,7 +193,7 @@ setHotkeyScopeAndMemorizePreviousScope( ### StyledComponents kullanın -Bileşenleri [styled-components](https://emotion.sh/docs/styled) ile stillendirin. +Bileşenleri [Linaria styled](https://github.com/callstack/linaria) ile stillendirin. ```tsx // ❌ Kötü diff --git a/packages/twenty-docs/l/tr/developers/self-host/capabilities/troubleshooting.mdx b/packages/twenty-docs/l/tr/developers/self-host/capabilities/troubleshooting.mdx index c3e70d0575..7c30a2883a 100644 --- a/packages/twenty-docs/l/tr/developers/self-host/capabilities/troubleshooting.mdx +++ b/packages/twenty-docs/l/tr/developers/self-host/capabilities/troubleshooting.mdx @@ -145,7 +145,7 @@ Aşağıdaki örnekte olduğu gibi `packages/twenty-ui/vite-config.ts` içindeki ``` plugins: [ - react({ jsxImportSource: '@emotion/react' }), + react({ jsxImportSource: 'react' }), tsconfigPaths(), svgr(), dts(dtsConfig), diff --git a/packages/twenty-docs/l/zh/developers/contribute/capabilities/frontend-development/style-guide.mdx b/packages/twenty-docs/l/zh/developers/contribute/capabilities/frontend-development/style-guide.mdx index 14e4a3ac5e..d7a9db2d2e 100644 --- a/packages/twenty-docs/l/zh/developers/contribute/capabilities/frontend-development/style-guide.mdx +++ b/packages/twenty-docs/l/zh/developers/contribute/capabilities/frontend-development/style-guide.mdx @@ -194,7 +194,7 @@ setHotkeyScopeAndMemorizePreviousScope( ### 使用StyledComponents -使用[styled-components](https://emotion.sh/docs/styled)对组件进行样式化。 +使用[Linaria styled](https://github.com/callstack/linaria)对组件进行样式化。 ```tsx // ❌ Bad diff --git a/packages/twenty-docs/l/zh/developers/self-host/capabilities/troubleshooting.mdx b/packages/twenty-docs/l/zh/developers/self-host/capabilities/troubleshooting.mdx index cc1ec60a5f..ab13f4fc9f 100644 --- a/packages/twenty-docs/l/zh/developers/self-host/capabilities/troubleshooting.mdx +++ b/packages/twenty-docs/l/zh/developers/self-host/capabilities/troubleshooting.mdx @@ -145,7 +145,7 @@ npx nx worker twenty-server ``` plugins: [ - react({ jsxImportSource: '@emotion/react' }), + react({ jsxImportSource: 'react' }), tsconfigPaths(), svgr(), dts(dtsConfig), diff --git a/packages/twenty-front/.storybook/preview.tsx b/packages/twenty-front/.storybook/preview.tsx index 6175fbda54..e882e1981e 100644 --- a/packages/twenty-front/.storybook/preview.tsx +++ b/packages/twenty-front/.storybook/preview.tsx @@ -1,4 +1,3 @@ -import { ThemeProvider } from '@emotion/react'; import { i18n } from '@lingui/core'; import { I18nProvider } from '@lingui/react'; import { type Preview } from '@storybook/react-vite'; @@ -71,15 +70,13 @@ const preview: Preview = { return ( - - - - - - - + + + + + ); }, diff --git a/packages/twenty-front/src/emotion.d.ts b/packages/twenty-front/src/emotion.d.ts deleted file mode 100644 index 4052bb6730..0000000000 --- a/packages/twenty-front/src/emotion.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { type ThemeType } from 'twenty-ui/theme'; - -declare module '@emotion/react' { - export interface Theme extends ThemeType {} -} diff --git a/packages/twenty-front/src/index.tsx b/packages/twenty-front/src/index.tsx index 17d431f263..714c56b917 100644 --- a/packages/twenty-front/src/index.tsx +++ b/packages/twenty-front/src/index.tsx @@ -1,7 +1,5 @@ import ReactDOM from 'react-dom/client'; -import '@emotion/react'; - import { App } from '@/app/components/App'; import 'react-loading-skeleton/dist/skeleton.css'; import 'twenty-ui/style.css'; diff --git a/packages/twenty-front/src/loading/components/RightPanelSkeletonLoader.tsx b/packages/twenty-front/src/loading/components/RightPanelSkeletonLoader.tsx index a0995af3ce..8b1df4cb37 100644 --- a/packages/twenty-front/src/loading/components/RightPanelSkeletonLoader.tsx +++ b/packages/twenty-front/src/loading/components/RightPanelSkeletonLoader.tsx @@ -2,8 +2,8 @@ import { SKELETON_LOADER_HEIGHT_SIZES } from '@/activities/components/SkeletonLo import { styled } from '@linaria/react'; import { useContext } from 'react'; import Skeleton, { SkeletonTheme } from 'react-loading-skeleton'; -import { BORDER_COMMON, MOBILE_VIEWPORT, ThemeContext } from 'twenty-ui/theme'; -import { themeCssVariables } from 'twenty-ui/theme-constants'; +import { ThemeContext } from 'twenty-ui/theme'; +import { MOBILE_VIEWPORT, themeCssVariables } from 'twenty-ui/theme-constants'; const StyledMainContainer = styled.div` background: ${themeCssVariables.background.noisy}; @@ -25,7 +25,7 @@ const StyledMainContainer = styled.div` const StyledPanel = styled.div` background: ${themeCssVariables.background.primary}; border: 1px solid ${themeCssVariables.border.color.medium}; - border-radius: ${BORDER_COMMON.radius.md}; + border-radius: ${themeCssVariables.border.radius.md}; height: 100%; overflow: auto; width: 100%; diff --git a/packages/twenty-front/src/loading/components/UserOrMetadataLoader.tsx b/packages/twenty-front/src/loading/components/UserOrMetadataLoader.tsx index 6609830ae0..db526b9472 100644 --- a/packages/twenty-front/src/loading/components/UserOrMetadataLoader.tsx +++ b/packages/twenty-front/src/loading/components/UserOrMetadataLoader.tsx @@ -3,8 +3,7 @@ import { styled } from '@linaria/react'; import { useShowAuthModal } from '@/ui/layout/hooks/useShowAuthModal'; import { Modal } from '@/ui/layout/modal/components/Modal'; import { NAVIGATION_DRAWER_CONSTRAINTS } from '@/ui/layout/resizable-panel/constants/NavigationDrawerConstraints'; -import { MOBILE_VIEWPORT } from 'twenty-ui/theme'; -import { themeCssVariables } from 'twenty-ui/theme-constants'; +import { MOBILE_VIEWPORT, themeCssVariables } from 'twenty-ui/theme-constants'; import { LeftPanelSkeletonLoader } from '~/loading/components/LeftPanelSkeletonLoader'; import { RightPanelSkeletonLoader } from '~/loading/components/RightPanelSkeletonLoader'; diff --git a/packages/twenty-front/src/modules/activities/calendar/components/CalendarDayCardContent.tsx b/packages/twenty-front/src/modules/activities/calendar/components/CalendarDayCardContent.tsx index 32e0571e12..8276e4d84c 100644 --- a/packages/twenty-front/src/modules/activities/calendar/components/CalendarDayCardContent.tsx +++ b/packages/twenty-front/src/modules/activities/calendar/components/CalendarDayCardContent.tsx @@ -4,7 +4,7 @@ import { differenceInSeconds, endOfDay, format } from 'date-fns'; import { CalendarEventRow } from '@/activities/calendar/components/CalendarEventRow'; import { getCalendarEventStartDate } from '@/activities/calendar/utils/getCalendarEventStartDate'; -import { motion } from 'framer-motion'; +import { CardContent } from 'twenty-ui/layout'; import { ThemeContext } from 'twenty-ui/theme'; import { themeCssVariables } from 'twenty-ui/theme-constants'; import { type TimelineCalendarEvent } from '~/generated/graphql'; @@ -14,19 +14,14 @@ type CalendarDayCardContentProps = { divider?: boolean; }; -const StyledCardContentBase = styled.div<{ divider?: boolean }>` +const StyledCardContent = styled(CardContent)` align-items: flex-start; - background-color: ${themeCssVariables.background.secondary}; - border-bottom: ${({ divider }) => - divider ? `1px solid ${themeCssVariables.border.color.light}` : 'none'}; display: flex; flex-direction: row; gap: ${themeCssVariables.spacing[3]}; padding: ${themeCssVariables.spacing[2]} ${themeCssVariables.spacing[3]}; `; -const StyledCardContent = motion.create(StyledCardContentBase); - const StyledDayContainer = styled.div` text-align: center; width: ${themeCssVariables.spacing[6]}; diff --git a/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventDetails.tsx b/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventDetails.tsx index 6f3a14ef44..8f8966cb1a 100644 --- a/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventDetails.tsx +++ b/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventDetails.tsx @@ -32,6 +32,7 @@ import { } from 'twenty-ui/components'; import { IconCalendarEvent } from 'twenty-ui/display'; import { themeCssVariables } from 'twenty-ui/theme-constants'; +import { PropertyBox } from '@/object-record/record-inline-cell/property-box/components/PropertyBox'; import { beautifyPastDateRelativeToNow } from '~/utils/date-utils'; type CalendarEventDetailsProps = { @@ -84,10 +85,7 @@ const StyledFields = styled.div` width: 100%; `; -const StyledPropertyBox = styled.div` - align-self: stretch; - display: flex; - flex-direction: column; +const StyledPropertyBox = styled(PropertyBox)` height: ${themeCssVariables.spacing[6]}; width: 100%; `; diff --git a/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventNotSharedContent.tsx b/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventNotSharedContent.tsx index 30aa259e52..4cf667e29d 100644 --- a/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventNotSharedContent.tsx +++ b/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventNotSharedContent.tsx @@ -2,20 +2,19 @@ import { useContext } from 'react'; import { styled } from '@linaria/react'; import { Trans } from '@lingui/react/macro'; import { IconLock } from 'twenty-ui/display'; +import { Card, CardContent } from 'twenty-ui/layout'; import { ThemeContext } from 'twenty-ui/theme'; import { themeCssVariables } from 'twenty-ui/theme-constants'; -const StyledVisibilityCard = styled.div` - border: 1px solid ${themeCssVariables.border.color.light}; - border-radius: ${themeCssVariables.border.radius.sm}; +const StyledVisibilityCard = styled(Card)` color: ${themeCssVariables.font.color.light}; flex: 1; - overflow: hidden; + border-color: ${themeCssVariables.border.color.light}; transition: color ${themeCssVariables.animation.duration.normal} ease; width: 100%; `; -const StyledVisibilityCardContent = styled.div` +const StyledVisibilityCardContent = styled(CardContent)` align-items: center; background-color: ${themeCssVariables.background.transparent.lighter}; box-sizing: border-box; diff --git a/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventParticipantsResponseStatusField.tsx b/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventParticipantsResponseStatusField.tsx index ace4aaa0d4..2b273446e9 100644 --- a/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventParticipantsResponseStatusField.tsx +++ b/packages/twenty-front/src/modules/activities/calendar/components/CalendarEventParticipantsResponseStatusField.tsx @@ -2,6 +2,7 @@ import { useContext, useRef } from 'react'; import { styled } from '@linaria/react'; import { type CalendarEventParticipant } from '@/activities/calendar/types/CalendarEventParticipant'; +import { PropertyBox } from '@/object-record/record-inline-cell/property-box/components/PropertyBox'; import { ParticipantChip } from '@/activities/components/ParticipantChip'; import { EllipsisDisplay } from '@/ui/field/display/components/EllipsisDisplay'; import { ExpandableList } from '@/ui/layout/expandable-list/components/ExpandableList'; @@ -21,10 +22,7 @@ const StyledInlineCellBaseContainer = styled.div` user-select: none; `; -const StyledPropertyBox = styled.div` - align-self: stretch; - display: flex; - flex-direction: column; +const StyledPropertyBox = styled(PropertyBox)` height: ${themeCssVariables.spacing[6]}; width: 100%; `; diff --git a/packages/twenty-front/src/modules/activities/components/ActivityRow.tsx b/packages/twenty-front/src/modules/activities/components/ActivityRow.tsx index d696ad33c5..cfdbb59451 100644 --- a/packages/twenty-front/src/modules/activities/components/ActivityRow.tsx +++ b/packages/twenty-front/src/modules/activities/components/ActivityRow.tsx @@ -1,15 +1,18 @@ import { styled } from '@linaria/react'; import React from 'react'; +import { CardContent } from 'twenty-ui/layout'; import { themeCssVariables } from 'twenty-ui/theme-constants'; -const StyledRowContent = styled.div<{ isClickable: boolean }>` +const StyledRowContent = styled(CardContent)` align-items: center; - background-color: ${themeCssVariables.background.secondary}; - cursor: ${({ isClickable }) => (isClickable ? 'pointer' : 'default')}; display: flex; gap: ${themeCssVariables.spacing[2]}; height: ${themeCssVariables.spacing[12]}; padding: ${themeCssVariables.spacing[0]} ${themeCssVariables.spacing[4]}; + + &[data-clickable='false'] { + cursor: default; + } `; export const ActivityRow = ({ diff --git a/packages/twenty-front/src/modules/activities/timeline-activities/components/TimelineCard.tsx b/packages/twenty-front/src/modules/activities/timeline-activities/components/TimelineCard.tsx index b86946a1ac..20a05c9adc 100644 --- a/packages/twenty-front/src/modules/activities/timeline-activities/components/TimelineCard.tsx +++ b/packages/twenty-front/src/modules/activities/timeline-activities/components/TimelineCard.tsx @@ -15,8 +15,7 @@ import { AnimatedPlaceholderEmptyTitle, EMPTY_PLACEHOLDER_TRANSITION_PROPS, } from 'twenty-ui/layout'; -import { MOBILE_VIEWPORT } from 'twenty-ui/theme'; -import { themeCssVariables } from 'twenty-ui/theme-constants'; +import { MOBILE_VIEWPORT, themeCssVariables } from 'twenty-ui/theme-constants'; const StyledMainContainer = styled.div` align-items: flex-start; diff --git a/packages/twenty-front/src/modules/activities/timeline-activities/rows/activity/components/EventRowActivity.tsx b/packages/twenty-front/src/modules/activities/timeline-activities/rows/activity/components/EventRowActivity.tsx index bffcec36c3..d84af27c5f 100644 --- a/packages/twenty-front/src/modules/activities/timeline-activities/rows/activity/components/EventRowActivity.tsx +++ b/packages/twenty-front/src/modules/activities/timeline-activities/rows/activity/components/EventRowActivity.tsx @@ -12,8 +12,7 @@ import { type CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectN import { useGetRecordFromCache } from '@/object-record/cache/hooks/useGetRecordFromCache'; import { isNonEmptyString } from '@sniptt/guards'; import { OverflowingTextWithTooltip } from 'twenty-ui/display'; -import { MOBILE_VIEWPORT } from 'twenty-ui/theme'; -import { themeCssVariables } from 'twenty-ui/theme-constants'; +import { MOBILE_VIEWPORT, themeCssVariables } from 'twenty-ui/theme-constants'; type EventRowActivityProps = EventRowDynamicComponentProps; diff --git a/packages/twenty-front/src/modules/activities/timeline-activities/rows/components/EventCard.tsx b/packages/twenty-front/src/modules/activities/timeline-activities/rows/components/EventCard.tsx index 0616307371..715302b23c 100644 --- a/packages/twenty-front/src/modules/activities/timeline-activities/rows/components/EventCard.tsx +++ b/packages/twenty-front/src/modules/activities/timeline-activities/rows/components/EventCard.tsx @@ -1,7 +1,6 @@ import { styled } from '@linaria/react'; import { Card } from 'twenty-ui/layout'; -import { MOBILE_VIEWPORT } from 'twenty-ui/theme'; -import { themeCssVariables } from 'twenty-ui/theme-constants'; +import { MOBILE_VIEWPORT, themeCssVariables } from 'twenty-ui/theme-constants'; type EventCardProps = { children: React.ReactNode; diff --git a/packages/twenty-front/src/modules/activities/timeline-activities/rows/main-object/components/EventRowMainObject.tsx b/packages/twenty-front/src/modules/activities/timeline-activities/rows/main-object/components/EventRowMainObject.tsx index ac77fcb940..2d1e50796d 100644 --- a/packages/twenty-front/src/modules/activities/timeline-activities/rows/main-object/components/EventRowMainObject.tsx +++ b/packages/twenty-front/src/modules/activities/timeline-activities/rows/main-object/components/EventRowMainObject.tsx @@ -6,8 +6,7 @@ import { import { EventRowMainObjectUpdated } from '@/activities/timeline-activities/rows/main-object/components/EventRowMainObjectUpdated'; import { styled } from '@linaria/react'; import { t } from '@lingui/core/macro'; -import { MOBILE_VIEWPORT } from 'twenty-ui/theme'; -import { themeCssVariables } from 'twenty-ui/theme-constants'; +import { MOBILE_VIEWPORT, themeCssVariables } from 'twenty-ui/theme-constants'; type EventRowMainObjectProps = EventRowDynamicComponentProps; diff --git a/packages/twenty-front/src/modules/activities/timeline-activities/rows/main-object/components/EventRowMainObjectUpdated.tsx b/packages/twenty-front/src/modules/activities/timeline-activities/rows/main-object/components/EventRowMainObjectUpdated.tsx index 1721579277..4df90c5a20 100644 --- a/packages/twenty-front/src/modules/activities/timeline-activities/rows/main-object/components/EventRowMainObjectUpdated.tsx +++ b/packages/twenty-front/src/modules/activities/timeline-activities/rows/main-object/components/EventRowMainObjectUpdated.tsx @@ -9,8 +9,7 @@ import { EventFieldDiffContainer } from '@/activities/timeline-activities/rows/m import { type TimelineActivity } from '@/activities/timeline-activities/types/TimelineActivity'; import { type FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem'; import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; -import { MOBILE_VIEWPORT } from 'twenty-ui/theme'; -import { themeCssVariables } from 'twenty-ui/theme-constants'; +import { MOBILE_VIEWPORT, themeCssVariables } from 'twenty-ui/theme-constants'; type EventRowMainObjectUpdatedProps = { mainObjectMetadataItem: ObjectMetadataItem; diff --git a/packages/twenty-front/src/modules/command-menu/components/CommandMenuContextChipIconWrapper.tsx b/packages/twenty-front/src/modules/command-menu/components/CommandMenuContextChipIconWrapper.tsx new file mode 100644 index 0000000000..e23f797b95 --- /dev/null +++ b/packages/twenty-front/src/modules/command-menu/components/CommandMenuContextChipIconWrapper.tsx @@ -0,0 +1,13 @@ +import { styled } from '@linaria/react'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; + +const StyledCommandMenuContextChipIconWrapper = styled.div` + align-items: center; + background: ${themeCssVariables.background.primary}; + border-radius: ${themeCssVariables.border.radius.sm}; + display: flex; + justify-content: center; +`; + +export const CommandMenuContextChipIconWrapper = + StyledCommandMenuContextChipIconWrapper; diff --git a/packages/twenty-front/src/modules/command-menu/components/CommandMenuList.tsx b/packages/twenty-front/src/modules/command-menu/components/CommandMenuList.tsx index 624eae5c59..9bd04b200e 100644 --- a/packages/twenty-front/src/modules/command-menu/components/CommandMenuList.tsx +++ b/packages/twenty-front/src/modules/command-menu/components/CommandMenuList.tsx @@ -12,8 +12,7 @@ import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomStat import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper'; import { styled } from '@linaria/react'; import { t } from '@lingui/core/macro'; -import { MOBILE_VIEWPORT } from 'twenty-ui/theme'; -import { themeCssVariables } from 'twenty-ui/theme-constants'; +import { MOBILE_VIEWPORT, themeCssVariables } from 'twenty-ui/theme-constants'; export type CommandMenuListProps = { commandGroups: ActionGroupConfig[]; diff --git a/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuContextChips.tsx b/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuContextChips.tsx index ff13ddbc7c..6f2f9d0041 100644 --- a/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuContextChips.tsx +++ b/packages/twenty-front/src/modules/command-menu/hooks/useCommandMenuContextChips.tsx @@ -1,28 +1,19 @@ +import { CommandMenuContextChipIconWrapper } from '@/command-menu/components/CommandMenuContextChipIconWrapper'; import { CommandMenuContextRecordChipAvatars } from '@/command-menu/components/CommandMenuContextRecordChipAvatars'; import { useCommandMenuHistory } from '@/command-menu/hooks/useCommandMenuHistory'; import { commandMenuNavigationMorphItemsByPageState } from '@/command-menu/states/commandMenuNavigationMorphItemsByPageState'; import { commandMenuNavigationStackState } from '@/command-menu/states/commandMenuNavigationStackState'; -import { CommandMenuPages } from 'twenty-shared/types'; +import { allowRequestsToTwentyIconsState } from '@/client-config/states/allowRequestsToTwentyIcons'; import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState'; import { recordStoreIdentifiersFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreIdentifiersSelector'; import { recordStoreRecordsSelector } from '@/object-record/record-store/states/selectors/recordStoreRecordsSelector'; -import { styled } from '@linaria/react'; -import { useContext, useMemo } from 'react'; -import { isDefined } from 'twenty-shared/utils'; -import { allowRequestsToTwentyIconsState } from '@/client-config/states/allowRequestsToTwentyIcons'; import { useAtomFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilySelectorValue'; import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; -import { themeCssVariables } from 'twenty-ui/theme-constants'; +import { useContext, useMemo } from 'react'; +import { CommandMenuPages } from 'twenty-shared/types'; +import { isDefined } from 'twenty-shared/utils'; import { ThemeContext } from 'twenty-ui/theme'; -const StyledIconWrapper = styled.div` - background: ${themeCssVariables.background.primary}; - border-radius: ${themeCssVariables.border.radius.sm}; - display: flex; - align-items: center; - justify-content: center; -`; - export const useCommandMenuContextChips = () => { const commandMenuNavigationStack = useAtomStateValue( commandMenuNavigationStackState, @@ -122,7 +113,7 @@ export const useCommandMenuContextChips = () => { Icons: isLastChip ? [] : [ - + { : theme.font.color.tertiary } /> - , + , ], text: page.pageTitle, onClick: isLastChip diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuColumn.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuColumn.tsx index 76fd845ff8..0da8660aa9 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuColumn.tsx +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuColumn.tsx @@ -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; diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuContainer.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuContainer.tsx index f941945553..b6e8d57535 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuContainer.tsx @@ -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%; `; diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuLogicalOperatorCell.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuLogicalOperatorCell.tsx index 1b78511855..1971f86575 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuLogicalOperatorCell.tsx +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuLogicalOperatorCell.tsx @@ -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 = { diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuRecordFilterColumn.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuRecordFilterColumn.tsx index 2fa8c4936d..974768556f 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuRecordFilterColumn.tsx +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuRecordFilterColumn.tsx @@ -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 = { diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuRecordFilterGroupChildren.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuRecordFilterGroupChildren.tsx index 335b4f6874..bb50b019c0 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuRecordFilterGroupChildren.tsx +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuRecordFilterGroupChildren.tsx @@ -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 = { diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuRecordFilterGroupColumn.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuRecordFilterGroupColumn.tsx index 817b8c65f5..86946f5a24 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuRecordFilterGroupColumn.tsx +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/command-menu/components/AdvancedFilterCommandMenuRecordFilterGroupColumn.tsx @@ -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 = ({ diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterDropdownRow.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterDropdownRow.tsx index 5fb2b1e4e6..d511e661b9 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterDropdownRow.tsx +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterDropdownRow.tsx @@ -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; diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterFieldSelectDropdownButton.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterFieldSelectDropdownButton.tsx index 32ec5ee297..8add14c1cb 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterFieldSelectDropdownButton.tsx +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterFieldSelectDropdownButton.tsx @@ -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; diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterFieldSelectSearchInput.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterFieldSelectSearchInput.tsx index 76622cda4b..8d34eb2f39 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterFieldSelectSearchInput.tsx +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterFieldSelectSearchInput.tsx @@ -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}; } `; diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterLogicalOperatorCell.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterLogicalOperatorCell.tsx index cbcdf9b888..66ebbe45a6 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterLogicalOperatorCell.tsx +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterLogicalOperatorCell.tsx @@ -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 = { diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterGroupChildren.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterGroupChildren.tsx index 0544386b27..88ff98c01c 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterGroupChildren.tsx +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterGroupChildren.tsx @@ -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 = { diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterOperandSelect.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterOperandSelect.tsx index 763be722f3..741816dc41 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterOperandSelect.tsx +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterOperandSelect.tsx @@ -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'; diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRootRecordFilterGroup.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRootRecordFilterGroup.tsx index fb0c3d66d8..0c4cf193a9 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRootRecordFilterGroup.tsx +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRootRecordFilterGroup.tsx @@ -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 = () => { diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterValueInput.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterValueInput.tsx index af7e63eaab..358fbdb027 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterValueInput.tsx +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterValueInput.tsx @@ -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` diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterValueInputDropdownButtonClickableSelect.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterValueInputDropdownButtonClickableSelect.tsx index 4ade62801c..701f5d5ca7 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterValueInputDropdownButtonClickableSelect.tsx +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterValueInputDropdownButtonClickableSelect.tsx @@ -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; `; diff --git a/packages/twenty-front/src/modules/object-record/components/MainContainerLayoutWithCommandMenu.tsx b/packages/twenty-front/src/modules/object-record/components/MainContainerLayoutWithCommandMenu.tsx index f1bb8ce242..2dbb0fb1d8 100644 --- a/packages/twenty-front/src/modules/object-record/components/MainContainerLayoutWithCommandMenu.tsx +++ b/packages/twenty-front/src/modules/object-record/components/MainContainerLayoutWithCommandMenu.tsx @@ -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 = ({ diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownBooleanSelect.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownBooleanSelect.tsx index 24230d582d..b1754216a2 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownBooleanSelect.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownBooleanSelect.tsx @@ -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 } = diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownRatingInput.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownRatingInput.tsx index 0e1ac9ed5c..841e78a8a4 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownRatingInput.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownRatingInput.tsx @@ -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 = ( diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownRecordPinnedItems.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownRecordPinnedItems.tsx index 25f0135108..35d3c59ea4 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownRecordPinnedItems.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownRecordPinnedItems.tsx @@ -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: { diff --git a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownMenuViewName.tsx b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownMenuViewName.tsx index a4465ba82f..1d768497a9 100644 --- a/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownMenuViewName.tsx +++ b/packages/twenty-front/src/modules/object-record/object-options-dropdown/components/ObjectOptionsDropdownMenuViewName.tsx @@ -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); diff --git a/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoard.tsx b/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoard.tsx index 084af0b214..742dc8d2c8 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoard.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoard.tsx @@ -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; `; diff --git a/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardColumns.tsx b/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardColumns.tsx index 60a401b1ee..23fe106b64 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardColumns.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardColumns.tsx @@ -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}; } `; diff --git a/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardFetchMoreInViewTriggerComponent.tsx b/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardFetchMoreInViewTriggerComponent.tsx index b9df7a5b93..4b2d3321fd 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardFetchMoreInViewTriggerComponent.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardFetchMoreInViewTriggerComponent.tsx @@ -1,4 +1,4 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { useEffect } from 'react'; import { useInView } from 'react-intersection-observer'; diff --git a/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardHeader.tsx b/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardHeader.tsx index 56fc616386..a7f6acc1cc 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardHeader.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/components/RecordBoardHeader.tsx @@ -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}; } `; diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx index be40c552b3..95541ea088 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCard.tsx @@ -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%; `; diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCardDraggableContainer.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCardDraggableContainer.tsx index cfbb276dcb..f752d65b5e 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCardDraggableContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCardDraggableContainer.tsx @@ -1,4 +1,4 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { Draggable } from '@hello-pangea/dnd'; import { useContext } from 'react'; diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCardHeader.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCardHeader.tsx index 38f5db67c6..be2202ad11 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCardHeader.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCardHeader.tsx @@ -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` diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCardMultiDragCounterChip.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCardMultiDragCounterChip.tsx index edb2bdedbe..453a6a56ff 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCardMultiDragCounterChip.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCardMultiDragCounterChip.tsx @@ -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)` diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCardMultiDragStack.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCardMultiDragStack.tsx index 0b4f1ec1a5..d49bf7a4d3 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCardMultiDragStack.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/RecordBoardCardMultiDragStack.tsx @@ -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}; `; diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/StopPropagationContainer.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/StopPropagationContainer.tsx index ce8942e376..96ed98d14b 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/StopPropagationContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-card/components/StopPropagationContainer.tsx @@ -1,4 +1,4 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { type ReactNode } from 'react'; const StyledFieldContainer = styled.div` diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumn.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumn.tsx index e7000513c7..7a3eebe9e3 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumn.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumn.tsx @@ -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%; diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnCardContainerSkeletonLoader.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnCardContainerSkeletonLoader.tsx index 09d3a3fa7a..2ac532ba99 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnCardContainerSkeletonLoader.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnCardContainerSkeletonLoader.tsx @@ -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(); diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnCardsContainer.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnCardsContainer.tsx index e78ef43fef..a8c76e7455 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnCardsContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnCardsContainer.tsx @@ -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 = { diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeader.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeader.tsx index a9dac3b763..c7c6523371 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeader.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeader.tsx @@ -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; `; diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdown.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdown.tsx index 5070e04f5d..03a839b718 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdown.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdown.tsx @@ -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 = { diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownButton.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownButton.tsx index 53be332772..89ff4d75f7 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownButton.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdownButton.tsx @@ -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'; diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnLoadingSkeletonCards.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnLoadingSkeletonCards.tsx index 0787d407a4..3b04df05b5 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnLoadingSkeletonCards.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnLoadingSkeletonCards.tsx @@ -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 = () => { diff --git a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnNewRecordButton.tsx b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnNewRecordButton.tsx index 9505ded406..2b827d1f3e 100644 --- a/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnNewRecordButton.tsx +++ b/packages/twenty-front/src/modules/object-record/record-board/record-board-column/components/RecordBoardColumnNewRecordButton.tsx @@ -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); diff --git a/packages/twenty-front/src/modules/object-record/record-calendar/components/RecordCalendar.tsx b/packages/twenty-front/src/modules/object-record/record-calendar/components/RecordCalendar.tsx index 7baca3e57f..b113011920 100644 --- a/packages/twenty-front/src/modules/object-record/record-calendar/components/RecordCalendar.tsx +++ b/packages/twenty-front/src/modules/object-record/record-calendar/components/RecordCalendar.tsx @@ -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 = () => { diff --git a/packages/twenty-front/src/modules/object-record/record-calendar/components/RecordCalendarAddNew.tsx b/packages/twenty-front/src/modules/object-record/record-calendar/components/RecordCalendarAddNew.tsx index f1bb68d504..6ecebbed66 100644 --- a/packages/twenty-front/src/modules/object-record/record-calendar/components/RecordCalendarAddNew.tsx +++ b/packages/twenty-front/src/modules/object-record/record-calendar/components/RecordCalendarAddNew.tsx @@ -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, diff --git a/packages/twenty-front/src/modules/object-record/record-calendar/components/RecordCalendarTopBar.tsx b/packages/twenty-front/src/modules/object-record/record-calendar/components/RecordCalendarTopBar.tsx index 767c94d6cf..ec5f2c8774 100644 --- a/packages/twenty-front/src/modules/object-record/record-calendar/components/RecordCalendarTopBar.tsx +++ b/packages/twenty-front/src/modules/object-record/record-calendar/components/RecordCalendarTopBar.tsx @@ -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; `; diff --git a/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonth.tsx b/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonth.tsx index da9a68fd37..0c887d2562 100644 --- a/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonth.tsx +++ b/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonth.tsx @@ -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, diff --git a/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonthBody.tsx b/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonthBody.tsx index 9ea32b96d7..2f88be9a3c 100644 --- a/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonthBody.tsx +++ b/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonthBody.tsx @@ -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; `; diff --git a/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonthBodyDay.tsx b/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonthBodyDay.tsx index 9103811170..3beff1b796 100644 --- a/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonthBodyDay.tsx +++ b/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonthBodyDay.tsx @@ -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 = { diff --git a/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonthBodyWeek.tsx b/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonthBodyWeek.tsx index 14c975ccea..07fadf9eee 100644 --- a/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonthBodyWeek.tsx +++ b/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonthBodyWeek.tsx @@ -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}; } `; diff --git a/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonthHeader.tsx b/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonthHeader.tsx index 2ae5e79b32..ed2a7200e4 100644 --- a/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonthHeader.tsx +++ b/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonthHeader.tsx @@ -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; diff --git a/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonthHeaderDay.tsx b/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonthHeaderDay.tsx index c13f4276af..1d33955090 100644 --- a/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonthHeaderDay.tsx +++ b/packages/twenty-front/src/modules/object-record/record-calendar/month/components/RecordCalendarMonthHeaderDay.tsx @@ -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); `; diff --git a/packages/twenty-front/src/modules/object-record/record-calendar/record-calendar-card/components/RecordCalendarCard.tsx b/packages/twenty-front/src/modules/object-record/record-calendar/record-calendar-card/components/RecordCalendarCard.tsx index b873ebbb0b..8e286c49a4 100644 --- a/packages/twenty-front/src/modules/object-record/record-calendar/record-calendar-card/components/RecordCalendarCard.tsx +++ b/packages/twenty-front/src/modules/object-record/record-calendar/record-calendar-card/components/RecordCalendarCard.tsx @@ -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` diff --git a/packages/twenty-front/src/modules/object-record/record-calendar/record-calendar-card/components/RecordCalendarCardBody.tsx b/packages/twenty-front/src/modules/object-record/record-calendar/record-calendar-card/components/RecordCalendarCardBody.tsx index feaa60b0c3..368655b073 100644 --- a/packages/twenty-front/src/modules/object-record/record-calendar/record-calendar-card/components/RecordCalendarCardBody.tsx +++ b/packages/twenty-front/src/modules/object-record/record-calendar/record-calendar-card/components/RecordCalendarCardBody.tsx @@ -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 = { diff --git a/packages/twenty-front/src/modules/object-record/record-calendar/record-calendar-card/components/RecordCalendarCardDraggableContainer.tsx b/packages/twenty-front/src/modules/object-record/record-calendar/record-calendar-card/components/RecordCalendarCardDraggableContainer.tsx index 82d127ccbb..35c7f1278d 100644 --- a/packages/twenty-front/src/modules/object-record/record-calendar/record-calendar-card/components/RecordCalendarCardDraggableContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-calendar/record-calendar-card/components/RecordCalendarCardDraggableContainer.tsx @@ -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'; diff --git a/packages/twenty-front/src/modules/object-record/record-calendar/record-calendar-card/components/RecordCalendarCardHeader.tsx b/packages/twenty-front/src/modules/object-record/record-calendar/record-calendar-card/components/RecordCalendarCardHeader.tsx index 7c24567129..6567c577e9 100644 --- a/packages/twenty-front/src/modules/object-record/record-calendar/record-calendar-card/components/RecordCalendarCardHeader.tsx +++ b/packages/twenty-front/src/modules/object-record/record-calendar/record-calendar-card/components/RecordCalendarCardHeader.tsx @@ -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 = { diff --git a/packages/twenty-front/src/modules/object-record/record-card/components/RecordCard.tsx b/packages/twenty-front/src/modules/object-record/record-card/components/RecordCard.tsx index eafd98d4c8..b9be38398e 100644 --- a/packages/twenty-front/src/modules/object-record/record-card/components/RecordCard.tsx +++ b/packages/twenty-front/src/modules/object-record/record-card/components/RecordCard.tsx @@ -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}; } } diff --git a/packages/twenty-front/src/modules/object-record/record-card/components/RecordCardBodyContainer.tsx b/packages/twenty-front/src/modules/object-record/record-card/components/RecordCardBodyContainer.tsx index 573c2661ac..bb7bcfacec 100644 --- a/packages/twenty-front/src/modules/object-record/record-card/components/RecordCardBodyContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-card/components/RecordCardBodyContainer.tsx @@ -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]}; } } `; diff --git a/packages/twenty-front/src/modules/object-record/record-card/components/RecordCardHeaderContainer.tsx b/packages/twenty-front/src/modules/object-record/record-card/components/RecordCardHeaderContainer.tsx index ca8437bd80..292d31922d 100644 --- a/packages/twenty-front/src/modules/object-record/record-card/components/RecordCardHeaderContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-card/components/RecordCardHeaderContainer.tsx @@ -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; } `; diff --git a/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/components/RecordDetailRecordsListContainer.tsx b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/components/RecordDetailRecordsListContainer.tsx index e7f670edb1..e35c8ac42e 100644 --- a/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/components/RecordDetailRecordsListContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/components/RecordDetailRecordsListContainer.tsx @@ -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 }; diff --git a/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/components/RecordDetailRecordsListItemContainer.tsx b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/components/RecordDetailRecordsListItemContainer.tsx index 11ce48f2c2..63afc960a7 100644 --- a/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/components/RecordDetailRecordsListItemContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/components/RecordDetailRecordsListItemContainer.tsx @@ -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 = ({ {children} diff --git a/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/components/RecordDetailSectionContainer.tsx b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/components/RecordDetailSectionContainer.tsx index be582e014a..a487303954 100644 --- a/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/components/RecordDetailSectionContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/components/RecordDetailSectionContainer.tsx @@ -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}; } `; diff --git a/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationRecordsListItem.tsx b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationRecordsListItem.tsx index 6dd1c86a46..688f6271e3 100644 --- a/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationRecordsListItem.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field-list/record-detail-section/relation/components/RecordDetailRelationRecordsListItem.tsx @@ -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 ( <> - @@ -286,7 +264,7 @@ export const RecordDetailRelationRecordsListItem = ({ } /> )} - + theme.spacing(1)}; + padding: 0 ${themeCssVariables.spacing[1]}; `; export type LightCopyIconButtonProps = { diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/BaseChip.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/BaseChip.tsx index 90232c0ca3..1c44f6fb2b 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/BaseChip.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/BaseChip.tsx @@ -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 ( diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormAdvancedTextFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormAdvancedTextFieldInput.tsx index cdf40c240e..127a8c2bef 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormAdvancedTextFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormAdvancedTextFieldInput.tsx @@ -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(); diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormArrayFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormArrayFieldInput.tsx index bec33e6bb9..b2853017ca 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormArrayFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormArrayFieldInput.tsx @@ -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(); diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormBooleanFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormBooleanFieldInput.tsx index fe60b4b96c..f4c41da20e 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormBooleanFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormBooleanFieldInput.tsx @@ -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(); diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormBooleanFieldToggleInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormBooleanFieldToggleInput.tsx index 2619b6dbcd..4e829ba050 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormBooleanFieldToggleInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormBooleanFieldToggleInput.tsx @@ -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 = ({ diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormDateFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormDateFieldInput.tsx index 175f03a7d7..b118c45e38 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormDateFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormDateFieldInput.tsx @@ -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` diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormDateTimeFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormDateTimeFieldInput.tsx index c118e604b3..0d54a4b07c 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormDateTimeFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormDateTimeFieldInput.tsx @@ -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` diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormFieldInputContainer.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormFieldInputContainer.tsx index 7ea0e36f56..bb76e956da 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormFieldInputContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormFieldInputContainer.tsx @@ -1,4 +1,4 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; const StyledFormFieldInputContainer = styled.div` display: flex; diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormFieldInputInnerContainer.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormFieldInputInnerContainer.tsx index edab7c4d4e..0a2efe5301 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormFieldInputInnerContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormFieldInputInnerContainer.tsx @@ -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 >` - 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; diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormFieldInputRowContainer.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormFieldInputRowContainer.tsx index 35ec5bd612..36ceb9c163 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormFieldInputRowContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormFieldInputRowContainer.tsx @@ -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; diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormFieldPlaceholder.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormFieldPlaceholder.tsx index 6e349b868b..1a8e1ec5c2 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormFieldPlaceholder.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormFieldPlaceholder.tsx @@ -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} diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormMultiSelectFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormMultiSelectFieldInput.tsx index 151e350c69..edfbd30b3f 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormMultiSelectFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormMultiSelectFieldInput.tsx @@ -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 } = diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormNestedFieldInputContainer.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormNestedFieldInputContainer.tsx index c2beb37f18..e216bbe50a 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormNestedFieldInputContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormNestedFieldInputContainer.tsx @@ -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 = diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormSelectFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormSelectFieldInput.tsx index ef6b03f1fd..938a5b8ff4 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormSelectFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormSelectFieldInput.tsx @@ -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(); diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormSingleRecordFieldChip.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormSingleRecordFieldChip.tsx index 6eb92ae472..6e88154453 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormSingleRecordFieldChip.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormSingleRecordFieldChip.tsx @@ -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 = { diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormSingleRecordPicker.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormSingleRecordPicker.tsx index 02d2c3bd26..4ae719b234 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormSingleRecordPicker.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/FormSingleRecordPicker.tsx @@ -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) => { - // Prevents the dropdown to open when clicking on the chip event?.stopPropagation(); onClear?.(); }; diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/TextVariableEditor.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/TextVariableEditor.tsx index 29e332e0ee..c32121ca8a 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/TextVariableEditor.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/TextVariableEditor.tsx @@ -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]}; } } diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/VariableChip.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/VariableChip.tsx index d7f22a1cdd..85d8f70941 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/VariableChip.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/VariableChip.tsx @@ -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({ diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/VariableChipStandalone.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/VariableChipStandalone.tsx index c07b28225c..ade6102fc7 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/VariableChipStandalone.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/form-types/components/VariableChipStandalone.tsx @@ -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 = { diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/display/components/ForbiddenFieldDisplay.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/display/components/ForbiddenFieldDisplay.tsx index ef383e8f55..1edbad8c6d 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/display/components/ForbiddenFieldDisplay.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/display/components/ForbiddenFieldDisplay.tsx @@ -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 ( - + Not shared diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/display/components/RelationFromManyFieldDisplay.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/display/components/RelationFromManyFieldDisplay.tsx index 0fc61b7d67..86535b8f02 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/display/components/RelationFromManyFieldDisplay.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/display/components/RelationFromManyFieldDisplay.tsx @@ -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; diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/MultiItemBaseInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/MultiItemBaseInput.tsx index 0c1e31052e..a9b790d735 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/MultiItemBaseInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/MultiItemBaseInput.tsx @@ -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; diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/PhonesFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/PhonesFieldInput.tsx index 84008ede03..e13daf536e 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/PhonesFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/PhonesFieldInput.tsx @@ -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 = () => { diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx index 42ef7887cd..4768e75881 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/RawJsonFieldInput.tsx @@ -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; `; diff --git a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/RichTextFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/RichTextFieldInput.tsx index a5bc356fcd..5aabe2a137 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/RichTextFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/ui/meta-types/input/components/RichTextFieldInput.tsx @@ -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 ( theme.spacing(10)}); - margin-left: ${({ theme }) => theme.spacing(2)}; + height: calc(100% - ${themeCssVariables.spacing[10]}); + margin-left: ${themeCssVariables.spacing[2]}; `; export const RecordIndexContainer = () => { diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainerGater.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainerGater.tsx index c9f20a99c6..edbdf87899 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainerGater.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexContainerGater.tsx @@ -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'; diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageHeader.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageHeader.tsx index 564832702b..c2cfff8ef8 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageHeader.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageHeader.tsx @@ -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 = () => { diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageHeaderIcon.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageHeaderIcon.tsx index 154cbc5325..439f2be38b 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageHeaderIcon.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageHeaderIcon.tsx @@ -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, ); diff --git a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageKanbanAddMenuItem.tsx b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageKanbanAddMenuItem.tsx index 847449db42..ed5470b40a 100644 --- a/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageKanbanAddMenuItem.tsx +++ b/packages/twenty-front/src/modules/object-record/record-index/components/RecordIndexPageKanbanAddMenuItem.tsx @@ -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'; diff --git a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellContainer.tsx b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellContainer.tsx index d9704585b3..0af9e83e43 100644 --- a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellContainer.tsx @@ -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, diff --git a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellDisplayMode.tsx b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellDisplayMode.tsx index 9b8833db15..e5a12663bb 100644 --- a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellDisplayMode.tsx +++ b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellDisplayMode.tsx @@ -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; `; diff --git a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellEditButton.tsx b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellEditButton.tsx index ca5781202c..621580c83c 100644 --- a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellEditButton.tsx +++ b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellEditButton.tsx @@ -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'; diff --git a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellEditMode.tsx b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellEditMode.tsx index eb960474f0..3462661ae1 100644 --- a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellEditMode.tsx +++ b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellEditMode.tsx @@ -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, diff --git a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellHoveredPortal.tsx b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellHoveredPortal.tsx index b59f667996..9948588e02 100644 --- a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellHoveredPortal.tsx +++ b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellHoveredPortal.tsx @@ -1,4 +1,4 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; const StyledRecordTableCellHoveredPortal = styled.div` height: 100%; diff --git a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellHoveredPortalContent.tsx b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellHoveredPortalContent.tsx index 4d33c12dbf..5b921bfc09 100644 --- a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellHoveredPortalContent.tsx +++ b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellHoveredPortalContent.tsx @@ -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; `; diff --git a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellSkeletonLoader.tsx b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellSkeletonLoader.tsx index bd912d7b55..3a19ee2fb5 100644 --- a/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellSkeletonLoader.tsx +++ b/packages/twenty-front/src/modules/object-record/record-inline-cell/components/RecordInlineCellSkeletonLoader.tsx @@ -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 ( ` 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 = () => { diff --git a/packages/twenty-front/src/modules/object-record/record-inline-cell/property-box/components/PropertyBox.tsx b/packages/twenty-front/src/modules/object-record/record-inline-cell/property-box/components/PropertyBox.tsx index 126e91831d..d697638fef 100644 --- a/packages/twenty-front/src/modules/object-record/record-inline-cell/property-box/components/PropertyBox.tsx +++ b/packages/twenty-front/src/modules/object-record/record-inline-cell/property-box/components/PropertyBox.tsx @@ -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 = ({ diff --git a/packages/twenty-front/src/modules/object-record/record-inline-cell/property-box/components/PropertyBoxSkeletonLoader.tsx b/packages/twenty-front/src/modules/object-record/record-inline-cell/property-box/components/PropertyBoxSkeletonLoader.tsx index 88a499952c..cdcaeb4bd4 100644 --- a/packages/twenty-front/src/modules/object-record/record-inline-cell/property-box/components/PropertyBoxSkeletonLoader.tsx +++ b/packages/twenty-front/src/modules/object-record/record-inline-cell/property-box/components/PropertyBoxSkeletonLoader.tsx @@ -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}`, })); diff --git a/packages/twenty-front/src/modules/object-record/record-merge/components/MergeRecordsContainer.tsx b/packages/twenty-front/src/modules/object-record/record-merge/components/MergeRecordsContainer.tsx index a8ee634633..5f852e76b7 100644 --- a/packages/twenty-front/src/modules/object-record/record-merge/components/MergeRecordsContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-merge/components/MergeRecordsContainer.tsx @@ -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 = { diff --git a/packages/twenty-front/src/modules/object-record/record-merge/components/MergeRecordsFooter.tsx b/packages/twenty-front/src/modules/object-record/record-merge/components/MergeRecordsFooter.tsx index 228af53c68..4c2896ccc0 100644 --- a/packages/twenty-front/src/modules/object-record/record-merge/components/MergeRecordsFooter.tsx +++ b/packages/twenty-front/src/modules/object-record/record-merge/components/MergeRecordsFooter.tsx @@ -1,26 +1,27 @@ import { SIDE_PANEL_FOCUS_ID } from '@/command-menu/constants/SidePanelFocusId'; import { useMergeRecordsActions } from '@/object-record/record-merge/hooks/useMergeRecordsActions'; import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { Key } from 'ts-key-enum'; import { t } from '@lingui/core/macro'; import { IconArrowMerge } from 'twenty-ui/display'; import { Button } from 'twenty-ui/input'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledFooterContainer = styled.div` align-items: flex-end; - background: ${({ theme }) => theme.background.primary}; - border-top: 1px solid ${({ theme }) => theme.border.color.light}; + background: ${themeCssVariables.background.primary}; + border-top: 1px solid ${themeCssVariables.border.color.light}; display: flex; - gap: ${({ theme }) => theme.spacing(2)}; + gap: ${themeCssVariables.spacing[2]}; justify-content: flex-end; - padding: ${({ theme }) => theme.spacing(3)}; + padding: ${themeCssVariables.spacing[3]}; `; const StyledFooterActions = styled.div` display: flex; align-items: flex-end; - gap: ${({ theme }) => theme.spacing(2)}; + gap: ${themeCssVariables.spacing[2]}; `; type MergeRecordsFooterProps = { diff --git a/packages/twenty-front/src/modules/object-record/record-merge/components/MergeSettingsTab.tsx b/packages/twenty-front/src/modules/object-record/record-merge/components/MergeSettingsTab.tsx index e318654554..323022cadb 100644 --- a/packages/twenty-front/src/modules/object-record/record-merge/components/MergeSettingsTab.tsx +++ b/packages/twenty-front/src/modules/object-record/record-merge/components/MergeSettingsTab.tsx @@ -2,13 +2,14 @@ import { t } from '@lingui/core/macro'; import { useMergeRecordsSelectedRecords } from '@/object-record/record-merge/hooks/useMergeRecordsSelectedRecords'; import { useMergeRecordsSettings } from '@/object-record/record-merge/hooks/useMergeRecordsSettings'; import { Select } from '@/ui/input/components/Select'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { Section } from 'twenty-ui/layout'; import { getPositionNumberIcon } from '@/object-record/record-merge/utils/getPositionNumberIcon'; import { getPositionWordLabel } from '@/object-record/record-merge/utils/getPositionWordLabel'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledSection = styled(Section)` - margin: ${({ theme }) => theme.spacing(4)}; + margin: ${themeCssVariables.spacing[4]}; width: auto; `; diff --git a/packages/twenty-front/src/modules/object-record/record-picker/components/RecordPickerInitialLoadingEmptyContainer.tsx b/packages/twenty-front/src/modules/object-record/record-picker/components/RecordPickerInitialLoadingEmptyContainer.tsx index b7e895c1a8..4620e46ace 100644 --- a/packages/twenty-front/src/modules/object-record/record-picker/components/RecordPickerInitialLoadingEmptyContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-picker/components/RecordPickerInitialLoadingEmptyContainer.tsx @@ -1,4 +1,4 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; const StyledRecordPickerInitialLoadingEmptyContainer = styled.div` height: 320px; diff --git a/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerFetchMoreLoader.tsx b/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerFetchMoreLoader.tsx index ef602b99f9..3e47edd39b 100644 --- a/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerFetchMoreLoader.tsx +++ b/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerFetchMoreLoader.tsx @@ -14,19 +14,20 @@ import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/com import { useAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentState'; import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue'; import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { useCallback } from 'react'; import { useInView } from 'react-intersection-observer'; import { useStore } from 'jotai'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledText = styled.div` align-items: center; box-shadow: none; - color: ${({ theme }) => theme.grayScale.gray9}; + color: ${themeCssVariables.grayScale.gray9}; display: flex; height: 32px; - margin-left: ${({ theme }) => theme.spacing(8)}; - padding-left: ${({ theme }) => theme.spacing(2)}; + margin-left: ${themeCssVariables.spacing[8]}; + padding-left: ${themeCssVariables.spacing[2]}; `; const StyledIntersectionObserver = styled.div` diff --git a/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerMenuItem.tsx b/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerMenuItem.tsx index 99f6b69afd..837ae06ba6 100644 --- a/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerMenuItem.tsx +++ b/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerMenuItem.tsx @@ -1,4 +1,4 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { useRecordPickerGetSearchRecordAndObjectMetadataItemFromRecordId } from '@/object-record/record-picker/hooks/useRecordPickerGetSearchRecordAndObjectMetadataItemFromRecordId'; import { MultipleRecordPickerMenuItemContent } from '@/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerMenuItemContent'; diff --git a/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerMenuItemContent.tsx b/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerMenuItemContent.tsx index 4655fbbdea..8a97314b2a 100644 --- a/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerMenuItemContent.tsx +++ b/packages/twenty-front/src/modules/object-record/record-picker/multiple-record-picker/components/MultipleRecordPickerMenuItemContent.tsx @@ -1,5 +1,5 @@ import { t } from '@lingui/core/macro'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { type ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem'; import { getAvatarType } from '@/object-metadata/utils/getAvatarType'; diff --git a/packages/twenty-front/src/modules/object-record/record-picker/single-record-picker/components/SingleRecordPickerMenuItem.tsx b/packages/twenty-front/src/modules/object-record/record-picker/single-record-picker/components/SingleRecordPickerMenuItem.tsx index 73b6f29d8a..a127079af8 100644 --- a/packages/twenty-front/src/modules/object-record/record-picker/single-record-picker/components/SingleRecordPickerMenuItem.tsx +++ b/packages/twenty-front/src/modules/object-record/record-picker/single-record-picker/components/SingleRecordPickerMenuItem.tsx @@ -1,4 +1,4 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { getAvatarType } from '@/object-metadata/utils/getAvatarType'; import { searchRecordStoreFamilyState } from '@/object-record/record-picker/multiple-record-picker/states/searchRecordStoreComponentFamilyState'; diff --git a/packages/twenty-front/src/modules/object-record/record-show/components/ObjectRecordShowPageBreadcrumb.tsx b/packages/twenty-front/src/modules/object-record/record-show/components/ObjectRecordShowPageBreadcrumb.tsx index 24c2417b2f..390cd952a5 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/components/ObjectRecordShowPageBreadcrumb.tsx +++ b/packages/twenty-front/src/modules/object-record/record-show/components/ObjectRecordShowPageBreadcrumb.tsx @@ -8,9 +8,11 @@ import { useRecordShowPage } from '@/object-record/record-show/hooks/useRecordSh import { useRecordShowPagePagination } from '@/object-record/record-show/hooks/useRecordShowPagePagination'; import { RecordTitleCell } from '@/object-record/record-title-cell/components/RecordTitleCell'; import { RecordTitleCellContainerType } from '@/object-record/record-title-cell/types/RecordTitleCellContainerType'; -import { useTheme } from '@emotion/react'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; +import { useContext } from 'react'; import { FieldMetadataType } from 'twenty-shared/types'; +import { ThemeContext } from 'twenty-ui/theme'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledEditableTitleContainer = styled.div` align-items: center; @@ -22,11 +24,11 @@ const StyledEditableTitleContainer = styled.div` const StyledEditableTitlePrefix = styled.div` align-items: center; - color: ${({ theme }) => theme.font.color.tertiary}; + color: ${themeCssVariables.font.color.tertiary}; cursor: pointer; display: flex; flex-direction: row; - gap: ${({ theme }) => theme.spacing(1)}; + gap: ${themeCssVariables.spacing[1]}; `; const StyledTitle = styled.div` @@ -36,7 +38,7 @@ const StyledTitle = styled.div` `; const StyledPaginationInformation = styled.span` - color: ${({ theme }) => theme.font.color.tertiary}; + color: ${themeCssVariables.font.color.tertiary}; `; export const ObjectRecordShowPageBreadcrumb = ({ @@ -80,7 +82,7 @@ export const ObjectRecordShowPageBreadcrumb = ({ objectRecordId, ); - const theme = useTheme(); + const { theme } = useContext(ThemeContext); if (loading) { return null; diff --git a/packages/twenty-front/src/modules/object-record/record-show/components/PageLayoutRecordPageRenderer.tsx b/packages/twenty-front/src/modules/object-record/record-show/components/PageLayoutRecordPageRenderer.tsx index d76a10cf68..5a5e8e59ed 100644 --- a/packages/twenty-front/src/modules/object-record/record-show/components/PageLayoutRecordPageRenderer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-show/components/PageLayoutRecordPageRenderer.tsx @@ -10,9 +10,10 @@ import { usePageLayoutIdForRecord } from '@/page-layout/hooks/usePageLayoutIdFor import { LayoutRenderingProvider } from '@/ui/layout/contexts/LayoutRenderingContext'; import { type TargetRecordIdentifier } from '@/ui/layout/contexts/TargetRecordIdentifier'; import { RightDrawerFooter } from '@/ui/layout/right-drawer/components/RightDrawerFooter'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { useAtomFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilySelectorValue'; import { isDefined } from 'twenty-shared/utils'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; import { PageLayoutType } from '~/generated-metadata/graphql'; const StyledShowPageBannerContainer = styled.div` @@ -31,9 +32,9 @@ const StyledShowPageRightContainer = styled.div` const StyledContentContainer = styled.div<{ isInRightDrawer: boolean }>` flex: 1; overflow-y: auto; - background: ${({ theme }) => theme.background.primary}; - padding-bottom: ${({ theme, isInRightDrawer }) => - isInRightDrawer ? theme.spacing(16) : 0}; + background: ${themeCssVariables.background.primary}; + padding-bottom: ${({ isInRightDrawer }) => + isInRightDrawer ? themeCssVariables.spacing[16] : 0}; `; export const PageLayoutRecordPageRenderer = ({ diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableContent.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableContent.tsx index b31a4b78fe..91dae7b2cf 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableContent.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableContent.tsx @@ -1,6 +1,9 @@ import { RecordTableColumnWidthEffect } from '@/object-record/record-table/components/RecordTableColumnWidthEffect'; import { RecordTableScrollAndZIndexEffect } from '@/object-record/record-table/components/RecordTableScrollAndZIndexEffect'; -import { RecordTableStyleWrapper } from '@/object-record/record-table/components/RecordTableStyleWrapper'; +import { + getRecordTableColumnWidthInlineStyles, + RecordTableStyleWrapper, +} from '@/object-record/record-table/components/RecordTableStyleWrapper'; import { RecordTableWidthEffect } from '@/object-record/record-table/components/RecordTableWidthEffect'; import { RECORD_TABLE_HTML_ID } from '@/object-record/record-table/constants/RecordTableHtmlId'; import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext'; @@ -15,8 +18,8 @@ import { RECORD_INDEX_DRAG_SELECT_BOUNDARY_CLASS } from '@/ui/utilities/drag-sel import { useAtomComponentStateCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateCallbackState'; import { useAtomComponentSelectorCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorCallbackState'; import { useAtomComponentFamilyStateCallbackState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyStateCallbackState'; -import styled from '@emotion/styled'; -import { useCallback, useRef, useState } from 'react'; +import { styled } from '@linaria/react'; +import { useCallback, useMemo, useRef, useState } from 'react'; import { useStore } from 'jotai'; const StyledTableContainer = styled.div` @@ -125,12 +128,17 @@ export const RecordTableContent = ({ [store, isSomeCellInEditMode, recordTableHoverPositionCallbackState], ); + const columnWidthStyles = useMemo( + () => getRecordTableColumnWidthInlineStyles(visibleRecordFields), + [visibleRecordFields], + ); + return ( ` @@ -81,11 +85,16 @@ export const RecordTableEmpty = ({ tableBodyRef }: RecordTableEmptyProps) => { hasRecordGroupsComponentSelector, ); + const columnWidthStyles = useMemo( + () => getRecordTableColumnWidthInlineStyles(visibleRecordFields), + [visibleRecordFields], + ); + return ( diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableStyleWrapper.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableStyleWrapper.tsx index 1507f7b569..a11d0237a7 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableStyleWrapper.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableStyleWrapper.tsx @@ -15,15 +15,15 @@ import { RECORD_TABLE_VERTICAL_SCROLL_SHADOW_VISIBILITY_CSS_VARIABLE_NAME } from import { TABLE_Z_INDEX } from '@/object-record/record-table/constants/TableZIndex'; import { getRecordTableColumnFieldWidthClassName } from '@/object-record/record-table/utils/getRecordTableColumnFieldWidthClassName'; import { getRecordTableColumnFieldWidthCSSVariableName } from '@/object-record/record-table/utils/getRecordTableColumnFieldWidthCSSVariableName'; -import { css, type Theme } from '@emotion/react'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; -export const VerticalScrollBoxShadowCSS = ({ theme }: { theme: Theme }) => css` +export const VerticalScrollBoxShadowCSS = ` &::before { bottom: -1px; box-shadow: - 0px 2px 4px 0px ${theme.boxShadow.color}, - 0px 0px 4px 0px ${theme.boxShadow.color}; + 0px 2px 4px 0px ${themeCssVariables.boxShadow.color}, + 0px 0px 4px 0px ${themeCssVariables.boxShadow.color}; clip-path: inset(0px 0px -4px 0px); content: ''; height: 4px; @@ -36,11 +36,7 @@ export const VerticalScrollBoxShadowCSS = ({ theme }: { theme: Theme }) => css` } `; -export const HorizontalScrollBoxShadowCSS = ({ - theme, -}: { - theme: Theme; -}) => css` +export const HorizontalScrollBoxShadowCSS = ` &::after { content: ''; position: absolute; @@ -49,8 +45,8 @@ export const HorizontalScrollBoxShadowCSS = ({ width: 4px; right: -1px; box-shadow: - 2px 0px 4px 0px ${theme.boxShadow.color}, - 0px 0px 4px 0px ${theme.boxShadow.color}; + 2px 0px 4px 0px ${themeCssVariables.boxShadow.color}, + 0px 0px 4px 0px ${themeCssVariables.boxShadow.color}; clip-path: inset(0px -4px 0px 0px); visibility: var( ${RECORD_TABLE_HORIZONTAL_SCROLL_SHADOW_VISIBILITY_CSS_VARIABLE_NAME}, @@ -59,9 +55,31 @@ export const HorizontalScrollBoxShadowCSS = ({ } `; +const MAX_COLUMNS = 100; + +const columnFieldWidthRules = Array.from( + { length: MAX_COLUMNS }, + (_, i) => + `div.${getRecordTableColumnFieldWidthClassName(i)} { + width: var(${getRecordTableColumnFieldWidthCSSVariableName(i)}); + min-width: var(${getRecordTableColumnFieldWidthCSSVariableName(i)}); + max-width: var(${getRecordTableColumnFieldWidthCSSVariableName(i)}); + }`, +).join('\n'); + +export const getRecordTableColumnWidthInlineStyles = ( + visibleRecordFields: RecordField[], +): Record => { + const style: Record = {}; + for (let i = 0; i < visibleRecordFields.length; i++) { + style[`--record-table-column-field-${i}`] = + `${visibleRecordFields[i].size}px`; + } + return style; +}; + const StyledTable = styled.div<{ isDragging?: boolean; - visibleRecordFields: RecordField[]; hasRecordGroups: boolean; }>` & > * { @@ -92,7 +110,7 @@ const StyledTable = styled.div<{ div.header-cell:nth-of-type(1) { left: 0px; - background-color: ${({ theme }) => theme.background.primary}; + background-color: ${themeCssVariables.background.primary}; z-index: ${({ hasRecordGroups }) => hasRecordGroups @@ -104,7 +122,7 @@ const StyledTable = styled.div<{ left: ${RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH}px; top: 0; - background-color: ${({ theme }) => theme.background.primary}; + background-color: ${themeCssVariables.background.primary}; z-index: ${({ hasRecordGroups }) => hasRecordGroups @@ -117,7 +135,7 @@ const StyledTable = styled.div<{ RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}px; right: 0; - background-color: ${({ theme }) => theme.background.primary}; + background-color: ${themeCssVariables.background.primary}; z-index: ${({ hasRecordGroups }) => hasRecordGroups @@ -183,23 +201,7 @@ const StyledTable = styled.div<{ max-width: ${RECORD_TABLE_COLUMN_ADD_COLUMN_BUTTON_WIDTH}px; } - ${({ visibleRecordFields }) => { - let returnedCSS = ''; - - for (let i = 0; i < visibleRecordFields.length; i++) { - returnedCSS += `--record-table-column-field-${i}: ${visibleRecordFields[i].size}px; \n`; - } - - for (let i = 0; i < visibleRecordFields.length; i++) { - returnedCSS += `div.${getRecordTableColumnFieldWidthClassName(i)} { - width: var(${getRecordTableColumnFieldWidthCSSVariableName(i)}); - min-width: var(${getRecordTableColumnFieldWidthCSSVariableName(i)}); - max-width: var(${getRecordTableColumnFieldWidthCSSVariableName(i)}); - } \n`; - } - - return returnedCSS; - }}; + ${columnFieldWidthRules} div.${RECORD_TABLE_COLUMN_LAST_EMPTY_COLUMN_WIDTH_CLASS_NAME} { width: var(${RECORD_TABLE_COLUMN_LAST_EMPTY_COLUMN_WIDTH_VARIABLE_NAME}); diff --git a/packages/twenty-front/src/modules/object-record/record-table/empty-state/components/RecordTableEmptyStateDisplay.tsx b/packages/twenty-front/src/modules/object-record/record-table/empty-state/components/RecordTableEmptyStateDisplay.tsx index 8bf547d328..b09a18116f 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/empty-state/components/RecordTableEmptyStateDisplay.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/empty-state/components/RecordTableEmptyStateDisplay.tsx @@ -4,8 +4,7 @@ import { hasAnySoftDeleteFilterOnViewComponentSelector } from '@/object-record/r import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext'; import { useScrollWrapperHTMLElement } from '@/ui/utilities/scroll/hooks/useScrollWrapperHTMLElement'; import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue'; -import styled from '@emotion/styled'; -import { isDefined } from 'twenty-shared/utils'; +import { styled } from '@linaria/react'; import { type IconComponent } from 'twenty-ui/display'; import { Button } from 'twenty-ui/input'; import { @@ -23,12 +22,6 @@ const StyledEmptyPlaceholderOuterContainer = styled( align-items: flex-start; `; -const StyledEmptyPlaceholderInnerContainer = styled( - AnimatedPlaceholderEmptyContainer, -)<{ width?: number }>` - width: ${({ width }) => (isDefined(width) ? `${width}px` : '100%')}; -`; - type RecordTableEmptyStateDisplayButtonComponentProps = { buttonComponent?: React.ReactNode; }; @@ -71,7 +64,7 @@ export const RecordTableEmptyStateDisplay = ( return ( - + @@ -93,7 +86,7 @@ export const RecordTableEmptyStateDisplay = ( disabled={props.buttonIsDisabled} /> )} - + ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBody.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBody.tsx index 00595fe97d..9509fe3746 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBody.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBody.tsx @@ -1,4 +1,4 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; const StyledTableBody = styled.div` display: flex; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyVirtualizedDraggableClone.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyVirtualizedDraggableClone.tsx index 2d80936210..525794c2bc 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyVirtualizedDraggableClone.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-body/components/RecordTableBodyVirtualizedDraggableClone.tsx @@ -1,5 +1,7 @@ -import { type RecordField } from '@/object-record/record-field/types/RecordField'; -import { HorizontalScrollBoxShadowCSS } from '@/object-record/record-table/components/RecordTableStyleWrapper'; +import { + getRecordTableColumnWidthInlineStyles, + HorizontalScrollBoxShadowCSS, +} from '@/object-record/record-table/components/RecordTableStyleWrapper'; import { RECORD_TABLE_COLUMN_ADD_COLUMN_BUTTON_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnAddColumnButtonWidth'; import { RECORD_TABLE_COLUMN_ADD_COLUMN_BUTTON_WIDTH_CLASS_NAME } from '@/object-record/record-table/constants/RecordTableColumnAddColumnButtonWidthClassName'; import { RECORD_TABLE_COLUMN_CHECKBOX_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnCheckboxWidth'; @@ -24,25 +26,48 @@ import { RecordTableRowMultiDragPreview } from '@/object-record/record-table/rec import { RecordTableTr } from '@/object-record/record-table/record-table-row/components/RecordTableTr'; import { useIsTableRowSecondaryDragged } from '@/object-record/record-table/record-table-row/hooks/useIsRecordSecondaryDragged'; import { getRecordTableColumnFieldWidthClassName } from '@/object-record/record-table/utils/getRecordTableColumnFieldWidthClassName'; -import { getRecordTableColumnFieldWidthCSSVariableName } from '@/object-record/record-table/utils/getRecordTableColumnFieldWidthCSSVariableName'; import { recordIdByRealIndexComponentFamilySelector } from '@/object-record/record-table/virtualization/states/recordIdByRealIndexComponentFamilySelector'; import { useAtomComponentFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilySelectorValue'; -import { useTheme } from '@emotion/react'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { type DraggableProvided, type DraggableRubric, type DraggableStateSnapshot, } from '@hello-pangea/dnd'; +import { useContext, useMemo } from 'react'; import { isDefined } from 'twenty-shared/utils'; -import { MOBILE_VIEWPORT } from 'twenty-ui/theme'; +import { ThemeContext } from 'twenty-ui/theme'; +import { MOBILE_VIEWPORT } from 'twenty-ui/theme-constants'; -// TODO: see how we can merge this with RecordTableStyleWrapper, -// because we have not decided a strategy for sharing CSS bits yet -const StyledRowDraggableCloneCSSBridge = styled.div<{ - visibleRecordFields: RecordField[]; - lastColumnWidth: number; -}>` +const MAX_COLUMNS = 100; + +const cloneColumnFieldWidthRules = Array.from( + { length: MAX_COLUMNS }, + (_, i) => { + const className = getRecordTableColumnFieldWidthClassName(i); + const cssVar = `var(--record-table-column-field-${i})`; + const baseRule = `div.${className} { + width: ${cssVar}; + min-width: ${cssVar}; + max-width: ${cssVar}; + }`; + + if (i === 0) { + return `${baseRule} + div.${className} { + @media (max-width: ${MOBILE_VIEWPORT}px) { + width: ${RECORD_TABLE_LABEL_IDENTIFIER_COLUMN_WIDTH_ON_MOBILE}px; + max-width: ${RECORD_TABLE_LABEL_IDENTIFIER_COLUMN_WIDTH_ON_MOBILE}px; + min-width: ${RECORD_TABLE_LABEL_IDENTIFIER_COLUMN_WIDTH_ON_MOBILE}px; + } + }`; + } + + return baseRule; + }, +).join('\n'); + +const StyledRowDraggableCloneCSSBridge = styled.div` div.table-cell:nth-of-type(1) { position: sticky; left: 0px; @@ -90,38 +115,7 @@ const StyledRowDraggableCloneCSSBridge = styled.div<{ max-width: ${RECORD_TABLE_COLUMN_ADD_COLUMN_BUTTON_WIDTH}px; } - ${({ visibleRecordFields, lastColumnWidth }) => { - let returnedCSS = ''; - - for (let i = 0; i < visibleRecordFields.length; i++) { - returnedCSS += `--record-table-column-field-${i}: ${visibleRecordFields[i].size}px; \n`; - } - - for (let i = 0; i < visibleRecordFields.length; i++) { - returnedCSS += `div.${getRecordTableColumnFieldWidthClassName(i)} { - width: var(${getRecordTableColumnFieldWidthCSSVariableName(i)}); - min-width: var(${getRecordTableColumnFieldWidthCSSVariableName(i)}); - max-width: var(${getRecordTableColumnFieldWidthCSSVariableName(i)}); - } \n`; - - const isLabelIdentifierColumn = i === 0; - - if (isLabelIdentifierColumn) { - returnedCSS += `div.${getRecordTableColumnFieldWidthClassName(i)} { - @media (max-width: ${MOBILE_VIEWPORT}px) { - width: ${RECORD_TABLE_LABEL_IDENTIFIER_COLUMN_WIDTH_ON_MOBILE}px; - max-width: ${RECORD_TABLE_LABEL_IDENTIFIER_COLUMN_WIDTH_ON_MOBILE}px; - min-width: ${RECORD_TABLE_LABEL_IDENTIFIER_COLUMN_WIDTH_ON_MOBILE}px; - } - } \n`; - } - } - - returnedCSS += `${RECORD_TABLE_COLUMN_LAST_EMPTY_COLUMN_WIDTH_VARIABLE_NAME}: ${lastColumnWidth}px;`; - returnedCSS += `${RECORD_TABLE_COLUMN_WITH_GROUP_LAST_EMPTY_COLUMN_WIDTH_VARIABLE_NAME}: ${lastColumnWidth}px;`; - - return returnedCSS; - }}; + ${cloneColumnFieldWidthRules} div.${RECORD_TABLE_COLUMN_LAST_EMPTY_COLUMN_WIDTH_CLASS_NAME} { width: var(${RECORD_TABLE_COLUMN_LAST_EMPTY_COLUMN_WIDTH_VARIABLE_NAME}); @@ -145,7 +139,7 @@ export const RecordTableBodyVirtualizedDraggableClone = ({ }) => { const realIndex = rubric.source.index; - const theme = useTheme(); + const { theme } = useContext(ThemeContext); const recordId = useAtomComponentFamilySelectorValue( recordIdByRealIndexComponentFamilySelector, @@ -158,15 +152,23 @@ export const RecordTableBodyVirtualizedDraggableClone = ({ const { isSecondaryDragged } = useIsTableRowSecondaryDragged(recordId); + const columnWidthStyles = useMemo(() => { + const styles: Record = + getRecordTableColumnWidthInlineStyles(visibleRecordFields); + styles[RECORD_TABLE_COLUMN_LAST_EMPTY_COLUMN_WIDTH_VARIABLE_NAME] = + `${lastColumnWidth}px`; + styles[ + RECORD_TABLE_COLUMN_WITH_GROUP_LAST_EMPTY_COLUMN_WIDTH_VARIABLE_NAME + ] = `${lastColumnWidth}px`; + return styles; + }, [visibleRecordFields, lastColumnWidth]); + if (!isDefined(recordId)) { return null; } return ( - + { - if (!props.isReadOnly) return ''; + outline: ${({ isReadOnly, fontColorMedium }) => + isReadOnly ? `1px solid ${fontColorMedium}` : 'unset'}; + border-radius: ${({ isReadOnly }) => (isReadOnly ? '0px' : 'unset')}; + background-color: ${({ isReadOnly, backgroundColorSecondary }) => + isReadOnly ? backgroundColorSecondary : 'unset'}; + color: ${({ isReadOnly, fontColorSecondary }) => + isReadOnly ? fontColorSecondary : 'unset'}; - return ` - outline: 1px solid ${props.fontColorMedium}; - border-radius: 0px; - background-color: ${props.backgroundColorSecondary}; - color: ${props.fontColorSecondary}; - - svg { - color: ${props.fontColorSecondary}; - } - - img { - opacity: 0.64; - } - `; - }} + svg { + color: ${({ isReadOnly, fontColorSecondary }) => + isReadOnly ? fontColorSecondary : 'unset'}; + } + + img { + opacity: ${({ isReadOnly }) => (isReadOnly ? '0.64' : 'unset')}; + } } `; @@ -74,11 +70,7 @@ export const RecordTableCellBaseContainer = ({ return ( theme.spacing(1)}; + margin: ${themeCssVariables.spacing[1]}; @media (max-width: ${MOBILE_VIEWPORT}px) { position: relative; right: 7px; } - border-radius: ${({ theme }) => theme.border.radius.sm}; - border: 1px solid ${({ theme }) => theme.border.color.strong}; + border-radius: ${themeCssVariables.border.radius.sm}; + border: 1px solid ${themeCssVariables.border.color.strong}; `; type RecordTableCellButtonsProps = { diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellCheckbox.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellCheckbox.tsx index cb3e81ea1d..3735578c0e 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellCheckbox.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellCheckbox.tsx @@ -1,5 +1,6 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { useCallback } from 'react'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; import { RECORD_TABLE_COLUMN_CHECKBOX_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnCheckboxWidth'; import { RECORD_TABLE_COLUMN_CHECKBOX_WIDTH_CLASS_NAME } from '@/object-record/record-table/constants/RecordTableColumnCheckboxWidthClassName'; @@ -18,7 +19,7 @@ const StyledContainer = styled.div` justify-content: center; min-width: ${RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}; width: ${RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}; - padding-right: ${({ theme }) => theme.spacing(1)}; + padding-right: ${themeCssVariables.spacing[1]}; `; // TODO: refactor diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellCheckboxPlaceholder.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellCheckboxPlaceholder.tsx index c200d0cea7..30ba1cdad7 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellCheckboxPlaceholder.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellCheckboxPlaceholder.tsx @@ -1,6 +1,7 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { RECORD_TABLE_COLUMN_CHECKBOX_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnCheckboxWidth'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; import { RECORD_TABLE_COLUMN_CHECKBOX_WIDTH_CLASS_NAME } from '@/object-record/record-table/constants/RecordTableColumnCheckboxWidthClassName'; import { RECORD_TABLE_ROW_HEIGHT } from '@/object-record/record-table/constants/RecordTableRowHeight'; import { useRecordTableBodyContextOrThrow } from '@/object-record/record-table/contexts/RecordTableBodyContext'; @@ -15,7 +16,7 @@ const StyledContainer = styled.div` justify-content: center; min-width: ${RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}; width: ${RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}; - padding-right: ${({ theme }) => theme.spacing(1)}; + padding-right: ${themeCssVariables.spacing[1]}; `; // TODO: refactor diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellDisplayContainer.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellDisplayContainer.tsx index 76522348cf..f68ff053b5 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellDisplayContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellDisplayContainer.tsx @@ -1,7 +1,7 @@ import { t } from '@lingui/core/macro'; -import { type Theme, withTheme } from '@emotion/react'; import { styled } from '@linaria/react'; import { type Ref } from 'react'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledOuterContainer = styled.div` align-items: center; @@ -21,10 +21,10 @@ const StyledInnerContainer = styled.div` white-space: nowrap; `; -const StyledEmptyPlaceholderField = withTheme(styled.div<{ theme: Theme }>` - color: ${({ theme }) => theme.font.color.light}; +const StyledEmptyPlaceholderField = styled.div` + color: ${themeCssVariables.font.color.light}; padding-left: 4px; -`); +`; export type EditableCellDisplayContainerProps = { focus?: boolean; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellDragAndDrop.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellDragAndDrop.tsx index 2ae657fe59..e8571c3390 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellDragAndDrop.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellDragAndDrop.tsx @@ -1,6 +1,7 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH_CLASS_NAME } from '@/object-record/record-table/constants/RecordTableColumnDragAndDropWidthClassName'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; import { RECORD_TABLE_ROW_HEIGHT } from '@/object-record/record-table/constants/RecordTableRowHeight'; import { TABLE_Z_INDEX } from '@/object-record/record-table/constants/TableZIndex'; import { useRecordTableRowDraggableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableRowDraggableContext'; @@ -24,7 +25,7 @@ const StyledIconWrapper = styled.div<{ isDragging: boolean }>` opacity: ${({ isDragging }) => (isDragging ? 1 : 0)}; transition: opacity 0.1s; svg path { - fill: ${({ theme }) => theme.border.color.strong}; + fill: ${themeCssVariables.border.color.strong}; } `; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellEditMode.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellEditMode.tsx index 718f3a8b2b..840a09ca0f 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellEditMode.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellEditMode.tsx @@ -9,7 +9,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, diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellFirstRowFirstColumn.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellFirstRowFirstColumn.tsx index 9b229954c8..4c1360a5a7 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellFirstRowFirstColumn.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellFirstRowFirstColumn.tsx @@ -6,7 +6,7 @@ import { recordTableHoverPositionComponentState } from '@/object-record/record-t import { getRecordTableColumnFieldWidthClassName } from '@/object-record/record-table/utils/getRecordTableColumnFieldWidthClassName'; import { useAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentState'; import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { type DraggableProvidedDragHandleProps } from '@hello-pangea/dnd'; import { cx } from '@linaria/core'; import { useContext, type ReactNode } from 'react'; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellFocusedPortalContent.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellFocusedPortalContent.tsx index d0416af17b..28091c5263 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellFocusedPortalContent.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellFocusedPortalContent.tsx @@ -9,26 +9,26 @@ import { recordTableFocusPositionComponentState } from '@/object-record/record-t import { recordTableHoverPositionComponentState } from '@/object-record/record-table/states/recordTableHoverPositionComponentState'; import { useAtomComponentFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyStateValue'; import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { isDefined } from 'twenty-shared/utils'; -import { BORDER_COMMON } from 'twenty-ui/theme'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledRecordTableCellFocusPortalContent = styled.div<{ isRecordTableRowActive: boolean; }>` align-items: center; - background: ${({ theme }) => theme.background.transparent.secondary}; - background-color: ${({ theme, isRecordTableRowActive }) => + background: ${themeCssVariables.background.transparent.secondary}; + background-color: ${({ isRecordTableRowActive }) => isRecordTableRowActive - ? theme.accent.quaternary - : theme.background.primary}; - border-radius: ${BORDER_COMMON.radius.sm}; + ? themeCssVariables.accent.quaternary + : themeCssVariables.background.primary}; + border-radius: ${themeCssVariables.border.radius.sm}; box-sizing: border-box; display: flex; height: ${RECORD_TABLE_ROW_HEIGHT}px; - outline: ${({ theme }) => `1px solid ${theme.color.blue8}`}; + outline: 1px solid ${themeCssVariables.color.blue8}; user-select: none; `; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellHoveredPortalContent.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellHoveredPortalContent.tsx index 8f4c0ae299..12743aba15 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellHoveredPortalContent.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellHoveredPortalContent.tsx @@ -13,9 +13,9 @@ import { isRecordTableRowActiveComponentFamilyState } from '@/object-record/reco import { recordTableHoverPositionComponentState } from '@/object-record/record-table/states/recordTableHoverPositionComponentState'; import { useAtomComponentFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyStateValue'; import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { useContext } from 'react'; -import { BORDER_COMMON } from 'twenty-ui/theme'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; import { useIsMobile } from 'twenty-ui/utilities'; const StyledRecordTableCellHoveredPortalContent = styled.div<{ @@ -23,13 +23,13 @@ const StyledRecordTableCellHoveredPortalContent = styled.div<{ isRecordTableRowActive: boolean; }>` align-items: center; - background: ${({ theme }) => theme.background.transparent.secondary}; - background-color: ${({ theme, isRecordTableRowActive }) => + background: ${themeCssVariables.background.transparent.secondary}; + background-color: ${({ isRecordTableRowActive }) => isRecordTableRowActive - ? theme.accent.quaternary - : theme.background.primary}; + ? themeCssVariables.accent.quaternary + : themeCssVariables.background.primary}; border-radius: ${({ showInteractiveStyle }) => - showInteractiveStyle ? BORDER_COMMON.radius.sm : 'none'}; + showInteractiveStyle ? themeCssVariables.border.radius.sm : 'none'}; box-sizing: border-box; cursor: ${({ showInteractiveStyle }) => showInteractiveStyle ? 'pointer' : 'default'}; @@ -37,12 +37,12 @@ const StyledRecordTableCellHoveredPortalContent = styled.div<{ height: ${RECORD_TABLE_ROW_HEIGHT}px; - outline: ${({ theme, showInteractiveStyle, isRecordTableRowActive }) => + outline: ${({ showInteractiveStyle, isRecordTableRowActive }) => isRecordTableRowActive ? 'none' : showInteractiveStyle - ? `1px solid ${theme.font.color.extraLight}` - : `1px solid ${theme.border.color.medium}`}; + ? `1px solid ${themeCssVariables.font.color.extraLight}` + : `1px solid ${themeCssVariables.border.color.medium}`}; user-select: none; `; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellLoading.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellLoading.tsx index 8a2ac1daee..e74377da75 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellLoading.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellLoading.tsx @@ -1,11 +1,11 @@ import { RecordTableCellStyleWrapper } from '@/object-record/record-table/record-table-cell/components/RecordTableCellStyleWrapper'; import { getRecordTableColumnFieldWidthClassName } from '@/object-record/record-table/utils/getRecordTableColumnFieldWidthClassName'; -import { type Theme, useTheme } from '@emotion/react'; import { styled } from '@linaria/react'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; -const StyledStaticCellSkeleton = styled.div<{ theme: Theme }>` - background-color: ${({ theme }) => theme.background.tertiary}; - border-radius: ${({ theme }) => theme.border.radius.sm}; +const StyledStaticCellSkeleton = styled.div` + background-color: ${themeCssVariables.background.tertiary}; + border-radius: ${themeCssVariables.border.radius.sm}; padding: 8px; margin: 8px; `; @@ -17,14 +17,12 @@ export const RecordTableCellLoading = ({ recordFieldIndex: number; isSelected?: boolean; }) => { - const theme = useTheme(); - return ( - + ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellPortalRootContainer.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellPortalRootContainer.tsx index 0a5d952230..c24f360669 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellPortalRootContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellPortalRootContainer.tsx @@ -1,4 +1,4 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; const StyledRecordTableCellPortalRootContainer = styled.div<{ zIndex?: number; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellSkeletonLoader.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellSkeletonLoader.tsx index 6a492bba02..ba960a42b4 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellSkeletonLoader.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-cell/components/RecordTableCellSkeletonLoader.tsx @@ -1,16 +1,18 @@ 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 StyledSkeletonContainer = styled.div` - padding-left: ${({ theme }) => theme.spacing(2)}; - padding-right: ${({ theme }) => theme.spacing(2)}; - padding-top: ${({ theme }) => theme.spacing(1.6)}; + padding-left: ${themeCssVariables.spacing[2]}; + padding-right: ${themeCssVariables.spacing[2]}; + padding-top: ${themeCssVariables.spacing['1.5']}; `; const StyledRecordTableCellLoader = ({ width }: { width?: number }) => { - const theme = useTheme(); + const { theme } = useContext(ThemeContext); return ( theme.background.primary}; + background-color: ${themeCssVariables.background.primary}; - border-bottom: 1px solid ${({ theme }) => theme.background.primary}; + border-bottom: 1px solid ${themeCssVariables.background.primary}; position: sticky; left: 0; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableAggregateFooter.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableAggregateFooter.tsx index 1d680ddd9b..1c1d63b330 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableAggregateFooter.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableAggregateFooter.tsx @@ -1,6 +1,7 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { RECORD_TABLE_COLUMN_ADD_COLUMN_BUTTON_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnAddColumnButtonWidth'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; import { RECORD_TABLE_COLUMN_CHECKBOX_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnCheckboxWidth'; import { RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnDragAndDropWidth'; import { RECORD_TABLE_COLUMN_LAST_EMPTY_COLUMN_WIDTH_CLASS_NAME } from '@/object-record/record-table/constants/RecordTableColumnLastEmptyColumnWidthClassName'; @@ -13,7 +14,7 @@ import { isDefined } from 'twenty-shared/utils'; const StyledPlaceholderDragAndDropFooterCell = styled.div<{ isTableWithGroups: boolean; }>` - background-color: ${({ theme }) => theme.background.primary}; + background-color: ${themeCssVariables.background.primary}; width: ${RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH + RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}px; position: sticky; @@ -29,7 +30,7 @@ const StyledPlaceholderDragAndDropFooterCell = styled.div<{ const StyledPlaceholderAddButtonPlaceholderFooterCell = styled.div<{ isTableWithGroups: boolean; }>` - background-color: ${({ theme }) => theme.background.primary}; + background-color: ${themeCssVariables.background.primary}; width: ${RECORD_TABLE_COLUMN_ADD_COLUMN_BUTTON_WIDTH}px; position: sticky; bottom: 0; @@ -42,7 +43,7 @@ const StyledPlaceholderAddButtonPlaceholderFooterCell = styled.div<{ const StyledPlaceholderLastColumnEmptyFooterCell = styled.div<{ isTableWithGroups: boolean; }>` - background-color: ${({ theme }) => theme.background.primary}; + background-color: ${themeCssVariables.background.primary}; position: sticky; bottom: 0; z-index: ${({ isTableWithGroups }) => diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableAggregateFooterCell.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableAggregateFooterCell.tsx index d1b5414ac6..a4bff55078 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableAggregateFooterCell.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableAggregateFooterCell.tsx @@ -1,5 +1,6 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { useContext } from 'react'; +import { themeCssVariables, MOBILE_VIEWPORT } from 'twenty-ui/theme-constants'; import { RECORD_TABLE_COLUMN_CHECKBOX_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnCheckboxWidth'; import { RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnDragAndDropWidth'; @@ -12,32 +13,25 @@ import { RecordTableColumnFooterWithDropdown } from '@/object-record/record-tabl import { getRecordTableColumnFieldWidthClassName } from '@/object-record/record-table/utils/getRecordTableColumnFieldWidthClassName'; import { cx } from '@linaria/core'; import { findByProperty, isDefined } from 'twenty-shared/utils'; -import { MOBILE_VIEWPORT } from 'twenty-ui/theme-constants'; const StyledColumnFooterCell = styled.div<{ columnWidth: number; isFirstCell: boolean; isTableWithGroups: boolean; }>` - background-color: ${({ theme }) => theme.background.primary}; - color: ${({ theme }) => theme.font.color.tertiary}; + background-color: ${themeCssVariables.background.primary}; + color: ${themeCssVariables.font.color.tertiary}; - border-right: solid 1px ${({ theme }) => theme.background.primary}; + border-right: solid 1px ${themeCssVariables.background.primary}; padding: 0; - ${({ columnWidth }) => ` - min-width: ${columnWidth}px; - width: ${columnWidth}px; - `} + min-width: ${({ columnWidth }) => columnWidth}px; + width: ${({ columnWidth }) => columnWidth}px; text-align: left; - ${({ theme }) => { - return ` - &:hover { - background: ${theme.background.secondary}; - }; - `; - }}; + &:hover { + background: ${themeCssVariables.background.secondary}; + } height: ${RECORD_TABLE_ROW_HEIGHT}px; overflow: hidden; @@ -45,21 +39,33 @@ const StyledColumnFooterCell = styled.div<{ position: sticky; bottom: 0; - ${({ isFirstCell }) => + left: ${({ isFirstCell }) => isFirstCell - ? ` - @media (max-width: ${MOBILE_VIEWPORT}px) { - width: ${RECORD_TABLE_LABEL_IDENTIFIER_COLUMN_WIDTH_ON_MOBILE}px; - max-width: ${RECORD_TABLE_LABEL_IDENTIFIER_COLUMN_WIDTH_ON_MOBILE}px; - min-width: ${RECORD_TABLE_LABEL_IDENTIFIER_COLUMN_WIDTH_ON_MOBILE}px; - } - ` - : ''} + ? `${RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH + RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}px` + : 'auto'}; + z-index: ${({ isFirstCell, isTableWithGroups }) => + isFirstCell + ? isTableWithGroups + ? TABLE_Z_INDEX.footer.tableWithGroups.stickyColumn + : TABLE_Z_INDEX.footer.tableWithoutGroups.stickyColumn + : isTableWithGroups + ? TABLE_Z_INDEX.footer.tableWithGroups.default + : TABLE_Z_INDEX.footer.tableWithoutGroups.default}; - ${({ isFirstCell, isTableWithGroups }) => - isFirstCell - ? `left: ${RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH + RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}px; z-index: ${isTableWithGroups ? TABLE_Z_INDEX.footer.tableWithGroups.stickyColumn : TABLE_Z_INDEX.footer.tableWithoutGroups.stickyColumn};` - : `z-index: ${isTableWithGroups ? TABLE_Z_INDEX.footer.tableWithGroups.default : TABLE_Z_INDEX.footer.tableWithoutGroups.default};`} + @media (max-width: ${MOBILE_VIEWPORT}px) { + max-width: ${({ isFirstCell }) => + isFirstCell + ? `${RECORD_TABLE_LABEL_IDENTIFIER_COLUMN_WIDTH_ON_MOBILE}px` + : 'none'}; + min-width: ${({ isFirstCell }) => + isFirstCell + ? `${RECORD_TABLE_LABEL_IDENTIFIER_COLUMN_WIDTH_ON_MOBILE}px` + : '0'}; + width: ${({ isFirstCell }) => + isFirstCell + ? `${RECORD_TABLE_LABEL_IDENTIFIER_COLUMN_WIDTH_ON_MOBILE}px` + : 'auto'}; + } `; const StyledColumnFootContainer = styled.div` diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterValue.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterValue.tsx index c32dc84792..90a42ae2cc 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterValue.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterValue.tsx @@ -1,7 +1,8 @@ import { RECORD_TABLE_ROW_HEIGHT } from '@/object-record/record-table/constants/RecordTableRowHeight'; import { useAggregateRecordsForRecordTableColumnFooter } from '@/object-record/record-table/record-table-footer/hooks/useAggregateRecordsForRecordTableColumnFooter'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { Trans } from '@lingui/react/macro'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; import { isDefined } from 'twenty-shared/utils'; import { OverflowingTextWithTooltip } from 'twenty-ui/display'; @@ -15,7 +16,7 @@ const StyledText = styled.span` gap: 4px; flex-grow: 1; - padding-left: ${({ theme }) => theme.spacing(2)}; + padding-left: ${themeCssVariables.spacing[2]}; z-index: 1; `; @@ -40,7 +41,7 @@ const StyledValueContainer = styled(StyledScrollableContainer)` `; const StyledValue = styled.div` - color: ${({ theme }) => theme.font.color.primary}; + color: ${themeCssVariables.font.color.primary}; max-width: 100%; `; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterValueCell.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterValueCell.tsx index dc1a11a5a4..8cf95e7bb2 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterValueCell.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-footer/components/RecordTableColumnAggregateFooterValueCell.tsx @@ -8,35 +8,35 @@ import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDrop import { useAtomFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilySelectorValue'; import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue'; import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; -import { useTheme } from '@emotion/react'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { useContext, useState } from 'react'; import { IconChevronDown } from 'twenty-ui/display'; +import { ThemeContext } from 'twenty-ui/theme'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledCell = styled.div<{ isUnfolded: boolean; isFirstCell: boolean }>` align-items: center; display: flex; flex-direction: row; flex-shrink: 0; - font-weight: ${({ theme }) => theme.font.weight.medium}; + font-weight: ${themeCssVariables.font.weight.medium}; - gap: ${({ theme }) => theme.spacing(1)}; - height: ${({ theme }) => theme.spacing(8)}; + gap: ${themeCssVariables.spacing[1]}; + height: ${themeCssVariables.spacing[8]}; justify-content: space-between; - min-width: ${({ theme }) => theme.spacing(7)}; + min-width: ${themeCssVariables.spacing[7]}; flex-grow: 1; max-width: 100%; cursor: pointer; - background: ${({ theme, isUnfolded }) => - isUnfolded ? theme.background.tertiary : 'none'}; + background: ${({ isUnfolded }) => + isUnfolded ? themeCssVariables.background.tertiary : 'none'}; - ${({ isFirstCell, theme }) => - isFirstCell && - ` - padding-left: calc(${RECORD_TABLE_COLUMN_CHECKBOX_WIDTH} + ${theme.spacing(1)}); - `} + padding-left: ${({ isFirstCell }) => + isFirstCell + ? `calc(${RECORD_TABLE_COLUMN_CHECKBOX_WIDTH} + ${themeCssVariables.spacing[1]})` + : '0'}; `; const StyledIcon = styled(IconChevronDown)` @@ -46,7 +46,7 @@ const StyledIcon = styled(IconChevronDown)` justify-content: center; flex-grow: 0; flex-shrink: 0; - padding-right: ${({ theme }) => theme.spacing(2)}; + padding-right: ${themeCssVariables.spacing[2]}; `; export const RecordTableColumnAggregateFooterValueCell = ({ @@ -63,7 +63,7 @@ export const RecordTableColumnAggregateFooterValueCell = ({ dropdownId, ); - const theme = useTheme(); + const { theme } = useContext(ThemeContext); const { viewFieldId, fieldMetadataId } = useContext( RecordTableColumnAggregateFooterCellContext, ); diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHead.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHead.tsx index 6ba7d873ce..35026533b6 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHead.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHead.tsx @@ -1,5 +1,5 @@ -import { css, useTheme } from '@emotion/react'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; +import { useContext } from 'react'; import { fieldMetadataItemByIdSelector } from '@/object-metadata/states/fieldMetadataItemByIdSelector'; import { isFieldMetadataItemLabelIdentifierSelector } from '@/object-metadata/states/isFieldMetadataItemLabelIdentifierSelector'; @@ -8,25 +8,22 @@ import { shouldCompactRecordTableFirstColumnComponentState } from '@/object-reco import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; import { useAtomFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilySelectorValue'; import { useIcons } from 'twenty-ui/display'; -import { MOBILE_VIEWPORT } from 'twenty-ui/theme'; +import { ThemeContext } from 'twenty-ui/theme'; +import { MOBILE_VIEWPORT, themeCssVariables } from 'twenty-ui/theme-constants'; const StyledTitle = styled.div<{ hideTitle?: boolean }>` align-items: center; display: flex; flex-direction: row; - font-weight: ${({ theme }) => theme.font.weight.medium}; - gap: ${({ theme }) => theme.spacing(1)}; - height: ${({ theme }) => theme.spacing(8)}; - padding-left: ${({ theme }) => theme.spacing(2)}; - padding-right: ${({ theme }) => theme.spacing(2)}; + font-weight: ${themeCssVariables.font.weight.medium}; + gap: ${themeCssVariables.spacing[1]}; + height: ${themeCssVariables.spacing[8]}; + padding-left: ${themeCssVariables.spacing[2]}; + padding-right: ${themeCssVariables.spacing[2]}; - ${({ hideTitle }) => - hideTitle && - css` - @media (max-width: ${MOBILE_VIEWPORT}px) { - display: none; - } - `} + @media (max-width: ${MOBILE_VIEWPORT}px) { + display: ${({ hideTitle }) => (hideTitle ? 'none' : 'flex')}; + } `; const StyledIcon = styled.div` @@ -34,8 +31,8 @@ const StyledIcon = styled.div` flex-shrink: 0; & > svg { - height: ${({ theme }) => theme.icon.size.md}px; - width: ${({ theme }) => theme.icon.size.md}px; + height: ${themeCssVariables.icon.size.md}px; + width: ${themeCssVariables.icon.size.md}px; } `; @@ -52,7 +49,7 @@ type RecordTableColumnHeadProps = { export const RecordTableColumnHead = ({ recordField, }: RecordTableColumnHeadProps) => { - const theme = useTheme(); + const { theme } = useContext(ThemeContext); const correspondingFieldMetadataItem = useAtomFamilySelectorValue( fieldMetadataItemByIdSelector, diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHeadDropdownMenu.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHeadDropdownMenu.tsx index 81d87d4944..785a53f456 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHeadDropdownMenu.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableColumnHeadDropdownMenu.tsx @@ -12,7 +12,8 @@ import { useOpenRecordFilterChipFromTableHeader } from '@/object-record/record-t import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent'; import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown'; import { useToggleScrollWrapper } from '@/ui/utilities/scroll/hooks/useToggleScrollWrapper'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; import { useLingui } from '@lingui/react/macro'; import { useAtomFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilySelectorValue'; import { @@ -30,7 +31,7 @@ export type RecordTableColumnHeadDropdownMenuProps = { }; const StyledDropdownMenuItemsContainer = styled(DropdownMenuItemsContainer)` - z-index: ${({ theme }) => theme.lastLayerZIndex}; + z-index: ${themeCssVariables.lastLayerZIndex}; `; export const RecordTableColumnHeadDropdownMenu = ({ diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderAddColumnButton.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderAddColumnButton.tsx index a8c5719ca6..6224ac3959 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderAddColumnButton.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderAddColumnButton.tsx @@ -1,4 +1,4 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { hasRecordGroupsComponentSelector } from '@/object-record/record-group/states/selectors/hasRecordGroupsComponentSelector'; import { HIDDEN_TABLE_COLUMN_DROPDOWN_ID } from '@/object-record/record-table/constants/HiddenTableColumnDropdownId'; @@ -16,21 +16,23 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { useAtomComponentFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyStateValue'; import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue'; import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; -import { useTheme } from '@emotion/react'; import { cx } from '@linaria/core'; +import { useContext } from 'react'; import { IconPlus } from 'twenty-ui/display'; +import { ThemeContext } from 'twenty-ui/theme'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledPlusIconHeaderCell = styled.div<{ shouldDisplayBorderBottom: boolean; }>` - border-bottom: ${({ theme, shouldDisplayBorderBottom }) => + border-bottom: ${({ shouldDisplayBorderBottom }) => shouldDisplayBorderBottom - ? `1px solid ${theme.border.color.light}` + ? `1px solid ${themeCssVariables.border.color.light}` : 'none'}; - background-color: ${({ theme }) => theme.background.primary}; + background-color: ${themeCssVariables.background.primary}; - color: ${({ theme }) => theme.font.color.tertiary}; - border-right: ${({ theme }) => theme.border.color.light} !important; + color: ${themeCssVariables.font.color.tertiary}; + border-right: ${themeCssVariables.border.color.light} !important; cursor: pointer; @@ -42,7 +44,7 @@ const StyledPlusIconHeaderCell = styled.div<{ max-height: ${RECORD_TABLE_ROW_HEIGHT}px; &:hover { - background: ${({ theme }) => theme.background.secondary}; + background: ${themeCssVariables.background.secondary}; } `; @@ -60,7 +62,7 @@ const StyledDropdownContainer = styled.div` `; export const RecordTableHeaderAddColumnButton = () => { - const theme = useTheme(); + const { theme } = useContext(ThemeContext); const isRecordTableRowActive = useAtomComponentFamilyStateValue( isRecordTableRowActiveComponentFamilyState, diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderCellContainer.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderCellContainer.tsx index 45cb8174e5..6a003f469b 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderCellContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderCellContainer.tsx @@ -1,12 +1,13 @@ import { RECORD_TABLE_ROW_HEIGHT } from '@/object-record/record-table/constants/RecordTableRowHeight'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledHeaderCell = styled.div<{ zIndex?: number; shouldDisplayBorderBottom: boolean; isResizing: boolean; }>` - color: ${({ theme }) => theme.font.color.tertiary}; + color: ${themeCssVariables.font.color.tertiary}; padding: 0; text-align: left; @@ -15,29 +16,29 @@ const StyledHeaderCell = styled.div<{ height: ${RECORD_TABLE_ROW_HEIGHT}px; max-height: ${RECORD_TABLE_ROW_HEIGHT}px; - background-color: ${({ theme }) => theme.background.primary}; - border-right: 1px solid ${({ theme }) => theme.border.color.light}; + background-color: ${themeCssVariables.background.primary}; + border-right: 1px solid ${themeCssVariables.border.color.light}; - border-bottom: ${({ theme, shouldDisplayBorderBottom }) => + border-bottom: ${({ shouldDisplayBorderBottom }) => shouldDisplayBorderBottom - ? `1px solid ${theme.border.color.light}` + ? `1px solid ${themeCssVariables.border.color.light}` : 'none'}; user-select: none; - ${({ theme, isResizing }) => { - if (isResizing) { - return ''; - } - return ` - &:hover { - background: ${theme.background.secondary}; - }; - &:active { - background: ${theme.background.tertiary}; - }; - `; - }}; + &:hover { + background: ${({ isResizing }) => + isResizing + ? themeCssVariables.background.primary + : themeCssVariables.background.secondary}; + } + + &:active { + background: ${({ isResizing }) => + isResizing + ? themeCssVariables.background.primary + : themeCssVariables.background.tertiary}; + } cursor: ${({ isResizing }) => (isResizing ? 'col-resize' : 'pointer')}; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderCheckboxColumn.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderCheckboxColumn.tsx index ea4f5e7d00..9760a6c083 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderCheckboxColumn.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderCheckboxColumn.tsx @@ -1,6 +1,7 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { recordIndexAllRecordIdsComponentSelector } from '@/object-record/record-index/states/selectors/recordIndexAllRecordIdsComponentSelector'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; import { hasRecordGroupsComponentSelector } from '@/object-record/record-group/states/selectors/hasRecordGroupsComponentSelector'; import { RECORD_TABLE_COLUMN_CHECKBOX_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnCheckboxWidth'; @@ -29,16 +30,16 @@ const StyledContainer = styled.div<{ height: ${RECORD_TABLE_ROW_HEIGHT}px; justify-content: center; min-width: 24px; - padding-right: ${({ theme }) => theme.spacing(1)}; - background-color: ${({ theme }) => theme.background.primary}; - border-bottom: ${({ theme, shouldDisplayBorderBottom }) => + padding-right: ${themeCssVariables.spacing[1]}; + background-color: ${themeCssVariables.background.primary}; + border-bottom: ${({ shouldDisplayBorderBottom }) => shouldDisplayBorderBottom - ? `1px solid ${theme.border.color.light}` + ? `1px solid ${themeCssVariables.border.color.light}` : 'none'}; `; const StyledColumnHeaderCell = styled.div` - background-color: ${({ theme }) => theme.background.primary}; + background-color: ${themeCssVariables.background.primary}; min-width: ${RECORD_TABLE_COLUMN_CHECKBOX_WIDTH}px; box-sizing: border-box; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderDragDropColumn.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderDragDropColumn.tsx index 6873818898..1fc2965626 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderDragDropColumn.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderDragDropColumn.tsx @@ -9,10 +9,11 @@ import { isRecordTableScrolledVerticallyComponentState } from '@/object-record/r import { useAtomComponentFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyStateValue'; import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue'; import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { cx } from '@linaria/core'; import { useContext } from 'react'; import { ThemeContext } from 'twenty-ui/theme'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledDragDropHeaderCell = styled.div<{ shouldDisplayBorderBottom: boolean; @@ -27,9 +28,9 @@ const StyledDragDropHeaderCell = styled.div<{ cursor: pointer; - border-bottom: ${({ theme, shouldDisplayBorderBottom }) => + border-bottom: ${({ shouldDisplayBorderBottom }) => shouldDisplayBorderBottom - ? `1px solid ${theme.background.primary}` + ? `1px solid ${themeCssVariables.background.primary}` : 'none'}; `; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderFirstCell.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderFirstCell.tsx index 0ca8fff4c0..84177df26a 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderFirstCell.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderFirstCell.tsx @@ -1,4 +1,4 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext'; import { RecordTableColumnHeadWithDropdown } from '@/object-record/record-table/record-table-header/components/RecordTableColumnHeadWithDropdown'; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderLabelIdentifierCellPlusButton.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderLabelIdentifierCellPlusButton.tsx index b3278c107a..e1454fb952 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderLabelIdentifierCellPlusButton.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderLabelIdentifierCellPlusButton.tsx @@ -3,13 +3,15 @@ import { hasAnySoftDeleteFilterOnViewComponentSelector } from '@/object-record/r import { useRecordTableContextOrThrow } from '@/object-record/record-table/contexts/RecordTableContext'; import { useCreateNewIndexRecord } from '@/object-record/record-table/hooks/useCreateNewIndexRecord'; import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { IconPlus } from 'twenty-ui/display'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; import { LightIconButton } from 'twenty-ui/input'; import { useIsMobile } from 'twenty-ui/utilities'; const StyledHeaderIcon = styled.div` - margin: ${({ theme }) => theme.spacing(1, 1, 1, 1.5)}; + margin: ${themeCssVariables.spacing[1]} ${themeCssVariables.spacing[1]} + ${themeCssVariables.spacing[1]} ${themeCssVariables.spacing['1.5']}; `; export const RecordTableHeaderLabelIdentifierCellPlusButton = () => { diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderLastEmptyColumn.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderLastEmptyColumn.tsx index c931425cb9..c13e27e0dc 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderLastEmptyColumn.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderLastEmptyColumn.tsx @@ -8,20 +8,21 @@ import { isRecordTableScrolledVerticallyComponentState } from '@/object-record/r import { useAtomComponentFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyStateValue'; import { useAtomComponentSelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentSelectorValue'; import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { cx } from '@linaria/core'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledLastColumnHeader = styled.div<{ shouldDisplayBorderBottom: boolean; }>` - border-bottom: ${({ theme, shouldDisplayBorderBottom }) => + border-bottom: ${({ shouldDisplayBorderBottom }) => shouldDisplayBorderBottom - ? `1px solid ${theme.border.color.light}` + ? `1px solid ${themeCssVariables.border.color.light}` : 'none'}; - background-color: ${({ theme }) => theme.background.primary}; + background-color: ${themeCssVariables.background.primary}; border-left: none !important; - color: ${({ theme }) => theme.font.color.tertiary}; + color: ${themeCssVariables.font.color.tertiary}; cursor: pointer; diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderResizeHandler.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderResizeHandler.tsx index d6c49b06ef..92e5ac6fad 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderResizeHandler.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-header/components/RecordTableHeaderResizeHandler.tsx @@ -3,7 +3,8 @@ import { useRecordTableContextOrThrow } from '@/object-record/record-table/conte import { resizedFieldMetadataIdComponentState } from '@/object-record/record-table/states/resizedFieldMetadataIdComponentState'; import { useDragSelect } from '@/ui/utilities/drag-select/hooks/useDragSelect'; import { useAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentState'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; import { useIsMobile } from 'twenty-ui/utilities'; const StyledResizeHandler = styled.div<{ @@ -13,26 +14,23 @@ const StyledResizeHandler = styled.div<{ bottom: 0; cursor: col-resize; position: absolute; - ${({ position }) => (position === 'left' ? 'left: -1px;' : 'right: -1px;')} + left: ${({ position }) => (position === 'left' ? '-1px' : 'auto')}; + right: ${({ position }) => (position === 'right' ? '-1px' : 'auto')}; top: 0; width: 10px; z-index: 1; - ${({ isResizing, theme, position }) => { - if (isResizing === true) { - return `&:after { - background-color: ${theme.color.blue}; - bottom: 0; - content: ''; - display: block; - position: absolute; - ${position === 'left' ? 'left: -1px;' : 'right: -1px;'} - - top: 0; - width: 2px; - }`; - } - }}; + &:after { + background-color: ${themeCssVariables.color.blue}; + bottom: 0; + content: ''; + display: ${({ isResizing }) => (isResizing ? 'block' : 'none')}; + left: ${({ position }) => (position === 'left' ? '-1px' : 'auto')}; + position: absolute; + right: ${({ position }) => (position === 'right' ? '-1px' : 'auto')}; + top: 0; + width: 2px; + } `; export const RecordTableHeaderResizeHandler = ({ diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableActionRow.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableActionRow.tsx index 4e2c91afa5..05766fba4d 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableActionRow.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableActionRow.tsx @@ -1,6 +1,8 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { useRecordIndexContextOrThrow } from '@/object-record/record-index/contexts/RecordIndexContext'; +import { ThemeContext } from 'twenty-ui/theme'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; import { RECORD_TABLE_COLUMN_CHECKBOX_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnCheckboxWidth'; import { RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnDragAndDropWidth'; import { RECORD_TABLE_COLUMN_MIN_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnMinWidth'; @@ -10,7 +12,7 @@ import { useRecordTableContextOrThrow } from '@/object-record/record-table/conte import { RecordTableDragAndDropPlaceholderCell } from '@/object-record/record-table/record-table-cell/components/RecordTableDragAndDropPlaceholderCell'; import { RecordTableAddButtonPlaceholderCell } from '@/object-record/record-table/record-table-row/components/RecordTableAddButtonPlaceholderCell'; import { RecordTableGroupSectionLastDynamicFillingCell } from '@/object-record/record-table/record-table-row/components/RecordTableGroupSectionLastDynamicFillingCell'; -import { useTheme } from '@emotion/react'; +import { useContext } from 'react'; import { filterOutByProperty, findByProperty, @@ -36,7 +38,7 @@ const StyledRecordTableDraggableTr = styled.div` cursor: pointer; border: none; - background: ${({ theme }) => theme.background.primary}; + background: ${themeCssVariables.background.primary}; display: flex; flex-direction: row; @@ -44,12 +46,12 @@ const StyledRecordTableDraggableTr = styled.div` &:hover { div:not(:first-of-type) { - background-color: ${({ theme }) => theme.background.secondary}; + background-color: ${themeCssVariables.background.secondary}; } } div:not(:first-of-type) { - border-bottom: 1px solid ${({ theme }) => theme.border.color.light}; + border-bottom: 1px solid ${themeCssVariables.border.color.light}; } width: 100%; @@ -59,7 +61,7 @@ const StyledIconContainer = styled.div` align-items: center; background-color: transparent; border-right: none; - color: ${({ theme }) => theme.font.color.secondary}; + color: ${themeCssVariables.font.color.secondary}; display: flex; height: ${RECORD_TABLE_ROW_HEIGHT}px; justify-content: center; @@ -85,9 +87,9 @@ const StyledActionTextContainer = styled.div<{ width: number }>` `; const StyledText = styled.span` - color: ${({ theme }) => theme.font.color.tertiary}; - margin-left: ${({ theme }) => theme.spacing(2)}; - font-size: ${({ theme }) => theme.font.size.md}; + color: ${themeCssVariables.font.color.tertiary}; + margin-left: ${themeCssVariables.spacing[2]}; + font-size: ${themeCssVariables.font.size.md}; text-align: left; vertical-align: middle; white-space: nowrap; @@ -106,7 +108,7 @@ export const RecordTableActionRow = ({ text, onClick, }: RecordTableActionRowProps) => { - const theme = useTheme(); + const { theme } = useContext(ThemeContext); const { visibleRecordFields } = useRecordTableContextOrThrow(); const { labelIdentifierFieldMetadataItem } = useRecordIndexContextOrThrow(); diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableAddButtonPlaceholderCell.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableAddButtonPlaceholderCell.tsx index a00a7cd532..3186087f0a 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableAddButtonPlaceholderCell.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableAddButtonPlaceholderCell.tsx @@ -1,6 +1,6 @@ import { RECORD_TABLE_COLUMN_ADD_COLUMN_BUTTON_WIDTH } from '@/object-record/record-table/constants/RecordTableColumnAddColumnButtonWidth'; import { RECORD_TABLE_ROW_HEIGHT } from '@/object-record/record-table/constants/RecordTableRowHeight'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { cx } from '@linaria/core'; const StyledPlaceholderAddButtonCell = styled.div` diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableDraggableTr.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableDraggableTr.tsx index 50cbd943fc..f1050040cb 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableDraggableTr.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableDraggableTr.tsx @@ -1,6 +1,6 @@ -import { useTheme } from '@emotion/react'; import { Draggable } from '@hello-pangea/dnd'; -import { type ReactNode } from 'react'; +import { type ReactNode, useContext } from 'react'; +import { ThemeContext } from 'twenty-ui/theme'; import { RecordTableRowDraggableContextProvider } from '@/object-record/record-table/contexts/RecordTableRowDraggableContext'; import { RecordTableRowMultiDragPreview } from '@/object-record/record-table/record-table-row/components/RecordTableRowMultiDragPreview'; @@ -26,7 +26,7 @@ export const RecordTableDraggableTr = ({ onClick, children, }: RecordTableDraggableTrProps) => { - const theme = useTheme(); + const { theme } = useContext(ThemeContext); const { isSecondaryDragged } = useIsTableRowSecondaryDragged(recordId); diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableDraggableTrFirstRowOfGroup.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableDraggableTrFirstRowOfGroup.tsx index 67bd892780..69d94e2718 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableDraggableTrFirstRowOfGroup.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableDraggableTrFirstRowOfGroup.tsx @@ -1,6 +1,6 @@ -import { useTheme } from '@emotion/react'; import { Draggable } from '@hello-pangea/dnd'; -import { type ReactNode } from 'react'; +import { type ReactNode, useContext } from 'react'; +import { ThemeContext } from 'twenty-ui/theme'; import { RecordTableRowDraggableContextProvider } from '@/object-record/record-table/contexts/RecordTableRowDraggableContext'; import { RecordTableRowMultiDragPreview } from '@/object-record/record-table/record-table-row/components/RecordTableRowMultiDragPreview'; @@ -29,7 +29,7 @@ export const RecordTableDraggableTrFirstRowOfGroup = ({ onClick, children, }: RecordTableDraggableTrFirstRowOfGroupProps) => { - const theme = useTheme(); + const { theme } = useContext(ThemeContext); const { isSecondaryDragged } = useIsTableRowSecondaryDragged(recordId); diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableGroupSectionLastDynamicFillingCell.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableGroupSectionLastDynamicFillingCell.tsx index a2b4dedd6a..687d74fb08 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableGroupSectionLastDynamicFillingCell.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableGroupSectionLastDynamicFillingCell.tsx @@ -1,6 +1,6 @@ import { RECORD_TABLE_COLUMN_WITH_GROUP_LAST_EMPTY_COLUMN_WIDTH_CLASS_NAME } from '@/object-record/record-table/constants/RecordTableColumnWithGroupLastEmptyColumnWidthClassName'; import { RECORD_TABLE_ROW_HEIGHT } from '@/object-record/record-table/constants/RecordTableRowHeight'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { cx } from '@linaria/core'; const StyledPlaceholderLastDynamicFillingCell = styled.div` diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableLastDynamicFillingCell.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableLastDynamicFillingCell.tsx index d2d65c8fc2..ee1d1b3828 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableLastDynamicFillingCell.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableLastDynamicFillingCell.tsx @@ -1,6 +1,6 @@ import { RECORD_TABLE_COLUMN_LAST_EMPTY_COLUMN_WIDTH_CLASS_NAME } from '@/object-record/record-table/constants/RecordTableColumnLastEmptyColumnWidthClassName'; import { RECORD_TABLE_ROW_HEIGHT } from '@/object-record/record-table/constants/RecordTableRowHeight'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { cx } from '@linaria/core'; const StyledPlaceholderLastDynamicFillingCell = styled.div` diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableRowDiv.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableRowDiv.tsx index ab101232b4..3789291de6 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableRowDiv.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableRowDiv.tsx @@ -1,5 +1,6 @@ import { TABLE_Z_INDEX } from '@/object-record/record-table/constants/TableZIndex'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledTr = styled.div<{ isDragging: boolean; @@ -30,8 +31,8 @@ const StyledTr = styled.div<{ ? TABLE_Z_INDEX.activeRows.afterFirstRow.normal.scrolledVertically : TABLE_Z_INDEX.activeRows.afterFirstRow.normal.noVerticalScroll}; - border-top: ${({ isDragging, theme }) => - isDragging ? `1px solid ${theme.border.color.medium}` : 'none'}; + border-top: ${({ isDragging }) => + isDragging ? `1px solid ${themeCssVariables.border.color.medium}` : 'none'}; display: flex; flex-direction: row; @@ -41,12 +42,12 @@ const StyledTr = styled.div<{ div.table-cell, div.table-cell-0-0 { &:not(:first-of-type) { - border-bottom: 1px solid ${({ theme }) => theme.border.color.medium}; - border-color: ${({ theme }) => theme.border.color.medium}; - background-color: ${({ theme }) => theme.background.tertiary}; + border-bottom: 1px solid ${themeCssVariables.border.color.medium}; + border-color: ${themeCssVariables.border.color.medium}; + background-color: ${themeCssVariables.background.tertiary}; } &:nth-of-type(2) { - border-left: 1px solid ${({ theme }) => theme.border.color.medium}; + border-left: 1px solid ${themeCssVariables.border.color.medium}; margin-left: -1px; @@ -55,9 +56,9 @@ const StyledTr = styled.div<{ } } &:last-of-type { - border-right: 1px solid ${({ theme }) => theme.border.color.medium}; - border-radius: 0 ${({ theme }) => theme.border.radius.sm} - ${({ theme }) => theme.border.radius.sm} 0; + border-right: 1px solid ${themeCssVariables.border.color.medium}; + border-radius: 0 ${themeCssVariables.border.radius.sm} + ${themeCssVariables.border.radius.sm} 0; } } } diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableRowMultiDragCounterChip.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableRowMultiDragCounterChip.tsx index 9f8b249695..c3a7064c9d 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableRowMultiDragCounterChip.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-row/components/RecordTableRowMultiDragCounterChip.tsx @@ -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)` diff --git a/packages/twenty-front/src/modules/object-record/record-table/record-table-section/components/RecordTableRecordGroupSection.tsx b/packages/twenty-front/src/modules/object-record/record-table/record-table-section/components/RecordTableRecordGroupSection.tsx index afe9ff1169..fe53fb9f02 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/record-table-section/components/RecordTableRecordGroupSection.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/record-table-section/components/RecordTableRecordGroupSection.tsx @@ -1,6 +1,7 @@ -import { useTheme } from '@emotion/react'; -import styled from '@emotion/styled'; -import { useCallback } from 'react'; +import { styled } from '@linaria/react'; +import { useCallback, useContext } from 'react'; +import { ThemeContext } from 'twenty-ui/theme'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; import { RecordBoardColumnHeaderAggregateDropdown } from '@/object-record/record-board/record-board-column/components/RecordBoardColumnHeaderAggregateDropdown'; import { visibleRecordFieldsComponentSelector } from '@/object-record/record-field/states/visibleRecordFieldsComponentSelector'; @@ -45,13 +46,13 @@ const StyledTrContainer = styled.div` flex-direction: row; div:not(:first-of-type) { - border-bottom: 1px solid ${({ theme }) => theme.border.color.light}; + border-bottom: 1px solid ${themeCssVariables.border.color.light}; } `; const StyledChevronContainer = styled.div` border-right: none; - color: ${({ theme }) => theme.font.color.secondary}; + color: ${themeCssVariables.font.color.secondary}; display: flex; text-align: center; vertical-align: middle; @@ -76,7 +77,7 @@ const StyledRecordGroupSection = styled.div<{ width: number }>` border-right: none; display: flex; flex-direction: row; - gap: ${({ theme }) => theme.spacing(1)}; + gap: ${themeCssVariables.spacing[1]}; height: ${RECORD_TABLE_ROW_HEIGHT}px; width: ${({ width }) => width}px; min-width: ${({ width }) => width}px; @@ -105,9 +106,9 @@ const StyledRecordTableDragAndDropPlaceholderCell = styled.div` width: ${RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH}px; min-width: ${RECORD_TABLE_COLUMN_DRAG_AND_DROP_WIDTH}px; - background-color: ${({ theme }) => theme.background.primary}; + background-color: ${themeCssVariables.background.primary}; - border-bottom: 1px solid ${({ theme }) => theme.background.primary}; + border-bottom: 1px solid ${themeCssVariables.background.primary}; position: sticky; left: 0; @@ -115,7 +116,7 @@ const StyledRecordTableDragAndDropPlaceholderCell = styled.div` `; export const RecordTableRecordGroupSection = () => { - const theme = useTheme(); + const { theme } = useContext(ThemeContext); const currentRecordGroupId = useCurrentRecordGroupId(); diff --git a/packages/twenty-front/src/modules/object-record/record-table/virtualization/components/RecordTableRowVirtualizedDebugRowHelper.tsx b/packages/twenty-front/src/modules/object-record/record-table/virtualization/components/RecordTableRowVirtualizedDebugRowHelper.tsx index 16bddf45e0..55eac7a598 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/virtualization/components/RecordTableRowVirtualizedDebugRowHelper.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/virtualization/components/RecordTableRowVirtualizedDebugRowHelper.tsx @@ -10,20 +10,21 @@ import { recordIdByRealIndexComponentFamilySelector } from '@/object-record/reco import { useAtomComponentFamilySelectorValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilySelectorValue'; import { useAtomComponentFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentFamilyStateValue'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { isDefined } from 'twenty-shared/utils'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledDebugRow = styled.div` position: absolute; left: 250px; top: 5px; z-index: 20; - color: ${({ theme }) => theme.font.color.primary}; - background-color: ${({ theme }) => theme.color.gray3}; - border: 1px solid ${({ theme }) => theme.color.blue8}; - padding: ${({ theme }) => theme.spacing(0.5)}; + color: ${themeCssVariables.font.color.primary}; + background-color: ${themeCssVariables.color.gray3}; + border: 1px solid ${themeCssVariables.color.blue8}; + padding: ${themeCssVariables.spacing['0.5']}; display: flex; - max-height: ${({ theme }) => theme.spacing(4)}; + max-height: ${themeCssVariables.spacing[4]}; overflow: hidden; `; @@ -35,8 +36,8 @@ const StyledDebugColumn = styled.div<{ width: number }>` display: flex; text-wrap-mode: nowrap; - padding-right: ${({ theme }) => theme.spacing(0.5)}; - padding-left: ${({ theme }) => theme.spacing(0.5)}; + padding-right: ${themeCssVariables.spacing['0.5']}; + padding-left: ${themeCssVariables.spacing['0.5']}; `; type RecordTableRowVirtualizedDebugRowHelperProps = { diff --git a/packages/twenty-front/src/modules/object-record/record-table/virtualization/constants/NumberOfVirtualizedRows.ts b/packages/twenty-front/src/modules/object-record/record-table/virtualization/constants/NumberOfVirtualizedRows.ts index 0b874e408a..4b89cde38f 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/virtualization/constants/NumberOfVirtualizedRows.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/virtualization/constants/NumberOfVirtualizedRows.ts @@ -1 +1 @@ -export const NUMBER_OF_VIRTUALIZED_ROWS = 200; +export const NUMBER_OF_VIRTUALIZED_ROWS = 240; diff --git a/packages/twenty-front/src/modules/object-record/record-table/virtualization/constants/TableVirtualizationNumberOfOverscanPages.ts b/packages/twenty-front/src/modules/object-record/record-table/virtualization/constants/TableVirtualizationNumberOfOverscanPages.ts index fb2cbc0f48..b716bacd0d 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/virtualization/constants/TableVirtualizationNumberOfOverscanPages.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/virtualization/constants/TableVirtualizationNumberOfOverscanPages.ts @@ -1 +1 @@ -export const TABLE_VIRTUALIZATION_NUMBER_OF_OVERSCAN_PAGES = 5; +export const TABLE_VIRTUALIZATION_NUMBER_OF_OVERSCAN_PAGES = 7; diff --git a/packages/twenty-front/src/modules/object-record/record-table/virtualization/hooks/useProcessTreadmillScrollTop.ts b/packages/twenty-front/src/modules/object-record/record-table/virtualization/hooks/useProcessTreadmillScrollTop.ts index 3ecae7dde8..f775a4e8b1 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/virtualization/hooks/useProcessTreadmillScrollTop.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/virtualization/hooks/useProcessTreadmillScrollTop.ts @@ -50,7 +50,7 @@ export const useProcessTreadmillScrollTop = () => { const numberOfRowsDisplayedInTable = Math.min( Math.floor(tableScrollWrapperHeight / (RECORD_TABLE_ROW_HEIGHT + 1)), - 30, + 40, ); const halfNumberOfRowsVisible = Math.floor( diff --git a/packages/twenty-front/src/modules/object-record/record-table/virtualization/utils/getVirtualizationOverscanWindow.ts b/packages/twenty-front/src/modules/object-record/record-table/virtualization/utils/getVirtualizationOverscanWindow.ts index 342e26afdd..041a97b11e 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/virtualization/utils/getVirtualizationOverscanWindow.ts +++ b/packages/twenty-front/src/modules/object-record/record-table/virtualization/utils/getVirtualizationOverscanWindow.ts @@ -9,7 +9,7 @@ export const getVirtualizationOverscanWindow = ( ) => { const numberOfRowsDisplayedInTable = Math.min( Math.floor(scrollWrapperHeight / (RECORD_TABLE_ROW_HEIGHT + 1)), - 30, + 40, ); const halfNumberOfRowsVisible = Math.floor(numberOfRowsDisplayedInTable / 2); diff --git a/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleCellTextFieldDisplay.tsx b/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleCellTextFieldDisplay.tsx index 739e31eb55..73c92b3df6 100644 --- a/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleCellTextFieldDisplay.tsx +++ b/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleCellTextFieldDisplay.tsx @@ -4,33 +4,33 @@ import { useAtomFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAto import { useRecordTitleCell } from '@/object-record/record-title-cell/hooks/useRecordTitleCell'; import { type RecordTitleCellContainerType } from '@/object-record/record-title-cell/types/RecordTitleCellContainerType'; import { getRecordFieldInputInstanceId } from '@/object-record/utils/getRecordFieldInputId'; -import { withTheme, type Theme } from '@emotion/react'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { t } from '@lingui/core/macro'; import { useContext } from 'react'; import { OverflowingTextWithTooltip } from 'twenty-ui/display'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledDiv = styled.div` background: inherit; border: none; - border-radius: ${({ theme }) => theme.border.radius.sm}; - color: ${({ theme }) => theme.font.color.primary}; + border-radius: ${themeCssVariables.border.radius.sm}; + color: ${themeCssVariables.font.color.primary}; cursor: pointer; overflow: hidden; height: 24px; - padding: ${({ theme }) => theme.spacing(0, 1.25)}; + padding: ${themeCssVariables.spacing[0]} 5px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; :hover { - background: ${({ theme }) => theme.background.transparent.light}; + background: ${themeCssVariables.background.transparent.light}; } `; -const StyledEmptyText = withTheme(styled.div<{ theme: Theme }>` - color: ${({ theme }) => theme.font.color.tertiary}; -`); +const StyledEmptyText = styled.div` + color: ${themeCssVariables.font.color.tertiary}; +`; export const RecordTitleCellSingleTextDisplayMode = ({ containerType, diff --git a/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleCellUuidFieldDisplay.tsx b/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleCellUuidFieldDisplay.tsx index 0e2a66effc..9e98d695a3 100644 --- a/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleCellUuidFieldDisplay.tsx +++ b/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleCellUuidFieldDisplay.tsx @@ -2,22 +2,23 @@ import { FieldContext } from '@/object-record/record-field/ui/contexts/FieldCont import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState'; import { useAtomFamilyStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomFamilyStateValue'; import { type RecordTitleCellContainerType } from '@/object-record/record-title-cell/types/RecordTitleCellContainerType'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { useContext } from 'react'; import { OverflowingTextWithTooltip } from 'twenty-ui/display'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledDiv = styled.div` align-items: center; background: inherit; border: none; - border-radius: ${({ theme }) => theme.border.radius.sm}; + border-radius: ${themeCssVariables.border.radius.sm}; box-sizing: border-box; - color: ${({ theme }) => theme.font.color.primary}; + color: ${themeCssVariables.font.color.primary}; display: flex; height: 24px; justify-content: center; overflow: hidden; - padding: ${({ theme }) => theme.spacing(0, 1.25)}; + padding: ${themeCssVariables.spacing[0]} 5px; `; export const RecordTitleCellUuidFieldDisplay = ({ diff --git a/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleDoubleTextInput.tsx b/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleDoubleTextInput.tsx index 6836504027..76099fbeab 100644 --- a/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleDoubleTextInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleDoubleTextInput.tsx @@ -1,4 +1,4 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { useEffect, useRef, useState, type ClipboardEvent } from 'react'; import { Key } from 'ts-key-enum'; @@ -9,12 +9,13 @@ import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotke import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside'; import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow'; import { isDefined } from 'twenty-shared/utils'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; import { splitFullName } from '~/utils/format/spiltFullName'; import { turnIntoEmptyStringIfWhitespacesOnly } from '~/utils/string/turnIntoEmptyStringIfWhitespacesOnly'; const StyledContainer = styled.div` display: flex; - gap: ${({ theme }) => theme.spacing(1)}; + gap: ${themeCssVariables.spacing[1]}; justify-content: inherit; width: 100%; `; diff --git a/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleFullNameFieldDisplay.tsx b/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleFullNameFieldDisplay.tsx index 559eb0e7ab..951b2bd115 100644 --- a/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleFullNameFieldDisplay.tsx +++ b/packages/twenty-front/src/modules/object-record/record-title-cell/components/RecordTitleFullNameFieldDisplay.tsx @@ -4,34 +4,34 @@ import { useRecordTitleCell } from '@/object-record/record-title-cell/hooks/useR import { getRecordFieldInputInstanceId } from '@/object-record/utils/getRecordFieldInputId'; import { usePushFocusItemToFocusStack } from '@/ui/utilities/focus/hooks/usePushFocusItemToFocusStack'; import { FocusComponentType } from '@/ui/utilities/focus/types/FocusComponentType'; -import { withTheme, type Theme } 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 { useContext } from 'react'; import { OverflowingTextWithTooltip } from 'twenty-ui/display'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledDiv = styled.div` background: inherit; border: none; - border-radius: ${({ theme }) => theme.border.radius.sm}; - color: ${({ theme }) => theme.font.color.primary}; + border-radius: ${themeCssVariables.border.radius.sm}; + color: ${themeCssVariables.font.color.primary}; cursor: pointer; overflow: hidden; height: 24px; - padding: ${({ theme }) => theme.spacing(0, 1.25)}; + padding: ${themeCssVariables.spacing[0]} 5px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; :hover { - background: ${({ theme }) => theme.background.transparent.light}; + background: ${themeCssVariables.background.transparent.light}; } `; -const StyledEmptyText = withTheme(styled.div<{ theme: Theme }>` - color: ${({ theme }) => theme.font.color.tertiary}; -`); +const StyledEmptyText = styled.div` + color: ${themeCssVariables.font.color.tertiary}; +`; export const RecordTitleFullNameFieldDisplay = ({ containerType, diff --git a/packages/twenty-front/src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx b/packages/twenty-front/src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx index 5721a5bbda..702e6bb508 100644 --- a/packages/twenty-front/src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx +++ b/packages/twenty-front/src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer.tsx @@ -5,9 +5,10 @@ import { useUpdateMultipleRecordsActions } from '@/object-record/record-update-m import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { ShowPageContainer } from '@/ui/layout/page/components/ShowPageContainer'; import { RightDrawerProvider } from '@/ui/layout/right-drawer/contexts/RightDrawerContext'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { useLingui } from '@lingui/react/macro'; import { useState } from 'react'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledShowPageRightContainer = styled.div` display: flex; @@ -21,8 +22,8 @@ const StyledShowPageRightContainer = styled.div` 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]}; `; export type UpdateMultipleRecordsState = Record; diff --git a/packages/twenty-front/src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx b/packages/twenty-front/src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx index 322cd3f12a..22e70768f2 100644 --- a/packages/twenty-front/src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx +++ b/packages/twenty-front/src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsFooter.tsx @@ -2,8 +2,9 @@ import { computeProgressText } from '@/action-menu/utils/computeProgressText'; import { SIDE_PANEL_FOCUS_ID } from '@/command-menu/constants/SidePanelFocusId'; import { type ObjectRecordQueryProgress } from '@/object-record/types/ObjectRecordQueryProgress'; import { useHotkeysOnFocusedElement } from '@/ui/utilities/hotkey/hooks/useHotkeysOnFocusedElement'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { useLingui } from '@lingui/react/macro'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; import { Key } from 'ts-key-enum'; import { IconBoxMultiple } from 'twenty-ui/display'; @@ -11,18 +12,18 @@ import { Button } from 'twenty-ui/input'; const StyledFooterContainer = styled.div` align-items: flex-end; - background: ${({ theme }) => theme.background.primary}; - border-top: 1px solid ${({ theme }) => theme.border.color.light}; + background: ${themeCssVariables.background.primary}; + border-top: 1px solid ${themeCssVariables.border.color.light}; display: flex; - gap: ${({ theme }) => theme.spacing(2)}; + gap: ${themeCssVariables.spacing[2]}; justify-content: flex-end; - padding: ${({ theme }) => theme.spacing(2)}; + padding: ${themeCssVariables.spacing[2]}; `; const StyledFooterActions = styled.div` display: flex; align-items: flex-end; - gap: ${({ theme }) => theme.spacing(2)}; + gap: ${themeCssVariables.spacing[2]}; `; type UpdateMultipleRecordsFooterProps = { diff --git a/packages/twenty-front/src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsForm.tsx b/packages/twenty-front/src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsForm.tsx index 473bbe6c9e..03d3910614 100644 --- a/packages/twenty-front/src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsForm.tsx +++ b/packages/twenty-front/src/modules/object-record/record-update-multiple/components/UpdateMultipleRecordsForm.tsx @@ -5,15 +5,16 @@ import { isFieldRelation } from '@/object-record/record-field/ui/types/guards/is import { type UpdateMultipleRecordsState } from '@/object-record/record-update-multiple/components/UpdateMultipleRecordsContainer'; import { isUpdateRecordValueEmpty } from '@/object-record/record-update-multiple/utils/isUpdateRecordValueEmpty'; import { shouldDisplayFormMultiEditField } from '@/object-record/record-update-multiple/utils/shouldDisplayFormMultiEditField'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { FieldMetadataType } from 'twenty-shared/types'; import { Section } from 'twenty-ui/layout'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledSection = styled(Section)` display: flex; flex-direction: column; - gap: ${({ theme }) => theme.spacing(6)}; - padding: ${({ theme }) => theme.spacing(4)} ${({ theme }) => theme.spacing(3)}; + gap: ${themeCssVariables.spacing[6]}; + padding: ${themeCssVariables.spacing[4]} ${themeCssVariables.spacing[3]}; width: auto; `; diff --git a/packages/twenty-front/src/modules/page-layout/constants/PageLayoutBreakpoints.ts b/packages/twenty-front/src/modules/page-layout/constants/PageLayoutBreakpoints.ts index 115d947c86..702c4f58cb 100644 --- a/packages/twenty-front/src/modules/page-layout/constants/PageLayoutBreakpoints.ts +++ b/packages/twenty-front/src/modules/page-layout/constants/PageLayoutBreakpoints.ts @@ -1,4 +1,4 @@ -import { MOBILE_VIEWPORT } from 'twenty-ui/theme'; +import { MOBILE_VIEWPORT } from 'twenty-ui/theme-constants'; export const PAGE_LAYOUT_CONFIG = { breakpoints: { diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountLoader.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountLoader.tsx index 89c31e34cd..fd14514b71 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountLoader.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountLoader.tsx @@ -1,8 +1,9 @@ +import { useContext } from 'react'; import Skeleton, { SkeletonTheme } from 'react-loading-skeleton'; -import { useTheme } from '@emotion/react'; +import { ThemeContext } from 'twenty-ui/theme'; export const SettingsAccountLoader = () => { - const theme = useTheme(); + const { theme } = useContext(ThemeContext); return ( theme.spacing(2)}; + margin-right: ${themeCssVariables.spacing[2]}; `; type SettingsAccountsBlocklistInputProps = { diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsBlocklistTable.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsBlocklistTable.tsx index e286298797..0bc00b238d 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsBlocklistTable.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsBlocklistTable.tsx @@ -4,8 +4,9 @@ import { Table } from '@/ui/layout/table/components/Table'; import { TableBody } from '@/ui/layout/table/components/TableBody'; import { TableHeader } from '@/ui/layout/table/components/TableHeader'; import { TableRow } from '@/ui/layout/table/components/TableRow'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { t } from '@lingui/core/macro'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; type SettingsAccountsBlocklistTableProps = { blocklist: BlocklistItem[]; @@ -13,11 +14,11 @@ type SettingsAccountsBlocklistTableProps = { }; const StyledTable = styled(Table)` - margin-top: ${({ theme }) => theme.spacing(4)}; + margin-top: ${themeCssVariables.spacing[4]}; `; const StyledTableBody = styled(TableBody)` - border-bottom: 1px solid ${({ theme }) => theme.border.color.light}; + border-bottom: 1px solid ${themeCssVariables.border.color.light}; `; export const SettingsAccountsBlocklistTable = ({ diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelDetails.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelDetails.tsx index ad3927a09f..84e2a877f9 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelDetails.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelDetails.tsx @@ -3,17 +3,18 @@ import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSi import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord'; import { SettingsAccountsEventVisibilitySettingsCard } from '@/settings/accounts/components/SettingsAccountsCalendarVisibilitySettingsCard'; import { SettingsOptionCardContentToggle } from '@/settings/components/SettingsOptions/SettingsOptionCardContentToggle'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { t } from '@lingui/core/macro'; import { Section } from '@react-email/components'; import { H2Title, IconUserPlus } from 'twenty-ui/display'; import { Card } from 'twenty-ui/layout'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; import { type CalendarChannelVisibility } from '~/generated/graphql'; const StyledDetailsContainer = styled.div` display: flex; flex-direction: column; - gap: ${({ theme }) => theme.spacing(6)}; + gap: ${themeCssVariables.spacing[6]}; `; type SettingsAccountsCalendarChannelDetailsProps = { diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelsContainer.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelsContainer.tsx index c88f63cab0..d794481b70 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelsContainer.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelsContainer.tsx @@ -1,4 +1,4 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { type CalendarChannel, @@ -16,9 +16,10 @@ import { TabList } from '@/ui/layout/tab-list/components/TabList'; import { activeTabIdComponentState } from '@/ui/layout/tab-list/states/activeTabIdComponentState'; import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue'; import React from 'react'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledCalenderContainer = styled.div` - padding-bottom: ${({ theme }) => theme.spacing(6)}; + padding-bottom: ${themeCssVariables.spacing[6]}; `; export const SettingsAccountsCalendarChannelsContainer = () => { diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelsGeneral.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelsGeneral.tsx index 67668cb28b..3142dadb8e 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelsGeneral.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarChannelsGeneral.tsx @@ -2,12 +2,13 @@ import { CalendarMonthCard } from '@/activities/calendar/components/CalendarMont import { CalendarContext } from '@/activities/calendar/contexts/CalendarContext'; import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState'; import { SettingsAccountsCalendarDisplaySettings } from '@/settings/accounts/components/SettingsAccountsCalendarDisplaySettings'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { t } from '@lingui/core/macro'; import { Section } from '@react-email/components'; import { addMinutes, endOfDay, min, startOfDay } from 'date-fns'; import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; import { H2Title } from 'twenty-ui/display'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; import { CalendarChannelVisibility, type TimelineCalendarEvent, @@ -16,8 +17,8 @@ import { const StyledGeneralContainer = styled.div` display: flex; flex-direction: column; - gap: ${({ theme }) => theme.spacing(6)}; - padding-top: ${({ theme }) => theme.spacing(6)}; + gap: ${themeCssVariables.spacing[6]}; + padding-top: ${themeCssVariables.spacing[6]}; `; export const SettingsAccountsCalendarChannelsGeneral = () => { diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarDisplaySettings.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarDisplaySettings.tsx index 25f584a5f6..cfafd1aecf 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarDisplaySettings.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarDisplaySettings.tsx @@ -1,15 +1,16 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { useDateTimeFormat } from '@/localization/hooks/useDateTimeFormat'; import { useFormatPreferences } from '@/localization/hooks/useFormatPreferences'; import { DateTimeSettingsDateFormatSelect } from '@/settings/experience/components/DateTimeSettingsDateFormatSelect'; import { DateTimeSettingsTimeFormatSelect } from '@/settings/experience/components/DateTimeSettingsTimeFormatSelect'; import { DateTimeSettingsTimeZoneSelect } from '@/settings/experience/components/DateTimeSettingsTimeZoneSelect'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledContainer = styled.div` display: flex; flex-direction: column; - gap: ${({ theme }) => theme.spacing(4)}; + gap: ${themeCssVariables.spacing[4]}; `; export const SettingsAccountsCalendarDisplaySettings = () => { diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarVisibilitySettingsCard.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarVisibilitySettingsCard.tsx index ee3fbde653..46f9195162 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarVisibilitySettingsCard.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCalendarVisibilitySettingsCard.tsx @@ -1,9 +1,10 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { SettingsAccountsRadioSettingsCard } from '@/settings/accounts/components/SettingsAccountsRadioSettingsCard'; import { SettingsAccountsVisibilityIcon } from '@/settings/accounts/components/SettingsAccountsVisibilityIcon'; import { msg } from '@lingui/core/macro'; import { CalendarChannelVisibility } from '~/generated/graphql'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; type SettingsAccountsEventVisibilitySettingsCardProps = { onChange: (nextValue: CalendarChannelVisibility) => void; @@ -11,7 +12,7 @@ type SettingsAccountsEventVisibilitySettingsCardProps = { }; const StyledCardMedia = styled(SettingsAccountsVisibilityIcon)` - height: ${({ theme }) => theme.spacing(6)}; + height: ${themeCssVariables.spacing[6]}; `; const eventSettingsVisibilityOptions = [ diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCardMedia.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCardMedia.tsx index 69f4e60e05..a0ab6adcae 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCardMedia.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsCardMedia.tsx @@ -1,17 +1,18 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledCardMedia = styled.div` align-items: center; - border: 2px solid ${({ theme }) => theme.border.color.medium}; - border-radius: ${({ theme }) => theme.border.radius.sm}; - color: ${({ theme }) => theme.font.color.light}; + border: 2px solid ${themeCssVariables.border.color.medium}; + border-radius: ${themeCssVariables.border.radius.sm}; + color: ${themeCssVariables.font.color.light}; display: flex; flex-direction: column; - gap: ${({ theme }) => theme.spacing(0.5)}; - height: ${({ theme }) => theme.spacing(8)}; + gap: ${themeCssVariables.spacing['0.5']}; + height: ${themeCssVariables.spacing[8]}; justify-content: center; - padding: ${({ theme }) => theme.spacing(0.5)}; - width: ${({ theme }) => theme.spacing(6)}; + padding: ${themeCssVariables.spacing['0.5']}; + width: ${themeCssVariables.spacing[6]}; `; export { StyledCardMedia as SettingsAccountsCardMedia }; diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsListCard.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsListCard.tsx index 8945cc4471..4a1cd11b45 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsListCard.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsListCard.tsx @@ -3,7 +3,7 @@ import { SettingsAccountsListEmptyStateCard } from '@/settings/accounts/componen import { SettingsConnectedAccountsTableHeader } from '@/settings/accounts/components/SettingsConnectedAccountsTableHeader'; import { SettingsConnectedAccountsTableRow } from '@/settings/components/SettingsConnectedAccountsTableRow'; import { Table } from '@/ui/layout/table/components/Table'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { SettingsPath } from 'twenty-shared/types'; import { useLingui } from '@lingui/react/macro'; @@ -11,18 +11,19 @@ import { IconPlus } from 'twenty-ui/display'; import { Button } from 'twenty-ui/input'; import { Section } from 'twenty-ui/layout'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; import { useNavigateSettings } from '~/hooks/useNavigateSettings'; const StyledTableRows = styled.div` - padding-bottom: ${({ theme }) => theme.spacing(2)}; - padding-top: ${({ theme }) => theme.spacing(2)}; + padding-bottom: ${themeCssVariables.spacing[2]}; + padding-top: ${themeCssVariables.spacing[2]}; `; const StyledAddAccountSection = styled(Section)` - border-top: 1px solid ${({ theme }) => theme.border.color.light}; + border-top: 1px solid ${themeCssVariables.border.color.light}; display: flex; justify-content: flex-end; - padding-top: ${({ theme }) => theme.spacing(2)}; + padding-top: ${themeCssVariables.spacing[2]}; `; export const SettingsAccountsConnectedAccountsListCard = ({ diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsRowRightContainer.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsRowRightContainer.tsx index 7b1d9e33a6..4d9f6a157e 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsRowRightContainer.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsConnectedAccountsRowRightContainer.tsx @@ -2,14 +2,15 @@ import { type ConnectedAccount } from '@/accounts/types/ConnectedAccount'; import { SettingsAccountsRowDropdownMenu } from '@/settings/accounts/components/SettingsAccountsRowDropdownMenu'; import { SyncStatus } from '@/settings/accounts/constants/SyncStatus'; import { computeSyncStatus } from '@/settings/accounts/utils/computeSyncStatus'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { t } from '@lingui/core/macro'; import { Status } from 'twenty-ui/display'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledRowRightContainer = styled.div` align-items: center; display: flex; - gap: ${({ theme }) => theme.spacing(4)}; + gap: ${themeCssVariables.spacing[4]}; `; export const SettingsAccountsConnectedAccountsRowRightContainer = ({ diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsConnectionForm.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsConnectionForm.tsx index 841af508a9..d4c60e44c7 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsConnectionForm.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsConnectionForm.tsx @@ -1,4 +1,4 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { useLingui } from '@lingui/react/macro'; import { type Control, Controller } from 'react-hook-form'; @@ -8,41 +8,41 @@ import { SettingsTextInput } from '@/ui/input/components/SettingsTextInput'; import { type ConnectionFormData } from '@/settings/accounts/hooks/useImapSmtpCaldavConnectionForm'; import { H2Title } from 'twenty-ui/display'; import { Section } from 'twenty-ui/layout'; -import { MOBILE_VIEWPORT } from 'twenty-ui/theme'; +import { MOBILE_VIEWPORT, themeCssVariables } from 'twenty-ui/theme-constants'; const StyledFormContainer = styled.div` display: flex; flex-direction: column; - gap: ${({ theme }) => theme.spacing(6)}; + gap: ${themeCssVariables.spacing[6]}; `; const StyledConnectionSection = styled.div` display: flex; flex-direction: column; - gap: ${({ theme }) => theme.spacing(2)}; + gap: ${themeCssVariables.spacing[2]}; `; const StyledSectionHeader = styled.div` - margin-bottom: ${({ theme }) => theme.spacing(2)}; + margin-bottom: ${themeCssVariables.spacing[2]}; `; const StyledSectionTitle = styled.h3` - color: ${({ theme }) => theme.font.color.primary}; - font-size: ${({ theme }) => theme.font.size.md}; - font-weight: ${({ theme }) => theme.font.weight.medium}; + color: ${themeCssVariables.font.color.primary}; + font-size: ${themeCssVariables.font.size.md}; + font-weight: ${themeCssVariables.font.weight.medium}; margin: 0; - margin-bottom: ${({ theme }) => theme.spacing(1)}; + margin-bottom: ${themeCssVariables.spacing[1]}; `; const StyledSectionDescription = styled.p` - color: ${({ theme }) => theme.font.color.tertiary}; - font-size: ${({ theme }) => theme.font.size.sm}; + color: ${themeCssVariables.font.color.tertiary}; + font-size: ${themeCssVariables.font.size.sm}; margin: 0; `; const StyledFieldRow = styled.div` display: flex; - gap: ${({ theme }) => theme.spacing(3)}; + gap: ${themeCssVariables.spacing[3]}; @media (max-width: ${MOBILE_VIEWPORT}px) { flex-direction: column; diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEditImapSmtpCaldavConnection.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEditImapSmtpCaldavConnection.tsx index 2e0712a888..72202b8ee6 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEditImapSmtpCaldavConnection.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsEditImapSmtpCaldavConnection.tsx @@ -1,4 +1,4 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { useLingui } from '@lingui/react/macro'; import { FormProvider } from 'react-hook-form'; import { useParams } from 'react-router-dom'; diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsListEmptyStateCard.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsListEmptyStateCard.tsx index 91cacff9d6..4a3e46c2cb 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsListEmptyStateCard.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsListEmptyStateCard.tsx @@ -5,26 +5,28 @@ import { isMicrosoftCalendarEnabledState } from '@/client-config/states/isMicros import { isMicrosoftMessagingEnabledState } from '@/client-config/states/isMicrosoftMessagingEnabledState'; import { useTriggerApisOAuth } from '@/settings/accounts/hooks/useTriggerApiOAuth'; import { SettingsCard } from '@/settings/components/SettingsCard'; -import { useTheme } from '@emotion/react'; -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; +import { useContext } from 'react'; import { useLingui } from '@lingui/react/macro'; import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue'; import { ConnectedAccountProvider, SettingsPath } from 'twenty-shared/types'; import { getSettingsPath } from 'twenty-shared/utils'; import { IconAt, IconGoogle, IconMicrosoft } from 'twenty-ui/display'; import { UndecoratedLink } from 'twenty-ui/navigation'; +import { ThemeContext } from 'twenty-ui/theme'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; const StyledCardsContainer = styled.div` display: flex; flex-direction: column; - gap: ${({ theme }) => theme.spacing(2)}; + gap: ${themeCssVariables.spacing[2]}; `; export const SettingsAccountsListEmptyStateCard = () => { const { triggerApisOAuth } = useTriggerApisOAuth(); const { t } = useLingui(); - const theme = useTheme(); + const { theme } = useContext(ThemeContext); const isGoogleMessagingEnabled = useAtomStateValue( isGoogleMessagingEnabledState, diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageAutoCreationIcon.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageAutoCreationIcon.tsx index d628f347c9..8307e68e1f 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageAutoCreationIcon.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageAutoCreationIcon.tsx @@ -1,6 +1,7 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { SettingsAccountsCardMedia } from '@/settings/accounts/components/SettingsAccountsCardMedia'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; type SettingsAccountsMessageAutoCreationIconProps = { className?: string; @@ -13,8 +14,10 @@ const StyledIconContainer = styled(SettingsAccountsCardMedia)` `; const StyledDirectionSkeleton = styled.div<{ isActive?: boolean }>` - background-color: ${({ isActive, theme }) => - isActive ? theme.accent.accent4060 : theme.background.quaternary}; + background-color: ${({ isActive }) => + isActive + ? themeCssVariables.accent.accent4060 + : themeCssVariables.background.quaternary}; border-radius: 1px; height: 24px; `; diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelDetails.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelDetails.tsx index 53a8cffbb1..edf18c2222 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelDetails.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageChannelDetails.tsx @@ -1,4 +1,4 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { type MessageChannel, @@ -14,6 +14,7 @@ import { SettingsOptionCardContentToggle } from '@/settings/components/SettingsO import { t } from '@lingui/core/macro'; import { H2Title, IconBriefcase, IconUsers } from 'twenty-ui/display'; import { Card, Section } from 'twenty-ui/layout'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; import { type MessageChannelVisibility } from '~/generated/graphql'; type SettingsAccountsMessageChannelDetailsProps = { @@ -33,7 +34,7 @@ type SettingsAccountsMessageChannelDetailsProps = { const StyledDetailsContainer = styled.div` display: flex; flex-direction: column; - gap: ${({ theme }) => theme.spacing(6)}; + gap: ${themeCssVariables.spacing[6]}; `; export const SettingsAccountsMessageChannelDetails = ({ @@ -98,7 +99,7 @@ export const SettingsAccountsMessageChannelDetails = ({
theme.spacing(6)}; + padding-bottom: ${themeCssVariables.spacing[6]}; `; export const SettingsAccountsMessageChannelsContainer = () => { diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageFolderIcon.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageFolderIcon.tsx index 92af0a5620..b78110137c 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageFolderIcon.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsMessageFolderIcon.tsx @@ -1,7 +1,8 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { MessageFolderImportPolicy } from '@/accounts/types/MessageChannel'; import { SettingsAccountsCardMedia } from '@/settings/accounts/components/SettingsAccountsCardMedia'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; type SettingsAccountsMessageFolderIconProps = { className?: string; @@ -20,16 +21,20 @@ const StyledFolderRow = styled.div` `; const StyledFolderIcon = styled.div<{ isDisabled?: boolean }>` - background-color: ${({ isDisabled, theme }) => - isDisabled ? theme.background.quaternary : theme.accent.accent4060}; + background-color: ${({ isDisabled }) => + isDisabled + ? themeCssVariables.background.quaternary + : themeCssVariables.accent.accent4060}; border-radius: 1px; height: 5px; width: 5px; `; const StyledFolderLabel = styled.div<{ isDisabled?: boolean }>` - background-color: ${({ isDisabled, theme }) => - isDisabled ? theme.background.quaternary : theme.accent.accent4060}; + background-color: ${({ isDisabled }) => + isDisabled + ? themeCssVariables.background.quaternary + : themeCssVariables.accent.accent4060}; border-radius: 1px; flex: 1; height: 5px; diff --git a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsRadioSettingsCard.tsx b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsRadioSettingsCard.tsx index 7856821857..70b366cbe5 100644 --- a/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsRadioSettingsCard.tsx +++ b/packages/twenty-front/src/modules/settings/accounts/components/SettingsAccountsRadioSettingsCard.tsx @@ -1,9 +1,10 @@ -import styled from '@emotion/styled'; +import { styled } from '@linaria/react'; import { type MessageDescriptor } from '@lingui/core'; import { Trans } from '@lingui/react'; import { type ReactNode } from 'react'; import { Radio } from 'twenty-ui/input'; import { Card, CardContent } from 'twenty-ui/layout'; +import { themeCssVariables } from 'twenty-ui/theme-constants'; type SettingsAccountsRadioSettingsCardProps