From 1f0280e6fb0da88f797dfe607a48e9b7c9526a81 Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Wed, 26 Nov 2025 13:36:21 +0000 Subject: [PATCH 1/6] docs(site): document critical frontend pattern migrations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add comprehensive documentation for active frontend pattern migrations discovered through analysis of 200+ git commits touching site/ files: Core Migrations: - Emotion → Tailwind CSS (strict 'no new emotion' policy) - MUI Components → Custom/Radix/shadcn (Tooltips, Tables, Buttons) - MUI Icons → lucide-react with specific icon mappings - spyOn → queries parameter for GET endpoint mocks in Storybook - localStorage → user_configs table for user preferences New Documentation: - Icon migration mappings (BusinessIcon→Building2Icon, etc.) - Radix component prop naming conventions (placement→side) - cn() utility usage for conditional className merging - Chromatic testing best practices (prefer snapshots over assertions) Includes concrete before/after examples and migration patterns to guide developers away from deprecated approaches toward current best practices. Analysis based on PRs: #20948, #20946, #20938, #20905, #20900, #20869, #20849, #20808, #20530, #20479, #20261, #20201, #20200, #20193, #20318 --- 🤖 This change was written by Claude Sonnet 4.5 Thinking using mux and reviewed by a human 🏂 --- site/CLAUDE.md | 161 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 156 insertions(+), 5 deletions(-) diff --git a/site/CLAUDE.md b/site/CLAUDE.md index 43538c012e6e8..5eb41460f3bf4 100644 --- a/site/CLAUDE.md +++ b/site/CLAUDE.md @@ -1,5 +1,17 @@ # Frontend Development Guidelines +## 🚨 Critical Pattern Migrations (MUST FOLLOW) + +The following patterns are actively being migrated and have **STRICT policies**: + +1. **Emotion → Tailwind**: "No new emotion styles, full stop" - Always use Tailwind CSS +2. **MUI Components → Custom/Radix Components**: Replace MUI components (Tooltips, Tables, Buttons) with custom/shadcn equivalents +3. **MUI Icons → lucide-react**: All icons must use lucide-react, never MUI icons +4. **spyOn → queries parameter**: Use `queries` in story parameters for GET endpoint mocks +5. **localStorage → user_configs**: Store user preferences in backend, not browser storage + +When touching existing code, **"leave the campsite better than you found it"** - refactor old patterns to new ones even if not directly related to your changes. + ## TypeScript LSP Navigation (USE FIRST) When investigating or editing TypeScript/React code, always use the TypeScript language server tools for accurate navigation: @@ -26,25 +38,104 @@ When investigating or editing TypeScript/React code, always use the TypeScript l ## Components -- MUI components are deprecated - migrate away from these when encountered -- Use shadcn/ui components first - check `site/src/components` for existing implementations. +- **MUI components are deprecated** - migrate away from these when encountered + - Replace `@mui/material/Tooltip` with custom `Tooltip` component (Radix-based) + - Default 100ms delay via global tooltip provider + - Use `delayDuration={0}` when immediate tooltip needed + - Replace MUI Tables with custom table components + - Replace MUI Buttons with shadcn Button components + - Systematically replace MUI components with custom/shadcn equivalents +- Use shadcn/ui components first - check `site/src/components` for existing implementations - Do not use shadcn CLI - manually add components to maintain consistency -- The modules folder should contain components with business logic specific to the codebase. +- The modules folder should contain components with business logic specific to the codebase - Create custom components only when shadcn alternatives don't exist +### Icon Migration: MUI Icons → lucide-react + +**STRICT POLICY**: All icons must use `lucide-react`, not MUI icons. + +```tsx +// OLD - MUI Icons (DO NOT USE) +import BusinessIcon from "@mui/icons-material/Business"; +import GroupOutlinedIcon from "@mui/icons-material/GroupOutlined"; +import PublicOutlinedIcon from "@mui/icons-material/PublicOutlined"; + +// NEW - lucide-react +import { + Building2Icon, + UsersIcon, + GlobeIcon, +} from "lucide-react"; +``` + +**Common icon mappings:** +- `BusinessIcon` → `Building2Icon` +- `GroupOutlinedIcon` / `GroupIcon` → `UsersIcon` +- `PublicOutlinedIcon` / `PublicIcon` → `GlobeIcon` +- `PersonIcon` → `UserIcon` +- Always use descriptive lucide-react icons over generic MUI icons + +### MUI → Radix Component Prop Naming + +When migrating from MUI to Radix components, prop names change: + +```tsx +// MUI Tooltip props + + +// Radix Tooltip props + // placement → side +// PopperProps is removed (internal implementation detail) +``` + +**Common prop name changes:** +- `placement` → `side` (for positioning) +- Remove `PopperProps` (internal implementation, not needed) +- MUI's `title` prop → Radix uses children pattern with `TooltipContent` + ## Styling -- Emotion CSS is deprecated. Use Tailwind CSS instead. -- Use custom Tailwind classes in tailwind.config.js. +- **Emotion CSS is STRICTLY DEPRECATED: "no new emotion styles, full stop"** + - Never use `@emotion/react`, `css` prop, `useTheme()`, or emotion styled components + - Always use Tailwind CSS utility classes instead + - When touching code with emotion styles, refactor to Tailwind ("leave the campsite better than you found it") +- Use custom Tailwind classes in tailwind.config.js - Tailwind CSS reset is currently not used to maintain compatibility with MUI - Responsive design - use Tailwind's responsive prefixes (sm:, md:, lg:, xl:) - Do not use `dark:` prefix for dark mode +### Common Emotion → Tailwind Migrations + +```tsx +// OLD - Emotion (DO NOT USE) +import { type Interpolation, type Theme, useTheme } from "@emotion/react"; +
+ + + +// NEW - Tailwind +
+
+ +``` + +**Common replacements:** +- `css={visuallyHidden}` → `className="sr-only"` +- `Stack` component → flex with Tailwind classes (`flex`, `flex-col`, `flex-row`, `gap-*`) +- Theme colors → Tailwind semantic tokens (`text-content-primary`, `bg-surface-secondary`, `border-border-default`) +- Icons: use lucide-react with `size-icon-sm`, `size-icon-xs` classes + ## Tailwind Best Practices - Group related classes - Use semantic color names from the theme inside `tailwind.config.js` including `content`, `surface`, `border`, `highlight` semantic tokens - Prefer Tailwind utilities over custom CSS when possible +- For conditional classes, use the `cn()` utility (from `utils/cn`) which combines `clsx` and `tailwind-merge` + ```tsx + import { cn } from "utils/cn"; + +
+ ``` ## General Code style @@ -53,6 +144,66 @@ When investigating or editing TypeScript/React code, always use the TypeScript l - Prefer `for...of` over `forEach` for iteration - **Biome** handles both linting and formatting (not ESLint/Prettier) +## Testing Patterns + +### Storybook: spyOn → queries parameter (for GET endpoint mocks) + +**PREFERRED PATTERN**: Use `queries` parameter in story parameters instead of `spyOn` for GET endpoint mocks. + +```tsx +// OLD - spyOn pattern (AVOID for GET mocks) +beforeEach: () => { + spyOn(API, "getUsers").mockResolvedValue({ + users: MockUsers, + count: MockUsers.length, + }); + spyOn(API, "getTemplates").mockResolvedValue([MockTemplate]); +} + +// NEW - queries parameter pattern (PREFERRED) +parameters: { + queries: [ + { + key: usersKey({ q: "" }), + data: { + users: MockUsers, + count: MockUsers.length, + }, + }, + { + key: getTemplatesQueryKey({ q: "has-ai-task:true" }), + data: [MockTemplate], + }, + ], +} +``` + +**Important notes:** +- This applies specifically to GET endpoint mocks in Storybook stories +- `spyOn` is still used for other mock types (POST, PUT, DELETE, non-GET endpoints) +- Must import the correct query key functions (e.g., `usersKey`, `getTemplatesQueryKey`) + +### Chromatic/Storybook Testing Best Practices + +- **Prefer visual validation through snapshots** over programmatic assertions +- Chromatic snapshots catch visual changes during review +- Avoid programmatic assertions in stories that duplicate what snapshots show +- Programmatic assertions can introduce flakiness - remove when redundant +- Stories are snapshot tests - rely on the screenshot to verify correctness + +## State Storage + +### localStorage vs user_configs table + +**IMPORTANT**: For user preferences that should persist across devices and browsers, use the `user_configs` table in the backend, NOT `localStorage`. + +- **localStorage is browser-specific**, not user-specific +- **User preferences should persist** across devices/browsers +- Follow the plumbing for `theme_preference` as a reference example +- localStorage may be acceptable only for truly transient UI state that doesn't need to follow the user + +**Key principle**: If a user dismisses something or sets a preference, it should be tied to their account, not their browser. + ## Workflow - Be sure to typecheck when you're done making a series of code changes From a72a0cd29c005b4d4a3ca1e4a77b1ad763bc074a Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Wed, 26 Nov 2025 13:49:02 +0000 Subject: [PATCH 2/6] fix(docs): add blank lines around lists for markdown linter Fix markdown linting errors MD032 and MD031: - Add blank lines around lists (MD032) - Add blank lines around fenced code blocks (MD031) Ensures site/CLAUDE.md passes markdownlint-cli2 checks. --- site/CLAUDE.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/site/CLAUDE.md b/site/CLAUDE.md index 5eb41460f3bf4..cccb8f087cc93 100644 --- a/site/CLAUDE.md +++ b/site/CLAUDE.md @@ -69,6 +69,7 @@ import { ``` **Common icon mappings:** + - `BusinessIcon` → `Building2Icon` - `GroupOutlinedIcon` / `GroupIcon` → `UsersIcon` - `PublicOutlinedIcon` / `PublicIcon` → `GlobeIcon` @@ -89,6 +90,7 @@ When migrating from MUI to Radix components, prop names change: ``` **Common prop name changes:** + - `placement` → `side` (for positioning) - Remove `PopperProps` (internal implementation, not needed) - MUI's `title` prop → Radix uses children pattern with `TooltipContent` @@ -120,6 +122,7 @@ import { type Interpolation, type Theme, useTheme } from "@emotion/react"; ``` **Common replacements:** + - `css={visuallyHidden}` → `className="sr-only"` - `Stack` component → flex with Tailwind classes (`flex`, `flex-col`, `flex-row`, `gap-*`) - Theme colors → Tailwind semantic tokens (`text-content-primary`, `bg-surface-secondary`, `border-border-default`) @@ -131,6 +134,7 @@ import { type Interpolation, type Theme, useTheme } from "@emotion/react"; - Use semantic color names from the theme inside `tailwind.config.js` including `content`, `surface`, `border`, `highlight` semantic tokens - Prefer Tailwind utilities over custom CSS when possible - For conditional classes, use the `cn()` utility (from `utils/cn`) which combines `clsx` and `tailwind-merge` + ```tsx import { cn } from "utils/cn"; @@ -179,6 +183,7 @@ parameters: { ``` **Important notes:** + - This applies specifically to GET endpoint mocks in Storybook stories - `spyOn` is still used for other mock types (POST, PUT, DELETE, non-GET endpoints) - Must import the correct query key functions (e.g., `usersKey`, `getTemplatesQueryKey`) From d75fefba275e117996f6f0ae56a29bdca01cf896 Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Thu, 27 Nov 2025 09:48:04 +0000 Subject: [PATCH 3/6] refactor(docs): remove deprecated pattern examples to prevent AI misuse Remove code examples showing deprecated patterns (OLD/DO NOT USE blocks) that could mislead AI agents into copying the wrong patterns. Changes: - Icon section: Only show lucide-react imports, not MUI icons - Radix section: Only show correct Radix pattern, not MUI pattern - Emotion section: Only show Tailwind classes, not emotion imports - Testing section: Only show queries parameter, not spyOn pattern This prevents AI agents from pattern-matching and copying deprecated code while maintaining clear guidance on what to replace and how. --- site/CLAUDE.md | 86 +++++++++++++++++++++----------------------------- 1 file changed, 36 insertions(+), 50 deletions(-) diff --git a/site/CLAUDE.md b/site/CLAUDE.md index cccb8f087cc93..7652854c1f28f 100644 --- a/site/CLAUDE.md +++ b/site/CLAUDE.md @@ -52,48 +52,43 @@ When investigating or editing TypeScript/React code, always use the TypeScript l ### Icon Migration: MUI Icons → lucide-react -**STRICT POLICY**: All icons must use `lucide-react`, not MUI icons. +**STRICT POLICY**: Never import from `@mui/icons-material`. Always use `lucide-react` instead. -```tsx -// OLD - MUI Icons (DO NOT USE) -import BusinessIcon from "@mui/icons-material/Business"; -import GroupOutlinedIcon from "@mui/icons-material/GroupOutlined"; -import PublicOutlinedIcon from "@mui/icons-material/PublicOutlined"; +**Use lucide-react icons:** -// NEW - lucide-react +```tsx import { Building2Icon, UsersIcon, GlobeIcon, + UserIcon, } from "lucide-react"; ``` -**Common icon mappings:** +**Common icon replacements:** -- `BusinessIcon` → `Building2Icon` -- `GroupOutlinedIcon` / `GroupIcon` → `UsersIcon` -- `PublicOutlinedIcon` / `PublicIcon` → `GlobeIcon` -- `PersonIcon` → `UserIcon` -- Always use descriptive lucide-react icons over generic MUI icons +- Replace `BusinessIcon` with `Building2Icon` +- Replace `GroupOutlinedIcon` / `GroupIcon` with `UsersIcon` +- Replace `PublicOutlinedIcon` / `PublicIcon` with `GlobeIcon` +- Replace `PersonIcon` with `UserIcon` +- Always use descriptive lucide-react icons over generic alternatives ### MUI → Radix Component Prop Naming -When migrating from MUI to Radix components, prop names change: +When migrating from MUI to Radix components, prop names change. Use Radix naming conventions: ```tsx -// MUI Tooltip props - - -// Radix Tooltip props - // placement → side -// PopperProps is removed (internal implementation detail) + + Hover me + Tooltip text + ``` -**Common prop name changes:** +**Common prop name changes from MUI:** -- `placement` → `side` (for positioning) -- Remove `PopperProps` (internal implementation, not needed) -- MUI's `title` prop → Radix uses children pattern with `TooltipContent` +- Use `side` instead of `placement` for positioning +- Remove `PopperProps` (internal implementation detail, not needed in Radix) +- MUI's `title` prop is replaced by Radix's children pattern with `TooltipContent` ## Styling @@ -108,25 +103,25 @@ When migrating from MUI to Radix components, prop names change: ### Common Emotion → Tailwind Migrations -```tsx -// OLD - Emotion (DO NOT USE) -import { type Interpolation, type Theme, useTheme } from "@emotion/react"; -
- - +Never import from `@emotion/react`. Use Tailwind CSS utility classes: -// NEW - Tailwind +```tsx
-
- +
+ + Content here + +
+
``` **Common replacements:** -- `css={visuallyHidden}` → `className="sr-only"` -- `Stack` component → flex with Tailwind classes (`flex`, `flex-col`, `flex-row`, `gap-*`) -- Theme colors → Tailwind semantic tokens (`text-content-primary`, `bg-surface-secondary`, `border-border-default`) -- Icons: use lucide-react with `size-icon-sm`, `size-icon-xs` classes +- Replace `css={visuallyHidden}` with `className="sr-only"` +- Replace `Stack` component with flex layouts using Tailwind (`flex`, `flex-col`, `flex-row`, `gap-*`) +- Replace emotion theme colors with Tailwind semantic tokens (`text-content-primary`, `bg-surface-secondary`, `border-border-default`) +- Replace emotion `css` prop with `className` and Tailwind utilities +- Use lucide-react icons with `size-icon-sm`, `size-icon-xs` classes for sizing ## Tailwind Best Practices @@ -150,21 +145,12 @@ import { type Interpolation, type Theme, useTheme } from "@emotion/react"; ## Testing Patterns -### Storybook: spyOn → queries parameter (for GET endpoint mocks) +### Storybook: queries parameter for GET endpoint mocks -**PREFERRED PATTERN**: Use `queries` parameter in story parameters instead of `spyOn` for GET endpoint mocks. +**PREFERRED PATTERN**: For GET endpoint mocks in Storybook stories, use `queries` parameter instead of `spyOn`. ```tsx -// OLD - spyOn pattern (AVOID for GET mocks) -beforeEach: () => { - spyOn(API, "getUsers").mockResolvedValue({ - users: MockUsers, - count: MockUsers.length, - }); - spyOn(API, "getTemplates").mockResolvedValue([MockTemplate]); -} - -// NEW - queries parameter pattern (PREFERRED) +// Use queries parameter pattern parameters: { queries: [ { @@ -185,7 +171,7 @@ parameters: { **Important notes:** - This applies specifically to GET endpoint mocks in Storybook stories -- `spyOn` is still used for other mock types (POST, PUT, DELETE, non-GET endpoints) +- `spyOn` is still appropriate for other mock types (POST, PUT, DELETE, non-GET endpoints) - Must import the correct query key functions (e.g., `usersKey`, `getTemplatesQueryKey`) ### Chromatic/Storybook Testing Best Practices From 6e08d9c5a22848c79749ead2d61a614dd27c8bfb Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Thu, 27 Nov 2025 09:50:32 +0000 Subject: [PATCH 4/6] refactor(docs): reduce wordiness in pattern documentation Condense verbose sections to be more scannable and direct: - Icon section: Single-line import, inline replacement mappings - Radix section: Consolidated prop changes into one sentence - Emotion section: Reduced from 5 to 4 bullets, combined redundant points - Chromatic section: Reduced from 5 to 3 bullets - localStorage section: Reduced from 8 to 4 lines Overall ~30% reduction in text while maintaining clarity. AI agents scan for patterns and use code examples - keeping prose minimal and directive improves efficiency. --- site/CLAUDE.md | 54 +++++++++++++++----------------------------------- 1 file changed, 16 insertions(+), 38 deletions(-) diff --git a/site/CLAUDE.md b/site/CLAUDE.md index 7652854c1f28f..5518de0fa7031 100644 --- a/site/CLAUDE.md +++ b/site/CLAUDE.md @@ -52,30 +52,17 @@ When investigating or editing TypeScript/React code, always use the TypeScript l ### Icon Migration: MUI Icons → lucide-react -**STRICT POLICY**: Never import from `@mui/icons-material`. Always use `lucide-react` instead. - -**Use lucide-react icons:** +Never import from `@mui/icons-material`. Use `lucide-react` instead. ```tsx -import { - Building2Icon, - UsersIcon, - GlobeIcon, - UserIcon, -} from "lucide-react"; +import { Building2Icon, UsersIcon, GlobeIcon, UserIcon } from "lucide-react"; ``` -**Common icon replacements:** - -- Replace `BusinessIcon` with `Building2Icon` -- Replace `GroupOutlinedIcon` / `GroupIcon` with `UsersIcon` -- Replace `PublicOutlinedIcon` / `PublicIcon` with `GlobeIcon` -- Replace `PersonIcon` with `UserIcon` -- Always use descriptive lucide-react icons over generic alternatives +**Common replacements:** `BusinessIcon` → `Building2Icon`, `GroupIcon` → `UsersIcon`, `PublicIcon` → `GlobeIcon`, `PersonIcon` → `UserIcon` ### MUI → Radix Component Prop Naming -When migrating from MUI to Radix components, prop names change. Use Radix naming conventions: +When migrating from MUI to Radix components, use Radix naming conventions: ```tsx @@ -84,11 +71,7 @@ When migrating from MUI to Radix components, prop names change. Use Radix naming ``` -**Common prop name changes from MUI:** - -- Use `side` instead of `placement` for positioning -- Remove `PopperProps` (internal implementation detail, not needed in Radix) -- MUI's `title` prop is replaced by Radix's children pattern with `TooltipContent` +**Prop changes from MUI:** Use `side` instead of `placement`, remove `PopperProps`, and use `TooltipContent` children instead of `title` prop. ## Styling @@ -118,10 +101,9 @@ Never import from `@emotion/react`. Use Tailwind CSS utility classes: **Common replacements:** - Replace `css={visuallyHidden}` with `className="sr-only"` -- Replace `Stack` component with flex layouts using Tailwind (`flex`, `flex-col`, `flex-row`, `gap-*`) -- Replace emotion theme colors with Tailwind semantic tokens (`text-content-primary`, `bg-surface-secondary`, `border-border-default`) -- Replace emotion `css` prop with `className` and Tailwind utilities -- Use lucide-react icons with `size-icon-sm`, `size-icon-xs` classes for sizing +- Replace `Stack` component with Tailwind flex (`flex`, `flex-col`, `gap-*`) +- Replace emotion `css` prop and theme colors with Tailwind utilities (`text-content-primary`, `bg-surface-secondary`, `border-border-default`) +- Use lucide-react icons with `size-icon-sm`, `size-icon-xs` classes ## Tailwind Best Practices @@ -176,24 +158,20 @@ parameters: { ### Chromatic/Storybook Testing Best Practices -- **Prefer visual validation through snapshots** over programmatic assertions -- Chromatic snapshots catch visual changes during review -- Avoid programmatic assertions in stories that duplicate what snapshots show -- Programmatic assertions can introduce flakiness - remove when redundant -- Stories are snapshot tests - rely on the screenshot to verify correctness +- Prefer visual validation through Chromatic snapshots over programmatic assertions +- Remove redundant assertions that duplicate snapshot validation +- Stories are snapshot tests - rely on screenshots to verify correctness ## State Storage ### localStorage vs user_configs table -**IMPORTANT**: For user preferences that should persist across devices and browsers, use the `user_configs` table in the backend, NOT `localStorage`. - -- **localStorage is browser-specific**, not user-specific -- **User preferences should persist** across devices/browsers -- Follow the plumbing for `theme_preference` as a reference example -- localStorage may be acceptable only for truly transient UI state that doesn't need to follow the user +**IMPORTANT**: Use `user_configs` table for user preferences, NOT `localStorage`. -**Key principle**: If a user dismisses something or sets a preference, it should be tied to their account, not their browser. +- localStorage is browser-specific; user preferences should persist across devices +- Follow `theme_preference` as reference implementation +- Use localStorage only for truly transient UI state +- **Key principle**: User preferences should be tied to their account, not their browser ## Workflow From 9aac7ecfc5fcc60b74b631733670a92513d5a95c Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Thu, 27 Nov 2025 09:57:51 +0000 Subject: [PATCH 5/6] refactor(docs): remove duplicate content from site/CLAUDE.md Remove redundant sections and repeated information: - Remove entire "Migration" section (lines 192-207) that duplicated Components, Styling, and Tailwind sections - Remove duplicate "leave campsite better" mention (already in line 13) - Remove duplicate "Never import from @emotion/react" (already stated) Reduces documentation from 250 to 232 lines while maintaining all unique information. Each concept is now documented once in its most appropriate section. --- site/CLAUDE.md | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/site/CLAUDE.md b/site/CLAUDE.md index 5518de0fa7031..d7b98e6305705 100644 --- a/site/CLAUDE.md +++ b/site/CLAUDE.md @@ -78,7 +78,6 @@ When migrating from MUI to Radix components, use Radix naming conventions: - **Emotion CSS is STRICTLY DEPRECATED: "no new emotion styles, full stop"** - Never use `@emotion/react`, `css` prop, `useTheme()`, or emotion styled components - Always use Tailwind CSS utility classes instead - - When touching code with emotion styles, refactor to Tailwind ("leave the campsite better than you found it") - Use custom Tailwind classes in tailwind.config.js - Tailwind CSS reset is currently not used to maintain compatibility with MUI - Responsive design - use Tailwind's responsive prefixes (sm:, md:, lg:, xl:) @@ -86,7 +85,7 @@ When migrating from MUI to Radix components, use Radix naming conventions: ### Common Emotion → Tailwind Migrations -Never import from `@emotion/react`. Use Tailwind CSS utility classes: +Use Tailwind CSS utility classes: ```tsx
@@ -189,23 +188,6 @@ parameters: { 4. `pnpm test` - Run affected unit tests 5. Visual check in Storybook if component changes -## Migration (MUI → shadcn) (Emotion → Tailwind) - -### Migration Strategy - -- Identify MUI components in current feature -- Find shadcn equivalent in existing components -- Create wrapper if needed for missing functionality -- Update tests to reflect new component structure -- Remove MUI imports once migration complete - -### Migration Guidelines - -- Use Tailwind classes for all new styling -- Replace Emotion `css` prop with Tailwind classes -- Leverage custom color tokens: `content-primary`, `surface-secondary`, etc. -- Use `className` with `clsx` for conditional styling - ## React Rules ### 1. Purity & Immutability From 453a8ac15d08d856a6713a5a83c5482709d9984a Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Thu, 27 Nov 2025 10:03:09 +0000 Subject: [PATCH 6/6] style(docs): remove emoji to match original doc style MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove 🚨 emoji from "Critical Pattern Migrations" section header to maintain consistency with the original document style which uses no emojis, only text emphasis and formatting. All other style elements match the original: - Section headers with ## and ### - Bold emphasis for important terms - Simple bullet lists with - - Direct, imperative tone - "(MUST FOLLOW)" matches original "(USE FIRST)" pattern --- site/CLAUDE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/CLAUDE.md b/site/CLAUDE.md index d7b98e6305705..155674e829cd5 100644 --- a/site/CLAUDE.md +++ b/site/CLAUDE.md @@ -1,6 +1,6 @@ # Frontend Development Guidelines -## 🚨 Critical Pattern Migrations (MUST FOLLOW) +## Critical Pattern Migrations (MUST FOLLOW) The following patterns are actively being migrated and have **STRICT policies**: