# Available Transforms URL: /react/developer-tools/codemods/available-transforms Source: https://github.com/daangn/seed-design/blob/dev/docs/content/react/developer-tools/codemods/available-transforms.mdx codemod를 통해 실행 가능한 변환 목록입니다. {/* Auto-generated from `scripts/generate-codemod-docs.ts` */} ## replace-custom-seed-design-typography - npm: npx @seed-design/codemod@latest replace-custom-seed-design-typography \ - pnpm: pnpm dlx @seed-design/codemod@latest replace-custom-seed-design-typography \ - yarn: yarn dlx @seed-design/codemod@latest replace-custom-seed-design-typography \ - bun: bun x @seed-design/codemod@latest replace-custom-seed-design-typography \ ```ts title="basic.input.ts" // @ts-nocheck import { style } from "@vanilla-extract/css"; import { vars } from "@seed-design/css"; import { f, reset } from "@/shared/styles"; import { typography, text } from '@/src/styles/tokens'; export const title = style([ typography.h4, { textAlign: "center", color: vars.$scale.color.gray900, margin: 0, }, ]); export const subtitle = style([ f.typography.title2Bold, { marginBottom: "0.375rem", color: vars.$scale.color.gray900, }, ]); export const smallText = style([ typo.caption2Regular, { color: vars.$scale.color.gray700, }, ]); export const largeTitle = style([ typo.bodyL1Regular, { color: vars.$scale.color.gray900, }, ]); export const button = style([ typography['$semantic.label2Regular'], { width: '100%', paddingTop: rem(14), paddingRight: rem(16), paddingBottom: rem(14), paddingLeft: rem(16), }, ]); export const day = style([ { display: 'flex', flex: 1, alignItems: 'center', justifyContent: 'center', height: rem(30), }, typography['$semantic.caption1Regular'], ]); // Additional test cases for various mappings export const titleBold = style([ typography.title3Bold, { fontWeight: 'bold', }, ]); export const subtitleRegular = style([ f.typography.subtitle2Regular, { color: vars.$scale.color.gray800, }, ]); export const bodyText = style([ typo.bodyM1Regular, { lineHeight: 1.5, }, ]); export const labelText = style([ typography['$semantic.label1Bold'], { textTransform: 'uppercase', }, ]); export const captionBold = style([ typography['$semantic.caption2Bold'], { fontSize: '12px', }, ]); // Test deprecated tokens with alternative export const deprecatedBody = style([ typo.bodyL2Regular, { margin: '8px 0', }, ]); export const deprecatedLabel = style([ typography['$semantic.label6Regular'], { opacity: 0.8, }, ]); // Test multiple token choices (should use first one) export const headerText = style([ typography.h4, { textAlign: 'center', }, ]); export const text = style([ text['$semantic.bodyL2Bold'], ]); ``` ```ts title="basic.output.ts" // @ts-nocheck import { style } from "@vanilla-extract/css"; import { vars } from "@seed-design/css"; import { f, reset } from "@/shared/styles"; import { typography, text } from '@/src/styles/tokens'; export const title = style([ typography.t10Bold, { textAlign: "center", color: vars.$scale.color.gray900, margin: 0, }, ]); export const subtitle = style([ f.typography.t7Bold, { marginBottom: "0.375rem", color: vars.$scale.color.gray900, }, ]); export const smallText = style([ typo.t2Regular, { color: vars.$scale.color.gray700, }, ]); export const largeTitle = style([ typo.articleBody, { color: vars.$scale.color.gray900, }, ]); export const button = style([ typography.t5Regular, { width: '100%', paddingTop: rem(14), paddingRight: rem(16), paddingBottom: rem(14), paddingLeft: rem(16), }, ]); export const day = style([ { display: 'flex', flex: 1, alignItems: 'center', justifyContent: 'center', height: rem(30), }, typography.t3Regular, ]); // Additional test cases for various mappings export const titleBold = style([ typography.t6Bold, { fontWeight: 'bold', }, ]); export const subtitleRegular = style([ f.typography.t4Regular, { color: vars.$scale.color.gray800, }, ]); export const bodyText = style([ typo.t5Regular, { lineHeight: 1.5, }, ]); export const labelText = style([ typography.t6Bold, { textTransform: 'uppercase', }, ]); export const captionBold = style([ typography.t2Bold, { fontSize: '12px', }, ]); // Test deprecated tokens with alternative export const deprecatedBody = style([ typo.t4Regular, { margin: '8px 0', }, ]); export const deprecatedLabel = style([ typography.t1Regular, { opacity: 0.8, }, ]); // Test multiple token choices (should use first one) export const headerText = style([ typography.t10Bold, { textAlign: 'center', }, ]); export const text = style([ text.t4Bold, ]); ``` ## replace-tailwind-typography - npm: npx @seed-design/codemod@latest replace-tailwind-typography \ - pnpm: pnpm dlx @seed-design/codemod@latest replace-tailwind-typography \ - yarn: yarn dlx @seed-design/codemod@latest replace-tailwind-typography \ - bun: bun x @seed-design/codemod@latest replace-tailwind-typography \ ```tsx title="basic.input.tsx" // @ts-nocheck export function BasicExample() { return (
Primary Background

{formState.content}

Hover Primary Low Background
Focus Primary Low Background
Focus Primary Low Background

{description}

Text with prefix
Another text with prefix

Title with prefix

); } ``` ```tsx title="basic.output.tsx" // @ts-nocheck export function BasicExample() { return (
Primary Background

{formState.content}

Hover Primary Low Background
Focus Primary Low Background
Focus Primary Low Background

{description}

Text with prefix
Another text with prefix

Title with prefix

); } ``` ## replace-custom-imported-typography-variable Sprout에서 SEED로 마이그레이션 시 import된 타이포그래피 변수를 변환합니다. ### 기능 - 타이포그래피 관련 import 문을 찾아 변수명을 변환합니다. - 변수가 사용된 모든 위치(템플릿 리터럴, 객체 속성 등)를 찾아 업데이트합니다. - typography.mjs의 매핑 정보에 따라 Sprout 타이포그래피 변수를 SEED로 변환합니다. - 같은 SEED 토큰으로 변환되는 중복 import를 제거합니다 (예: subtitle1Regular, bodyM1Regular가 모두 t5Regular로 변환되면 t5Regular는 한 번만 import). - 별칭(alias)으로 import된 변수명은 유지합니다 (예: `bodyM1Regular as customTypo`에서 `t5Regular as customTypo`로 변환). * npm: npx @seed-design/codemod@latest replace-custom-imported-typography-variable \ * pnpm: pnpm dlx @seed-design/codemod@latest replace-custom-imported-typography-variable \ * yarn: yarn dlx @seed-design/codemod@latest replace-custom-imported-typography-variable \ * bun: bun x @seed-design/codemod@latest replace-custom-imported-typography-variable \ ```ts title="basic.input.ts" // @ts-nocheck import { subtitle1Regular, subtitle2Regular, h4, title1Bold, title2Bold, bodyL1Regular, bodyL2Regular, caption1Regular, caption2Regular, label5Regular, } from '@src/constants/typography' import { bodyM1Regular as customTypo } from '@karrot/typography' const S_StoreRequestTitle = styled.h1` ${subtitle1Regular}; margin: 0 0 0.25rem; color: ${vars.$scale.color.gray900}; text-align: center; ` const S_StoreRequestText = styled.p` ${subtitle2Regular}; margin: 0; color: ${vars.$scale.color.gray600}; text-align: center; ` // 추가 테스트 케이스 // screenTitle 매핑 테스트 const S_ScreenHeader = styled.h1` ${h4}; margin-bottom: 1rem; ` // 일반 매핑 테스트 const S_Title = styled.h2` ${title1Bold}; color: ${vars.$scale.color.gray900}; ` // 여러 테스트 케이스를 담은 컴포넌트 const Card = styled.div` // title2Bold 매핑 테스트 h3 { ${title2Bold}; margin-bottom: 8px; } // bodyL1Regular 매핑 테스트 p.description { ${bodyL1Regular}; color: ${vars.$scale.color.gray800}; } // 대체 토큰으로 매핑되는 케이스 p.content { ${bodyL2Regular}; margin: 0; } // 캡션 스타일 p.caption { ${caption1Regular}; color: ${vars.$scale.color.gray600}; } // 작은 텍스트 small { ${caption2Regular}; color: ${vars.$scale.color.gray500}; } // 라벨 스타일 label { ${label5Regular}; margin-right: 4px; } ` // 다른 모듈에서 가져온 타이포그래피 처리 (별칭 유지해야 함) const S_CustomContent = styled.div` ${customTypo}; color: ${vars.$scale.color.gray700}; ` // 변수로 사용하는 경우 const titleStyle = title1Bold; const textStyle = subtitle1Regular; ``` ```ts title="basic.output.ts" // @ts-nocheck import { t5Regular, t4Regular, t10Bold, t9Bold, t7Bold, articleBody, t3Regular, t2Regular, t1Regular, } from '@src/constants/typography'; import { t5Regular as customTypo } from '@karrot/typography' const S_StoreRequestTitle = styled.h1` ${t5Regular}; margin: 0 0 0.25rem; color: ${vars.$scale.color.gray900}; text-align: center; ` const S_StoreRequestText = styled.p` ${t4Regular}; margin: 0; color: ${vars.$scale.color.gray600}; text-align: center; ` // 추가 테스트 케이스 // screenTitle 매핑 테스트 const S_ScreenHeader = styled.h1` ${t10Bold}; margin-bottom: 1rem; ` // 일반 매핑 테스트 const S_Title = styled.h2` ${t9Bold}; color: ${vars.$scale.color.gray900}; ` // 여러 테스트 케이스를 담은 컴포넌트 const Card = styled.div` // title2Bold 매핑 테스트 h3 { ${t7Bold}; margin-bottom: 8px; } // bodyL1Regular 매핑 테스트 p.description { ${articleBody}; color: ${vars.$scale.color.gray800}; } // 대체 토큰으로 매핑되는 케이스 p.content { ${t4Regular}; margin: 0; } // 캡션 스타일 p.caption { ${t3Regular}; color: ${vars.$scale.color.gray600}; } // 작은 텍스트 small { ${t2Regular}; color: ${vars.$scale.color.gray500}; } // 라벨 스타일 label { ${t1Regular}; margin-right: 4px; } ` // 다른 모듈에서 가져온 타이포그래피 처리 (별칭 유지해야 함) const S_CustomContent = styled.div` ${customTypo}; color: ${vars.$scale.color.gray700}; ` // 변수로 사용하는 경우 const titleStyle = t9Bold; const textStyle = t5Regular; ``` ## replace-custom-seed-design-vars - npm: npx @seed-design/codemod@latest replace-custom-seed-design-vars \ - pnpm: pnpm dlx @seed-design/codemod@latest replace-custom-seed-design-vars \ - yarn: yarn dlx @seed-design/codemod@latest replace-custom-seed-design-vars \ - bun: bun x @seed-design/codemod@latest replace-custom-seed-design-vars \ ```ts title="basic.input.ts" // @ts-nocheck import { vars } from '@/shared/style/vars'; export const date = style({ ...vars.typography.caption1Regular, color: vars.color.gray600, }); export const color1 = style({ color: vars.color.yellow500, }); export const color2 = style({ color: vars.color.blue500, }); export const color3 = style({ color: vars.color.red500, }); export const title = style({ ...vars.typography.bodyM1Bold, color: vars.color.primary, }); export const subtitle = style({ ...vars.typography.bodyM2Regular, color: vars.color.secondary, }); // 배경색 케이스 export const cardBackground = style({ backgroundColor: vars.color.paperSheet, padding: '16px', }); // 테두리 케이스 export const divider = style({ borderTop: `1px solid ${vars.color.divider1}`, marginTop: '8px', marginBottom: '8px', }); // 상태 색상 케이스 export const successMessage = style({ ...vars.typography.bodyM1Bold, color: vars.color.success, backgroundColor: vars.color.successLow, padding: '12px', borderRadius: '4px', }); export const warningMessage = style({ ...vars.typography.bodyM1Bold, color: vars.color.warning, backgroundColor: vars.color.warningLow, padding: '12px', borderRadius: '4px', }); export const errorMessage = style({ ...vars.typography.bodyM1Bold, color: vars.color.danger, backgroundColor: vars.color.dangerLow, padding: '12px', borderRadius: '4px', }); // 다양한 타이포그래피 케이스 export const heading = style({ ...vars.typography.h4, color: vars.color.inkText, }); export const body = style({ ...vars.typography.bodyL1Regular, color: vars.color.inkTextLow, }); export const label = style({ ...vars.typography.label3Bold, color: vars.color.grayActive, }); // 알파 색상 케이스 export const overlay = style({ backgroundColor: vars.color.overlayDim, position: 'absolute', top: 0, left: 0, right: 0, bottom: 0, }); // 복합 케이스와 상호작용 상태 export const button = style({ ...vars.typography.label2Bold, backgroundColor: vars.color.primary, color: vars.color.onPrimary, borderRadius: '4px', padding: '8px 16px', border: 'none', cursor: 'pointer', ':hover': { backgroundColor: vars.color.primaryHover, }, ':active': { backgroundColor: vars.color.primaryPressed, }, }); export const secondaryButton = style({ ...vars.typography.label2Bold, backgroundColor: vars.color.secondaryLow, color: vars.color.secondary, borderRadius: '4px', padding: '8px 16px', border: 'none', cursor: 'pointer', ':hover': { backgroundColor: vars.color.grayHover, }, ':active': { backgroundColor: vars.color.grayPressed, }, }); // 중첩 경로 케이스 export const floatingPanel = style({ backgroundColor: vars.color.paperFloating, boxShadow: `0 2px 8px ${vars.color.overlayLow}`, padding: '20px', borderRadius: '8px', }); export const dialogPanel = style({ backgroundColor: vars.color.paperDialog, padding: '24px', boxShadow: `0 4px 16px ${vars.color.overlayDim}`, borderRadius: '12px', }); // 정적 색상 케이스 export const staticColors = style({ color: vars.color.staticBlack, backgroundColor: vars.color.staticWhite, border: `1px solid ${vars.color.staticBlackAlpha200}`, }); // 정적 색상 케이스 (명시적으로 static 프리픽스 테스트) export const staticExplicitColors = style({ color: vars.color.staticBlack, backgroundColor: vars.color.staticWhite, boxShadow: `0 2px 4px ${vars.color.staticBlackAlpha500}`, outline: `1px solid ${vars.color.staticBlackAlpha200}`, }); export const specialBackground = style({ background: `linear-gradient(to bottom, ${vars.color.staticWhiteAlpha50}, ${vars.color.staticWhiteAlpha200})`, backdropFilter: 'blur(8px)', }); // 복합 스타일 및 다중 속성 케이스 export const multiProperty = style({ ...vars.typography.title2Bold, color: vars.color.accent, borderLeft: `4px solid ${vars.color.accent}`, borderRight: `4px solid ${vars.color.accent}`, boxShadow: `inset 0 0 0 1px ${vars.color.divider2}, 0 2px 4px ${vars.color.overlayLow}`, padding: '16px', backgroundColor: vars.color.paperDefault, }); // 믹스인 스타일 케이스 export const mixinStyle = { primary: { background: vars.color.primary, color: vars.color.onPrimary, }, secondary: { background: vars.color.secondary, }, accent: { background: vars.color.accent, color: vars.color.onGrayOverlay50, }, }; // 특수 속성 및 스케일 색상 케이스 export const scaleColors = style({ fill: vars.color.carrot500, stroke: vars.color.gray400, stopColor: vars.color.blue400, floodColor: vars.color.red400, lightingColor: vars.color.green400, }); // 특수 타이포그래피 케이스 export const specialTypographies = { title: vars.typography.title1Bold, subtitle: vars.typography.subtitle1Regular, label: vars.typography.label5Regular, caption: vars.typography.caption2Bold, }; // 다양한 경로를 가진 컬러 토큰 export const colorContexts = style({ // 일반 색상 color: vars.color.primaryLow, // 배경 색상 backgroundColor: vars.color.paperBackground, // 테두리 색상 borderColor: vars.color.divider3, // 호버 색상 ':hover': { backgroundColor: vars.color.primaryLowHover, borderColor: vars.color.primaryLowActive, }, }); // 복잡한 다중 경로와 중첩된 객체 export const nestedStyleObject = { button: { default: { backgroundColor: vars.color.paperAccent, color: vars.color.inkText, border: `1px solid ${vars.color.carrot300}`, }, hover: { backgroundColor: vars.color.carrot100, borderColor: vars.color.carrot400, }, active: { backgroundColor: vars.color.carrot200, color: vars.color.inkTextLow, }, }, panel: { header: { ...vars.typography.subtitle2Bold, color: vars.color.blue600, borderBottom: `1px solid ${vars.color.blue200}`, }, body: { ...vars.typography.bodyM2Regular, color: vars.color.inkTextLow, backgroundColor: vars.color.blue50, }, footer: { backgroundColor: vars.color.blue100, borderTop: `1px solid ${vars.color.blue200}`, }, }, }; // 테두리 속성 매핑 테스트 export const borderMapping = style({ // stroke 토큰으로 매핑될 속성 borderColor: vars.color.divider2, // stroke 토큰이 없어서 fg 토큰으로 대체되는 케이스 borderTopColor: vars.color.primary, borderBottomColor: vars.color.accent, // stroke 또는 fg 토큰으로 대체 boxShadow: `0 0 0 1px ${vars.color.primary}, 0 2px 4px ${vars.color.overlayLow}`, // 복합 속성 border: `1px solid ${vars.color.secondary}`, }); ``` ```ts title="basic.output.ts" // @ts-nocheck import { vars } from "@/shared/style/vars"; export const date = style({ ...vars.typography.t3Regular, color: vars.color.palette.gray700, }); export const color1 = style({ color: vars.color.palette.yellow700, }); export const color2 = style({ color: vars.color.palette.blue600, }); export const color3 = style({ color: vars.color.palette.red700, }); export const title = style({ ...vars.typography.t5Bold, color: vars.color.fg.brand, }); export const subtitle = style({ ...vars.typography.t4Regular, color: vars.color.palette.gray900, }); // 배경색 케이스 export const cardBackground = style({ backgroundColor: vars.color.bg.layerFloating, padding: "16px", }); // 테두리 케이스 export const divider = style({ borderTop: `1px solid ${vars.color.stroke.neutralSubtle}`, marginTop: "8px", marginBottom: "8px", }); // 상태 색상 케이스 export const successMessage = style({ ...vars.typography.t5Bold, color: vars.color.fg.positive, backgroundColor: vars.color.bg.positiveWeak, padding: "12px", borderRadius: "4px", }); export const warningMessage = style({ ...vars.typography.t5Bold, color: vars.color.bg.warningSolid, backgroundColor: vars.color.bg.warningWeak, padding: "12px", borderRadius: "4px", }); export const errorMessage = style({ ...vars.typography.t5Bold, color: vars.color.fg.critical, backgroundColor: vars.color.bg.criticalWeak, padding: "12px", borderRadius: "4px", }); // 다양한 타이포그래피 케이스 export const heading = style({ ...vars.typography.t10Bold, color: vars.color.fg.neutral, }); export const body = style({ ...vars.typography.articleBody, color: vars.color.fg.neutralSubtle, }); export const label = style({ ...vars.typography.t4Bold, color: vars.color.fg.neutralMuted, }); // 알파 색상 케이스 export const overlay = style({ backgroundColor: vars.color.bg.overlay, position: "absolute", top: 0, left: 0, right: 0, bottom: 0, }); // 복합 케이스와 상호작용 상태 export const button = style({ ...vars.typography.t5Bold, backgroundColor: vars.color.bg.brandSolid, color: vars.color.palette.staticWhite, borderRadius: "4px", padding: "8px 16px", border: "none", cursor: "pointer", ":hover": { backgroundColor: vars.color.bg.brandSolidPressed, }, ":active": { backgroundColor: vars.color.bg.brandSolidPressed, }, }); export const secondaryButton = style({ ...vars.typography.t5Bold, backgroundColor: vars.color.bg.neutralWeak, color: vars.color.palette.gray900, borderRadius: "4px", padding: "8px 16px", border: "none", cursor: "pointer", ":hover": { backgroundColor: vars.color.bg.neutralWeakPressed, }, ":active": { backgroundColor: vars.color.bg.neutralWeakPressed, }, }); // 중첩 경로 케이스 export const floatingPanel = style({ backgroundColor: vars.color.bg.layerFloating, boxShadow: `0 2px 8px ${vars.color.bg.overlayMuted}`, padding: "20px", borderRadius: "8px", }); export const dialogPanel = style({ backgroundColor: vars.color.bg.layerFloating, padding: "24px", boxShadow: `0 4px 16px ${vars.color.bg.overlay}`, borderRadius: "12px", }); // 정적 색상 케이스 export const staticColors = style({ color: vars.color.palette.staticBlack, backgroundColor: vars.color.palette.staticWhite, border: `1px solid ${vars.color.palette.staticBlackAlpha200}`, }); // 정적 색상 케이스 (명시적으로 static 프리픽스 테스트) export const staticExplicitColors = style({ color: vars.color.palette.staticBlack, backgroundColor: vars.color.palette.staticWhite, boxShadow: `0 2px 4px ${vars.color.palette.staticBlackAlpha500}`, outline: `1px solid ${vars.color.palette.staticBlackAlpha200}`, }); export const specialBackground = style({ background: `linear-gradient(to bottom, ${vars.color.palette.staticWhiteAlpha50}, ${vars.color.palette.staticWhiteAlpha200})`, backdropFilter: "blur(8px)", }); // 복합 스타일 및 다중 속성 케이스 export const multiProperty = style({ ...vars.typography.t7Bold, color: vars.color.fg.informative, borderLeft: `4px solid ${vars.color.fg.informative}`, borderRight: `4px solid ${vars.color.fg.informative}`, boxShadow: `inset 0 0 0 1px ${vars.color.stroke.neutral}, 0 2px 4px ${vars.color.bg.overlayMuted}`, padding: "16px", backgroundColor: vars.color.bg.layerDefault, }); // 믹스인 스타일 케이스 export const mixinStyle = { primary: { background: vars.color.bg.brandSolid, color: vars.color.palette.staticWhite, }, secondary: { background: vars.color.palette.gray900, }, accent: { background: vars.color.bg.informativeSolid, color: vars.color.stroke.onImage, }, }; // 특수 속성 및 스케일 색상 케이스 export const scaleColors = style({ fill: vars.color.palette.carrot600, stroke: vars.color.palette.gray500, stopColor: vars.color.palette.blue400, floodColor: vars.color.palette.red600, lightingColor: vars.color.palette.green500, }); // 특수 타이포그래피 케이스 export const specialTypographies = { title: vars.typography.t9Bold, subtitle: vars.typography.t5Regular, label: vars.typography.t1Regular, caption: vars.typography.t2Bold, }; // 다양한 경로를 가진 컬러 토큰 export const colorContexts = style({ // 일반 색상 color: vars.color.palette.carrot100, // 배경 색상 backgroundColor: vars.color.bg.layerBasement, // 테두리 색상 borderColor: vars.color.palette.gray400, // 호버 색상 ":hover": { backgroundColor: vars.color.palette.carrot200, borderColor: vars.color.palette.carrot100, }, }); // 복잡한 다중 경로와 중첩된 객체 export const nestedStyleObject = { button: { default: { backgroundColor: vars.color.palette.carrot100, color: vars.color.fg.neutral, border: `1px solid ${vars.color.palette.carrot400}`, }, hover: { backgroundColor: vars.color.palette.carrot200, borderColor: vars.color.palette.carrot500, }, active: { backgroundColor: vars.color.palette.carrot300, color: vars.color.fg.neutralSubtle, }, }, panel: { header: { ...vars.typography.t4Bold, color: vars.color.palette.blue600, borderBottom: `1px solid ${vars.color.palette.blue300}`, }, body: { ...vars.typography.t4Regular, color: vars.color.fg.neutralSubtle, backgroundColor: vars.color.palette.blue100, }, footer: { backgroundColor: vars.color.palette.blue200, borderTop: `1px solid ${vars.color.palette.blue300}`, }, }, }; // 테두리 속성 매핑 테스트 export const borderMapping = style({ // stroke 토큰으로 매핑될 속성 borderColor: vars.color.stroke.neutral, // stroke 토큰이 없어서 fg 토큰으로 대체되는 케이스 borderTopColor: vars.color.fg.brand, borderBottomColor: vars.color.fg.informative, // stroke 또는 fg 토큰으로 대체 boxShadow: `0 0 0 1px ${vars.color.bg.brandSolid}, 0 2px 4px ${vars.color.bg.overlayMuted}`, // 복합 속성 border: `1px solid ${vars.color.palette.gray900}`, }); ``` ## replace-stitches-styled-typography - npm: npx @seed-design/codemod@latest replace-stitches-styled-typography \ - pnpm: pnpm dlx @seed-design/codemod@latest replace-stitches-styled-typography \ - yarn: yarn dlx @seed-design/codemod@latest replace-stitches-styled-typography \ - bun: bun x @seed-design/codemod@latest replace-stitches-styled-typography \ ```tsx title="basic.input.tsx" // @ts-nocheck const ContentText = styled('p', { ...userSelectText, overflow: 'hidden', whiteSpace: 'pre-wrap', wordBreak: 'break-word', color: '$gray900', variants: { size: { medium: { $text: 'bodyM1Regular', }, large: { $text: 'bodyL1Regular', }, xlarge: { $text: "h4", }, }, }, }); const ContentText2 = styled('p', { ...userSelectText, overflow: 'hidden', whiteSpace: 'pre-wrap', wordBreak: 'break-word', color: '$gray900', variants: { size: { medium: { $typography: 'bodyM1Regular', }, large: { $typography: 'bodyL1Regular', }, xlarge: { $typography: "h4", }, }, }, }); ``` ```tsx title="basic.output.tsx" // @ts-nocheck const ContentText = styled('p', { ...userSelectText, overflow: 'hidden', whiteSpace: 'pre-wrap', wordBreak: 'break-word', color: '$gray900', variants: { size: { medium: { $text: "t5Regular", }, large: { $text: "articleBody", }, xlarge: { $text: "t10Bold", }, }, }, }); const ContentText2 = styled('p', { ...userSelectText, overflow: 'hidden', whiteSpace: 'pre-wrap', wordBreak: 'break-word', color: '$gray900', variants: { size: { medium: { $typography: "t5Regular", }, large: { $typography: "articleBody", }, xlarge: { $typography: "t10Bold", }, }, }, }); ``` ## replace-stitches-theme-color - npm: npx @seed-design/codemod@latest replace-stitches-theme-color \ - pnpm: pnpm dlx @seed-design/codemod@latest replace-stitches-theme-color \ - yarn: yarn dlx @seed-design/codemod@latest replace-stitches-theme-color \ - bun: bun x @seed-design/codemod@latest replace-stitches-theme-color \ ```tsx title="basic.input.tsx" // @ts-nocheck import { theme } from "@src/stitches/stitches.config"; const semanticColors = { primary: theme.colors["primary-semantic"].computedValue, onPrimary: theme.colors["onPrimary-semantic"].computedValue, primaryLow: theme.colors["primaryLow-semantic"].computedValue, success: theme.colors["success-semantic"].computedValue, warning: theme.colors["warning-semantic"].computedValue, danger: theme.colors["danger-semantic"].computedValue, paperDefault: theme.colors["paperDefault-semantic"].computedValue, paperContents: theme.colors["paperContents-semantic"].computedValue, paperDialog: theme.colors["paperDialog-semantic"].computedValue, inkText: theme.colors["inkText-semantic"].computedValue, inkTextLow: theme.colors["inkTextLow-semantic"].computedValue, divider1: theme.colors["divider1-semantic"].computedValue, divider2: theme.colors["divider2-semantic"].computedValue, overlayDim: theme.colors["overlayDim-semantic"].computedValue, accent: theme.colors["accent-semantic"].computedValue, }; const scaleColors = { gray00: theme.colors.gray00.computedValue, gray100: theme.colors.gray100.computedValue, gray200: theme.colors.gray200.computedValue, gray300: theme.colors.gray300.computedValue, gray400: theme.colors.gray400.computedValue, gray500: theme.colors.gray500.computedValue, gray600: theme.colors.gray600.computedValue, gray700: theme.colors.gray700.computedValue, gray800: theme.colors.gray800.computedValue, gray900: theme.colors.gray900.computedValue, carrot100: theme.colors.carrot100.computedValue, carrot500: theme.colors.carrot500.computedValue, carrot900: theme.colors.carrot900.computedValue, carrotAlpha50: theme.colors.carrotAlpha50.computedValue, carrotAlpha100: theme.colors.carrotAlpha100.computedValue, carrotAlpha200: theme.colors.carrotAlpha200.computedValue, blue300: theme.colors.blue300.computedValue, blue600: theme.colors.blue600.computedValue, red500: theme.colors.red500.computedValue, }; const staticColors = { white: theme.colors["white-static"].computedValue, black: theme.colors["black-static"].computedValue, blackAlpha200: theme.colors["blackAlpha200-static"].computedValue, whiteAlpha200: theme.colors["whiteAlpha200-static"].computedValue, gray900: theme.colors["gray900-static"].computedValue, carrot50: theme.colors["carrot50-static"].computedValue, carrot800: theme.colors["carrot800-static"].computedValue, blue50: theme.colors["blue50-static"].computedValue, blue800: theme.colors["blue800-static"].computedValue, red50: theme.colors["red50-static"].computedValue, red800: theme.colors["red800-static"].computedValue, }; const Component = () => { return (
안내사항 중요
); }; const Dialog = ({ isOpen, onClose }) => { const styles = { overlay: { backgroundColor: theme.colors["overlayDim-semantic"].computedValue, }, container: { backgroundColor: theme.colors["paperDialog-semantic"].computedValue, borderColor: theme.colors.gray300.computedValue, }, header: { borderBottom: `1px solid ${theme.colors["divider1-semantic"].computedValue}`, }, title: { color: theme.colors.gray900.computedValue, }, content: { color: theme.colors.gray700.computedValue, backgroundColor: theme.colors["paperContents-semantic"].computedValue, }, footer: { borderTop: `1px solid ${theme.colors["divider2-semantic"].computedValue}`, }, closeButton: { color: theme.colors.gray500.computedValue, }, submitButton: { backgroundColor: theme.colors.blue600.computedValue, color: theme.colors["white-static"].computedValue, }, }; return isOpen ? (

다이얼로그 제목

다이얼로그 내용
) : null; }; export { semanticColors, scaleColors, staticColors, Component, Dialog }; ``` ```tsx title="basic.output.tsx" // @ts-nocheck import { theme } from "@src/stitches/stitches.config"; const semanticColors = { primary: theme.colors["bg-brand-solid"].computedValue, onPrimary: theme.colors["palette-static-white"].computedValue, primaryLow: theme.colors["palette-carrot-100"].computedValue, success: theme.colors["bg-positive-solid"].computedValue, warning: theme.colors["bg-warning-solid"].computedValue, danger: theme.colors["bg-critical-solid"].computedValue, paperDefault: theme.colors["bg-layer-default"].computedValue, paperContents: theme.colors["bg-layer-fill"].computedValue, paperDialog: theme.colors["bg-layer-floating"].computedValue, inkText: theme.colors["fg-neutral"].computedValue, inkTextLow: theme.colors["fg-neutral-subtle"].computedValue, divider1: theme.colors["stroke-neutral-subtle"].computedValue, divider2: theme.colors["stroke-neutral-muted"].computedValue, overlayDim: theme.colors["bg-overlay"].computedValue, accent: theme.colors["bg-informative-solid"].computedValue, }; const scaleColors = { gray00: theme.colors["palette-gray-00"].computedValue, gray100: theme.colors["palette-gray-200"].computedValue, gray200: theme.colors["palette-gray-300"].computedValue, gray300: theme.colors["palette-gray-400"].computedValue, gray400: theme.colors["palette-gray-500"].computedValue, gray500: theme.colors["palette-gray-600"].computedValue, gray600: theme.colors["palette-gray-700"].computedValue, gray700: theme.colors["palette-gray-800"].computedValue, gray800: theme.colors["palette-gray-900"].computedValue, gray900: theme.colors["palette-gray-1000"].computedValue, carrot100: theme.colors["palette-carrot-200"].computedValue, carrot500: theme.colors["palette-carrot-600"].computedValue, carrot900: theme.colors["palette-carrot-800"].computedValue, carrotAlpha50: theme.colors["palette-carrot-100"].computedValue, carrotAlpha100: theme.colors["palette-carrot-200"].computedValue, carrotAlpha200: theme.colors["palette-carrot-200"].computedValue, blue300: theme.colors["palette-blue-400"].computedValue, blue600: theme.colors["palette-blue-600"].computedValue, red500: theme.colors["palette-red-700"].computedValue, }; const staticColors = { white: theme.colors["palette-static-white"].computedValue, black: theme.colors["palette-static-black"].computedValue, blackAlpha200: theme.colors["palette-static-black-alpha-500"].computedValue, whiteAlpha200: theme.colors["palette-static-white-alpha-300"].computedValue, gray900: theme.colors["palette-static-black"].computedValue, carrot50: theme.colors["palette-carrot-100"].computedValue, carrot800: theme.colors["palette-carrot-700"].computedValue, blue50: theme.colors["palette-blue-100"].computedValue, blue800: theme.colors["palette-blue-700"].computedValue, red50: theme.colors["palette-red-100"].computedValue, red800: theme.colors["palette-red-700"].computedValue, }; const Component = () => { return (
안내사항 중요
); }; const Dialog = ({ isOpen, onClose }) => { const styles = { overlay: { backgroundColor: theme.colors["bg-overlay"].computedValue, }, container: { backgroundColor: theme.colors["bg-layer-floating"].computedValue, borderColor: theme.colors["palette-gray-400"].computedValue, }, header: { borderBottom: `1px solid ${theme.colors["stroke-neutral-subtle"].computedValue}`, }, title: { color: theme.colors["palette-gray-1000"].computedValue, }, content: { color: theme.colors["palette-gray-800"].computedValue, backgroundColor: theme.colors["bg-layer-fill"].computedValue, }, footer: { borderTop: `1px solid ${theme.colors["stroke-neutral-muted"].computedValue}`, }, closeButton: { color: theme.colors["palette-gray-600"].computedValue, }, submitButton: { backgroundColor: theme.colors["palette-blue-600"].computedValue, color: theme.colors["palette-static-white"].computedValue, }, }; return isOpen ? (

다이얼로그 제목

다이얼로그 내용
) : null; }; export { semanticColors, scaleColors, staticColors, Component, Dialog }; ``` ## replace-css-seed-design-color-variable - npm: npx @seed-design/codemod@latest replace-css-seed-design-color-variable \ - pnpm: pnpm dlx @seed-design/codemod@latest replace-css-seed-design-color-variable \ - yarn: yarn dlx @seed-design/codemod@latest replace-css-seed-design-color-variable \ - bun: bun x @seed-design/codemod@latest replace-css-seed-design-color-variable \ ```css title="basic.input.css" :root[data-seed] { --seed-alert-dialog-backdrop-background: var(--seed-semantic-color-overlay-dim); --seed-alert-dialog-content-background: var(--seed-semantic-color-paper-dialog); --seed-alert-dialog-title-color: var(--seed-scale-color-gray-900); --seed-alert-dialog-description-color: var(--seed-scale-color-gray-900); --seed-box-button-focus-border: 2px solid var(--seed-scale-color-blue-600); box-shadow: 0 0 0 2px var(--seed-scale-color-blue-600); background: linear-gradient(to bottom, var(--seed-scale-color-blue-600), var(--seed-scale-color-blue-700)); } ``` ```css title="basic.output.css" :root[data-seed] { --seed-alert-dialog-backdrop-background: var(--seed-color-bg-overlay); --seed-alert-dialog-content-background: var(--seed-color-bg-layer-floating); --seed-alert-dialog-title-color: var(--seed-color-palette-gray-1000); --seed-alert-dialog-description-color: var(--seed-color-palette-gray-1000); --seed-box-button-focus-border: 2px solid var(--seed-color-palette-blue-600); box-shadow: 0 0 0 2px var(--seed-color-palette-blue-600); background: linear-gradient(to bottom, var(--seed-color-palette-blue-600), var(--seed-color-palette-blue-800)); } ``` ## replace-react-icon - npm: npx @seed-design/codemod@latest replace-react-icon \ - pnpm: pnpm dlx @seed-design/codemod@latest replace-react-icon \ - yarn: yarn dlx @seed-design/codemod@latest replace-react-icon \ - bun: bun x @seed-design/codemod@latest replace-react-icon \ ```tsx title="basic.input.tsx" // @ts-nocheck import { IconSellRegular, IconListFill, IconAddFill as AddIconAlias, } from "@seed-design/react-icon"; import IconSellFill from "@seed-design/react-icon/IconSellFill"; import IconAddThin from '@karrotmarket/karrot-ui-icon/lib/react/IconAddThin'; import IconCloseThin from '@karrotmarket/karrot-ui-icon/lib/react/IconCloseThin'; import IconCarRegular from '@karrotmarket/karrot-ui-icon/lib/react/IconCarRegular'; function App() { console.log(IconSellRegular); return ( <> ); } ``` ```tsx title="basic.output.tsx" // @ts-nocheck import { IconPlusSquareLine, IconDothorizline3VerticalFill, IconPlusFill as AddIconAlias, } from "@karrotmarket/react-monochrome-icon"; import IconPlusSquareFill from "@karrotmarket/react-monochrome-icon/IconPlusSquareFill"; import IconPlusLine from "@karrotmarket/react-monochrome-icon/IconPlusLine"; import IconXmarkLine from "@karrotmarket/react-monochrome-icon/IconXmarkLine"; import IconCarFrontsideLine from "@karrotmarket/react-monochrome-icon/IconCarFrontsideLine"; function App() { console.log(IconPlusSquareLine); return ( <> ); } ``` ## replace-seed-design-token-vars - npm: npx @seed-design/codemod@latest replace-seed-design-token-vars \ - pnpm: pnpm dlx @seed-design/codemod@latest replace-seed-design-token-vars \ - yarn: yarn dlx @seed-design/codemod@latest replace-seed-design-token-vars \ - bun: bun x @seed-design/codemod@latest replace-seed-design-token-vars \ ```tsx title="basic.input.tsx" import { vars as legacyVars } from "@seed-design/design-token"; import { vars } from "@seed-design/css/vars"; import { vars as typoVars } from "@seed-design/css/vars/component/typography"; const color = vars.$color.palette.gray600; const typography = typoVars.textStyleT5Bold.enabled.root; const legacyColor = legacyVars.$static.color.staticWhiteAlpha50; ``` ```tsx title="basic.output.tsx" import { vars as legacyVars } from "@seed-design/design-token"; import { vars } from "@seed-design/css/vars"; import { vars as typoVars } from "@seed-design/css/vars/component/typography"; const color = vars.$color.palette.gray600; const typography = typoVars.textStyleT5Bold.enabled.root; const legacyColor = legacyVars.$static.color.staticWhiteAlpha50; ``` ## replace-semantic-stroke-color 시맨틱 stroke 컬러 토큰을 v0.2.0에 맞춰 마이그레이션하는 transform입니다. ### 목적 @seed-design/css v0.2.0에서 업데이트된 시맨틱 stroke 컬러 토큰을 자동으로 마이그레이션합니다. 이전 버전의 stroke 토큰들을 새로운 네이밍 규칙에 맞게 변환합니다. ### 변환 매핑 #### 우선 순위 변환 (1차) ⚠️ **중요**: 다음 변환은 반드시 다른 변환보다 먼저 처리됩니다. | 기존 토큰 | 신규 토큰 | 비고 | | --------------------------------- | ---------------------------------- | ------------------ | | `vars.$color.stroke.neutralMuted` | `vars.$color.stroke.neutralSubtle` | 가장 먼저 마이그레이션해야 합니다 | #### 일반 변환 (2차) | 기존 토큰 | 신규 토큰 | | --------------------------------- | ------------------------------------ | | `vars.$color.stroke.onImage` | `vars.$color.stroke.neutralSubtle` | | `vars.$color.stroke.neutral` | `vars.$color.stroke.neutralMuted` | | `vars.$color.stroke.fieldFocused` | `vars.$color.stroke.neutralContrast` | | `vars.$color.stroke.control` | `vars.$color.stroke.neutralWeak` | | `vars.$color.stroke.field` | `vars.$color.stroke.neutralWeak` | | `vars.$color.stroke.brand` | `vars.$color.stroke.brandWeak` | | `vars.$color.stroke.positive` | `vars.$color.stroke.positiveWeak` | | `vars.$color.stroke.informative` | `vars.$color.stroke.informativeWeak` | | `vars.$color.stroke.warning` | `vars.$color.stroke.warningWeak` | | `vars.$color.stroke.critical` | `vars.$color.stroke.criticalWeak` | ### 지원하는 파일 형식 - TypeScript (`.ts`) - TypeScript JSX (`.tsx`) ### 변환 예시 #### 기본 사용 ```typescript // Before import { vars } from "@seed-design/css/vars"; const borderColor = vars.$color.stroke.neutralMuted; const outlineColor = vars.$color.stroke.neutral; // After import { vars } from "@seed-design/css/vars"; const borderColor = vars.$color.stroke.neutralSubtle; const outlineColor = vars.$color.stroke.neutralMuted; ``` #### React 컴포넌트에서의 사용 ```tsx // Before const Component = () => (
); // After const Component = () => (
); ``` ### 우선 순위의 중요성 이 transform은 2-pass 방식으로 동작합니다: 1. **1차 변환**: `neutralMuted` → `neutralSubtle`을 먼저 처리 2. **2차 변환**: `neutral` → `neutralMuted` 등 나머지 변환들을 처리 이 순서가 중요한 이유는 연쇄 변환을 방지하기 위해서입니다. 만약 순서가 바뀌면 `neutralMuted`가 `neutralSubtle`로 변환되기 전에 `neutral`이 `neutralMuted`로 변환될 수 있어 예상치 못한 결과가 나올 수 있습니다. ### 변환되지 않는 토큰들 다음 토큰들은 이미 SEED 형식이므로 변환되지 않습니다: - `vars.$color.stroke.brandWeak` - `vars.$color.stroke.brandSolid` - `vars.$color.stroke.neutralSubtle` - `vars.$color.stroke.neutralContrast` - `vars.$color.stroke.neutralWeak` - 기타 `-weak`, `-solid` 접미사를 가진 토큰들 ### 로깅 transform 실행 시 다음과 같은 로그가 생성됩니다: - `.report/replace-semantic-stroke-color-success.log`: 성공한 변환들 - `.report/replace-semantic-stroke-color-issues.log`: 경고 및 실패 - `.report/replace-semantic-stroke-color-debug.log`: 디버그 정보 * npm: npx @seed-design/codemod@latest replace-semantic-stroke-color \ * pnpm: pnpm dlx @seed-design/codemod@latest replace-semantic-stroke-color \ * yarn: yarn dlx @seed-design/codemod@latest replace-semantic-stroke-color \ * bun: bun x @seed-design/codemod@latest replace-semantic-stroke-color \ ```tsx title="basic.input.tsx" // @ts-nocheck import React from "react"; import { vars } from "@seed-design/css/vars"; // 인라인 스타일에서 stroke 토큰 사용 const Component1 = () => (
); // 객체 스타일에서 사용 const styles = { container: { borderColor: vars.$color.stroke.control, border: `1px solid ${vars.$color.stroke.field}`, }, button: { borderColor: vars.$color.stroke.brand, outlineColor: vars.$color.stroke.positive, }, input: { borderColor: vars.$color.stroke.informative, "&:focus": { borderColor: vars.$color.stroke.warning, }, }, error: { borderColor: vars.$color.stroke.critical, }, }; // 삼항 연산자에서 사용 const ConditionalComponent = ({ isActive }: { isActive: boolean }) => (
); // 새로운 토큰들 (변경되지 않아야 함) const NewTokensComponent = () => (
); ``` ```tsx title="basic.output.tsx" // @ts-nocheck import React from "react"; import { vars } from "@seed-design/css/vars"; // 인라인 스타일에서 stroke 토큰 사용 const Component1 = () => (
); // 객체 스타일에서 사용 const styles = { container: { borderColor: vars.$color.stroke.neutralWeak, border: `1px solid ${vars.$color.stroke.neutralWeak}`, }, button: { borderColor: vars.$color.stroke.brandWeak, outlineColor: vars.$color.stroke.positiveWeak, }, input: { borderColor: vars.$color.stroke.informativeWeak, "&:focus": { borderColor: vars.$color.stroke.warningWeak, }, }, error: { borderColor: vars.$color.stroke.criticalWeak, }, }; // 삼항 연산자에서 사용 const ConditionalComponent = ({ isActive }: { isActive: boolean }) => (
); // 새로운 토큰들 (변경되지 않아야 함) const NewTokensComponent = () => (
); ``` ## replace-custom-seed-design-text-component - npm: npx @seed-design/codemod@latest replace-custom-seed-design-text-component \ - pnpm: pnpm dlx @seed-design/codemod@latest replace-custom-seed-design-text-component \ - yarn: yarn dlx @seed-design/codemod@latest replace-custom-seed-design-text-component \ - bun: bun x @seed-design/codemod@latest replace-custom-seed-design-text-component \ ```tsx title="basic.input.tsx" // @ts-nocheck import Text from 'components/Base/Text'; const Component = () => { return (
{/* 기존 variant prop 케이스 */} 광고 노출 기준 앱 내 최근 활동 이력을 분석하여 이용자의 관심사와 관련성이 높은 게시글을 노출해요. {/* typography prop + color prop 케이스 */} 앱 내 최근 활동 이력을 분석하여 이용자의 관심사와 관련성이 높은 게시글을 노출해요. 지역 선택하기 지표별 성과 {/* 다양한 typography prop 형태 */} 접두사 없는 토큰 또 다른 토큰 {/* 다양한 color prop 형태 */} 시맨틱 컬러 스태틱 컬러 textColor prop {/* 조건부 표현식 케이스 */} 조건부 variant 조건부 color {/* JSX 표현식 컨테이너 케이스 */} 표현식 컨테이너
); }; ``` ```tsx title="basic.output.tsx" // @ts-nocheck import { Text } from "@seed-design/react"; const Component = () => { return (
{/* 기존 variant prop 케이스 */} 광고 노출 기준 앱 내 최근 활동 이력을 분석하여 이용자의 관심사와 관련성이 높은 게시글을 노출해요. {/* typography prop + color prop 케이스 */} 앱 내 최근 활동 이력을 분석하여 이용자의 관심사와 관련성이 높은 게시글을 노출해요. 지역 선택하기 지표별 성과 {/* 다양한 typography prop 형태 */} 접두사 없는 토큰 또 다른 토큰 {/* 다양한 color prop 형태 */} 시맨틱 컬러 스태틱 컬러 textColor prop {/* 조건부 표현식 케이스 */} 조건부 variant 조건부 color {/* JSX 표현식 컨테이너 케이스 */} 표현식 컨테이너
); }; ``` ## replace-seed-design-token-typography-classname - npm: npx @seed-design/codemod@latest replace-seed-design-token-typography-classname \ - pnpm: pnpm dlx @seed-design/codemod@latest replace-seed-design-token-typography-classname \ - yarn: yarn dlx @seed-design/codemod@latest replace-seed-design-token-typography-classname \ - bun: bun x @seed-design/codemod@latest replace-seed-design-token-typography-classname \ ```tsx title="basic.input.tsx" // @ts-nocheck import { classNames } from "@seed-design/design-token"; import { style } from "@vanilla-extract/css"; const typography = { one: classNames.$semantic.typography.title2Regular, two: classNames.$semantic.typography.label3Regular, three: classNames.$semantic.typography.label5Regular, four: classNames.$semantic.typography.label6Regular, } export const footer = style([ classNames.$semantic.typography.caption1Regular, { padding: "16px", marginTop: "12px", color: vars.$scale.color.gray700, backgroundColor: vars.$semantic.color.paperContents, }, ]); ``` ```tsx title="basic.output.tsx" // @ts-nocheck import { text } from "@seed-design/css/recipes/text"; import { style } from "@vanilla-extract/css"; const typography = { one: text({ textStyle: "t7Regular" }), two: text({ textStyle: "t4Regular" }), three: text({ textStyle: "t1Regular" }), four: text({ textStyle: "t1Regular" }), } export const footer = style([ text({ textStyle: "t3Regular" }), { padding: "16px", marginTop: "12px", color: vars.$scale.color.gray700, backgroundColor: vars.$semantic.color.paperContents, }, ]); ``` ## replace-stitches-styled-color Stitches로 스타일링된 컴포넌트의 색상을 SEED 형식으로 변환해요. ### 변환 내용 - Stitches `styled()` 함수에서 사용된 Sprout 색상 토큰을 SEED 색상 토큰으로 변환합니다. - 모든 색상 관련 스타일 속성(color, backgroundColor, borderColor 등)을 지원합니다. - 상태 변이(variants)에 적용된 색상 변경도 함께 변환합니다. ### 대상 파일 - `.tsx`, `.jsx`, `.ts`, `.js` 파일에서 Stitches 스타일링 사용 부분 ### 주의사항 - 기존 코드의 구조와 포맷을 최대한 유지하면서 색상 값만 변경합니다. - 커스텀 색상 값이나 CSS 변수는 변환하지 않습니다. * npm: npx @seed-design/codemod@latest replace-stitches-styled-color \ * pnpm: pnpm dlx @seed-design/codemod@latest replace-stitches-styled-color \ * yarn: yarn dlx @seed-design/codemod@latest replace-stitches-styled-color \ * bun: bun x @seed-design/codemod@latest replace-stitches-styled-color \ ```tsx title="basic.input.tsx" // @ts-nocheck const SemanticColorTestComponent = styled("div", { // Semantic Color 테스트 color: "$primary-semantic", color: "$onPrimary-semantic", color: "$primaryLow-semantic", color: "$secondary-semantic", color: "$secondaryLow-semantic", color: "$success-semantic", color: "$successLow-semantic", color: "$warning-semantic", color: "$warningLow-semantic", color: "$danger-semantic", color: "$dangerLow-semantic", color: "$overlayDim-semantic", color: "$overlayLow-semantic", color: "$paperSheet-semantic", color: "$paperDialog-semantic", color: "$paperFloating-semantic", color: "$paperContents-semantic", color: "$paperDefault-semantic", color: "$paperBackground-semantic", color: "$paperAccent-semantic", color: "$primaryHover-semantic", color: "$primaryPressed-semantic", color: "$primaryLowHover-semantic", color: "$primaryLowActive-semantic", color: "$primaryLowPressed-semantic", color: "$grayHover-semantic", color: "$grayPressed-semantic", color: "$onPrimaryOverlay50-semantic", color: "$onPrimaryOverlay200-semantic", color: "$onPrimaryLowOverlay50-semantic", color: "$onPrimaryLowOverlay100-semantic", color: "$onPrimaryLowOverlay200-semantic", color: "$onGrayOverlay50-semantic", color: "$onGrayOverlay100-semantic", color: "$divider1-semantic", color: "$divider2-semantic", color: "$divider3-semantic", color: "$accent-semantic", color: "$inkText-semantic", color: "$inkTextLow-semantic", color: "$grayActive-semantic", }); const ScaleColorTestComponent = styled("div", { // Scale Color Gray 테스트 color: "$gray00", color: "$gray50", color: "$gray100", color: "$gray200", color: "$gray300", color: "$gray400", color: "$gray500", color: "$gray600", color: "$gray700", color: "$gray800", color: "$gray900", color: "$grayAlpha50", color: "$grayAlpha100", color: "$grayAlpha200", color: "$grayAlpha500", // Scale Color Carrot 테스트 color: "$carrot50", color: "$carrot100", color: "$carrot200", color: "$carrot300", color: "$carrot400", color: "$carrot500", color: "$carrot600", color: "$carrot700", color: "$carrot800", color: "$carrot900", color: "$carrot950", color: "$carrotAlpha50", color: "$carrotAlpha100", color: "$carrotAlpha200", // Scale Color Blue 테스트 color: "$blue50", color: "$blue100", color: "$blue200", color: "$blue300", color: "$blue400", color: "$blue500", color: "$blue600", color: "$blue700", color: "$blue800", color: "$blue900", color: "$blue950", color: "$blueAlpha50", color: "$blueAlpha100", color: "$blueAlpha200", // Scale Color Red 테스트 color: "$red50", color: "$red100", color: "$red200", color: "$red300", color: "$red400", color: "$red500", color: "$red600", color: "$red700", color: "$red800", color: "$red900", color: "$red950", color: "$redAlpha50", color: "$redAlpha100", color: "$redAlpha200", // Scale Color Green 테스트 color: "$green50", color: "$green100", color: "$green200", color: "$green300", color: "$green400", color: "$green500", color: "$green600", color: "$green700", color: "$green800", color: "$green900", color: "$green950", color: "$greenAlpha50", color: "$greenAlpha100", color: "$greenAlpha200", // Scale Color Yellow 테스트 color: "$yellow50", color: "$yellow100", color: "$yellow200", color: "$yellow300", color: "$yellow400", color: "$yellow500", color: "$yellow600", color: "$yellow700", color: "$yellow800", color: "$yellow900", color: "$yellow950", color: "$yellowAlpha50", color: "$yellowAlpha100", color: "$yellowAlpha200", // Scale Color Purple 테스트 color: "$purple50", color: "$purple100", color: "$purple200", color: "$purple300", color: "$purple400", color: "$purple500", color: "$purple600", color: "$purple700", color: "$purple800", color: "$purple900", color: "$purple950", }); const StaticColorTestComponent = styled("div", { // Static Color 테스트 color: "$black-static", color: "$white-static", color: "$gray900-static", color: "$carrot50-static", color: "$carrot800-static", color: "$green50-static", color: "$green800-static", color: "$yellow50-static", color: "$yellow800-static", color: "$red50-static", color: "$red800-static", color: "$blue50-static", color: "$blue800-static", color: "$blackAlpha200-static", color: "$blackAlpha500-static", color: "$whiteAlpha50-static", color: "$whiteAlpha200-static", }); // 복합 속성 테스트 const ComplexPropertyTestComponent = styled("div", { border: "1px solid $gray700", boxShadow: "0 0 10px $overlayDim-semantic", outline: "2px solid $accent-semantic", textDecoration: "underline $danger-semantic", // 네스팅된 속성 테스트 "&:before": { borderBottom: "1px solid $divider1-semantic", background: "$paperContents-semantic", }, // 변형 테스트 variants: { theme: { primary: { background: "$primary-semantic", color: "$onPrimary-semantic", }, secondary: { background: "$secondaryLow-semantic", color: "$inkText-semantic", }, danger: { background: "$danger-semantic", color: "$white-static", }, }, }, }); // 복합 속성 (색상 토큰이 앞에 있는 경우) 테스트 const BorderAndColorTestComponent = styled("div", { color: "$scale-red500 solid 1px", color: "$red600 dashed 2px", color: "$scale-blue400 dotted 3px", color: "$scale-green600 double 4px", color: "$scale-yellow500 groove 2px", outlineColor: "$scale-purple500", }); const ImportantTest = styled("div", { color: "$primary-semantic !important", color: "$onPrimary-semantic !important", color: "$primaryLow-semantic !important", color: "$gray00 !important", color: "$gray50 !important", color: "$gray100 !important", css: { color: "$scale-gray600 !important", borderColor: "$scale-gray400 !important", backgroundColor: "$scale-gray100 !important", }, }); const Li_FieldItem = styled("li", { borderBottom: `${rem(1)} solid $semantic-divider1`, borderBottom: `0.5rem solid $semantic-paperBackground`, border: check ? "1px solid $semantic-divider1" : "0.5rem solid $semantic-paperBackground", }); ``` ```tsx title="basic.output.tsx" // @ts-nocheck const SemanticColorTestComponent = styled("div", { // Semantic Color 테스트 color: "$fg-brand", color: "$palette-static-white", color: "$palette-carrot-100", color: "$palette-gray-900", color: "$bg-neutral-weak", color: "$fg-positive", color: "$bg-positive-weak", color: "$bg-warning-solid", color: "$bg-warning-weak", color: "$fg-critical", color: "$bg-critical-weak", color: "$bg-overlay", color: "$bg-overlay-muted", color: "$bg-layer-floating", color: "$bg-layer-floating", color: "$bg-layer-floating", color: "$bg-layer-fill", color: "$bg-layer-default", color: "$bg-layer-basement", color: "$palette-carrot-100", color: "$bg-brand-solid-pressed", color: "$bg-brand-solid-pressed", color: "$palette-carrot-200", color: "$palette-carrot-100", color: "$palette-carrot-200", color: "$bg-neutral-weak-pressed", color: "$bg-neutral-weak-pressed", color: "$onPrimaryOverlay50-semantic", color: "$onPrimaryOverlay200-semantic", color: "$onPrimaryLowOverlay50-semantic", color: "$onPrimaryLowOverlay100-semantic", color: "$onPrimaryLowOverlay200-semantic", color: "$stroke-neutral-subtle", color: "$onGrayOverlay100-semantic", color: "$stroke-neutral-subtle", color: "$stroke-neutral-muted", color: "$palette-gray-400", color: "$fg-informative", color: "$fg-neutral", color: "$fg-neutral-subtle", color: "$fg-neutral-muted", }); const ScaleColorTestComponent = styled("div", { // Scale Color Gray 테스트 color: "$palette-gray-00", color: "$palette-gray-100", color: "$palette-gray-200", color: "$palette-gray-300", color: "$palette-gray-400", color: "$palette-gray-500", color: "$palette-gray-600", color: "$palette-gray-700", color: "$palette-gray-800", color: "$palette-gray-900", color: "$palette-gray-1000", color: "$palette-gray-200", color: "$palette-gray-300", color: "$palette-gray-500", color: "$palette-gray-700", // Scale Color Carrot 테스트 color: "$palette-carrot-100", color: "$palette-carrot-200", color: "$palette-carrot-300", color: "$palette-carrot-400", color: "$palette-carrot-500", color: "$palette-carrot-600", color: "$palette-carrot-600", color: "$palette-carrot-700", color: "$palette-carrot-700", color: "$palette-carrot-800", color: "$palette-carrot-800", color: "$palette-carrot-100", color: "$palette-carrot-200", color: "$palette-carrot-200", // Scale Color Blue 테스트 color: "$palette-blue-100", color: "$palette-blue-200", color: "$palette-blue-300", color: "$palette-blue-400", color: "$palette-blue-400", color: "$palette-blue-600", color: "$palette-blue-600", color: "$palette-blue-800", color: "$palette-blue-900", color: "$palette-blue-900", color: "$palette-blue-1000", color: "$palette-blue-100", color: "$palette-blue-100", color: "$palette-blue-200", // Scale Color Red 테스트 color: "$palette-red-100", color: "$palette-red-200", color: "$palette-red-300", color: "$palette-red-400", color: "$palette-red-600", color: "$palette-red-700", color: "$palette-red-700", color: "$palette-red-800", color: "$palette-red-900", color: "$palette-red-900", color: "$palette-red-900", color: "$palette-red-100", color: "$palette-red-200", color: "$palette-red-300", // Scale Color Green 테스트 color: "$palette-green-100", color: "$palette-green-200", color: "$palette-green-300", color: "$palette-green-400", color: "$palette-green-500", color: "$palette-green-600", color: "$palette-green-700", color: "$palette-green-800", color: "$palette-green-900", color: "$palette-green-900", color: "$palette-green-900", color: "$palette-green-100", color: "$palette-green-200", color: "$palette-green-200", // Scale Color Yellow 테스트 color: "$palette-yellow-100", color: "$palette-yellow-200", color: "$palette-yellow-300", color: "$palette-yellow-400", color: "$palette-yellow-500", color: "$palette-yellow-700", color: "$palette-yellow-700", color: "$palette-yellow-800", color: "$palette-yellow-800", color: "$palette-yellow-900", color: "$palette-yellow-900", color: "$palette-yellow-100", color: "$palette-yellow-100", color: "$palette-yellow-100", // Scale Color Purple 테스트 color: "$palette-purple-100", color: "$palette-purple-300", color: "$palette-purple-400", color: "$palette-purple-400", color: "$palette-purple-500", color: "$palette-purple-600", color: "$palette-purple-700", color: "$palette-purple-800", color: "$palette-purple-900", color: "$palette-purple-900", color: "$palette-purple-1000", }); const StaticColorTestComponent = styled("div", { // Static Color 테스트 color: "$palette-static-black", color: "$palette-static-white", color: "$palette-static-black", color: "$palette-carrot-100", color: "$palette-carrot-700", color: "$palette-green-100", color: "$palette-green-700", color: "$palette-yellow-100", color: "$palette-yellow-700", color: "$palette-red-100", color: "$palette-red-700", color: "$palette-blue-100", color: "$palette-blue-700", color: "$palette-static-black-alpha-500", color: "$palette-static-black-alpha-700", color: "$palette-static-white-alpha-50", color: "$palette-static-white-alpha-300", }); // 복합 속성 테스트 const ComplexPropertyTestComponent = styled("div", { border: "1px solid $palette-gray-800", boxShadow: "0 0 10px $bg-overlay", outline: "2px solid $fg-informative", textDecoration: "underline $fg-critical", // 네스팅된 속성 테스트 "&:before": { borderBottom: "1px solid $stroke-neutral-subtle", background: "$bg-layer-fill", }, // 변형 테스트 variants: { theme: { primary: { background: "$bg-brand-solid", color: "$palette-static-white", }, secondary: { background: "$bg-neutral-weak", color: "$fg-neutral", }, danger: { background: "$bg-critical-solid", color: "$palette-static-white", }, }, }, }); // 복합 속성 (색상 토큰이 앞에 있는 경우) 테스트 const BorderAndColorTestComponent = styled("div", { color: "$palette-red-700 solid 1px", color: "$palette-red-700 dashed 2px", color: "$palette-blue-400 dotted 3px", color: "$palette-green-700 double 4px", color: "$palette-yellow-700 groove 2px", outlineColor: "$palette-purple-600", }); const ImportantTest = styled("div", { color: "$fg-brand !important", color: "$palette-static-white !important", color: "$palette-carrot-100 !important", color: "$palette-gray-00 !important", color: "$palette-gray-100 !important", color: "$palette-gray-200 !important", css: { color: "$palette-gray-700 !important", borderColor: "$palette-gray-500 !important", backgroundColor: "$palette-gray-200 !important", }, }); const Li_FieldItem = styled("li", { borderBottom: `${rem(1)} solid $stroke-neutral-subtle`, borderBottom: `0.5rem solid $bg-layer-basement`, border: check ? "1px solid $stroke-neutral-subtle" : "0.5rem solid $bg-layer-basement", }); ``` ## replace-custom-text-component-color-prop - npm: npx @seed-design/codemod@latest replace-custom-text-component-color-prop \ - pnpm: pnpm dlx @seed-design/codemod@latest replace-custom-text-component-color-prop \ - yarn: yarn dlx @seed-design/codemod@latest replace-custom-text-component-color-prop \ - bun: bun x @seed-design/codemod@latest replace-custom-text-component-color-prop \ ```tsx title="basic.input.tsx" // @ts-nocheck const Component = () => { return ( <> ); }; ``` ```tsx title="basic.output.tsx" // @ts-nocheck const Component = () => { return ( <> ); }; ``` ## replace-alpha-color SEED 알파 컬러 토큰을 새로운 이름으로 업데이트하는 transform입니다. 이 transform은 다음과 같은 알파 컬러 토큰들을 새로운 값으로 변경합니다: - `staticBlackAlpha50` → `staticBlackAlpha200` - `staticBlackAlpha200` → `staticBlackAlpha500` - `staticBlackAlpha500` → `staticBlackAlpha700` - `staticWhiteAlpha200` → `staticWhiteAlpha300` ### 주의사항 - 이 transform은 JavaScript/TypeScript 파일과 CSS 파일을 모두 자동으로 처리합니다. - **한 번만 실행**: 동일한 파일에 여러 번 실행하면 연쇄 변환이 발생할 수 있습니다 - **SEED 전용**: 이미 SEED를 사용 중인 프로젝트에서만 사용하세요 - **백업 권장**: 변환 전에 코드를 백업하는 것을 권장합니다 - **순서 중요**: 큰 번호부터 작은 번호 순으로 변환하여 연쇄 변환을 방지합니다 * npm: npx @seed-design/codemod@latest replace-alpha-color \ * pnpm: pnpm dlx @seed-design/codemod@latest replace-alpha-color \ * yarn: yarn dlx @seed-design/codemod@latest replace-alpha-color \ * bun: bun x @seed-design/codemod@latest replace-alpha-color \ ```tsx title="basic.input.tsx" // @ts-nocheck import { vars } from "@seed-design/css/vars"; export const Component = () => { const styles = { overlay: { backgroundColor: vars.$color.palette.staticBlackAlpha50, }, shadow: { backgroundColor: vars.$color.palette.staticBlackAlpha200, }, darkOverlay: { backgroundColor: vars.$color.palette.staticBlackAlpha500, }, lightOverlay: { backgroundColor: vars.$color.palette.staticWhiteAlpha200, }, }; return (
Light overlay
Shadow
Dark overlay
Light overlay
Direct usage
); }; ``` ```tsx title="basic.output.tsx" // @ts-nocheck import { vars } from "@seed-design/css/vars"; export const Component = () => { const styles = { overlay: { backgroundColor: vars.$color.palette.staticBlackAlpha200, }, shadow: { backgroundColor: vars.$color.palette.staticBlackAlpha500, }, darkOverlay: { backgroundColor: vars.$color.palette.staticBlackAlpha700, }, lightOverlay: { backgroundColor: vars.$color.palette.staticWhiteAlpha300, }, }; return (
Light overlay
Shadow
Dark overlay
Light overlay
Direct usage
); }; ``` ## replace-custom-seed-design-color 커스텀 컬러 토큰을 SEED 형식으로 변환하는 트랜스폼 - npm: npx @seed-design/codemod@latest replace-custom-seed-design-color \ - pnpm: pnpm dlx @seed-design/codemod@latest replace-custom-seed-design-color \ - yarn: yarn dlx @seed-design/codemod@latest replace-custom-seed-design-color \ - bun: bun x @seed-design/codemod@latest replace-custom-seed-design-color \ ```ts title="basic.input.ts" // @ts-nocheck import { style } from "@vanilla-extract/css"; import { color, backgroundColor, background } from "@/shared/styles"; export const container = style({ backgroundColor: color.gray100, color: color.gray900, borderColor: color.carrot500, }); export const box = style({ background: color.gray50, color: color.red500, border: `1px solid ${color.gray300}`, }); export const alert = style({ backgroundColor: color.red50, color: color.red900, }); export const button = style({ backgroundColor: background.gray100, color: color.gray900, }); export const highlight = style({ color: color.carrot500, backgroundColor: backgroundColor.primary, }); export const primary = style({ color: color.primary, }); ``` ```ts title="basic.output.ts" // @ts-nocheck import { style } from "@vanilla-extract/css"; import { color, backgroundColor, background } from "@/shared/styles"; export const container = style({ backgroundColor: color.palette.gray200, color: color.palette.gray1000, borderColor: color.palette.carrot600, }); export const box = style({ background: color.palette.gray100, color: color.palette.red700, border: `1px solid ${color.palette.gray400}`, }); export const alert = style({ backgroundColor: color.palette.red100, color: color.palette.red900, }); export const button = style({ backgroundColor: background.palette.gray200, color: color.palette.gray1000, }); export const highlight = style({ color: color.palette.carrot600, backgroundColor: backgroundColor.bg.brandSolid, }); export const primary = style({ color: color.fg.brand, }); ``` ## replace-custom-color-to-seed-design-vars-color - npm: npx @seed-design/codemod@latest replace-custom-color-to-seed-design-vars-color \ - pnpm: pnpm dlx @seed-design/codemod@latest replace-custom-color-to-seed-design-vars-color \ - yarn: yarn dlx @seed-design/codemod@latest replace-custom-color-to-seed-design-vars-color \ - bun: bun x @seed-design/codemod@latest replace-custom-color-to-seed-design-vars-color \ ```ts title="basic.input.ts" // @ts-nocheck import { color, bg, typography, mode } from '@/src/styles/tokens'; export const container = style({ backgroundColor: color['$semantic.paperDefault'], color: color['$scale.gray900'], borderColor: color['$scale.carrot500'], }); export const box = style({ background: color['$scale.gray50'], color: color['$scale.red500'], border: `1px solid ${color['$scale.gray300']}`, }); export const alert = style({ backgroundColor: color['$scale.red50'], color: color['$scale.red900'], }); export const button = style({ backgroundColor: color['$scale.gray100'], color: color['$scale.gray900'], }); export const highlight = style({ color: color['$scale.carrot500'], backgroundColor: color['$semantic.primary'], }); export const primary = style({ color: color['$semantic.primary'], }); // Additional test cases for various mappings export const semanticColors = style({ backgroundColor: color['$semantic.primary'], color: color['$semantic.inkText'], borderColor: color['$semantic.divider1'], }); export const scaleColors = style({ background: color['$scale.gray100'], color: color['$scale.carrot600'], border: `1px solid ${color['$scale.blue500']}`, }); export const staticColors = style({ backgroundColor: color['$static.staticWhite'], color: color['$static.staticBlack'], borderColor: color['$static.staticBlackAlpha200'], }); // Test deprecated tokens with alternative export const deprecatedColors = style({ backgroundColor: color['$semantic.paperContents'], color: color['$semantic.inkTextLow'], }); // Test multiple token choices (should use first one) export const multipleChoices = style({ backgroundColor: color['$semantic.success'], color: color['$semantic.warning'], }); export const icon = { color: color['$scale.gray600'], bg: bg['$scale.gray100'], }; ``` ```ts title="basic.output.ts" // @ts-nocheck import { color, bg, typography, mode } from "@/src/styles/tokens"; export const container = style({ backgroundColor: color["bg.layerDefault"], color: color["palette.gray1000"], borderColor: color["palette.carrot600"], }); export const box = style({ background: color["palette.gray100"], color: color["palette.red700"], border: `1px solid ${color["palette.gray400"]}`, }); export const alert = style({ backgroundColor: color["palette.red100"], color: color["palette.red900"], }); export const button = style({ backgroundColor: color["palette.gray200"], color: color["palette.gray1000"], }); export const highlight = style({ color: color["palette.carrot600"], backgroundColor: color["bg.brandSolid"], }); export const primary = style({ color: color["fg.brand"], }); // Additional test cases for various mappings export const semanticColors = style({ backgroundColor: color["bg.brandSolid"], color: color["fg.neutral"], borderColor: color["stroke.neutralSubtle"], }); export const scaleColors = style({ background: color["palette.gray200"], color: color["palette.carrot600"], border: `1px solid ${color["palette.blue600"]}`, }); export const staticColors = style({ backgroundColor: color["palette.staticWhite"], color: color["palette.staticBlack"], borderColor: color["palette.staticBlackAlpha500"], }); // Test deprecated tokens with alternative export const deprecatedColors = style({ backgroundColor: color["bg.layerFill"], color: color["fg.neutralSubtle"], }); // Test multiple token choices (should use first one) export const multipleChoices = style({ backgroundColor: color["bg.positiveSolid"], color: color["bg.warningSolid"], }); export const icon = { color: color["palette.gray700"], bg: bg["palette.gray200"], }; ``` ## replace-css-seed-design-typography-variable - npm: npx @seed-design/codemod@latest replace-css-seed-design-typography-variable \ - pnpm: pnpm dlx @seed-design/codemod@latest replace-css-seed-design-typography-variable \ - yarn: yarn dlx @seed-design/codemod@latest replace-css-seed-design-typography-variable \ - bun: bun x @seed-design/codemod@latest replace-css-seed-design-typography-variable \ ```css title="basic.input.css" /* Radio Label */ .seed-radio-group[data-size="small"] [data-part="radio-label"] { margin-inline-start: var(--seed-radio-small-label-margin-inline-start); margin-block-start: var(--seed-radio-small-label-margin-block-start); font-size: var(--seed-semantic-typography-label4-regular-font-size); font-weight: var(--seed-semantic-typography-label4-regular-font-weight); line-height: var(--seed-semantic-typography-label4-regular-line-height); letter-spacing: var(--seed-semantic-typography-label4-regular-letter-spacing); } .seed-radio-group[data-size="medium"] [data-part="radio-label"] { margin-inline-start: var(--seed-radio-medium-label-margin-inline-start); margin-block-start: var(--seed-radio-medium-label-margin-block-start); font-size: var(--seed-semantic-typography-label3-regular-font-size); font-weight: var(--seed-semantic-typography-label3-regular-font-weight); line-height: var(--seed-semantic-typography-label3-regular-line-height); letter-spacing: var(--seed-semantic-typography-label3-regular-letter-spacing); } .seed-radio-group[data-size="large"] [data-part="radio-label"] { margin-inline-start: var(--seed-radio-large-label-margin-inline-start); margin-block-start: var(--seed-radio-large-label-margin-block-start); font-size: var(--seed-semantic-typography-label2-regular-font-size); font-weight: var(--seed-semantic-typography-label2-regular-font-weight); line-height: var(--seed-semantic-typography-label2-regular-line-height); letter-spacing: var(--seed-semantic-typography-label2-regular-letter-spacing); } ``` ```css title="basic.output.css" /* Radio Label */ .seed-radio-group[data-size="small"] [data-part="radio-label"] { margin-inline-start: var(--seed-radio-small-label-margin-inline-start); margin-block-start: var(--seed-radio-small-label-margin-block-start); font-size: var(--seed-font-size-t2); font-weight: var(--seed-font-weight-regular); line-height: var(--seed-line-height-t2); letter-spacing: normal; } .seed-radio-group[data-size="medium"] [data-part="radio-label"] { margin-inline-start: var(--seed-radio-medium-label-margin-inline-start); margin-block-start: var(--seed-radio-medium-label-margin-block-start); font-size: var(--seed-font-size-t4); font-weight: var(--seed-font-weight-regular); line-height: var(--seed-line-height-t4); letter-spacing: normal; } .seed-radio-group[data-size="large"] [data-part="radio-label"] { margin-inline-start: var(--seed-radio-large-label-margin-inline-start); margin-block-start: var(--seed-radio-large-label-margin-block-start); font-size: var(--seed-font-size-t5); font-weight: var(--seed-font-weight-regular); line-height: var(--seed-line-height-t5); letter-spacing: normal; } ``` ## replace-tailwind-color Tailwind CSS 색상 클래스를 SEED 형식으로 변환해요. ### 변환 내용 - Sprout의 색상 클래스 네이밍을 SEED 형식으로 변환합니다. - `text-`, `bg-`, `border-` 등의 접두사를 가진 Tailwind 색상 클래스를 변환합니다. - 색상 강도(shade)에 따른 변환 매핑을 적용합니다. ### 변환 예시 - `text-carrot-500` → `text-static-orange-base` - `bg-salmon-100` → `bg-static-red-light` - `border-navy-900` → `border-static-blue-dark` ### 대상 파일 - `.tsx`, `.jsx`, `.ts`, `.js`, `.html`, `.css` 파일에서 Tailwind 클래스를 사용하는 부분 ### 주의사항 - className 문자열, 템플릿 리터럴, 배열 형태 모두 지원합니다. - Tailwind 동적 클래스 조합(`clsx`, `cx`, `classnames` 등)도 변환됩니다. * npm: npx @seed-design/codemod@latest replace-tailwind-color \ * pnpm: pnpm dlx @seed-design/codemod@latest replace-tailwind-color \ * yarn: yarn dlx @seed-design/codemod@latest replace-tailwind-color \ * bun: bun x @seed-design/codemod@latest replace-tailwind-color \ ```tsx title="basic.input.tsx" // @ts-nocheck export function BackgroundExample() { return (
Primary Background
Primary Low Background
Hover Primary Low Background
Focus Primary Low Background
Active Primary Low Background
Scale Background
Scale Carrot Low Background
Scale Carrot Mid Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Static Black Background
Static White Background
Static Gray900 Background
); } export function SeedBackgroundExample() { return (
Primary Background
Primary Low Background
Hover Primary Low Background
Focus Primary Low Background
Active Primary Low Background
Scale Background
Scale Carrot Low Background
Scale Carrot Mid Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Static Black Background
Static White Background
Static Gray900 Background
); } // Class Variance Authority Example import { cva } from "class-variance-authority"; // Button component with variants const buttonVariants = cva( "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors", { variants: { variant: { default: "bg-primary text-staticWhite hover:bg-primaryLow", destructive: "bg-danger text-staticWhite hover:bg-dangerLow", outline: "border border-gray300 bg-staticWhite text-gray900 hover:bg-gray100", secondary: "bg-seed-secondaryLow text-seed-secondary hover:bg-seed-gray200", ghost: "text-seed-primary hover:bg-seed-primaryLow", link: "text-seed-primary underline-offset-4 hover:underline", }, size: { default: "h-10 px-4 py-2", sm: "h-9 rounded-md px-3", lg: "h-11 rounded-md px-8", icon: "h-10 w-10", }, }, defaultVariants: { variant: "default", size: "default", }, } ); ``` ```tsx title="basic.output.tsx" // @ts-nocheck export function BackgroundExample() { return (
Primary Background
Primary Low Background
Hover Primary Low Background
Focus Primary Low Background
Active Primary Low Background
Scale Background
Scale Carrot Low Background
Scale Carrot Mid Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Static Black Background
Static White Background
Static Gray900 Background
); } export function SeedBackgroundExample() { return (
Primary Background
Primary Low Background
Hover Primary Low Background
Focus Primary Low Background
Active Primary Low Background
Scale Background
Scale Carrot Low Background
Scale Carrot Mid Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Scale Carrot High Background
Static Black Background
Static White Background
Static Gray900 Background
); } // Class Variance Authority Example import { cva } from "class-variance-authority"; // Button component with variants const buttonVariants = cva( "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors", { variants: { variant: { default: "bg-bg-brand-solid text-palette-static-white hover:bg-palette-carrot-100", destructive: "bg-bg-critical-solid text-palette-static-white hover:bg-bg-critical-weak", outline: "border border-palette-gray-400 bg-palette-static-white text-palette-gray-1000 hover:bg-palette-gray-200", secondary: "bg-bg-neutral-weak text-palette-gray-900 hover:bg-palette-gray-300", ghost: "text-fg-brand hover:bg-palette-carrot-100", link: "text-fg-brand underline-offset-4 hover:underline", }, size: { default: "h-10 px-4 py-2", sm: "h-9 rounded-md px-3", lg: "h-11 rounded-md px-8", icon: "h-10 w-10", }, }, defaultVariants: { variant: "default", size: "default", }, } ); ```