component-builder

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Component Builder

组件构建器

This skill documents the tailwind-variants pattern used for UI components in this project. All UI components should follow this pattern for consistency and type safety.
本技能文档介绍了本项目中UI组件所使用的tailwind-variants模式。所有UI组件都应遵循此模式,以保证一致性和类型安全性。

When to Use

适用场景

Use this skill when:
  • Creating new UI components in
    src/lib/ui/
  • Refactoring existing components to use tailwind-variants
  • Adding new variants to existing components
在以下场景中使用本技能:
  • src/lib/ui/
    目录下创建新的UI组件
  • 重构现有组件以使用tailwind-variants
  • 为现有组件添加新的变体

Quick Start

快速开始

Every component needs two files:
  1. componentName.variants.ts
    - Variant definitions
  2. ComponentName.svelte
    - The component
每个组件都需要两个文件:
  1. componentName.variants.ts
    - 变体定义文件
  2. ComponentName.svelte
    - 组件文件

Reference Files

参考文件

  • Canonical example:
    src/lib/ui/Button.svelte
    and
    src/lib/ui/button.variants.ts
  • Compound variants example:
    src/lib/ui/Tag.svelte
    and
    src/lib/ui/tag.variants.ts
  • Multi-variant example:
    src/lib/ui/ContentCard.svelte
    and
    src/lib/ui/contentCard.variants.ts
  • 标准示例
    src/lib/ui/Button.svelte
    src/lib/ui/button.variants.ts
  • 复合变体示例
    src/lib/ui/Tag.svelte
    src/lib/ui/tag.variants.ts
  • 多变体示例
    src/lib/ui/ContentCard.svelte
    src/lib/ui/contentCard.variants.ts

Pattern Overview

模式概述

Step 1: Create Variants File

步骤1:创建变体文件

typescript
// componentName.variants.ts
import { tv, type VariantProps } from 'tailwind-variants'

export const componentVariants = tv({
	base: 'common-classes-for-all-variants',
	variants: {
		variant: {
			primary: 'classes-for-primary',
			secondary: 'classes-for-secondary'
		},
		size: {
			sm: 'text-sm px-2',
			md: 'text-base px-4',
			lg: 'text-lg px-6'
		}
	},
	defaultVariants: {
		variant: 'primary',
		size: 'md'
	}
})

// Export types for each variant dimension
export type ComponentVariant = VariantProps<typeof componentVariants>['variant']
export type ComponentSize = VariantProps<typeof componentVariants>['size']
typescript
// componentName.variants.ts
import { tv, type VariantProps } from 'tailwind-variants'

export const componentVariants = tv({
	base: 'common-classes-for-all-variants',
	variants: {
		variant: {
			primary: 'classes-for-primary',
			secondary: 'classes-for-secondary'
		},
		size: {
			sm: 'text-sm px-2',
			md: 'text-base px-4',
			lg: 'text-lg px-6'
		}
	},
	defaultVariants: {
		variant: 'primary',
		size: 'md'
	}
})

// Export types for each variant dimension
export type ComponentVariant = VariantProps<typeof componentVariants>['variant']
export type ComponentSize = VariantProps<typeof componentVariants>['size']

Step 2: Use in Component

步骤2:在组件中使用

svelte
<script lang="ts">
  import type { ClassValue } from 'svelte/elements'
  import { componentVariants, type ComponentVariant, type ComponentSize } from './componentName.variants'

  type Props = {
    variant?: ComponentVariant
    size?: ComponentSize
    class?: ClassValue
  }

  let { variant, size, class: className, ...rest }: Props = $props()
</script>

<div class={[componentVariants({ variant, size }), className]} {...rest}>
  <!-- content -->
</div>
svelte
<script lang="ts">
  import type { ClassValue } from 'svelte/elements'
  import { componentVariants, type ComponentVariant, type ComponentSize } from './componentName.variants'

  type Props = {
    variant?: ComponentVariant
    size?: ComponentSize
    class?: ClassValue
  }

  let { variant, size, class: className, ...rest }: Props = $props()
</script>

<div class={[componentVariants({ variant, size }), className]} {...rest}>
  <!-- content -->
</div>

Key Patterns

核心模式

Boolean Variants

布尔型变体

For on/off states like
active
,
disabled
,
error
:
typescript
variants: {
  active: {
    true: 'bg-svelte-100 border-svelte-300',
    false: ''
  },
  error: {
    true: 'border-red-300 bg-red-50',
    false: 'border-transparent'
  }
}
针对
active
disabled
error
这类开关状态:
typescript
variants: {
  active: {
    true: 'bg-svelte-100 border-svelte-300',
    false: ''
  },
  error: {
    true: 'border-red-300 bg-red-50',
    false: 'border-transparent'
  }
}

Compound Variants

复合变体

Apply styles only when specific combinations match:
typescript
compoundVariants: [
	{
		active: true,
		removable: false,
		class: 'hover:bg-svelte-200'
	}
]
仅当特定组合匹配时才应用样式:
typescript
compoundVariants: [
	{
		active: true,
		removable: false,
		class: 'hover:bg-svelte-200'
	}
]

Class Merging

类名合并

Always use array syntax to allow consumer overrides:
svelte
<div class={[componentVariants({ variant, size }), className]}>
始终使用数组语法以支持使用者覆盖样式:
svelte
<div class={[componentVariants({ variant, size }), className]}>

Templates

模板

For copy-paste templates, see TEMPLATES.md.
如需可直接复制粘贴的模板,请查看TEMPLATES.md