@nextsparkjs/ai-workflow 0.1.0-beta.100
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/LICENSE +21 -0
- package/README.md +115 -0
- package/claude/_docs/workflows-optimizations.md +359 -0
- package/claude/agents/api-tester.md +634 -0
- package/claude/agents/architecture-supervisor.md +1351 -0
- package/claude/agents/backend-developer.md +997 -0
- package/claude/agents/backend-validator.md +417 -0
- package/claude/agents/bdd-docs-writer.md +737 -0
- package/claude/agents/block-developer.md +677 -0
- package/claude/agents/code-reviewer.md +1432 -0
- package/claude/agents/db-developer.md +721 -0
- package/claude/agents/db-validator.md +407 -0
- package/claude/agents/demo-video-generator.md +493 -0
- package/claude/agents/documentation-writer.md +1268 -0
- package/claude/agents/frontend-developer.md +1234 -0
- package/claude/agents/frontend-validator.md +777 -0
- package/claude/agents/functional-validator.md +630 -0
- package/claude/agents/mock-analyst.md +387 -0
- package/claude/agents/product-manager.md +963 -0
- package/claude/agents/qa-automation.md +1762 -0
- package/claude/agents/release-manager.md +634 -0
- package/claude/agents/selectors-translator.md +262 -0
- package/claude/agents/unit-test-writer.md +785 -0
- package/claude/agents/visual-comparator.md +329 -0
- package/claude/agents/workflow-maintainer.md +352 -0
- package/claude/commands/do/README.md +88 -0
- package/claude/commands/do/create-api.md +64 -0
- package/claude/commands/do/create-entity.md +66 -0
- package/claude/commands/do/create-migration.md +64 -0
- package/claude/commands/do/create-plugin.md +56 -0
- package/claude/commands/do/create-theme.md +70 -0
- package/claude/commands/do/mock-data.md +67 -0
- package/claude/commands/do/reset-db.md +71 -0
- package/claude/commands/do/setup-scheduled-action.md +75 -0
- package/claude/commands/do/sync-code-review.md +117 -0
- package/claude/commands/do/update-selectors.md +112 -0
- package/claude/commands/do/use-skills.md +90 -0
- package/claude/commands/do/validate-blocks.md +69 -0
- package/claude/commands/how-to/README.md +261 -0
- package/claude/commands/how-to/add-metadata.md +692 -0
- package/claude/commands/how-to/add-taxonomies.md +806 -0
- package/claude/commands/how-to/add-translations.md +571 -0
- package/claude/commands/how-to/create-api.md +577 -0
- package/claude/commands/how-to/create-block.md +575 -0
- package/claude/commands/how-to/create-child-entities.md +771 -0
- package/claude/commands/how-to/create-entity.md +597 -0
- package/claude/commands/how-to/create-migrations.md +605 -0
- package/claude/commands/how-to/create-plugin.md +654 -0
- package/claude/commands/how-to/customize-app.md +481 -0
- package/claude/commands/how-to/customize-dashboard.md +553 -0
- package/claude/commands/how-to/customize-theme.md +438 -0
- package/claude/commands/how-to/define-features-flows.md +632 -0
- package/claude/commands/how-to/deploy.md +507 -0
- package/claude/commands/how-to/handle-file-uploads.md +746 -0
- package/claude/commands/how-to/implement-search.md +1001 -0
- package/claude/commands/how-to/install-plugins.md +352 -0
- package/claude/commands/how-to/manage-test-coverage.md +984 -0
- package/claude/commands/how-to/run-tests.md +400 -0
- package/claude/commands/how-to/set-app-languages.md +601 -0
- package/claude/commands/how-to/set-plans-and-permissions.md +575 -0
- package/claude/commands/how-to/set-scheduled-actions.md +527 -0
- package/claude/commands/how-to/set-user-roles-and-permissions.md +550 -0
- package/claude/commands/how-to/setup-authentication.md +388 -0
- package/claude/commands/how-to/setup-claude-code.md +440 -0
- package/claude/commands/how-to/setup-database.md +274 -0
- package/claude/commands/how-to/setup-email-providers.md +598 -0
- package/claude/commands/how-to/setup-mobile-dev.md +627 -0
- package/claude/commands/how-to/start.md +500 -0
- package/claude/commands/how-to/use-devtools.md +639 -0
- package/claude/commands/how-to/use-superadmin.md +622 -0
- package/claude/commands/session/README.md +193 -0
- package/claude/commands/session/block-create.md +190 -0
- package/claude/commands/session/block-list.md +203 -0
- package/claude/commands/session/block-update.md +192 -0
- package/claude/commands/session/block-validate.md +218 -0
- package/claude/commands/session/changelog.md +115 -0
- package/claude/commands/session/close.md +225 -0
- package/claude/commands/session/commit.md +174 -0
- package/claude/commands/session/db-entity.md +206 -0
- package/claude/commands/session/db-fix.md +212 -0
- package/claude/commands/session/db-sample.md +206 -0
- package/claude/commands/session/demo.md +178 -0
- package/claude/commands/session/doc-bdd.md +207 -0
- package/claude/commands/session/doc-feature.md +218 -0
- package/claude/commands/session/doc-read.md +225 -0
- package/claude/commands/session/execute.md +204 -0
- package/claude/commands/session/explain.md +202 -0
- package/claude/commands/session/fix-bug.md +210 -0
- package/claude/commands/session/fix-build.md +182 -0
- package/claude/commands/session/fix-test.md +189 -0
- package/claude/commands/session/pending.md +232 -0
- package/claude/commands/session/refine.md +188 -0
- package/claude/commands/session/resume.md +192 -0
- package/claude/commands/session/review.md +192 -0
- package/claude/commands/session/scope-change.md +181 -0
- package/claude/commands/session/start-blocks.md +347 -0
- package/claude/commands/session/start.md +604 -0
- package/claude/commands/session/status.md +169 -0
- package/claude/commands/session/test-fix.md +221 -0
- package/claude/commands/session/test-run.md +203 -0
- package/claude/commands/session/test-write.md +242 -0
- package/claude/commands/session/validate.md +162 -0
- package/claude/config/context.json +40 -0
- package/claude/config/github.json +69 -0
- package/claude/config/github.schema.json +106 -0
- package/claude/config/team.json +46 -0
- package/claude/config/team.schema.json +106 -0
- package/claude/config/workspace.json +43 -0
- package/claude/config/workspace.schema.json +75 -0
- package/claude/skills/README.md +228 -0
- package/claude/skills/accessibility/SKILL.md +573 -0
- package/claude/skills/api-bypass-layers/SKILL.md +550 -0
- package/claude/skills/asana-integration/SKILL.md +499 -0
- package/claude/skills/better-auth/SKILL.md +666 -0
- package/claude/skills/billing-subscriptions/SKILL.md +660 -0
- package/claude/skills/block-decision-matrix/SKILL.md +359 -0
- package/claude/skills/clickup-integration/SKILL.md +434 -0
- package/claude/skills/core-theme-responsibilities/SKILL.md +485 -0
- package/claude/skills/create-plugin/SKILL.md +425 -0
- package/claude/skills/create-theme/SKILL.md +331 -0
- package/claude/skills/cypress-api/SKILL.md +511 -0
- package/claude/skills/cypress-api/scripts/generate-api-controller.py +329 -0
- package/claude/skills/cypress-api/scripts/generate-api-test.py +930 -0
- package/claude/skills/cypress-e2e/SKILL.md +526 -0
- package/claude/skills/cypress-e2e/scripts/extract-selectors.py +383 -0
- package/claude/skills/cypress-e2e/scripts/generate-uat-test.py +788 -0
- package/claude/skills/cypress-selectors/SKILL.md +309 -0
- package/claude/skills/cypress-selectors/scripts/extract-missing.py +243 -0
- package/claude/skills/cypress-selectors/scripts/generate-block-selectors.py +283 -0
- package/claude/skills/cypress-selectors/scripts/validate-selectors.py +145 -0
- package/claude/skills/database-migrations/SKILL.md +335 -0
- package/claude/skills/database-migrations/scripts/generate-sample-data.py +284 -0
- package/claude/skills/database-migrations/scripts/validate-migration.py +323 -0
- package/claude/skills/design-system/SKILL.md +682 -0
- package/claude/skills/documentation/SKILL.md +540 -0
- package/claude/skills/entity-api/SKILL.md +482 -0
- package/claude/skills/entity-system/SKILL.md +635 -0
- package/claude/skills/entity-system/scripts/generate-child-migration.py +298 -0
- package/claude/skills/entity-system/scripts/generate-metas-migration.py +233 -0
- package/claude/skills/entity-system/scripts/generate-migration.py +382 -0
- package/claude/skills/entity-system/scripts/generate-sample-data.py +418 -0
- package/claude/skills/entity-system/scripts/scaffold-entity.py +661 -0
- package/claude/skills/github/SKILL.md +467 -0
- package/claude/skills/i18n-nextintl/SKILL.md +302 -0
- package/claude/skills/i18n-nextintl/scripts/add-translation.py +243 -0
- package/claude/skills/i18n-nextintl/scripts/extract-hardcoded.py +246 -0
- package/claude/skills/i18n-nextintl/scripts/validate-translations.py +260 -0
- package/claude/skills/impact-analysis/SKILL.md +203 -0
- package/claude/skills/jest-unit/SKILL.md +306 -0
- package/claude/skills/jest-unit/references/component-testing.md +371 -0
- package/claude/skills/jest-unit/references/mocking-patterns.md +380 -0
- package/claude/skills/jest-unit/references/service-hook-testing.md +454 -0
- package/claude/skills/jira-integration/SKILL.md +539 -0
- package/claude/skills/media-library/SKILL.md +743 -0
- package/claude/skills/mock-analysis/SKILL.md +276 -0
- package/claude/skills/monorepo-architecture/SKILL.md +162 -0
- package/claude/skills/nextjs-api-development/SKILL.md +364 -0
- package/claude/skills/nextjs-api-development/scripts/generate-crud-tests.py +456 -0
- package/claude/skills/nextjs-api-development/scripts/scaffold-endpoint.py +481 -0
- package/claude/skills/nextjs-api-development/scripts/validate-api.py +283 -0
- package/claude/skills/notion-integration/SKILL.md +641 -0
- package/claude/skills/npm-development-workflow/SKILL.md +480 -0
- package/claude/skills/page-builder-blocks/SKILL.md +530 -0
- package/claude/skills/page-builder-blocks/scripts/scaffold-block.py +444 -0
- package/claude/skills/permissions-system/SKILL.md +619 -0
- package/claude/skills/plugins/SKILL.md +340 -0
- package/claude/skills/plugins/references/plugin-templates.md +414 -0
- package/claude/skills/plugins/references/plugin-testing.md +353 -0
- package/claude/skills/plugins/references/plugin-types.md +198 -0
- package/claude/skills/plugins/scripts/scaffold-plugin.py +443 -0
- package/claude/skills/pom-patterns/SKILL.md +452 -0
- package/claude/skills/pom-patterns/scripts/generate-pom.py +392 -0
- package/claude/skills/rate-limiting/SKILL.md +342 -0
- package/claude/skills/react-best-practices/AGENTS.md +2410 -0
- package/claude/skills/react-best-practices/README.md +123 -0
- package/claude/skills/react-best-practices/SKILL.md +125 -0
- package/claude/skills/react-best-practices/metadata.json +15 -0
- package/claude/skills/react-best-practices/rules/_sections.md +46 -0
- package/claude/skills/react-best-practices/rules/_template.md +28 -0
- package/claude/skills/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/claude/skills/react-best-practices/rules/advanced-use-latest.md +49 -0
- package/claude/skills/react-best-practices/rules/async-api-routes.md +38 -0
- package/claude/skills/react-best-practices/rules/async-defer-await.md +80 -0
- package/claude/skills/react-best-practices/rules/async-dependencies.md +36 -0
- package/claude/skills/react-best-practices/rules/async-parallel.md +28 -0
- package/claude/skills/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/claude/skills/react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/claude/skills/react-best-practices/rules/bundle-conditional.md +31 -0
- package/claude/skills/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/claude/skills/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/claude/skills/react-best-practices/rules/bundle-preload.md +50 -0
- package/claude/skills/react-best-practices/rules/client-event-listeners.md +74 -0
- package/claude/skills/react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/claude/skills/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/claude/skills/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/claude/skills/react-best-practices/rules/js-batch-dom-css.md +82 -0
- package/claude/skills/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/claude/skills/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/claude/skills/react-best-practices/rules/js-cache-storage.md +70 -0
- package/claude/skills/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/claude/skills/react-best-practices/rules/js-early-exit.md +50 -0
- package/claude/skills/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/claude/skills/react-best-practices/rules/js-index-maps.md +37 -0
- package/claude/skills/react-best-practices/rules/js-length-check-first.md +49 -0
- package/claude/skills/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/claude/skills/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/claude/skills/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/claude/skills/react-best-practices/rules/rendering-activity.md +26 -0
- package/claude/skills/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/claude/skills/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/claude/skills/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/claude/skills/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/claude/skills/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/claude/skills/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/claude/skills/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/claude/skills/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/claude/skills/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/claude/skills/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/claude/skills/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/claude/skills/react-best-practices/rules/rerender-memo.md +44 -0
- package/claude/skills/react-best-practices/rules/rerender-transitions.md +40 -0
- package/claude/skills/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/claude/skills/react-best-practices/rules/server-cache-lru.md +41 -0
- package/claude/skills/react-best-practices/rules/server-cache-react.md +76 -0
- package/claude/skills/react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/claude/skills/react-best-practices/rules/server-serialization.md +38 -0
- package/claude/skills/react-patterns/SKILL.md +688 -0
- package/claude/skills/registry-system/SKILL.md +331 -0
- package/claude/skills/scheduled-actions/SKILL.md +671 -0
- package/claude/skills/scope-enforcement/SKILL.md +542 -0
- package/claude/skills/scope-enforcement/scripts/validate-scope.py +357 -0
- package/claude/skills/server-actions/SKILL.md +493 -0
- package/claude/skills/service-layer/SKILL.md +587 -0
- package/claude/skills/session-management/SKILL.md +266 -0
- package/claude/skills/session-management/scripts/create-session.py +166 -0
- package/claude/skills/session-management/scripts/iteration-close.sh +105 -0
- package/claude/skills/session-management/scripts/iteration-init.sh +180 -0
- package/claude/skills/session-management/scripts/session-archive.sh +87 -0
- package/claude/skills/session-management/scripts/session-close.sh +133 -0
- package/claude/skills/session-management/scripts/session-init.sh +225 -0
- package/claude/skills/session-management/scripts/session-list.sh +163 -0
- package/claude/skills/session-management/scripts/split-plan.sh +116 -0
- package/claude/skills/shadcn-components/SKILL.md +586 -0
- package/claude/skills/shadcn-theming/SKILL.md +446 -0
- package/claude/skills/suspense-loading/SKILL.md +280 -0
- package/claude/skills/tailwind-theming/SKILL.md +507 -0
- package/claude/skills/tanstack-query/SKILL.md +608 -0
- package/claude/skills/test-coverage/SKILL.md +239 -0
- package/claude/skills/web-design-guidelines/SKILL.md +39 -0
- package/claude/skills/zod-validation/SKILL.md +537 -0
- package/claude/templates/blocks/progress.md +86 -0
- package/claude/templates/iteration/changes.md +61 -0
- package/claude/templates/iteration/progress.md +55 -0
- package/claude/templates/log.md +31 -0
- package/claude/templates/story/context.md +77 -0
- package/claude/templates/story/pendings.md +37 -0
- package/claude/templates/story/plan.md +299 -0
- package/claude/templates/story/requirements.md +109 -0
- package/claude/templates/story/scope.json +10 -0
- package/claude/templates/story/tests.md +91 -0
- package/claude/templates/task/progress.md +58 -0
- package/claude/templates/task/requirements.md +54 -0
- package/claude/workflows/README.md +154 -0
- package/claude/workflows/blocks.md +614 -0
- package/claude/workflows/story.md +1207 -0
- package/claude/workflows/task.md +927 -0
- package/claude/workflows/tweak.md +527 -0
- package/cursor/.gitkeep +0 -0
- package/package.json +35 -0
- package/scripts/postinstall.mjs +198 -0
- package/scripts/setup.mjs +282 -0
- package/scripts/sync.mjs +209 -0
|
@@ -0,0 +1,586 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: shadcn-components
|
|
3
|
+
description: |
|
|
4
|
+
shadcn/ui component patterns for this Next.js application.
|
|
5
|
+
Covers available components, compound patterns, variants, form integration, and accessibility.
|
|
6
|
+
Use this skill when building UI with shadcn/ui components.
|
|
7
|
+
allowed-tools: Read, Glob, Grep
|
|
8
|
+
version: 1.0.0
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# shadcn/ui Components Skill
|
|
12
|
+
|
|
13
|
+
Patterns and best practices for using shadcn/ui components in this Next.js application.
|
|
14
|
+
|
|
15
|
+
## Architecture Overview
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
core/components/ui/ # Base shadcn/ui components (62 total)
|
|
19
|
+
├── button.tsx # With variants (cva)
|
|
20
|
+
├── card.tsx # Compound component
|
|
21
|
+
├── form.tsx # React Hook Form integration
|
|
22
|
+
├── input.tsx # forwardRef pattern
|
|
23
|
+
└── ...
|
|
24
|
+
|
|
25
|
+
contents/themes/{theme}/components/ # Theme-specific extensions
|
|
26
|
+
└── custom-components/
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## When to Use This Skill
|
|
30
|
+
|
|
31
|
+
- Building UI with shadcn/ui components
|
|
32
|
+
- Creating custom components that extend shadcn/ui
|
|
33
|
+
- Implementing forms with validation
|
|
34
|
+
- Understanding variant and compound patterns
|
|
35
|
+
- Ensuring accessibility compliance
|
|
36
|
+
|
|
37
|
+
## Available Components (62 total)
|
|
38
|
+
|
|
39
|
+
### Primitives
|
|
40
|
+
|
|
41
|
+
| Component | Description | Pattern |
|
|
42
|
+
|-----------|-------------|---------|
|
|
43
|
+
| `alert` | Feedback messages | Compound |
|
|
44
|
+
| `accordion` | Collapsible sections | Compound |
|
|
45
|
+
| `alert-dialog` | Confirmation dialogs | Compound |
|
|
46
|
+
| `avatar` | User avatars | Compound |
|
|
47
|
+
| `badge` | Status indicators | Variant |
|
|
48
|
+
| `breadcrumb` | Navigation path | Compound |
|
|
49
|
+
| `button` | Interactive buttons | Variant |
|
|
50
|
+
| `button-group` | Grouped buttons | - |
|
|
51
|
+
| `calendar` | Date picker | - |
|
|
52
|
+
| `card` | Content container | Compound |
|
|
53
|
+
| `checkbox` | Boolean input | forwardRef |
|
|
54
|
+
| `collapsible` | Toggle content | Compound |
|
|
55
|
+
| `command` | Command palette | Compound |
|
|
56
|
+
| `context-menu` | Right-click menu | Compound |
|
|
57
|
+
| `dialog` | Modal dialogs | Compound |
|
|
58
|
+
| `dropdown-menu` | Action menus | Compound |
|
|
59
|
+
| `input` | Text input | forwardRef |
|
|
60
|
+
| `label` | Form labels | forwardRef |
|
|
61
|
+
| `menubar` | Application menu | Compound |
|
|
62
|
+
| `pagination` | Page navigation | Compound |
|
|
63
|
+
| `popover` | Floating content | Compound |
|
|
64
|
+
| `progress` | Progress indicator | forwardRef |
|
|
65
|
+
| `radio-group` | Single selection | Compound |
|
|
66
|
+
| `scroll-area` | Custom scrollbar | Compound |
|
|
67
|
+
| `select` | Dropdown select | Compound |
|
|
68
|
+
| `separator` | Visual divider | forwardRef |
|
|
69
|
+
| `sheet` | Side panel | Compound + Variant |
|
|
70
|
+
| `slider` | Range input | forwardRef |
|
|
71
|
+
| `switch` | Toggle switch | forwardRef |
|
|
72
|
+
| `tabs` | Tab navigation | Compound |
|
|
73
|
+
| `toggle` | Toggle button | Variant |
|
|
74
|
+
| `tooltip` | Hover hints | Compound |
|
|
75
|
+
| `table` | Data tables | Compound |
|
|
76
|
+
| `textarea` | Multi-line input | forwardRef |
|
|
77
|
+
|
|
78
|
+
### Custom/Extended Components
|
|
79
|
+
|
|
80
|
+
| Component | Description |
|
|
81
|
+
|-----------|-------------|
|
|
82
|
+
| `address-input` | Address form fields |
|
|
83
|
+
| `combobox` | Searchable select |
|
|
84
|
+
| `currency-select` | Currency picker |
|
|
85
|
+
| `country-select` | Country picker |
|
|
86
|
+
| `timezone-select` | Timezone picker |
|
|
87
|
+
| `double-range` | Two-handle slider |
|
|
88
|
+
| `rating` | Star rating |
|
|
89
|
+
| `file-upload` | File upload with validation |
|
|
90
|
+
| `image-upload` | Image upload with preview |
|
|
91
|
+
| `audio-upload` | Audio file upload |
|
|
92
|
+
| `video-upload` | Video file upload |
|
|
93
|
+
| `form` | React Hook Form wrapper |
|
|
94
|
+
| `google-icon` | Google Material icons |
|
|
95
|
+
| `last-used-badge` | Recently used indicator |
|
|
96
|
+
| `multi-select` | Multiple selection |
|
|
97
|
+
| `password-input` | Password with toggle |
|
|
98
|
+
| `phone-input` | Phone number input |
|
|
99
|
+
| `relation-display` | Related entity display |
|
|
100
|
+
| `simple-relation-select` | Entity relation picker |
|
|
101
|
+
| `user-select` | User picker |
|
|
102
|
+
| `user-display` | User avatar + name |
|
|
103
|
+
| `rich-text-editor` | WYSIWYG editor |
|
|
104
|
+
| `skeleton` | Loading placeholders |
|
|
105
|
+
| `sonner` | Toast notifications |
|
|
106
|
+
| `tags-input` | Tag entry |
|
|
107
|
+
|
|
108
|
+
## Key Patterns
|
|
109
|
+
|
|
110
|
+
### 1. Compound Component Pattern
|
|
111
|
+
|
|
112
|
+
All compound components follow the Card pattern:
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
// Exports multiple related components
|
|
116
|
+
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }
|
|
117
|
+
|
|
118
|
+
// Usage
|
|
119
|
+
<Card>
|
|
120
|
+
<CardHeader>
|
|
121
|
+
<CardTitle>Title</CardTitle>
|
|
122
|
+
<CardDescription>Description text</CardDescription>
|
|
123
|
+
</CardHeader>
|
|
124
|
+
<CardContent>
|
|
125
|
+
Main content here
|
|
126
|
+
</CardContent>
|
|
127
|
+
<CardFooter>
|
|
128
|
+
<Button>Action</Button>
|
|
129
|
+
</CardFooter>
|
|
130
|
+
</Card>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**Components using this pattern:**
|
|
134
|
+
- Card, Dialog, Alert, Sheet, Popover
|
|
135
|
+
- Select, Accordion, Tabs, Command
|
|
136
|
+
- ContextMenu, DropdownMenu, Menubar
|
|
137
|
+
- Breadcrumb, Table, RadioGroup
|
|
138
|
+
|
|
139
|
+
### 2. Variant Pattern with cva()
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
import { cva, type VariantProps } from 'class-variance-authority'
|
|
143
|
+
|
|
144
|
+
const buttonVariants = cva(
|
|
145
|
+
// Base classes
|
|
146
|
+
"inline-flex items-center justify-center rounded-md text-sm font-medium",
|
|
147
|
+
{
|
|
148
|
+
variants: {
|
|
149
|
+
variant: {
|
|
150
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
151
|
+
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
152
|
+
outline: "border border-input bg-background hover:bg-accent",
|
|
153
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
154
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
155
|
+
link: "text-primary underline-offset-4 hover:underline",
|
|
156
|
+
},
|
|
157
|
+
size: {
|
|
158
|
+
default: "h-9 px-4 py-2",
|
|
159
|
+
sm: "h-8 rounded-md px-3 text-xs",
|
|
160
|
+
lg: "h-10 rounded-md px-8",
|
|
161
|
+
icon: "h-9 w-9",
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
defaultVariants: {
|
|
165
|
+
variant: "default",
|
|
166
|
+
size: "default",
|
|
167
|
+
},
|
|
168
|
+
}
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
// Component definition
|
|
172
|
+
interface ButtonProps
|
|
173
|
+
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
174
|
+
VariantProps<typeof buttonVariants> {}
|
|
175
|
+
|
|
176
|
+
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
177
|
+
({ className, variant, size, ...props }, ref) => (
|
|
178
|
+
<button
|
|
179
|
+
className={cn(buttonVariants({ variant, size, className }))}
|
|
180
|
+
ref={ref}
|
|
181
|
+
{...props}
|
|
182
|
+
/>
|
|
183
|
+
)
|
|
184
|
+
)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Components using variants:**
|
|
188
|
+
- Button (variant + size)
|
|
189
|
+
- Badge (variant)
|
|
190
|
+
- Alert (variant)
|
|
191
|
+
- Toggle (variant + size)
|
|
192
|
+
- Sheet (side)
|
|
193
|
+
|
|
194
|
+
### 3. forwardRef Pattern
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
const Input = React.forwardRef<
|
|
198
|
+
HTMLInputElement,
|
|
199
|
+
React.ComponentProps<"input">
|
|
200
|
+
>(({ className, type, ...props }, ref) => (
|
|
201
|
+
<input
|
|
202
|
+
type={type}
|
|
203
|
+
className={cn(
|
|
204
|
+
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1",
|
|
205
|
+
"text-base shadow-sm transition-colors file:border-0",
|
|
206
|
+
"placeholder:text-muted-foreground focus-visible:outline-none",
|
|
207
|
+
"focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed",
|
|
208
|
+
className
|
|
209
|
+
)}
|
|
210
|
+
ref={ref}
|
|
211
|
+
{...props}
|
|
212
|
+
/>
|
|
213
|
+
))
|
|
214
|
+
Input.displayName = "Input"
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### 4. cn() Utility
|
|
218
|
+
|
|
219
|
+
All components use `cn()` from `@/core/lib/utils` for class merging:
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
import { cn } from '@/core/lib/utils'
|
|
223
|
+
|
|
224
|
+
// Merges classes with Tailwind conflict resolution
|
|
225
|
+
className={cn(
|
|
226
|
+
"base-tailwind-classes",
|
|
227
|
+
isActive && "active-classes",
|
|
228
|
+
className // Props override
|
|
229
|
+
)}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Form Integration
|
|
233
|
+
|
|
234
|
+
### Form Components
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
export {
|
|
238
|
+
Form, // = FormProvider from react-hook-form
|
|
239
|
+
FormField, // Controller wrapper with context
|
|
240
|
+
FormItem, // Layout wrapper with useId
|
|
241
|
+
FormLabel, // Accessible label with error styling
|
|
242
|
+
FormControl, // Slot-based control that adds ARIA attributes
|
|
243
|
+
FormDescription,// Helper text
|
|
244
|
+
FormMessage, // Error message display
|
|
245
|
+
useFormField // Custom hook for field state
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Complete Form Example
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
import { useForm } from 'react-hook-form'
|
|
253
|
+
import { zodResolver } from '@hookform/resolvers/zod'
|
|
254
|
+
import { z } from 'zod'
|
|
255
|
+
import {
|
|
256
|
+
Form,
|
|
257
|
+
FormControl,
|
|
258
|
+
FormDescription,
|
|
259
|
+
FormField,
|
|
260
|
+
FormItem,
|
|
261
|
+
FormLabel,
|
|
262
|
+
FormMessage,
|
|
263
|
+
} from '@/core/components/ui/form'
|
|
264
|
+
import { Input } from '@/core/components/ui/input'
|
|
265
|
+
import { Button } from '@/core/components/ui/button'
|
|
266
|
+
|
|
267
|
+
const formSchema = z.object({
|
|
268
|
+
name: z.string().min(2, 'Name must be at least 2 characters'),
|
|
269
|
+
email: z.string().email('Invalid email address'),
|
|
270
|
+
})
|
|
271
|
+
|
|
272
|
+
type FormData = z.infer<typeof formSchema>
|
|
273
|
+
|
|
274
|
+
export function MyForm() {
|
|
275
|
+
const form = useForm<FormData>({
|
|
276
|
+
resolver: zodResolver(formSchema),
|
|
277
|
+
defaultValues: {
|
|
278
|
+
name: '',
|
|
279
|
+
email: '',
|
|
280
|
+
},
|
|
281
|
+
})
|
|
282
|
+
|
|
283
|
+
function onSubmit(data: FormData) {
|
|
284
|
+
console.log(data)
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return (
|
|
288
|
+
<Form {...form}>
|
|
289
|
+
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4">
|
|
290
|
+
<FormField
|
|
291
|
+
control={form.control}
|
|
292
|
+
name="name"
|
|
293
|
+
render={({ field }) => (
|
|
294
|
+
<FormItem>
|
|
295
|
+
<FormLabel>Name</FormLabel>
|
|
296
|
+
<FormControl>
|
|
297
|
+
<Input
|
|
298
|
+
placeholder="Enter your name"
|
|
299
|
+
data-cy="name-input"
|
|
300
|
+
{...field}
|
|
301
|
+
/>
|
|
302
|
+
</FormControl>
|
|
303
|
+
<FormDescription>
|
|
304
|
+
Your display name
|
|
305
|
+
</FormDescription>
|
|
306
|
+
<FormMessage />
|
|
307
|
+
</FormItem>
|
|
308
|
+
)}
|
|
309
|
+
/>
|
|
310
|
+
|
|
311
|
+
<FormField
|
|
312
|
+
control={form.control}
|
|
313
|
+
name="email"
|
|
314
|
+
render={({ field }) => (
|
|
315
|
+
<FormItem>
|
|
316
|
+
<FormLabel>Email</FormLabel>
|
|
317
|
+
<FormControl>
|
|
318
|
+
<Input
|
|
319
|
+
type="email"
|
|
320
|
+
placeholder="you@example.com"
|
|
321
|
+
data-cy="email-input"
|
|
322
|
+
{...field}
|
|
323
|
+
/>
|
|
324
|
+
</FormControl>
|
|
325
|
+
<FormMessage />
|
|
326
|
+
</FormItem>
|
|
327
|
+
)}
|
|
328
|
+
/>
|
|
329
|
+
|
|
330
|
+
<Button type="submit" data-cy="submit-btn">
|
|
331
|
+
Submit
|
|
332
|
+
</Button>
|
|
333
|
+
</form>
|
|
334
|
+
</Form>
|
|
335
|
+
)
|
|
336
|
+
}
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## data-cy Attributes
|
|
340
|
+
|
|
341
|
+
**IMPORTANT:** Core shadcn/ui components do NOT include `data-cy` attributes. They must be added at the usage layer.
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
// CORRECT - Add data-cy when using components
|
|
345
|
+
<Button
|
|
346
|
+
data-cy="create-task-btn"
|
|
347
|
+
onClick={handleCreate}
|
|
348
|
+
>
|
|
349
|
+
Create Task
|
|
350
|
+
</Button>
|
|
351
|
+
|
|
352
|
+
<Input
|
|
353
|
+
data-cy="task-title-input"
|
|
354
|
+
placeholder="Task title"
|
|
355
|
+
{...field}
|
|
356
|
+
/>
|
|
357
|
+
|
|
358
|
+
<Dialog>
|
|
359
|
+
<DialogTrigger data-cy="open-dialog-btn">
|
|
360
|
+
Open
|
|
361
|
+
</DialogTrigger>
|
|
362
|
+
<DialogContent data-cy="task-dialog">
|
|
363
|
+
{/* ... */}
|
|
364
|
+
</DialogContent>
|
|
365
|
+
</Dialog>
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
## Accessibility
|
|
369
|
+
|
|
370
|
+
### Built-in ARIA Support
|
|
371
|
+
|
|
372
|
+
```typescript
|
|
373
|
+
// FormControl automatically adds:
|
|
374
|
+
<FormControl>
|
|
375
|
+
{/* aria-invalid, aria-describedby */}
|
|
376
|
+
</FormControl>
|
|
377
|
+
|
|
378
|
+
// Dialog adds focus trap and escape handling
|
|
379
|
+
<Dialog>
|
|
380
|
+
{/* role="dialog", aria-modal="true" */}
|
|
381
|
+
</Dialog>
|
|
382
|
+
|
|
383
|
+
// Select adds:
|
|
384
|
+
<Select>
|
|
385
|
+
{/* role="combobox", aria-expanded */}
|
|
386
|
+
</Select>
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### Keyboard Navigation
|
|
390
|
+
|
|
391
|
+
All interactive components support:
|
|
392
|
+
- **Tab** - Navigate between elements
|
|
393
|
+
- **Enter/Space** - Activate buttons, toggles
|
|
394
|
+
- **Escape** - Close dialogs, popovers
|
|
395
|
+
- **Arrow keys** - Navigate lists, menus
|
|
396
|
+
|
|
397
|
+
### Labels and Descriptions
|
|
398
|
+
|
|
399
|
+
```typescript
|
|
400
|
+
<FormItem>
|
|
401
|
+
<FormLabel htmlFor="email">Email</FormLabel>
|
|
402
|
+
<FormControl>
|
|
403
|
+
<Input id="email" aria-describedby="email-description" />
|
|
404
|
+
</FormControl>
|
|
405
|
+
<FormDescription id="email-description">
|
|
406
|
+
We'll never share your email
|
|
407
|
+
</FormDescription>
|
|
408
|
+
</FormItem>
|
|
409
|
+
```
|
|
410
|
+
|
|
411
|
+
## Theming
|
|
412
|
+
|
|
413
|
+
### CSS Variables
|
|
414
|
+
|
|
415
|
+
All components use CSS variables instead of hardcoded colors:
|
|
416
|
+
|
|
417
|
+
```typescript
|
|
418
|
+
// CORRECT - Use semantic colors
|
|
419
|
+
className="bg-background text-foreground"
|
|
420
|
+
className="bg-primary text-primary-foreground"
|
|
421
|
+
className="bg-destructive text-destructive-foreground"
|
|
422
|
+
className="border-input"
|
|
423
|
+
className="ring-ring"
|
|
424
|
+
|
|
425
|
+
// WRONG - Hardcoded colors
|
|
426
|
+
className="bg-white text-black"
|
|
427
|
+
className="bg-blue-500 text-white"
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
### Available Color Tokens
|
|
431
|
+
|
|
432
|
+
| Token | Usage |
|
|
433
|
+
|-------|-------|
|
|
434
|
+
| `background` / `foreground` | Page background, main text |
|
|
435
|
+
| `card` / `card-foreground` | Card backgrounds |
|
|
436
|
+
| `primary` / `primary-foreground` | Primary actions |
|
|
437
|
+
| `secondary` / `secondary-foreground` | Secondary actions |
|
|
438
|
+
| `destructive` / `destructive-foreground` | Destructive actions |
|
|
439
|
+
| `accent` / `accent-foreground` | Highlights, hover states |
|
|
440
|
+
| `muted` / `muted-foreground` | Subdued elements |
|
|
441
|
+
| `success` / `success-foreground` | Success states |
|
|
442
|
+
| `input` | Input borders |
|
|
443
|
+
| `ring` | Focus rings |
|
|
444
|
+
|
|
445
|
+
## Common Patterns
|
|
446
|
+
|
|
447
|
+
### Dialog with Form
|
|
448
|
+
|
|
449
|
+
```typescript
|
|
450
|
+
<Dialog>
|
|
451
|
+
<DialogTrigger asChild>
|
|
452
|
+
<Button data-cy="open-create-dialog">Create New</Button>
|
|
453
|
+
</DialogTrigger>
|
|
454
|
+
<DialogContent data-cy="create-dialog">
|
|
455
|
+
<DialogHeader>
|
|
456
|
+
<DialogTitle>Create Item</DialogTitle>
|
|
457
|
+
<DialogDescription>
|
|
458
|
+
Fill in the details below
|
|
459
|
+
</DialogDescription>
|
|
460
|
+
</DialogHeader>
|
|
461
|
+
<Form {...form}>
|
|
462
|
+
<form onSubmit={form.handleSubmit(onSubmit)}>
|
|
463
|
+
{/* Form fields */}
|
|
464
|
+
<DialogFooter>
|
|
465
|
+
<Button type="submit" data-cy="submit-create">
|
|
466
|
+
Create
|
|
467
|
+
</Button>
|
|
468
|
+
</DialogFooter>
|
|
469
|
+
</form>
|
|
470
|
+
</Form>
|
|
471
|
+
</DialogContent>
|
|
472
|
+
</Dialog>
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
### Dropdown Menu
|
|
476
|
+
|
|
477
|
+
```typescript
|
|
478
|
+
<DropdownMenu>
|
|
479
|
+
<DropdownMenuTrigger asChild>
|
|
480
|
+
<Button variant="ghost" data-cy="actions-menu-btn">
|
|
481
|
+
Actions
|
|
482
|
+
</Button>
|
|
483
|
+
</DropdownMenuTrigger>
|
|
484
|
+
<DropdownMenuContent data-cy="actions-menu">
|
|
485
|
+
<DropdownMenuLabel>Actions</DropdownMenuLabel>
|
|
486
|
+
<DropdownMenuSeparator />
|
|
487
|
+
<DropdownMenuItem data-cy="edit-action">
|
|
488
|
+
Edit
|
|
489
|
+
</DropdownMenuItem>
|
|
490
|
+
<DropdownMenuItem
|
|
491
|
+
className="text-destructive"
|
|
492
|
+
data-cy="delete-action"
|
|
493
|
+
>
|
|
494
|
+
Delete
|
|
495
|
+
</DropdownMenuItem>
|
|
496
|
+
</DropdownMenuContent>
|
|
497
|
+
</DropdownMenu>
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
### Toast Notifications
|
|
501
|
+
|
|
502
|
+
```typescript
|
|
503
|
+
import { toast } from 'sonner'
|
|
504
|
+
|
|
505
|
+
// Success
|
|
506
|
+
toast.success('Task created successfully')
|
|
507
|
+
|
|
508
|
+
// Error
|
|
509
|
+
toast.error('Failed to create task')
|
|
510
|
+
|
|
511
|
+
// With action
|
|
512
|
+
toast('Task created', {
|
|
513
|
+
action: {
|
|
514
|
+
label: 'Undo',
|
|
515
|
+
onClick: () => handleUndo(),
|
|
516
|
+
},
|
|
517
|
+
})
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
## Anti-Patterns
|
|
521
|
+
|
|
522
|
+
```typescript
|
|
523
|
+
// NEVER: Modify core/components/ui/ directly
|
|
524
|
+
// Files in this directory are auto-generated by shadcn/ui
|
|
525
|
+
|
|
526
|
+
// CORRECT: Create extensions in theme
|
|
527
|
+
// contents/themes/{theme}/components/custom-button.tsx
|
|
528
|
+
|
|
529
|
+
// NEVER: Hardcode colors
|
|
530
|
+
className="bg-green-500 text-white border-gray-300"
|
|
531
|
+
|
|
532
|
+
// CORRECT: Use CSS variables
|
|
533
|
+
className="bg-success text-success-foreground border-input"
|
|
534
|
+
|
|
535
|
+
// NEVER: Skip forwardRef for inputs
|
|
536
|
+
function MyInput(props) {
|
|
537
|
+
return <input {...props} /> // Can't attach refs!
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// CORRECT: Use forwardRef
|
|
541
|
+
const MyInput = React.forwardRef((props, ref) => (
|
|
542
|
+
<input ref={ref} {...props} />
|
|
543
|
+
))
|
|
544
|
+
|
|
545
|
+
// NEVER: Missing accessibility attributes
|
|
546
|
+
<button onClick={toggle}>
|
|
547
|
+
{isOpen ? 'Close' : 'Open'}
|
|
548
|
+
</button>
|
|
549
|
+
|
|
550
|
+
// CORRECT: Include ARIA attributes
|
|
551
|
+
<button
|
|
552
|
+
onClick={toggle}
|
|
553
|
+
aria-expanded={isOpen}
|
|
554
|
+
aria-controls="panel-id"
|
|
555
|
+
>
|
|
556
|
+
{isOpen ? 'Close' : 'Open'}
|
|
557
|
+
</button>
|
|
558
|
+
|
|
559
|
+
// NEVER: Skip data-cy on interactive elements
|
|
560
|
+
<Button onClick={handleSubmit}>Submit</Button>
|
|
561
|
+
|
|
562
|
+
// CORRECT: Always include data-cy
|
|
563
|
+
<Button data-cy="submit-form-btn" onClick={handleSubmit}>Submit</Button>
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
## Checklist
|
|
567
|
+
|
|
568
|
+
Before finalizing UI with shadcn/ui:
|
|
569
|
+
|
|
570
|
+
- [ ] Uses CSS variable colors (not hardcoded)
|
|
571
|
+
- [ ] Includes `data-cy` on all interactive elements
|
|
572
|
+
- [ ] Uses `cn()` for class merging
|
|
573
|
+
- [ ] Implements proper form validation with Zod
|
|
574
|
+
- [ ] Includes ARIA attributes where needed
|
|
575
|
+
- [ ] Uses forwardRef for custom inputs
|
|
576
|
+
- [ ] Follows compound component patterns
|
|
577
|
+
- [ ] Extensions are in theme directory, not core
|
|
578
|
+
- [ ] Keyboard navigation works correctly
|
|
579
|
+
- [ ] Loading states use Skeleton components
|
|
580
|
+
|
|
581
|
+
## Related Skills
|
|
582
|
+
|
|
583
|
+
- `tailwind-theming` - CSS variables and theming
|
|
584
|
+
- `react-patterns` - React best practices
|
|
585
|
+
- `cypress-selectors` - data-cy naming conventions
|
|
586
|
+
- `accessibility` - WCAG compliance
|