emotion-migrate
Migrate Emotion styled-components to Mantine components with style props and CSS modules. Use when converting .styled.tsx files or removing @emotion imports from components.
DeepseekModel
キュレーション済みスキル
品質 優秀 · 90
v1.0.0
取得
https://deepseekmodel.com/api/download.php?id=metabase-metabase-claude-skills-emotion-migrate-skill-md&format=skill
ダウンロード .skill
標準形式。system_prompt と model_config を収録し、任意の Agent で利用可能
.skill ファイルの system_prompt フィールドの実際の内容。
name emotion-migrate description Migrate Emotion styled-components to Mantine components with style props and CSS modules. Use when converting .styled.tsx files or removing @emotion imports from components. Emotion → Mantine + CSS Modules Migration Skill Migrate Emotion styled-components ( @emotion/styled , @emotion/react ) to Mantine layout components with style props and CSS modules. The goal is zero Emotion imports, zero inline styles, and maximum use of design system tokens. Priority Order (Strict) Mantine components + style props — Box , Flex , Stack , Group , Text , Title , Card . This is the DEFAULT. Every CSS property must be checked against style props FIRST. CSS modules ( .module.css ) — ONLY for properties that Mantine style props genuinely cannot express: pseudo-selectors ( :hover , :focus , ::before ), box-shadow , border shorthand, animation / @keyframes , complex selectors, cursor , pointer-events , overflow , text-overflow , white-space , transition . Inline styles ONLY for dynamic values — style={{ }} is allowed only for truly dynamic runtime values (e.g., computed widths, positions, data-driven colors). All static styles must use Mantine props or CSS modules. Mantine-First Decision Gate (CRITICAL) For EACH styled component, go through every CSS property and ask: "Can this be a Mantine style prop?" If yes → style prop. If no → CSS module. Do NOT dump an entire component into a CSS module just because one property needs it — split them. Properties that ARE style props (use these, not CSS modules): display → display prop color → c prop ( c="core-brand" , c="text-primary" ) background-color → bg prop ( bg="background_page-primary" ) font-size → fz prop ( fz="md" ) font-weight → fw prop ( fw="bold" ) line-height → lh prop ( lh="md" ) text-align → ta prop ( ta="center" ) padding (all variants) → p , px , py , pt , pb , pl , pr margin (all variants) → m , mx , my , mt , mb , ml , mr width → w , min-width → miw , max-width → maw height → h , min-height → mih , max-height → mah flex → flex prop ( flex="0 0 auto" , flex={1} ) gap → gap prop (on Flex/Stack/Group) align-items → align prop (on Flex/Stack/Group) justify-content → justify prop (on Flex/Stack/Group) flex-direction → direction prop (on Flex) flex-wrap → wrap prop (on Flex) position → pos prop top/right/bottom/left → top , right , bottom , left props opacity → opacity prop Properties that NEED CSS modules (no style prop equivalent): :hover , :focus , :active , ::before , ::after (pseudo-selectors) box-shadow , border (shorthand with color), outline cursor , pointer-events overflow , text-overflow , white-space animation , transition , transform @media queries (UNLESS it's simple responsive spacing/sizing — then use responsive syntax: p={{ base: "md", lg: "xl" }} ) Hybrid approach — when a component needs BOTH, put style props on the Mantine component AND add a CSS module class for the rest: < Flex className={S. root } /* for :hover, box-shadow, border */ align= "center" /* style prop */ gap= "sm" /* style prop */ p= "md" /* style prop */ bg= "background_page-primary" /* style prop */ > CSS Module Conventions (Strict) Class Naming: camelCase All CSS module class names MUST use camelCase . This is the dominant convention across the codebase (~830 camelCase vs ~620 PascalCase classes), used consistently in Mantine UI components, and matches standard CSS module conventions. /* CORRECT */ .root { } .settingsSection { } .dragHandle { } .closeIcon { } /* WRONG — do not use PascalCase or kebab-case */ .ItemRoot { } .settings-section { } Modifier/state classes also use camelCase: .selected { } .disabled { } .interactive { } .draggable { } No Cascading — Direct Class Assignment Cascading selectors are discouraged . Instead of styling through parent-child relationships, assign a class directly to the element that needs styling. /* WRONG — cascading/descendant selectors */ .root > input { } .root .label { } .container > div > span { } /* CORRECT — direct class on the target element */ .input { } .label { } .title { } The only acceptable nesting patterns are: Pseudo-selectors on the same element : .item { &:hover { } } Modifier composition : .item { &.selected { } } Hover-reveal patterns where a parent hover affects a child: .root:hover .showOnHover { opacity: 1; } — but only when structurally necessary (the child has no way to know about the parent's hover state) Import Alias Always import the CSS module as S : import S from "./ComponentName.module.css" ; Step-by-Step Migration Process Step 1: Read and Understand Read the .styled.tsx file AND every component that imports from it. Understand: Which styled components are used and where Which props drive dynamic styles Which styles are static vs conditional Which styles can map directly to Mantine style props Step 2: Classify Each Styled Component For each styled component, apply the Mantine-First Decision Gate above. Then determine the migration target: Emotion Pattern Migration Target styled.div with only layout/spacing/color Box , Flex , Stack , or Group with style props. NO CSS module needed. styled.div with flexbox column Stack component with style props styled.div with flexbox row Flex or Group component with style props styled.span / styled.p with color/weight/size Text component="span" with style props ( c , fw , fz ). NO CSS module. styled.div with hover/focus/pseudo-selectors Hybrid : Mantine component with style props for expressible properties + CSS module class for pseudo-selectors only styled.div with media queries (simple spacing/sizing) Responsive style props : p={{ base: "md", lg: "xl" }} . NO CSS module. styled.div with media queries (complex/non-spacing) CSS module for the media query parts, style props for the rest styled.div with animations/keyframes CSS module for animation, style props for layout styled(SomeComponent) with only color/spacing/flex Wrap in Mantine component with style props: <Box c="core-brand" flex="0 0 auto"><Icon /></Box> , or pass style props if the component accepts them styled(SomeComponent) with pseudo-selectors/complex styles CSS module className on the component Dynamic props styled.div<{ isActive: boolean }> Mantine style props for simple toggles ( c={active ? "core-brand" : "text-primary"} ), cx() with CSS module classes for complex state combinations involving pseudo-selectors Step 3: Create CSS Module (if needed) Create ComponentName.module.css alongside the component file: /* Use design system tokens — NEVER raw color/spacing values */ .root { border : 1px solid var (--mb-color-border-neutral); border-radius : var (--mantine-radius-md); background-color : var (--mb-color-background_page-primary); } /* Conditional states as separate classes, combined with cx() */ .active { background-color : var (--mb-color-core-brand); color : var (--mb-color-text-primary-inverse); } .disabled { color : var (--mb-color-text-disabled); pointer-events : none; } /* Hover/focus/pseudo-selectors — nest with & */ .interactive { cursor : pointer; & :hover { color : var (--mb-color-core-brand); background-color : var (--mb-color-background_surface-hover); } } /* Hover-reveal: acceptable parent→child nesting */ .root :hover .showOnHover { opacity : 1 ; } /* Responsive styles */ @media (--breakpoint-min-md) { .root { padding : var (--mantine-spacing-lg); } } Step 4: Update the Component TSX import cx from "classnames" ; import CS from "metabase/css/core/index.css" ; import { Box , Flex , Group , Stack , Text } from "metabase/ui" ; import S from "./ComponentName.module.css" ; // Dynamic props → cx() with conditional classes < Flex className = {cx(S.root, { [ S.active ] : isActive , [ S.disabled ] : disabled , })} align = "center" gap = "sm" p = "md" w = "100%" > Step 5: Delete the .styled.tsx File Remove the old styled file entirely. Remove all imports of it from other files. Step 6: Verify Confirm zero @emotion/styled or @emotion/react imports remain in the migrated files Confirm no static inline styles (dynamic runtime values are fine) Confirm all colors use tokens, not raw hex/rgb values Design System Token Reference Mantine Style Props (use directly on components) Spacing ( p , px , py , pt , pb , pl , pr , m , mx , my , mt , mb , ml , mr ): "xs" = 4px, "sm" = 8px, "md" = 16px, "lg" = 24px, "xl" = 32px Custom: rem(48) for non-standard values (import rem from metabase/ui ) Dimensions ( w , h , maw , mah , miw , mih ): "100%" , "100vh" , rem(400) , etc. Colors ( c , bg ): Text: "text-primary" , "text-secondary" , "text-disabled" Background: "background_page-primary" , "background_page-secondary" , "background_surface-hover"
このスキルを起動するキーワード。クリックでコピーできます。
このスキルにはトリガーワードがありません。
ダウンロードした .skill に含まれるフィールド。
| フィールド | 説明 |
|---|---|
| format | フォーマット識別子(skill/v1) |
| skill_id | スキル固有 ID |
| name | スキル名 |
| version | バージョン |
| description | 説明 |
| category | カテゴリ(配列) |
| trigger_words | トリガーワード |
| tags | タグ |
| source | ソース |
| source_url | ソース URL(本ページ) |
| exported_at | エクスポート日時(ダウンロード毎) |
| system_prompt | システムプロンプト本文 |
| model_config | モデル設定:provider / model / temperature / max_tokens / top_p |
| examples | サンプル |
| install_guide | 各プラットフォームの導入説明(Coze / Dify / Claude / カスタム) |