@sylix/coworker 2.0.11 → 2.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/slash/config.d.ts.map +1 -1
- package/dist/commands/slash/config.js +22 -4
- package/dist/commands/slash/config.js.map +1 -1
- package/dist/core/CoWorkerAgent.d.ts.map +1 -1
- package/dist/core/CoWorkerAgent.js +6 -3
- package/dist/core/CoWorkerAgent.js.map +1 -1
- package/dist/skills/defaults/accessibility/screen-reader-testing.md +545 -0
- package/dist/skills/defaults/accessibility/wcag-audit-patterns.md +555 -0
- package/dist/skills/defaults/ai-ml/rag.md +276 -0
- package/dist/skills/defaults/backend-development/api-design-principles.md +528 -0
- package/dist/skills/defaults/backend-development/api-design.md +285 -0
- package/dist/skills/defaults/backend-development/architecture-patterns.md +494 -0
- package/dist/skills/defaults/backend-development/async-python.md +237 -0
- package/dist/skills/defaults/backend-development/auth-implementation-patterns.md +638 -0
- package/dist/skills/defaults/backend-development/bazel-build-optimization.md +387 -0
- package/dist/skills/defaults/backend-development/billing-automation/SKILL.md +566 -0
- package/dist/skills/defaults/backend-development/code-review-excellence.md +538 -0
- package/dist/skills/defaults/backend-development/cqrs-implementation.md +554 -0
- package/dist/skills/defaults/backend-development/database-design.md +305 -0
- package/dist/skills/defaults/backend-development/debugging-strategies.md +536 -0
- package/dist/skills/defaults/backend-development/e2e-testing-patterns.md +544 -0
- package/dist/skills/defaults/backend-development/error-handling-patterns.md +641 -0
- package/dist/skills/defaults/backend-development/fastapi-templates.md +559 -0
- package/dist/skills/defaults/backend-development/fastapi.md +309 -0
- package/dist/skills/defaults/backend-development/git-advanced-workflows.md +405 -0
- package/dist/skills/defaults/backend-development/microservices-patterns.md +595 -0
- package/dist/skills/defaults/backend-development/microservices.md +284 -0
- package/dist/skills/defaults/backend-development/monorepo-management.md +623 -0
- package/dist/skills/defaults/backend-development/nodejs-backend-patterns.md +1048 -0
- package/dist/skills/defaults/backend-development/nx-workspace-patterns.md +457 -0
- package/dist/skills/defaults/backend-development/paypal-integration/SKILL.md +478 -0
- package/dist/skills/defaults/backend-development/pci-compliance/SKILL.md +480 -0
- package/dist/skills/defaults/backend-development/python-anti-patterns.md +349 -0
- package/dist/skills/defaults/backend-development/python-background-jobs.md +364 -0
- package/dist/skills/defaults/backend-development/python-code-style.md +360 -0
- package/dist/skills/defaults/backend-development/python-configuration.md +368 -0
- package/dist/skills/defaults/backend-development/python-design-patterns.md +296 -0
- package/dist/skills/defaults/backend-development/python-error-handling.md +323 -0
- package/dist/skills/defaults/backend-development/python-packaging.md +887 -0
- package/dist/skills/defaults/backend-development/python-performance-optimization.md +874 -0
- package/dist/skills/defaults/backend-development/python-project-structure.md +252 -0
- package/dist/skills/defaults/backend-development/python-resilience.md +376 -0
- package/dist/skills/defaults/backend-development/python-resource-management.md +421 -0
- package/dist/skills/defaults/backend-development/python-type-safety.md +428 -0
- package/dist/skills/defaults/backend-development/sql-optimization-patterns.md +509 -0
- package/dist/skills/defaults/backend-development/stripe-integration/SKILL.md +522 -0
- package/dist/skills/defaults/backend-development/turborepo-caching.md +376 -0
- package/dist/skills/defaults/blockchain/defi-protocol-templates.md +430 -0
- package/dist/skills/defaults/blockchain/nft-standards.md +364 -0
- package/dist/skills/defaults/blockchain/solidity-security.md +514 -0
- package/dist/skills/defaults/blockchain/web3-testing.md +360 -0
- package/dist/skills/defaults/business/competitive-landscape/SKILL.md +527 -0
- package/dist/skills/defaults/business/market-sizing-analysis/SKILL.md +451 -0
- package/dist/skills/defaults/business/startup-financial-modeling/SKILL.md +494 -0
- package/dist/skills/defaults/business/startup-metrics-framework/SKILL.md +564 -0
- package/dist/skills/defaults/business/team-composition-analysis.md +437 -0
- package/dist/skills/defaults/compliance/employment-contract-templates/SKILL.md +527 -0
- package/dist/skills/defaults/compliance/gdpr-data-handling/SKILL.md +630 -0
- package/dist/skills/defaults/data-engineering/airflow-dag-patterns.md +436 -0
- package/dist/skills/defaults/data-engineering/airflow.md +519 -0
- package/dist/skills/defaults/data-engineering/data-quality.md +583 -0
- package/dist/skills/defaults/data-engineering/dbt-transformation-patterns.md +482 -0
- package/dist/skills/defaults/data-engineering/dbt.md +556 -0
- package/dist/skills/defaults/data-engineering/ml-pipeline-workflow/SKILL.md +247 -0
- package/dist/skills/defaults/data-engineering/spark-optimization.md +348 -0
- package/dist/skills/defaults/data-engineering/spark.md +411 -0
- package/dist/skills/defaults/database/postgresql.md +202 -0
- package/dist/skills/defaults/debugging/systematic-debugging.md +249 -0
- package/dist/skills/defaults/devops/architecture-decision-records.md +448 -0
- package/dist/skills/defaults/devops/changelog-automation.md +580 -0
- package/dist/skills/defaults/devops/cicd.md +314 -0
- package/dist/skills/defaults/devops/cloud.md +263 -0
- package/dist/skills/defaults/devops/code-review-excellence.md +299 -0
- package/dist/skills/defaults/devops/cost-optimization.md +295 -0
- package/dist/skills/defaults/devops/deployment-pipeline-design.md +356 -0
- package/dist/skills/defaults/devops/docker.md +281 -0
- package/dist/skills/defaults/devops/git-workflows.md +205 -0
- package/dist/skills/defaults/devops/github-actions.md +311 -0
- package/dist/skills/defaults/devops/gitlab-ci-patterns.md +266 -0
- package/dist/skills/defaults/devops/hybrid-cloud-networking.md +241 -0
- package/dist/skills/defaults/devops/istio-traffic-management.md +327 -0
- package/dist/skills/defaults/devops/kubernetes.md +339 -0
- package/dist/skills/defaults/devops/linkerd-patterns.md +311 -0
- package/dist/skills/defaults/devops/multi-cloud-architecture.md +181 -0
- package/dist/skills/defaults/devops/observability.md +243 -0
- package/dist/skills/defaults/devops/openapi-spec-generation.md +1024 -0
- package/dist/skills/defaults/devops/postmortem-writing.md +396 -0
- package/dist/skills/defaults/devops/prometheus-configuration.md +265 -0
- package/dist/skills/defaults/devops/secrets-management.md +341 -0
- package/dist/skills/defaults/devops/service-mesh-observability.md +385 -0
- package/dist/skills/defaults/devops/terraform-module-library.md +244 -0
- package/dist/skills/defaults/finance/backtesting-frameworks/SKILL.md +663 -0
- package/dist/skills/defaults/finance/risk-metrics-calculation/SKILL.md +557 -0
- package/dist/skills/defaults/frontend/accessibility-compliance.md +420 -0
- package/dist/skills/defaults/frontend/design-system-patterns.md +337 -0
- package/dist/skills/defaults/frontend/interaction-design.md +327 -0
- package/dist/skills/defaults/frontend/javascript.md +311 -0
- package/dist/skills/defaults/frontend/modern-javascript-patterns.md +927 -0
- package/dist/skills/defaults/frontend/react-native-design.md +440 -0
- package/dist/skills/defaults/frontend/react.md +345 -0
- package/dist/skills/defaults/frontend/responsive-design.md +472 -0
- package/dist/skills/defaults/frontend/tailwind-design-system.md +337 -0
- package/dist/skills/defaults/frontend/typescript-advanced-types.md +724 -0
- package/dist/skills/defaults/frontend/typescript.md +334 -0
- package/dist/skills/defaults/frontend/visual-design-foundations.md +326 -0
- package/dist/skills/defaults/frontend/web-component-design.md +279 -0
- package/dist/skills/defaults/game-development/godot-gdscript-patterns.md +188 -0
- package/dist/skills/defaults/game-development/unity-ecs-patterns.md +594 -0
- package/dist/skills/defaults/kubernetes/gitops-workflow.md +285 -0
- package/dist/skills/defaults/kubernetes/gitops.md +280 -0
- package/dist/skills/defaults/kubernetes/helm-chart-scaffolding.md +553 -0
- package/dist/skills/defaults/kubernetes/helm.md +343 -0
- package/dist/skills/defaults/kubernetes/k8s-manifest-generator.md +501 -0
- package/dist/skills/defaults/kubernetes/k8s-security-policies.md +342 -0
- package/dist/skills/defaults/kubernetes/manifests.md +330 -0
- package/dist/skills/defaults/kubernetes/security.md +337 -0
- package/dist/skills/defaults/llm-application/embedding-strategies.md +608 -0
- package/dist/skills/defaults/llm-application/hybrid-search-implementation.md +570 -0
- package/dist/skills/defaults/llm-application/hybrid-search.md +570 -0
- package/dist/skills/defaults/llm-application/langchain-architecture.md +666 -0
- package/dist/skills/defaults/llm-application/langchain.md +259 -0
- package/dist/skills/defaults/llm-application/llm-evaluation.md +695 -0
- package/dist/skills/defaults/llm-application/prompt-engineering-patterns.md +449 -0
- package/dist/skills/defaults/llm-application/prompt-engineering.md +219 -0
- package/dist/skills/defaults/llm-application/rag-implementation.md +434 -0
- package/dist/skills/defaults/llm-application/similarity-search-patterns.md +560 -0
- package/dist/skills/defaults/llm-application/similarity-search.md +560 -0
- package/dist/skills/defaults/llm-application/vector-index-tuning.md +523 -0
- package/dist/skills/defaults/mobile/mobile-android-design.md +440 -0
- package/dist/skills/defaults/mobile/mobile-ios-design.md +266 -0
- package/dist/skills/defaults/monitoring/distributed-tracing.md +436 -0
- package/dist/skills/defaults/monitoring/grafana-dashboards.md +370 -0
- package/dist/skills/defaults/monitoring/prometheus-configuration.md +379 -0
- package/dist/skills/defaults/monitoring/slo-implementation.md +323 -0
- package/dist/skills/defaults/refactoring/code-refactoring.md +349 -0
- package/dist/skills/defaults/security/anti-reversing-techniques/SKILL.md +559 -0
- package/dist/skills/defaults/security/auditor.md +168 -0
- package/dist/skills/defaults/security/binary-analysis-patterns/SKILL.md +438 -0
- package/dist/skills/defaults/security/memory-forensics/SKILL.md +483 -0
- package/dist/skills/defaults/security/mtls-configuration.md +349 -0
- package/dist/skills/defaults/security/protocol-reverse-engineering/SKILL.md +520 -0
- package/dist/skills/defaults/security/sast-configuration.md +182 -0
- package/dist/skills/defaults/security/security.md +313 -0
- package/dist/skills/defaults/security/stride-analysis.md +273 -0
- package/dist/skills/defaults/security/threat-mitigation-mapping.md +290 -0
- package/dist/skills/defaults/systems/bash-defensive-patterns/SKILL.md +539 -0
- package/dist/skills/defaults/systems/bats-testing-patterns/SKILL.md +631 -0
- package/dist/skills/defaults/systems/go-concurrency-patterns.md +657 -0
- package/dist/skills/defaults/systems/memory-safety-patterns.md +605 -0
- package/dist/skills/defaults/systems/rust-async-patterns.md +519 -0
- package/dist/skills/defaults/systems/shellcheck-configuration/SKILL.md +456 -0
- package/dist/skills/defaults/team-collaboration/multi-reviewer-patterns.md +126 -0
- package/dist/skills/defaults/team-collaboration/parallel-feature-development.md +151 -0
- package/dist/skills/defaults/testing/javascript-testing-patterns.md +1021 -0
- package/dist/skills/defaults/testing/python-testing-patterns.md +351 -0
- package/dist/skills/defaults/testing/testing.md +332 -0
- package/dist/skills/defaults/workflows/context-driven-development.md +384 -0
- package/dist/skills/defaults/workflows/track-management.md +592 -0
- package/dist/skills/defaults/workflows/workflow-patterns.md +622 -0
- package/dist/skills/index.d.ts +11 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +129 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/utils/character.js +4 -4
- package/dist/utils/character.js.map +1 -1
- package/dist/utils/inputbar.d.ts.map +1 -1
- package/dist/utils/inputbar.js +7 -0
- package/dist/utils/inputbar.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: design-system-patterns
|
|
3
|
+
description: Build scalable design systems with design tokens, theming infrastructure, and component architecture patterns. Use when creating design tokens, implementing theme switching, building component libraries, or establishing design system foundations.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Design System Patterns
|
|
7
|
+
|
|
8
|
+
Master design system architecture to create consistent, maintainable, and scalable UI foundations across web and mobile applications.
|
|
9
|
+
|
|
10
|
+
## When to Use This Skill
|
|
11
|
+
|
|
12
|
+
- Creating design tokens for colors, typography, spacing, and shadows
|
|
13
|
+
- Implementing light/dark theme switching with CSS custom properties
|
|
14
|
+
- Building multi-brand theming systems
|
|
15
|
+
- Architecting component libraries with consistent APIs
|
|
16
|
+
- Establishing design-to-code workflows with Figma tokens
|
|
17
|
+
- Creating semantic token hierarchies (primitive, semantic, component)
|
|
18
|
+
- Setting up design system documentation and guidelines
|
|
19
|
+
|
|
20
|
+
## Core Capabilities
|
|
21
|
+
|
|
22
|
+
### 1. Design Tokens
|
|
23
|
+
|
|
24
|
+
- Primitive tokens (raw values: colors, sizes, fonts)
|
|
25
|
+
- Semantic tokens (contextual meaning: text-primary, surface-elevated)
|
|
26
|
+
- Component tokens (specific usage: button-bg, card-border)
|
|
27
|
+
- Token naming conventions and organization
|
|
28
|
+
- Multi-platform token generation (CSS, iOS, Android)
|
|
29
|
+
|
|
30
|
+
### 2. Theming Infrastructure
|
|
31
|
+
|
|
32
|
+
- CSS custom properties architecture
|
|
33
|
+
- Theme context providers in React
|
|
34
|
+
- Dynamic theme switching
|
|
35
|
+
- System preference detection (prefers-color-scheme)
|
|
36
|
+
- Persistent theme storage
|
|
37
|
+
- Reduced motion and high contrast modes
|
|
38
|
+
|
|
39
|
+
### 3. Component Architecture
|
|
40
|
+
|
|
41
|
+
- Compound component patterns
|
|
42
|
+
- Polymorphic components (as prop)
|
|
43
|
+
- Variant and size systems
|
|
44
|
+
- Slot-based composition
|
|
45
|
+
- Headless UI patterns
|
|
46
|
+
- Style props and responsive variants
|
|
47
|
+
|
|
48
|
+
### 4. Token Pipeline
|
|
49
|
+
|
|
50
|
+
- Figma to code synchronization
|
|
51
|
+
- Style Dictionary configuration
|
|
52
|
+
- Token transformation and formatting
|
|
53
|
+
- CI/CD integration for token updates
|
|
54
|
+
|
|
55
|
+
## Quick Start
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
// Design tokens with CSS custom properties
|
|
59
|
+
const tokens = {
|
|
60
|
+
colors: {
|
|
61
|
+
// Primitive tokens
|
|
62
|
+
gray: {
|
|
63
|
+
50: "#fafafa",
|
|
64
|
+
100: "#f5f5f5",
|
|
65
|
+
900: "#171717",
|
|
66
|
+
},
|
|
67
|
+
blue: {
|
|
68
|
+
500: "#3b82f6",
|
|
69
|
+
600: "#2563eb",
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
// Semantic tokens (reference primitives)
|
|
73
|
+
semantic: {
|
|
74
|
+
light: {
|
|
75
|
+
"text-primary": "var(--color-gray-900)",
|
|
76
|
+
"text-secondary": "var(--color-gray-600)",
|
|
77
|
+
"surface-default": "var(--color-white)",
|
|
78
|
+
"surface-elevated": "var(--color-gray-50)",
|
|
79
|
+
"border-default": "var(--color-gray-200)",
|
|
80
|
+
"interactive-primary": "var(--color-blue-500)",
|
|
81
|
+
},
|
|
82
|
+
dark: {
|
|
83
|
+
"text-primary": "var(--color-gray-50)",
|
|
84
|
+
"text-secondary": "var(--color-gray-400)",
|
|
85
|
+
"surface-default": "var(--color-gray-900)",
|
|
86
|
+
"surface-elevated": "var(--color-gray-800)",
|
|
87
|
+
"border-default": "var(--color-gray-700)",
|
|
88
|
+
"interactive-primary": "var(--color-blue-400)",
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Key Patterns
|
|
95
|
+
|
|
96
|
+
### Pattern 1: Token Hierarchy
|
|
97
|
+
|
|
98
|
+
```css
|
|
99
|
+
/* Layer 1: Primitive tokens (raw values) */
|
|
100
|
+
:root {
|
|
101
|
+
--color-blue-500: #3b82f6;
|
|
102
|
+
--color-blue-600: #2563eb;
|
|
103
|
+
--color-gray-50: #fafafa;
|
|
104
|
+
--color-gray-900: #171717;
|
|
105
|
+
|
|
106
|
+
--space-1: 0.25rem;
|
|
107
|
+
--space-2: 0.5rem;
|
|
108
|
+
--space-4: 1rem;
|
|
109
|
+
|
|
110
|
+
--font-size-sm: 0.875rem;
|
|
111
|
+
--font-size-base: 1rem;
|
|
112
|
+
--font-size-lg: 1.125rem;
|
|
113
|
+
|
|
114
|
+
--radius-sm: 0.25rem;
|
|
115
|
+
--radius-md: 0.5rem;
|
|
116
|
+
--radius-lg: 1rem;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/* Layer 2: Semantic tokens (meaning) */
|
|
120
|
+
:root {
|
|
121
|
+
--text-primary: var(--color-gray-900);
|
|
122
|
+
--text-secondary: var(--color-gray-600);
|
|
123
|
+
--surface-default: white;
|
|
124
|
+
--interactive-primary: var(--color-blue-500);
|
|
125
|
+
--interactive-primary-hover: var(--color-blue-600);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* Layer 3: Component tokens (specific usage) */
|
|
129
|
+
:root {
|
|
130
|
+
--button-bg: var(--interactive-primary);
|
|
131
|
+
--button-bg-hover: var(--interactive-primary-hover);
|
|
132
|
+
--button-text: white;
|
|
133
|
+
--button-radius: var(--radius-md);
|
|
134
|
+
--button-padding-x: var(--space-4);
|
|
135
|
+
--button-padding-y: var(--space-2);
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Pattern 2: Theme Switching with React
|
|
140
|
+
|
|
141
|
+
```tsx
|
|
142
|
+
import { createContext, useContext, useEffect, useState } from "react";
|
|
143
|
+
|
|
144
|
+
type Theme = "light" | "dark" | "system";
|
|
145
|
+
|
|
146
|
+
interface ThemeContextValue {
|
|
147
|
+
theme: Theme;
|
|
148
|
+
resolvedTheme: "light" | "dark";
|
|
149
|
+
setTheme: (theme: Theme) => void;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const ThemeContext = createContext<ThemeContextValue | null>(null);
|
|
153
|
+
|
|
154
|
+
export function ThemeProvider({ children }: { children: React.ReactNode }) {
|
|
155
|
+
const [theme, setTheme] = useState<Theme>(() => {
|
|
156
|
+
if (typeof window !== "undefined") {
|
|
157
|
+
return (localStorage.getItem("theme") as Theme) || "system";
|
|
158
|
+
}
|
|
159
|
+
return "system";
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
const [resolvedTheme, setResolvedTheme] = useState<"light" | "dark">("light");
|
|
163
|
+
|
|
164
|
+
useEffect(() => {
|
|
165
|
+
const root = document.documentElement;
|
|
166
|
+
|
|
167
|
+
const applyTheme = (isDark: boolean) => {
|
|
168
|
+
root.classList.remove("light", "dark");
|
|
169
|
+
root.classList.add(isDark ? "dark" : "light");
|
|
170
|
+
setResolvedTheme(isDark ? "dark" : "light");
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
if (theme === "system") {
|
|
174
|
+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
175
|
+
applyTheme(mediaQuery.matches);
|
|
176
|
+
|
|
177
|
+
const handler = (e: MediaQueryListEvent) => applyTheme(e.matches);
|
|
178
|
+
mediaQuery.addEventListener("change", handler);
|
|
179
|
+
return () => mediaQuery.removeEventListener("change", handler);
|
|
180
|
+
} else {
|
|
181
|
+
applyTheme(theme === "dark");
|
|
182
|
+
}
|
|
183
|
+
}, [theme]);
|
|
184
|
+
|
|
185
|
+
useEffect(() => {
|
|
186
|
+
localStorage.setItem("theme", theme);
|
|
187
|
+
}, [theme]);
|
|
188
|
+
|
|
189
|
+
return (
|
|
190
|
+
<ThemeContext.Provider value={{ theme, resolvedTheme, setTheme }}>
|
|
191
|
+
{children}
|
|
192
|
+
</ThemeContext.Provider>
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export const useTheme = () => {
|
|
197
|
+
const context = useContext(ThemeContext);
|
|
198
|
+
if (!context) throw new Error("useTheme must be used within ThemeProvider");
|
|
199
|
+
return context;
|
|
200
|
+
};
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Pattern 3: Variant System with CVA
|
|
204
|
+
|
|
205
|
+
```tsx
|
|
206
|
+
import { cva, type VariantProps } from "class-variance-authority";
|
|
207
|
+
import { cn } from "@/lib/utils";
|
|
208
|
+
|
|
209
|
+
const buttonVariants = cva(
|
|
210
|
+
// Base styles
|
|
211
|
+
"inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50",
|
|
212
|
+
{
|
|
213
|
+
variants: {
|
|
214
|
+
variant: {
|
|
215
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
216
|
+
destructive:
|
|
217
|
+
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
218
|
+
outline:
|
|
219
|
+
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
220
|
+
secondary:
|
|
221
|
+
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
222
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
223
|
+
link: "text-primary underline-offset-4 hover:underline",
|
|
224
|
+
},
|
|
225
|
+
size: {
|
|
226
|
+
sm: "h-9 px-3 text-sm",
|
|
227
|
+
md: "h-10 px-4 text-sm",
|
|
228
|
+
lg: "h-11 px-8 text-base",
|
|
229
|
+
icon: "h-10 w-10",
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
defaultVariants: {
|
|
233
|
+
variant: "default",
|
|
234
|
+
size: "md",
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
interface ButtonProps
|
|
240
|
+
extends
|
|
241
|
+
React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
242
|
+
VariantProps<typeof buttonVariants> {
|
|
243
|
+
asChild?: boolean;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export function Button({ className, variant, size, ...props }: ButtonProps) {
|
|
247
|
+
return (
|
|
248
|
+
<button
|
|
249
|
+
className={cn(buttonVariants({ variant, size, className }))}
|
|
250
|
+
{...props}
|
|
251
|
+
/>
|
|
252
|
+
);
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Pattern 4: Style Dictionary Configuration
|
|
257
|
+
|
|
258
|
+
```javascript
|
|
259
|
+
// style-dictionary.config.js
|
|
260
|
+
module.exports = {
|
|
261
|
+
source: ["tokens/**/*.json"],
|
|
262
|
+
platforms: {
|
|
263
|
+
css: {
|
|
264
|
+
transformGroup: "css",
|
|
265
|
+
buildPath: "dist/css/",
|
|
266
|
+
files: [
|
|
267
|
+
{
|
|
268
|
+
destination: "variables.css",
|
|
269
|
+
format: "css/variables",
|
|
270
|
+
options: {
|
|
271
|
+
outputReferences: true, // Preserve token references
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
],
|
|
275
|
+
},
|
|
276
|
+
scss: {
|
|
277
|
+
transformGroup: "scss",
|
|
278
|
+
buildPath: "dist/scss/",
|
|
279
|
+
files: [
|
|
280
|
+
{
|
|
281
|
+
destination: "_variables.scss",
|
|
282
|
+
format: "scss/variables",
|
|
283
|
+
},
|
|
284
|
+
],
|
|
285
|
+
},
|
|
286
|
+
ios: {
|
|
287
|
+
transformGroup: "ios-swift",
|
|
288
|
+
buildPath: "dist/ios/",
|
|
289
|
+
files: [
|
|
290
|
+
{
|
|
291
|
+
destination: "DesignTokens.swift",
|
|
292
|
+
format: "ios-swift/class.swift",
|
|
293
|
+
className: "DesignTokens",
|
|
294
|
+
},
|
|
295
|
+
],
|
|
296
|
+
},
|
|
297
|
+
android: {
|
|
298
|
+
transformGroup: "android",
|
|
299
|
+
buildPath: "dist/android/",
|
|
300
|
+
files: [
|
|
301
|
+
{
|
|
302
|
+
destination: "colors.xml",
|
|
303
|
+
format: "android/colors",
|
|
304
|
+
filter: { attributes: { category: "color" } },
|
|
305
|
+
},
|
|
306
|
+
],
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
};
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## Best Practices
|
|
313
|
+
|
|
314
|
+
1. **Name Tokens by Purpose**: Use semantic names (text-primary) not visual descriptions (dark-gray)
|
|
315
|
+
2. **Maintain Token Hierarchy**: Primitives > Semantic > Component tokens
|
|
316
|
+
3. **Document Token Usage**: Include usage guidelines with token definitions
|
|
317
|
+
4. **Version Tokens**: Treat token changes as API changes with semver
|
|
318
|
+
5. **Test Theme Combinations**: Verify all themes work with all components
|
|
319
|
+
6. **Automate Token Pipeline**: CI/CD for Figma-to-code synchronization
|
|
320
|
+
7. **Provide Migration Paths**: Deprecate tokens gradually with clear alternatives
|
|
321
|
+
|
|
322
|
+
## Common Issues
|
|
323
|
+
|
|
324
|
+
- **Token Sprawl**: Too many tokens without clear hierarchy
|
|
325
|
+
- **Inconsistent Naming**: Mixed conventions (camelCase vs kebab-case)
|
|
326
|
+
- **Missing Dark Mode**: Tokens that don't adapt to theme changes
|
|
327
|
+
- **Hardcoded Values**: Using raw values instead of tokens
|
|
328
|
+
- **Circular References**: Tokens referencing each other in loops
|
|
329
|
+
- **Platform Gaps**: Tokens missing for some platforms (web but not mobile)
|
|
330
|
+
|
|
331
|
+
## Resources
|
|
332
|
+
|
|
333
|
+
- [Style Dictionary Documentation](https://amzn.github.io/style-dictionary/)
|
|
334
|
+
- [Tokens Studio for Figma](https://tokens.studio/)
|
|
335
|
+
- [Design Tokens W3C Spec](https://design-tokens.github.io/community-group/format/)
|
|
336
|
+
- [Radix UI Themes](https://www.radix-ui.com/themes)
|
|
337
|
+
- [shadcn/ui Theming](https://ui.shadcn.com/docs/theming)
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: interaction-design
|
|
3
|
+
description: Design and implement microinteractions, motion design, transitions, and user feedback patterns. Use when adding polish to UI interactions, implementing loading states, or creating delightful user experiences.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Interaction Design
|
|
7
|
+
|
|
8
|
+
Create engaging, intuitive interactions through motion, feedback, and thoughtful state transitions that enhance usability and delight users.
|
|
9
|
+
|
|
10
|
+
## When to Use This Skill
|
|
11
|
+
|
|
12
|
+
- Adding microinteractions to enhance user feedback
|
|
13
|
+
- Implementing smooth page and component transitions
|
|
14
|
+
- Designing loading states and skeleton screens
|
|
15
|
+
- Creating gesture-based interactions
|
|
16
|
+
- Building notification and toast systems
|
|
17
|
+
- Implementing drag-and-drop interfaces
|
|
18
|
+
- Adding scroll-triggered animations
|
|
19
|
+
- Designing hover and focus states
|
|
20
|
+
|
|
21
|
+
## Core Principles
|
|
22
|
+
|
|
23
|
+
### 1. Purposeful Motion
|
|
24
|
+
|
|
25
|
+
Motion should communicate, not decorate:
|
|
26
|
+
|
|
27
|
+
- **Feedback**: Confirm user actions occurred
|
|
28
|
+
- **Orientation**: Show where elements come from/go to
|
|
29
|
+
- **Focus**: Direct attention to important changes
|
|
30
|
+
- **Continuity**: Maintain context during transitions
|
|
31
|
+
|
|
32
|
+
### 2. Timing Guidelines
|
|
33
|
+
|
|
34
|
+
| Duration | Use Case |
|
|
35
|
+
| --------- | ----------------------------------------- |
|
|
36
|
+
| 100-150ms | Micro-feedback (hovers, clicks) |
|
|
37
|
+
| 200-300ms | Small transitions (toggles, dropdowns) |
|
|
38
|
+
| 300-500ms | Medium transitions (modals, page changes) |
|
|
39
|
+
| 500ms+ | Complex choreographed animations |
|
|
40
|
+
|
|
41
|
+
### 3. Easing Functions
|
|
42
|
+
|
|
43
|
+
```css
|
|
44
|
+
/* Common easings */
|
|
45
|
+
--ease-out: cubic-bezier(0.16, 1, 0.3, 1); /* Decelerate - entering */
|
|
46
|
+
--ease-in: cubic-bezier(0.55, 0, 1, 0.45); /* Accelerate - exiting */
|
|
47
|
+
--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1); /* Both - moving between */
|
|
48
|
+
--spring: cubic-bezier(0.34, 1.56, 0.64, 1); /* Overshoot - playful */
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Quick Start: Button Microinteraction
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import { motion } from "framer-motion";
|
|
55
|
+
|
|
56
|
+
export function InteractiveButton({ children, onClick }) {
|
|
57
|
+
return (
|
|
58
|
+
<motion.button
|
|
59
|
+
onClick={onClick}
|
|
60
|
+
whileHover={{ scale: 1.02 }}
|
|
61
|
+
whileTap={{ scale: 0.98 }}
|
|
62
|
+
transition={{ type: "spring", stiffness: 400, damping: 17 }}
|
|
63
|
+
className="px-4 py-2 bg-blue-600 text-white rounded-lg"
|
|
64
|
+
>
|
|
65
|
+
{children}
|
|
66
|
+
</motion.button>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Interaction Patterns
|
|
72
|
+
|
|
73
|
+
### 1. Loading States
|
|
74
|
+
|
|
75
|
+
**Skeleton Screens**: Preserve layout while loading
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
function CardSkeleton() {
|
|
79
|
+
return (
|
|
80
|
+
<div className="animate-pulse">
|
|
81
|
+
<div className="h-48 bg-gray-200 rounded-lg" />
|
|
82
|
+
<div className="mt-4 h-4 bg-gray-200 rounded w-3/4" />
|
|
83
|
+
<div className="mt-2 h-4 bg-gray-200 rounded w-1/2" />
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**Progress Indicators**: Show determinate progress
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
function ProgressBar({ progress }: { progress: number }) {
|
|
93
|
+
return (
|
|
94
|
+
<div className="h-2 bg-gray-200 rounded-full overflow-hidden">
|
|
95
|
+
<motion.div
|
|
96
|
+
className="h-full bg-blue-600"
|
|
97
|
+
initial={{ width: 0 }}
|
|
98
|
+
animate={{ width: `${progress}%` }}
|
|
99
|
+
transition={{ ease: "easeOut" }}
|
|
100
|
+
/>
|
|
101
|
+
</div>
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 2. State Transitions
|
|
107
|
+
|
|
108
|
+
**Toggle with smooth transition**:
|
|
109
|
+
|
|
110
|
+
```tsx
|
|
111
|
+
function Toggle({ checked, onChange }) {
|
|
112
|
+
return (
|
|
113
|
+
<button
|
|
114
|
+
role="switch"
|
|
115
|
+
aria-checked={checked}
|
|
116
|
+
onClick={() => onChange(!checked)}
|
|
117
|
+
className={`
|
|
118
|
+
relative w-12 h-6 rounded-full transition-colors duration-200
|
|
119
|
+
${checked ? "bg-blue-600" : "bg-gray-300"}
|
|
120
|
+
`}
|
|
121
|
+
>
|
|
122
|
+
<motion.span
|
|
123
|
+
className="absolute top-1 left-1 w-4 h-4 bg-white rounded-full shadow"
|
|
124
|
+
animate={{ x: checked ? 24 : 0 }}
|
|
125
|
+
transition={{ type: "spring", stiffness: 500, damping: 30 }}
|
|
126
|
+
/>
|
|
127
|
+
</button>
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### 3. Page Transitions
|
|
133
|
+
|
|
134
|
+
**Framer Motion layout animations**:
|
|
135
|
+
|
|
136
|
+
```tsx
|
|
137
|
+
import { AnimatePresence, motion } from "framer-motion";
|
|
138
|
+
|
|
139
|
+
function PageTransition({ children, key }) {
|
|
140
|
+
return (
|
|
141
|
+
<AnimatePresence mode="wait">
|
|
142
|
+
<motion.div
|
|
143
|
+
key={key}
|
|
144
|
+
initial={{ opacity: 0, y: 20 }}
|
|
145
|
+
animate={{ opacity: 1, y: 0 }}
|
|
146
|
+
exit={{ opacity: 0, y: -20 }}
|
|
147
|
+
transition={{ duration: 0.3 }}
|
|
148
|
+
>
|
|
149
|
+
{children}
|
|
150
|
+
</motion.div>
|
|
151
|
+
</AnimatePresence>
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### 4. Feedback Patterns
|
|
157
|
+
|
|
158
|
+
**Ripple effect on click**:
|
|
159
|
+
|
|
160
|
+
```tsx
|
|
161
|
+
function RippleButton({ children, onClick }) {
|
|
162
|
+
const [ripples, setRipples] = useState([]);
|
|
163
|
+
|
|
164
|
+
const handleClick = (e) => {
|
|
165
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
166
|
+
const ripple = {
|
|
167
|
+
x: e.clientX - rect.left,
|
|
168
|
+
y: e.clientY - rect.top,
|
|
169
|
+
id: Date.now(),
|
|
170
|
+
};
|
|
171
|
+
setRipples((prev) => [...prev, ripple]);
|
|
172
|
+
setTimeout(() => {
|
|
173
|
+
setRipples((prev) => prev.filter((r) => r.id !== ripple.id));
|
|
174
|
+
}, 600);
|
|
175
|
+
onClick?.(e);
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
return (
|
|
179
|
+
<button onClick={handleClick} className="relative overflow-hidden">
|
|
180
|
+
{children}
|
|
181
|
+
{ripples.map((ripple) => (
|
|
182
|
+
<span
|
|
183
|
+
key={ripple.id}
|
|
184
|
+
className="absolute bg-white/30 rounded-full animate-ripple"
|
|
185
|
+
style={{ left: ripple.x, top: ripple.y }}
|
|
186
|
+
/>
|
|
187
|
+
))}
|
|
188
|
+
</button>
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### 5. Gesture Interactions
|
|
194
|
+
|
|
195
|
+
**Swipe to dismiss**:
|
|
196
|
+
|
|
197
|
+
```tsx
|
|
198
|
+
function SwipeCard({ children, onDismiss }) {
|
|
199
|
+
return (
|
|
200
|
+
<motion.div
|
|
201
|
+
drag="x"
|
|
202
|
+
dragConstraints={{ left: 0, right: 0 }}
|
|
203
|
+
onDragEnd={(_, info) => {
|
|
204
|
+
if (Math.abs(info.offset.x) > 100) {
|
|
205
|
+
onDismiss();
|
|
206
|
+
}
|
|
207
|
+
}}
|
|
208
|
+
className="cursor-grab active:cursor-grabbing"
|
|
209
|
+
>
|
|
210
|
+
{children}
|
|
211
|
+
</motion.div>
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## CSS Animation Patterns
|
|
217
|
+
|
|
218
|
+
### Keyframe Animations
|
|
219
|
+
|
|
220
|
+
```css
|
|
221
|
+
@keyframes fadeIn {
|
|
222
|
+
from {
|
|
223
|
+
opacity: 0;
|
|
224
|
+
transform: translateY(10px);
|
|
225
|
+
}
|
|
226
|
+
to {
|
|
227
|
+
opacity: 1;
|
|
228
|
+
transform: translateY(0);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
@keyframes pulse {
|
|
233
|
+
0%,
|
|
234
|
+
100% {
|
|
235
|
+
opacity: 1;
|
|
236
|
+
}
|
|
237
|
+
50% {
|
|
238
|
+
opacity: 0.5;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
@keyframes spin {
|
|
243
|
+
to {
|
|
244
|
+
transform: rotate(360deg);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.animate-fadeIn {
|
|
249
|
+
animation: fadeIn 0.3s ease-out;
|
|
250
|
+
}
|
|
251
|
+
.animate-pulse {
|
|
252
|
+
animation: pulse 2s ease-in-out infinite;
|
|
253
|
+
}
|
|
254
|
+
.animate-spin {
|
|
255
|
+
animation: spin 1s linear infinite;
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
### CSS Transitions
|
|
260
|
+
|
|
261
|
+
```css
|
|
262
|
+
.card {
|
|
263
|
+
transition:
|
|
264
|
+
transform 0.2s ease-out,
|
|
265
|
+
box-shadow 0.2s ease-out;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.card:hover {
|
|
269
|
+
transform: translateY(-4px);
|
|
270
|
+
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.1);
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
## Accessibility Considerations
|
|
275
|
+
|
|
276
|
+
```css
|
|
277
|
+
/* Respect user motion preferences */
|
|
278
|
+
@media (prefers-reduced-motion: reduce) {
|
|
279
|
+
*,
|
|
280
|
+
*::before,
|
|
281
|
+
*::after {
|
|
282
|
+
animation-duration: 0.01ms !important;
|
|
283
|
+
animation-iteration-count: 1 !important;
|
|
284
|
+
transition-duration: 0.01ms !important;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
```tsx
|
|
290
|
+
function AnimatedComponent() {
|
|
291
|
+
const prefersReducedMotion = window.matchMedia(
|
|
292
|
+
"(prefers-reduced-motion: reduce)",
|
|
293
|
+
).matches;
|
|
294
|
+
|
|
295
|
+
return (
|
|
296
|
+
<motion.div
|
|
297
|
+
animate={{ opacity: 1 }}
|
|
298
|
+
transition={{ duration: prefersReducedMotion ? 0 : 0.3 }}
|
|
299
|
+
/>
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## Best Practices
|
|
305
|
+
|
|
306
|
+
1. **Performance First**: Use `transform` and `opacity` for smooth 60fps
|
|
307
|
+
2. **Reduce Motion Support**: Always respect `prefers-reduced-motion`
|
|
308
|
+
3. **Consistent Timing**: Use a timing scale across the app
|
|
309
|
+
4. **Natural Physics**: Prefer spring animations over linear
|
|
310
|
+
5. **Interruptible**: Allow users to cancel long animations
|
|
311
|
+
6. **Progressive Enhancement**: Work without JS animations
|
|
312
|
+
7. **Test on Devices**: Performance varies significantly
|
|
313
|
+
|
|
314
|
+
## Common Issues
|
|
315
|
+
|
|
316
|
+
- **Janky Animations**: Avoid animating `width`, `height`, `top`, `left`
|
|
317
|
+
- **Over-animation**: Too much motion causes fatigue
|
|
318
|
+
- **Blocking Interactions**: Never prevent user input during animations
|
|
319
|
+
- **Memory Leaks**: Clean up animation listeners on unmount
|
|
320
|
+
- **Flash of Content**: Use `will-change` sparingly for optimization
|
|
321
|
+
|
|
322
|
+
## Resources
|
|
323
|
+
|
|
324
|
+
- [Framer Motion Documentation](https://www.framer.com/motion/)
|
|
325
|
+
- [CSS Animation Guide](https://web.dev/animations-guide/)
|
|
326
|
+
- [Material Design Motion](https://m3.material.io/styles/motion/overview)
|
|
327
|
+
- [GSAP Animation Library](https://greensock.com/gsap/)
|