create-inox-app 0.1.0
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/README.md +110 -0
- package/dist/cli.js +22196 -0
- package/dist/prompt-Bp8saGVV.js +852 -0
- package/dist/templates/base/.gitignore.hbs +9 -0
- package/dist/templates/base/package.json.hbs +29 -0
- package/dist/templates/base/packages/typescript-config/base.json +17 -0
- package/dist/templates/base/packages/typescript-config/nextjs.json +8 -0
- package/dist/templates/base/packages/typescript-config/package.json +10 -0
- package/dist/templates/base/packages/typescript-config/react-library.json +7 -0
- package/dist/templates/base/turbo.json.hbs +32 -0
- package/dist/templates/ci/.gitlab-ci.yml.hbs +70 -0
- package/dist/templates/ci/scripts/build.sh.hbs +94 -0
- package/dist/templates/ci/scripts/prebuild.sh.hbs +11 -0
- package/dist/templates/claude-config/app/.agents/skills/agent-browser/SKILL.md +325 -0
- package/dist/templates/claude-config/app/.agents/skills/agent-browser/references/authentication.md +202 -0
- package/dist/templates/claude-config/app/.agents/skills/agent-browser/references/commands.md +259 -0
- package/dist/templates/claude-config/app/.agents/skills/agent-browser/references/proxy-support.md +188 -0
- package/dist/templates/claude-config/app/.agents/skills/agent-browser/references/session-management.md +193 -0
- package/dist/templates/claude-config/app/.agents/skills/agent-browser/references/snapshot-refs.md +194 -0
- package/dist/templates/claude-config/app/.agents/skills/agent-browser/references/video-recording.md +173 -0
- package/dist/templates/claude-config/app/.agents/skills/agent-browser/templates/authenticated-session.sh +100 -0
- package/dist/templates/claude-config/app/.agents/skills/agent-browser/templates/capture-workflow.sh +69 -0
- package/dist/templates/claude-config/app/.agents/skills/agent-browser/templates/form-automation.sh +62 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/SKILL.md +150 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/agent.md +131 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/artifact.md +84 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/attachments.md +190 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/audio-player.md +134 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/canvas.md +32 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/chain-of-thought.md +81 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/checkpoint.md +163 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/code-block.md +170 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/commit.md +177 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/confirmation.md +252 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/connection.md +32 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/context.md +126 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/controls.md +30 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/conversation.md +210 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/edge.md +50 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/environment-variables.md +102 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/file-tree.md +72 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/image.md +143 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/inline-citation.md +293 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/jsx-preview.md +101 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/message.md +256 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/mic-selector.md +186 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/model-selector.md +112 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/node.md +71 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/open-in-chat.md +67 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/package-info.md +95 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/panel.md +31 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/persona.md +158 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/plan.md +79 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/prompt-input.md +555 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/queue.md +172 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/reasoning.md +219 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/sandbox.md +126 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/schema-display.md +102 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/shimmer.md +48 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/snippet.md +64 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/sources.md +193 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/speech-input.md +160 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/stack-trace.md +218 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/suggestion.md +121 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/task.md +215 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/terminal.md +103 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/test-results.md +157 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/tool.md +275 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/toolbar.md +30 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/transcription.md +120 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/voice-selector.md +241 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/references/web-preview.md +197 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/agent.tsx +61 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/artifact.tsx +111 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/attachments-inline.tsx +117 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/attachments-list.tsx +88 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/attachments.tsx +78 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/audio-player-remote.tsx +35 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/audio-player.tsx +69 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/chain-of-thought.tsx +74 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/checkpoint.tsx +90 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/code-block-dark.tsx +46 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/code-block.tsx +115 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/commit.tsx +94 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/confirmation-accepted.tsx +35 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/confirmation-rejected.tsx +35 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/confirmation-request.tsx +54 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/confirmation.tsx +53 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/context.tsx +45 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/conversation.tsx +176 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/environment-variables.tsx +55 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/file-tree-basic.tsx +14 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/file-tree-expanded.tsx +17 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/file-tree-selection.tsx +20 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/file-tree.tsx +38 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/image.tsx +20 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/inline-citation.tsx +95 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/jsx-preview.tsx +99 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/message.tsx +324 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/mic-selector.tsx +46 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/model-selector.tsx +362 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/open-in-chat.tsx +33 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/package-info.tsx +46 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/persona-command.tsx +96 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/persona-glint.tsx +96 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/persona-halo.tsx +96 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/persona-mana.tsx +96 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/persona-obsidian.tsx +96 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/persona-opal.tsx +96 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/plan.tsx +63 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/prompt-input-cursor.tsx +459 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/prompt-input-tooltip.tsx +40 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/prompt-input.tsx +247 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/queue-prompt-input.tsx +367 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/queue.tsx +276 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/reasoning.tsx +67 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/sandbox.tsx +166 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/schema-display-basic.tsx +7 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/schema-display-body.tsx +20 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/schema-display-nested.tsx +23 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/schema-display-params.tsx +16 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/schema-display.tsx +110 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/shimmer-duration.tsx +29 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/shimmer-elements.tsx +39 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/shimmer.tsx +17 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/snippet-plain.tsx +19 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/snippet.tsx +25 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/sources-custom.tsx +34 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/sources.tsx +27 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/speech-input.tsx +79 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/stack-trace-collapsed.tsx +39 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/stack-trace-no-internal.tsx +41 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/stack-trace.tsx +54 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/suggestion-input.tsx +137 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/suggestion.tsx +28 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/task.tsx +60 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/terminal-basic.tsx +7 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/terminal-clear.tsx +19 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/terminal-streaming.tsx +38 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/terminal.tsx +77 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/test-results-basic.tsx +27 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/test-results-errors.tsx +51 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/test-results-suites.tsx +40 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/test-results.tsx +78 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/tool-input-available.tsx +31 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/tool-input-streaming.tsx +30 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/tool-output-available.tsx +76 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/tool-output-error.tsx +45 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/tool.tsx +205 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/transcription.tsx +284 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/voice-selector.tsx +228 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-elements/scripts/web-preview.tsx +99 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-sdk/SKILL.md +78 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-sdk/references/ai-gateway.md +66 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-sdk/references/common-errors.md +439 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-sdk/references/devtools.md +52 -0
- package/dist/templates/claude-config/app/.agents/skills/ai-sdk/references/type-safe-agents.md +200 -0
- package/dist/templates/claude-config/app/.agents/skills/better-auth-best-practices/SKILL.md +166 -0
- package/dist/templates/claude-config/app/.agents/skills/building-components/SKILL.md +37 -0
- package/dist/templates/claude-config/app/.agents/skills/building-components/references/accessibility.mdx +819 -0
- package/dist/templates/claude-config/app/.agents/skills/building-components/references/as-child.mdx +324 -0
- package/dist/templates/claude-config/app/.agents/skills/building-components/references/composition.mdx +239 -0
- package/dist/templates/claude-config/app/.agents/skills/building-components/references/data-attributes.mdx +413 -0
- package/dist/templates/claude-config/app/.agents/skills/building-components/references/definitions.mdx +258 -0
- package/dist/templates/claude-config/app/.agents/skills/building-components/references/design-tokens.mdx +57 -0
- package/dist/templates/claude-config/app/.agents/skills/building-components/references/docs.mdx +155 -0
- package/dist/templates/claude-config/app/.agents/skills/building-components/references/marketplaces.mdx +144 -0
- package/dist/templates/claude-config/app/.agents/skills/building-components/references/npm.mdx +166 -0
- package/dist/templates/claude-config/app/.agents/skills/building-components/references/polymorphism.mdx +583 -0
- package/dist/templates/claude-config/app/.agents/skills/building-components/references/principles.mdx +61 -0
- package/dist/templates/claude-config/app/.agents/skills/building-components/references/registry.mdx +169 -0
- package/dist/templates/claude-config/app/.agents/skills/building-components/references/state.mdx +99 -0
- package/dist/templates/claude-config/app/.agents/skills/building-components/references/styling.mdx +286 -0
- package/dist/templates/claude-config/app/.agents/skills/building-components/references/types.mdx +191 -0
- package/dist/templates/claude-config/app/.agents/skills/docker-expert/SKILL.md +409 -0
- package/dist/templates/claude-config/app/.agents/skills/email-and-password-best-practices/SKILL.md +224 -0
- package/dist/templates/claude-config/app/.agents/skills/find-skills/SKILL.md +133 -0
- package/dist/templates/claude-config/app/.agents/skills/frontend-design/LICENSE.txt +177 -0
- package/dist/templates/claude-config/app/.agents/skills/frontend-design/SKILL.md +42 -0
- package/dist/templates/claude-config/app/.agents/skills/git-commit/SKILL.md +124 -0
- package/dist/templates/claude-config/app/.agents/skills/gitlab-ci-patterns/SKILL.md +271 -0
- package/dist/templates/claude-config/app/.agents/skills/hono/SKILL.md +90 -0
- package/dist/templates/claude-config/app/.agents/skills/langfuse-observability/SKILL.md +139 -0
- package/dist/templates/claude-config/app/.agents/skills/logging-best-practices/SKILL.md +127 -0
- package/dist/templates/claude-config/app/.agents/skills/logging-best-practices/rules/context.md +157 -0
- package/dist/templates/claude-config/app/.agents/skills/logging-best-practices/rules/pitfalls.md +118 -0
- package/dist/templates/claude-config/app/.agents/skills/logging-best-practices/rules/structure.md +193 -0
- package/dist/templates/claude-config/app/.agents/skills/logging-best-practices/rules/wide-events.md +113 -0
- package/dist/templates/claude-config/app/.agents/skills/next-best-practices/SKILL.md +153 -0
- package/dist/templates/claude-config/app/.agents/skills/next-best-practices/async-patterns.md +87 -0
- package/dist/templates/claude-config/app/.agents/skills/next-best-practices/bundling.md +180 -0
- package/dist/templates/claude-config/app/.agents/skills/next-best-practices/data-patterns.md +297 -0
- package/dist/templates/claude-config/app/.agents/skills/next-best-practices/debug-tricks.md +105 -0
- package/dist/templates/claude-config/app/.agents/skills/next-best-practices/directives.md +73 -0
- package/dist/templates/claude-config/app/.agents/skills/next-best-practices/error-handling.md +227 -0
- package/dist/templates/claude-config/app/.agents/skills/next-best-practices/file-conventions.md +140 -0
- package/dist/templates/claude-config/app/.agents/skills/next-best-practices/font.md +245 -0
- package/dist/templates/claude-config/app/.agents/skills/next-best-practices/functions.md +108 -0
- package/dist/templates/claude-config/app/.agents/skills/next-best-practices/hydration-error.md +91 -0
- package/dist/templates/claude-config/app/.agents/skills/next-best-practices/image.md +173 -0
- package/dist/templates/claude-config/app/.agents/skills/next-best-practices/metadata.md +301 -0
- package/dist/templates/claude-config/app/.agents/skills/next-best-practices/parallel-routes.md +287 -0
- package/dist/templates/claude-config/app/.agents/skills/next-best-practices/route-handlers.md +146 -0
- package/dist/templates/claude-config/app/.agents/skills/next-best-practices/rsc-boundaries.md +159 -0
- package/dist/templates/claude-config/app/.agents/skills/next-best-practices/runtime-selection.md +39 -0
- package/dist/templates/claude-config/app/.agents/skills/next-best-practices/scripts.md +141 -0
- package/dist/templates/claude-config/app/.agents/skills/next-best-practices/self-hosting.md +371 -0
- package/dist/templates/claude-config/app/.agents/skills/next-best-practices/suspense-boundaries.md +67 -0
- package/dist/templates/claude-config/app/.agents/skills/next-cache-components/SKILL.md +411 -0
- package/dist/templates/claude-config/app/.agents/skills/next-upgrade/SKILL.md +50 -0
- package/dist/templates/claude-config/app/.agents/skills/postgres-drizzle/SKILL.md +179 -0
- package/dist/templates/claude-config/app/.agents/skills/postgres-drizzle/references/CHEATSHEET.md +418 -0
- package/dist/templates/claude-config/app/.agents/skills/postgres-drizzle/references/MIGRATIONS.md +536 -0
- package/dist/templates/claude-config/app/.agents/skills/postgres-drizzle/references/PERFORMANCE.md +559 -0
- package/dist/templates/claude-config/app/.agents/skills/postgres-drizzle/references/POSTGRES.md +588 -0
- package/dist/templates/claude-config/app/.agents/skills/postgres-drizzle/references/QUERIES.md +764 -0
- package/dist/templates/claude-config/app/.agents/skills/postgres-drizzle/references/RELATIONS.md +624 -0
- package/dist/templates/claude-config/app/.agents/skills/postgres-drizzle/references/SCHEMA.md +554 -0
- package/dist/templates/claude-config/app/.agents/skills/skill-creator/LICENSE.txt +202 -0
- package/dist/templates/claude-config/app/.agents/skills/skill-creator/SKILL.md +356 -0
- package/dist/templates/claude-config/app/.agents/skills/skill-creator/references/output-patterns.md +82 -0
- package/dist/templates/claude-config/app/.agents/skills/skill-creator/references/workflows.md +28 -0
- package/dist/templates/claude-config/app/.agents/skills/skill-creator/scripts/init_skill.py +303 -0
- package/dist/templates/claude-config/app/.agents/skills/skill-creator/scripts/package_skill.py +113 -0
- package/dist/templates/claude-config/app/.agents/skills/skill-creator/scripts/quick_validate.py +95 -0
- package/dist/templates/claude-config/app/.agents/skills/streamdown/SKILL.md +164 -0
- package/dist/templates/claude-config/app/.agents/skills/streamdown/assets/examples/basic-streaming.tsx +34 -0
- package/dist/templates/claude-config/app/.agents/skills/streamdown/assets/examples/custom-security.tsx +38 -0
- package/dist/templates/claude-config/app/.agents/skills/streamdown/assets/examples/full-featured.tsx +60 -0
- package/dist/templates/claude-config/app/.agents/skills/streamdown/assets/examples/static-mode.tsx +17 -0
- package/dist/templates/claude-config/app/.agents/skills/streamdown/assets/examples/with-caret.tsx +39 -0
- package/dist/templates/claude-config/app/.agents/skills/streamdown/references/api.md +278 -0
- package/dist/templates/claude-config/app/.agents/skills/streamdown/references/features.md +201 -0
- package/dist/templates/claude-config/app/.agents/skills/streamdown/references/plugins.md +239 -0
- package/dist/templates/claude-config/app/.agents/skills/streamdown/references/security.md +192 -0
- package/dist/templates/claude-config/app/.agents/skills/streamdown/references/styling.md +166 -0
- package/dist/templates/claude-config/app/.agents/skills/tdd/SKILL.md +107 -0
- package/dist/templates/claude-config/app/.agents/skills/tdd/deep-modules.md +33 -0
- package/dist/templates/claude-config/app/.agents/skills/tdd/interface-design.md +31 -0
- package/dist/templates/claude-config/app/.agents/skills/tdd/mocking.md +60 -0
- package/dist/templates/claude-config/app/.agents/skills/tdd/refactoring.md +10 -0
- package/dist/templates/claude-config/app/.agents/skills/tdd/tests.md +61 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/SKILL.md +914 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/command/turborepo.md +70 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/best-practices/RULE.md +241 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/best-practices/dependencies.md +246 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/best-practices/packages.md +335 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/best-practices/structure.md +270 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/boundaries/RULE.md +126 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/caching/RULE.md +107 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/caching/gotchas.md +169 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/caching/remote-cache.md +127 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/ci/RULE.md +79 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/ci/github-actions.md +162 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/ci/patterns.md +145 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/ci/vercel.md +103 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/cli/RULE.md +100 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/cli/commands.md +297 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/configuration/RULE.md +211 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/configuration/global-options.md +191 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/configuration/gotchas.md +348 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/configuration/tasks.md +281 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/environment/RULE.md +96 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/environment/gotchas.md +141 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/environment/modes.md +101 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/filtering/RULE.md +148 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/filtering/patterns.md +152 -0
- package/dist/templates/claude-config/app/.agents/skills/turborepo/references/watch/RULE.md +99 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-composition-patterns/AGENTS.md +917 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-composition-patterns/SKILL.md +88 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-composition-patterns/rules/architecture-avoid-boolean-props.md +94 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-composition-patterns/rules/architecture-compound-components.md +108 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-composition-patterns/rules/patterns-children-over-render-props.md +84 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-composition-patterns/rules/patterns-explicit-variants.md +94 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-composition-patterns/rules/react19-no-forwardref.md +42 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-composition-patterns/rules/state-context-interface.md +191 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-composition-patterns/rules/state-decouple-implementation.md +103 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-composition-patterns/rules/state-lift-state.md +125 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/AGENTS.md +2883 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/SKILL.md +138 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/advanced-init-once.md +42 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/advanced-use-latest.md +39 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/async-api-routes.md +35 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/async-defer-await.md +80 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/async-dependencies.md +48 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/async-parallel.md +24 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/bundle-conditional.md +37 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +48 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +34 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/bundle-preload.md +44 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/client-event-listeners.md +78 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +74 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/client-swr-dedup.md +56 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +110 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/js-cache-function-results.md +80 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/js-cache-property-access.md +28 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/js-cache-storage.md +68 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/js-combine-iterations.md +32 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/js-early-exit.md +50 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/js-index-maps.md +37 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/js-length-check-first.md +50 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/js-min-max-loop.md +82 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/rendering-activity.md +26 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +38 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +32 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +36 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +72 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +26 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +75 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/rerender-dependencies.md +45 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state.md +29 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +77 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +56 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +36 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/rerender-memo.md +44 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/rerender-transitions.md +40 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/server-auth-actions.md +96 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/server-cache-lru.md +41 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/server-cache-react.md +76 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/server-dedup-props.md +65 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/dist/templates/claude-config/app/.agents/skills/vercel-react-best-practices/rules/server-serialization.md +38 -0
- package/dist/templates/claude-config/app/.agents/skills/web-design-guidelines/SKILL.md +40 -0
- package/dist/templates/claude-config/app/.agents/skills/workflow/SKILL.md +181 -0
- package/dist/templates/claude-config/app/.claude/commands/council.md +7 -0
- package/dist/templates/claude-config/app/.claude/commands/deslop.md +25 -0
- package/dist/templates/claude-config/app/.claude/commands/diagram.md +101 -0
- package/dist/templates/claude-config/app/.claude/commands/fix-merge.md +47 -0
- package/dist/templates/claude-config/app/.claude/commands/you-might-not-need-an-effect.md +10 -0
- package/dist/templates/claude-config/app/.claude/hooks/post-tool-use-tracker.sh +187 -0
- package/dist/templates/claude-config/app/.claude/hooks/skill-activation-prompt.sh +5 -0
- package/dist/templates/claude-config/app/.claude/hooks/skill-activation-prompt.ts +134 -0
- package/dist/templates/claude-config/app/.claude/rules/comments.md +12 -0
- package/dist/templates/claude-config/app/.claude/rules/typescript.md +31 -0
- package/dist/templates/claude-config/app/.claude/settings.json.hbs +74 -0
- package/dist/templates/claude-config/app/.claude/skills/skill-rules.json.hbs +309 -0
- package/dist/templates/claude-config/app/AGENTS.md.hbs +185 -0
- package/dist/templates/claude-config/app/CLAUDE.md.hbs +5 -0
- package/dist/templates/claude-config/kustomize/.agents/skills/git-commit/SKILL.md +124 -0
- package/dist/templates/claude-config/kustomize/.agents/skills/k8s-manifest-generator/SKILL.md +534 -0
- package/dist/templates/claude-config/kustomize/.agents/skills/k8s-manifest-generator/assets/configmap-template.yaml +296 -0
- package/dist/templates/claude-config/kustomize/.agents/skills/k8s-manifest-generator/assets/deployment-template.yaml +203 -0
- package/dist/templates/claude-config/kustomize/.agents/skills/k8s-manifest-generator/assets/service-template.yaml +171 -0
- package/dist/templates/claude-config/kustomize/.agents/skills/k8s-manifest-generator/references/deployment-spec.md +780 -0
- package/dist/templates/claude-config/kustomize/.agents/skills/k8s-manifest-generator/references/service-spec.md +748 -0
- package/dist/templates/claude-config/kustomize/.claude/settings.json +42 -0
- package/dist/templates/claude-config/kustomize/.claude/skills/git-commit/SKILL.md +124 -0
- package/dist/templates/claude-config/kustomize/.claude/skills/k8s-manifest-generator/SKILL.md +534 -0
- package/dist/templates/claude-config/kustomize/.claude/skills/k8s-manifest-generator/assets/configmap-template.yaml +296 -0
- package/dist/templates/claude-config/kustomize/.claude/skills/k8s-manifest-generator/assets/deployment-template.yaml +203 -0
- package/dist/templates/claude-config/kustomize/.claude/skills/k8s-manifest-generator/assets/service-template.yaml +171 -0
- package/dist/templates/claude-config/kustomize/.claude/skills/k8s-manifest-generator/references/deployment-spec.md +780 -0
- package/dist/templates/claude-config/kustomize/.claude/skills/k8s-manifest-generator/references/service-spec.md +748 -0
- package/dist/templates/docker/.dockerignore.hbs +8 -0
- package/dist/templates/docker/Dockerfile.hbs +81 -0
- package/dist/templates/docker/docker-compose.yml.hbs +55 -0
- package/dist/templates/kustomize/base/deployments/app.yaml.hbs +44 -0
- package/dist/templates/kustomize/base/ingress/app.yaml.hbs +20 -0
- package/dist/templates/kustomize/base/jobs/app-jobs.yaml.hbs +43 -0
- package/dist/templates/kustomize/base/kustomization.yaml.hbs +13 -0
- package/dist/templates/kustomize/base/secrets/regcred.yaml.hbs +7 -0
- package/dist/templates/kustomize/base/services/app.yaml.hbs +12 -0
- package/dist/templates/kustomize/overlays/{{env}}/configs/app.config.env.hbs +21 -0
- package/dist/templates/kustomize/overlays/{{env}}/configs/paradedb.config.env.hbs +3 -0
- package/dist/templates/kustomize/overlays/{{env}}/deployments/paradedb.yaml.hbs +28 -0
- package/dist/templates/kustomize/overlays/{{env}}/deployments/redis.yaml.hbs +18 -0
- package/dist/templates/kustomize/overlays/{{env}}/kustomization.yaml.hbs +36 -0
- package/dist/templates/kustomize/overlays/{{env}}/patch-operation/ingress-host.yaml.hbs +15 -0
- package/dist/templates/kustomize/overlays/{{env}}/services/paradedb.yaml.hbs +11 -0
- package/dist/templates/kustomize/overlays/{{env}}/services/redis.yaml.hbs +11 -0
- package/dist/templates/kustomize/overlays/{{env}}/storage/paradedb-pvc.yaml.hbs +10 -0
- package/dist/templates/presets/ai-chat-app/apps/web/.env.example +11 -0
- package/dist/templates/presets/ai-chat-app/apps/web/app/api/auth/[...all]/route.ts +5 -0
- package/dist/templates/presets/ai-chat-app/apps/web/app/api/chat/input-guardrail.ts +47 -0
- package/dist/templates/presets/ai-chat-app/apps/web/app/api/chat/route.ts +266 -0
- package/dist/templates/presets/ai-chat-app/apps/web/app/api/chat/sessions/[id]/messages/route.ts +38 -0
- package/dist/templates/presets/ai-chat-app/apps/web/app/api/chat/sessions/[id]/route.ts +59 -0
- package/dist/templates/presets/ai-chat-app/apps/web/app/api/chat/sessions/route.ts +24 -0
- package/dist/templates/presets/ai-chat-app/apps/web/app/api/health/route.ts +21 -0
- package/dist/templates/presets/ai-chat-app/apps/web/app/chat/[id]/page.tsx +54 -0
- package/dist/templates/presets/ai-chat-app/apps/web/app/chat/layout.tsx +23 -0
- package/dist/templates/presets/ai-chat-app/apps/web/app/chat/page.tsx +9 -0
- package/dist/templates/presets/ai-chat-app/apps/web/app/error.tsx +20 -0
- package/dist/templates/presets/ai-chat-app/apps/web/app/global-error.tsx +42 -0
- package/dist/templates/presets/ai-chat-app/apps/web/app/globals.css +187 -0
- package/dist/templates/presets/ai-chat-app/apps/web/app/layout.tsx.hbs +30 -0
- package/dist/templates/presets/ai-chat-app/apps/web/app/login/login-form.tsx +96 -0
- package/dist/templates/presets/ai-chat-app/apps/web/app/login/page.tsx +14 -0
- package/dist/templates/presets/ai-chat-app/apps/web/app/not-found.tsx +15 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ai-elements/code-block.tsx +518 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ai-elements/context.tsx +356 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ai-elements/conversation.tsx +150 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ai-elements/environment-variables.tsx +303 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ai-elements/message.tsx +295 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ai-elements/prompt-input.tsx +1179 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ai-elements/sources.tsx +54 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ai-elements/tool.tsx +157 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/app-sidebar.tsx +110 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/chat-sessions-provider.tsx +89 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/chat-sidebar-list.tsx +174 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/chat-view.tsx +156 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/accordion.tsx +72 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/alert-dialog.tsx +162 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/alert.tsx +73 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/aspect-ratio.tsx +22 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/avatar.tsx +93 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/badge.tsx +49 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/breadcrumb.tsx +103 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/button-group.tsx +78 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/button.tsx +60 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/calendar.tsx +185 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/card.tsx +92 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/carousel.tsx +231 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/chart.tsx +325 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/checkbox.tsx +28 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/collapsible.tsx +17 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/combobox.tsx +273 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/command.tsx +181 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/context-menu.tsx +245 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/dialog.tsx +135 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/direction.tsx +3 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/drawer.tsx +120 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/dropdown-menu.tsx +258 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/empty.tsx +94 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/field.tsx +224 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/hover-card.tsx +46 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/input-group.tsx +146 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/input-otp.tsx +86 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/input.tsx +20 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/item.tsx +188 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/kbd.tsx +26 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/label.tsx +20 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/menubar.tsx +270 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/native-select.tsx +43 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/navigation-menu.tsx +161 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/pagination.tsx +118 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/popover.tsx +77 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/progress.tsx +66 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/radio-group.tsx +39 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/resizable.tsx +42 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/scroll-area.tsx +51 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/select.tsx +190 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/separator.tsx +21 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/sheet.tsx +125 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/sidebar.tsx +689 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/skeleton.tsx +13 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/slider.tsx +54 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/sonner.tsx +45 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/spinner.tsx +15 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/switch.tsx +32 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/table.tsx +89 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/tabs.tsx +75 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/textarea.tsx +18 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/toggle-group.tsx +87 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/toggle.tsx +44 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components/ui/tooltip.tsx +54 -0
- package/dist/templates/presets/ai-chat-app/apps/web/components.json +20 -0
- package/dist/templates/presets/ai-chat-app/apps/web/drizzle.config.ts +10 -0
- package/dist/templates/presets/ai-chat-app/apps/web/env.ts +30 -0
- package/dist/templates/presets/ai-chat-app/apps/web/hooks/use-mobile.ts +19 -0
- package/dist/templates/presets/ai-chat-app/apps/web/instrumentation.ts +21 -0
- package/dist/templates/presets/ai-chat-app/apps/web/lib/auth-client.ts +3 -0
- package/dist/templates/presets/ai-chat-app/apps/web/lib/auth-session.ts +9 -0
- package/dist/templates/presets/ai-chat-app/apps/web/lib/auth.ts +16 -0
- package/dist/templates/presets/ai-chat-app/apps/web/lib/db/index.ts +11 -0
- package/dist/templates/presets/ai-chat-app/apps/web/lib/db/migrate.ts +53 -0
- package/dist/templates/presets/ai-chat-app/apps/web/lib/db/schema.ts +94 -0
- package/dist/templates/presets/ai-chat-app/apps/web/lib/db/seed.ts +123 -0
- package/dist/templates/presets/ai-chat-app/apps/web/lib/group-by-date.ts +34 -0
- package/dist/templates/presets/ai-chat-app/apps/web/lib/logger.ts +21 -0
- package/dist/templates/presets/ai-chat-app/apps/web/lib/openrouter.ts +7 -0
- package/dist/templates/presets/ai-chat-app/apps/web/lib/schemas/auth.ts +8 -0
- package/dist/templates/presets/ai-chat-app/apps/web/lib/utils.ts +4 -0
- package/dist/templates/presets/ai-chat-app/apps/web/next-env.d.ts +6 -0
- package/dist/templates/presets/ai-chat-app/apps/web/next.config.ts +14 -0
- package/dist/templates/presets/ai-chat-app/apps/web/package.json +70 -0
- package/dist/templates/presets/ai-chat-app/apps/web/postcss.config.mjs +7 -0
- package/dist/templates/presets/ai-chat-app/apps/web/proxy.ts +13 -0
- package/dist/templates/presets/ai-chat-app/apps/web/tsconfig.json +14 -0
- package/dist/templates/presets/blank/apps/web/.env.example +1 -0
- package/dist/templates/presets/blank/apps/web/app/api/health/route.ts +11 -0
- package/dist/templates/presets/blank/apps/web/app/globals.css +49 -0
- package/dist/templates/presets/blank/apps/web/app/layout.tsx.hbs +30 -0
- package/dist/templates/presets/blank/apps/web/app/page.tsx.hbs +10 -0
- package/dist/templates/presets/blank/apps/web/env.ts +10 -0
- package/dist/templates/presets/blank/apps/web/next-env.d.ts +2 -0
- package/dist/templates/presets/blank/apps/web/next.config.ts +9 -0
- package/dist/templates/presets/blank/apps/web/package.json.hbs +27 -0
- package/dist/templates/presets/blank/apps/web/postcss.config.mjs +7 -0
- package/dist/templates/presets/blank/apps/web/tsconfig.json +14 -0
- package/dist/templates/tooling/.oxfmtrc.json +6 -0
- package/dist/templates/tooling/.oxlintrc.json +20 -0
- package/dist/templates/tooling/commitlint.config.ts.hbs +3 -0
- package/dist/templates/tooling/lefthook.yml.hbs +25 -0
- package/package.json +47 -0
package/dist/templates/claude-config/app/.agents/skills/building-components/references/registry.mdx
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Registry
|
|
3
|
+
description: Understand the concept of component registries, how they work, and why they're revolutionizing how developers share and discover UI components.
|
|
4
|
+
type: conceptual
|
|
5
|
+
summary: What component registries are, their source-code distribution model, and how to create one using the shadcn ecosystem.
|
|
6
|
+
related:
|
|
7
|
+
- /npm
|
|
8
|
+
- /marketplaces
|
|
9
|
+
- /docs
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Component registries are a way to share and discover UI components. Popularized by [shadcn/ui](https://ui.shadcn.com), they allow you to discover and copy components directly into your projects.
|
|
13
|
+
|
|
14
|
+
Registries represent a fundamental shift in how developers share and discover UI components. Unlike traditional npm packages, registries rely on an open source model and work through downloading the source code to your project.
|
|
15
|
+
|
|
16
|
+
## What Makes a Registry?
|
|
17
|
+
|
|
18
|
+
### 1. Source Code Distribution
|
|
19
|
+
|
|
20
|
+
Unlike npm packages that distribute compiled code, registries distribute source code:
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
// Traditional npm package
|
|
24
|
+
import { Button } from "some-ui-library";
|
|
25
|
+
|
|
26
|
+
// Registry-based component
|
|
27
|
+
// Copy source from registry into your project
|
|
28
|
+
// src/components/ui/button.tsx contains the full source
|
|
29
|
+
import { Button } from "@/components/ui/button";
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 2. Metadata and Configuration
|
|
33
|
+
|
|
34
|
+
Good registries include rich metadata about components like the name, description, dependencies, and category.
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"name": "announcement",
|
|
39
|
+
"type": "registry:component",
|
|
40
|
+
"description": "A compound badge component designed to display announcements with theming support",
|
|
41
|
+
"dependencies": ["class-variance-authority", "lucide-react"],
|
|
42
|
+
"registryDependencies": ["badge"],
|
|
43
|
+
"files": [
|
|
44
|
+
{
|
|
45
|
+
"type": "registry:component",
|
|
46
|
+
"content": "..."
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"category": "ui"
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### 3. Preview and Documentation
|
|
54
|
+
|
|
55
|
+
While not downloaded, registry websites typically provide:
|
|
56
|
+
|
|
57
|
+
- Live component previews
|
|
58
|
+
- Interactive examples
|
|
59
|
+
- Detailed documentation
|
|
60
|
+
- Code snippets ready to copy
|
|
61
|
+
|
|
62
|
+
## Registry Architecture Benefits
|
|
63
|
+
|
|
64
|
+
Component registries offer significant advantages for both authors and users, streamlining the process of sharing and adopting UI components.
|
|
65
|
+
|
|
66
|
+
### For Authors
|
|
67
|
+
|
|
68
|
+
For component authors, registries make distribution remarkably simple. Once a component is created, it can be added to the registry, making it instantly accessible to users without the need for complex publishing steps. This ease of distribution accelerates the feedback loop and encourages rapid iteration.
|
|
69
|
+
|
|
70
|
+
Version control is another key benefit. Registries typically track component versions, changelogs, and compatibility information. For example, a component entry might specify its current version, highlight recent changes such as improved accessibility or new features, and indicate which versions of shadcn/ui it supports. This transparency helps maintainers communicate updates and ensures users can select components that fit their project requirements.
|
|
71
|
+
|
|
72
|
+
Community engagement is also enhanced through registries. Authors can receive direct feedback from users, who are able to report issues, request features, and contribute to collaborative improvements. This fosters a more interactive and responsive development environment, benefiting both creators and consumers.
|
|
73
|
+
|
|
74
|
+
### For Consumers
|
|
75
|
+
|
|
76
|
+
From the perspective of component users, registries greatly improve the discovery process. Users can browse components by category, utilize search functionality, view popularity metrics, and explore related components, making it easier to find exactly what they need for their projects.
|
|
77
|
+
|
|
78
|
+
Before integrating a component, users can preview it in action, experiment with different variants, and review its behavior and code quality. This ability to evaluate components beforehand reduces risk and increases confidence in adoption.
|
|
79
|
+
|
|
80
|
+
Perhaps most importantly, registries empower users with true ownership. Instead of being locked into a dependency, users copy the source code directly into their projects. This means they can modify components as needed, avoid dependency management headaches, and retain full control over their codebase.
|
|
81
|
+
|
|
82
|
+
## Creating a Registry
|
|
83
|
+
|
|
84
|
+
You can create a simple registry quite quickly. Practically speaking, you only need 3 core elements:
|
|
85
|
+
|
|
86
|
+
### 1. Components
|
|
87
|
+
|
|
88
|
+
Create a component, or set of components, that you want to share. Make sure you have the source code for the components, and that they are well-documented and easy to understand.
|
|
89
|
+
|
|
90
|
+
Consider adding things like Markdown documentation, example implementations, and a way to preview the component.
|
|
91
|
+
|
|
92
|
+
### 2. A public endpoint
|
|
93
|
+
|
|
94
|
+
Create a public endpoint that serves the components. This can be a simple JSON file, or a more complex website. As long as it is public and accessible, you can use any endpoint you want.
|
|
95
|
+
|
|
96
|
+
### 3. CLI
|
|
97
|
+
|
|
98
|
+
Create a CLI that allows you to install the components into your project. This can be as simple as a single command, like `npx myregistry add button`, or a more complex command with options and flags.
|
|
99
|
+
|
|
100
|
+
## Using the shadcn Registry
|
|
101
|
+
|
|
102
|
+
Building your own registry is a fantastic way to share your components with the community, but it requires a lot of effort and maintenance. If you just want to share a component or two, you can use the shadcn/ui ecosystem - registry, CLI and variables.
|
|
103
|
+
|
|
104
|
+
Let's see how we can publish a `MetricCard` component live in less than 5 minutes using [Vercel](https://vercel.com)'s static hosting.
|
|
105
|
+
|
|
106
|
+
### Step 1: Create a Folder
|
|
107
|
+
|
|
108
|
+
Make a folder with this structure:
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
my-component/
|
|
112
|
+
├── public/
|
|
113
|
+
│ └── metric-card.json
|
|
114
|
+
└── vercel.json
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Put your registry item JSON (e.g. `metric-card.json`) in the `public/` folder.
|
|
118
|
+
|
|
119
|
+
### Step 2: Add a `vercel.json`
|
|
120
|
+
|
|
121
|
+
Create a `vercel.json` file next to `public/` with the following:
|
|
122
|
+
|
|
123
|
+
```json title="vercel.json"
|
|
124
|
+
{
|
|
125
|
+
"headers": [
|
|
126
|
+
{
|
|
127
|
+
"source": "/(.*).json",
|
|
128
|
+
"headers": [
|
|
129
|
+
{
|
|
130
|
+
"key": "Access-Control-Allow-Origin",
|
|
131
|
+
"value": "*"
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"key": "Content-Type",
|
|
135
|
+
"value": "application/json"
|
|
136
|
+
}
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
]
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
This ensures your JSON is served with the correct CORS and content headers.
|
|
144
|
+
|
|
145
|
+
### Step 3: Deploy to Vercel
|
|
146
|
+
|
|
147
|
+
From the root of your folder, run:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
vercel --prod
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
and answer the prompts to deploy your project.
|
|
154
|
+
|
|
155
|
+
When it's done, your file will be live at something like:
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
https://your-project-name.vercel.app/metric-card.json
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Step 4: Install the Component
|
|
162
|
+
|
|
163
|
+
Anyone can now run:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
npx shadcn@latest add https://your-project-name.vercel.app/metric-card.json
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
No npm package, no build step, no complexity.
|
package/dist/templates/claude-config/app/.agents/skills/building-components/references/state.mdx
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: State
|
|
3
|
+
description: How to manage state in a component, as well as merging controllable and uncontrolled state.
|
|
4
|
+
type: reference
|
|
5
|
+
summary: Controlled vs uncontrolled state patterns and merging both modes with useControllableState from Radix UI.
|
|
6
|
+
prerequisites:
|
|
7
|
+
- /composition
|
|
8
|
+
- /types
|
|
9
|
+
related:
|
|
10
|
+
- /as-child
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
Building flexible components that work in both controlled and uncontrolled modes is a hallmark of professional components.
|
|
14
|
+
|
|
15
|
+
## Uncontrolled State
|
|
16
|
+
|
|
17
|
+
Uncontrolled state is when the component manages its own state internally. This is the default usage pattern for most components.
|
|
18
|
+
|
|
19
|
+
For example, here's a simple `Stepper` component that manages its own state internally:
|
|
20
|
+
|
|
21
|
+
```tsx title="stepper.tsx"
|
|
22
|
+
import { useState } from "react";
|
|
23
|
+
|
|
24
|
+
export const Stepper = () => {
|
|
25
|
+
const [value, setValue] = useState(0);
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<div>
|
|
29
|
+
<p>{value}</p>
|
|
30
|
+
<button onClick={() => setValue(value + 1)}>Increment</button>
|
|
31
|
+
</div>
|
|
32
|
+
);
|
|
33
|
+
};
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Controlled State
|
|
37
|
+
|
|
38
|
+
Controlled state is when the component's state is managed by the parent component. Rather than keeping track of the state internally, we delegate this responsibility to the parent component.
|
|
39
|
+
|
|
40
|
+
Let's rework the `Stepper` component to be controlled by the parent component:
|
|
41
|
+
|
|
42
|
+
```tsx title="stepper.tsx"
|
|
43
|
+
type StepperProps = {
|
|
44
|
+
value: number;
|
|
45
|
+
setValue: (value: number) => void;
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export const Stepper = ({ value, setValue }: StepperProps) => (
|
|
49
|
+
<div>
|
|
50
|
+
<p>{value}</p>
|
|
51
|
+
<button onClick={() => setValue(value + 1)}>Increment</button>
|
|
52
|
+
</div>
|
|
53
|
+
);
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Merging states
|
|
57
|
+
|
|
58
|
+
The best components support both controlled and uncontrolled state. This allows the component to be used in a variety of scenarios, and to be easily customized.
|
|
59
|
+
|
|
60
|
+
[Radix UI](https://www.radix-ui.com/) maintain an internal utility for merging controllable and uncontrolled state called [`use-controllable-state`](https://github.com/radix-ui/primitives/tree/main/packages/react/use-controllable-state). While not intended for public use, registries like [Kibo UI](https://www.kibo-ui.com) have implemented this utility to build their own Radix-like components.
|
|
61
|
+
|
|
62
|
+
Let's install the hook:
|
|
63
|
+
|
|
64
|
+
```package-install
|
|
65
|
+
npm install @radix-ui/react-use-controllable-state
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
This lightweight hook gives you the same state management patterns used internally by Radix UI's component library, ensuring your components behave consistently with industry standards.
|
|
69
|
+
|
|
70
|
+
The hook accepts three main parameters and returns a tuple with the current value and setter. Let's use it to merge the controlled and uncontrolled state of the `Stepper` component:
|
|
71
|
+
|
|
72
|
+
```tsx title="stepper.tsx"
|
|
73
|
+
import { useControllableState } from "@radix-ui/react-use-controllable-state";
|
|
74
|
+
|
|
75
|
+
type StepperProps = {
|
|
76
|
+
value: number;
|
|
77
|
+
defaultValue: number;
|
|
78
|
+
onValueChange: (value: number) => void;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const Stepper = ({
|
|
82
|
+
value: controlledValue,
|
|
83
|
+
defaultValue,
|
|
84
|
+
onValueChange,
|
|
85
|
+
}: StepperProps) => {
|
|
86
|
+
const [value, setValue] = useControllableState({
|
|
87
|
+
prop: controlledValue, // The controlled value prop
|
|
88
|
+
defaultProp: defaultValue, // Default value for uncontrolled mode
|
|
89
|
+
onChange: onValueChange, // Called when value changes
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
<div>
|
|
94
|
+
<p>{value}</p>
|
|
95
|
+
<button onClick={() => setValue(value + 1)}>Increment</button>
|
|
96
|
+
</div>
|
|
97
|
+
);
|
|
98
|
+
};
|
|
99
|
+
```
|
package/dist/templates/claude-config/app/.agents/skills/building-components/references/styling.mdx
ADDED
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Styling
|
|
3
|
+
description: Conditional and composable styling with Tailwind classes.
|
|
4
|
+
type: guide
|
|
5
|
+
summary: Using tailwind-merge, clsx, the cn utility, and Class Variance Authority for conditional and composable component styling.
|
|
6
|
+
prerequisites:
|
|
7
|
+
- /composition
|
|
8
|
+
related:
|
|
9
|
+
- /design-tokens
|
|
10
|
+
- /data-attributes
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
Modern component libraries need flexible styling systems that can handle complex requirements without sacrificing developer experience. The combination of Tailwind CSS with intelligent class merging has emerged as a powerful pattern for building customizable components.
|
|
14
|
+
|
|
15
|
+
This approach solves the fundamental tension between providing sensible defaults and allowing complete customization - a challenge that has plagued component libraries for years.
|
|
16
|
+
|
|
17
|
+
## The problem with traditional styling
|
|
18
|
+
|
|
19
|
+
Traditional CSS approaches often lead to specificity wars, style conflicts, and unpredictable overrides. When you pass `className="bg-blue-500"` to a component that already has `bg-red-500`, which one wins?
|
|
20
|
+
|
|
21
|
+
Without proper handling, both classes apply and the result depends on a lot of factors - CSS source order, the specificity of the classes, the bundler's class merging algorithm, etc.
|
|
22
|
+
|
|
23
|
+
## Merging classes intelligently
|
|
24
|
+
|
|
25
|
+
The `tailwind-merge` library solves this by understanding Tailwind's class structure and intelligently resolving conflicts. When two classes target the same CSS property, it keeps only the last one.
|
|
26
|
+
|
|
27
|
+
```tsx title="Without tailwind-merge"
|
|
28
|
+
// Both bg-red-500 and bg-blue-500 apply - unpredictable result
|
|
29
|
+
<Button className="bg-blue-500" />
|
|
30
|
+
// Renders: className="bg-red-500 bg-blue-500"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
```tsx title="With tailwind-merge"
|
|
34
|
+
import { twMerge } from "tailwind-merge";
|
|
35
|
+
|
|
36
|
+
// bg-blue-500 wins as it comes last
|
|
37
|
+
const className = twMerge("bg-red-500", "bg-blue-500");
|
|
38
|
+
// Returns: "bg-blue-500"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
This works for all Tailwind utilities:
|
|
42
|
+
|
|
43
|
+
```tsx
|
|
44
|
+
twMerge("px-4 py-2", "px-8"); // Returns: "py-2 px-8"
|
|
45
|
+
twMerge("text-sm", "text-lg"); // Returns: "text-lg"
|
|
46
|
+
twMerge("hover:bg-red-500", "hover:bg-blue-500"); // Returns: "hover:bg-blue-500"
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The library understands Tailwind's modifier system too:
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
// Modifiers are handled correctly
|
|
53
|
+
twMerge("hover:bg-red-500 focus:bg-red-500", "hover:bg-blue-500");
|
|
54
|
+
// Returns: "focus:bg-red-500 hover:bg-blue-500"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Conditional classes
|
|
58
|
+
|
|
59
|
+
Often you need to apply classes conditionally based on props or state. The `clsx` library provides a clean API for this:
|
|
60
|
+
|
|
61
|
+
```tsx title="Using clsx"
|
|
62
|
+
import clsx from "clsx";
|
|
63
|
+
|
|
64
|
+
// Basic conditionals
|
|
65
|
+
clsx("base", isActive && "active");
|
|
66
|
+
// Returns: "base active" (if isActive is true)
|
|
67
|
+
|
|
68
|
+
// Object syntax
|
|
69
|
+
clsx("base", {
|
|
70
|
+
active: isActive,
|
|
71
|
+
disabled: isDisabled,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Arrays
|
|
75
|
+
clsx(["base", isLarge ? "text-lg" : "text-sm"]);
|
|
76
|
+
|
|
77
|
+
// Mixed
|
|
78
|
+
clsx(
|
|
79
|
+
"base",
|
|
80
|
+
["array-item"],
|
|
81
|
+
{ "object-conditional": true },
|
|
82
|
+
isActive && "conditional",
|
|
83
|
+
);
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
A common pattern is to merge a default set of classes with incoming props, as well as any custom logic we have:
|
|
87
|
+
|
|
88
|
+
```tsx title="component.tsx"
|
|
89
|
+
const Component = ({ className, ...props }: ComponentProps) => {
|
|
90
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
91
|
+
|
|
92
|
+
return (
|
|
93
|
+
<div
|
|
94
|
+
className={cn(
|
|
95
|
+
"rounded-lg border bg-white shadow-sm",
|
|
96
|
+
isOpen && "bg-blue-500",
|
|
97
|
+
className,
|
|
98
|
+
)}
|
|
99
|
+
{...props}
|
|
100
|
+
/>
|
|
101
|
+
);
|
|
102
|
+
};
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## The `cn` utility function
|
|
106
|
+
|
|
107
|
+
The `cn` function, popularized by [shadcn/ui](https://ui.shadcn.com/), combines `clsx` and `tailwind-merge` to give you both conditional logic and intelligent merging:
|
|
108
|
+
|
|
109
|
+
```tsx title="lib/utils.ts"
|
|
110
|
+
import { type ClassValue, clsx } from "clsx";
|
|
111
|
+
import { twMerge } from "tailwind-merge";
|
|
112
|
+
|
|
113
|
+
export function cn(...inputs: ClassValue[]) {
|
|
114
|
+
return twMerge(clsx(inputs));
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
The power comes from the ordering - base styles first, conditionals second, user overrides last. This ensures predictable behavior while maintaining full customization.
|
|
119
|
+
|
|
120
|
+
## Class Variance Authority (CVA)
|
|
121
|
+
|
|
122
|
+
For complex components with many variants, manually managing conditional classes becomes unwieldy. [Class Variance Authority (CVA)](https://cva.style/docs) provides a declarative API for defining component variants.
|
|
123
|
+
|
|
124
|
+
For example, here's an extract from the [Button](https://ui.shadcn.com/docs/components/button) component from shadcn/ui:
|
|
125
|
+
|
|
126
|
+
```tsx title="@/components/ui/button.tsx"
|
|
127
|
+
const buttonVariants = cva(
|
|
128
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
|
129
|
+
{
|
|
130
|
+
variants: {
|
|
131
|
+
variant: {
|
|
132
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
133
|
+
destructive:
|
|
134
|
+
"bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
|
|
135
|
+
outline:
|
|
136
|
+
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
|
|
137
|
+
secondary:
|
|
138
|
+
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
139
|
+
ghost:
|
|
140
|
+
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
|
141
|
+
link: "text-primary underline-offset-4 hover:underline",
|
|
142
|
+
},
|
|
143
|
+
size: {
|
|
144
|
+
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
|
145
|
+
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
|
|
146
|
+
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
|
|
147
|
+
icon: "size-9",
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
defaultVariants: {
|
|
151
|
+
variant: "default",
|
|
152
|
+
size: "default",
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
);
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Best practices
|
|
159
|
+
|
|
160
|
+
### 1. Order matters
|
|
161
|
+
|
|
162
|
+
Always apply classes in this order:
|
|
163
|
+
|
|
164
|
+
1. Base styles (always applied)
|
|
165
|
+
2. Variant styles (based on props)
|
|
166
|
+
3. Conditional styles (based on state)
|
|
167
|
+
4. User overrides (className prop)
|
|
168
|
+
|
|
169
|
+
```tsx
|
|
170
|
+
className={cn(
|
|
171
|
+
'base-styles', // 1. Base
|
|
172
|
+
variant && variantStyles, // 2. Variants
|
|
173
|
+
isActive && 'active', // 3. Conditionals
|
|
174
|
+
className // 4. User overrides
|
|
175
|
+
)}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### 2. Document your variants
|
|
179
|
+
|
|
180
|
+
Use TypeScript and JSDoc to document what each variant does:
|
|
181
|
+
|
|
182
|
+
```tsx
|
|
183
|
+
type ButtonProps = {
|
|
184
|
+
/**
|
|
185
|
+
* The visual style of the button
|
|
186
|
+
* @default "primary"
|
|
187
|
+
*/
|
|
188
|
+
variant?: "primary" | "secondary" | "destructive" | "ghost";
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* The size of the button
|
|
192
|
+
* @default "md"
|
|
193
|
+
*/
|
|
194
|
+
size?: "sm" | "md" | "lg";
|
|
195
|
+
};
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### 3. Extract repeated patterns
|
|
199
|
+
|
|
200
|
+
If you find yourself writing the same conditional logic repeatedly, extract it:
|
|
201
|
+
|
|
202
|
+
```tsx title="utils/styles.ts"
|
|
203
|
+
export const focusRing = 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500';
|
|
204
|
+
export const disabled = 'disabled:pointer-events-none disabled:opacity-50';
|
|
205
|
+
|
|
206
|
+
// Use in components
|
|
207
|
+
className={cn(focusRing, disabled, className)}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Migration guide
|
|
211
|
+
|
|
212
|
+
If you're migrating from a different styling approach, here's how to adapt common patterns:
|
|
213
|
+
|
|
214
|
+
### From CSS Modules
|
|
215
|
+
|
|
216
|
+
```tsx title="Before - CSS Modules"
|
|
217
|
+
import styles from "./Button.module.css";
|
|
218
|
+
|
|
219
|
+
<button className={`${styles.button} ${styles[variant]} ${className}`} />;
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
```tsx title="After - cn + Tailwind"
|
|
223
|
+
import { cn } from "@/lib/utils";
|
|
224
|
+
|
|
225
|
+
<button
|
|
226
|
+
className={cn(
|
|
227
|
+
"px-4 py-2 rounded-lg",
|
|
228
|
+
variant === "primary" && "bg-blue-500 text-white",
|
|
229
|
+
className,
|
|
230
|
+
)}
|
|
231
|
+
/>;
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### From styled-components
|
|
235
|
+
|
|
236
|
+
```tsx title="Before - styled-components"
|
|
237
|
+
const Button = styled.button<{ $primary?: boolean }>`
|
|
238
|
+
padding: 8px 16px;
|
|
239
|
+
background: ${(props) => (props.$primary ? "blue" : "gray")};
|
|
240
|
+
`;
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
```tsx title="After - cn + Tailwind"
|
|
244
|
+
function Button({ primary, className, ...props }) {
|
|
245
|
+
return (
|
|
246
|
+
<button
|
|
247
|
+
className={cn(
|
|
248
|
+
"px-4 py-2",
|
|
249
|
+
primary ? "bg-blue-500" : "bg-gray-500",
|
|
250
|
+
className,
|
|
251
|
+
)}
|
|
252
|
+
{...props}
|
|
253
|
+
/>
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Performance considerations
|
|
259
|
+
|
|
260
|
+
Both `clsx` and `tailwind-merge` are highly optimized, but keep these tips in mind:
|
|
261
|
+
|
|
262
|
+
1. **Define variants outside components** - CVA variants should be defined outside the component to avoid recreation on every render.
|
|
263
|
+
|
|
264
|
+
2. **Memoize complex computations** - If you have expensive conditional logic, consider memoizing:
|
|
265
|
+
|
|
266
|
+
```tsx
|
|
267
|
+
const className = useMemo(
|
|
268
|
+
() => cn(baseStyles, expensiveComputation(props), className),
|
|
269
|
+
[props, className],
|
|
270
|
+
);
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
3. **Use CSS variables for dynamic values** - Instead of generating classes dynamically, use CSS variables:
|
|
274
|
+
|
|
275
|
+
```tsx title="Prefer CSS variables"
|
|
276
|
+
// Good
|
|
277
|
+
<div
|
|
278
|
+
className="bg-[var(--color)]"
|
|
279
|
+
style={{ '--color': dynamicColor } as React.CSSProperties}
|
|
280
|
+
/>
|
|
281
|
+
|
|
282
|
+
// Avoid
|
|
283
|
+
<div className={`bg-[${dynamicColor}]`} />
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
The combination of Tailwind CSS, intelligent class merging, and variant APIs provides a robust foundation for component styling. This approach scales from simple buttons to complex design systems while maintaining predictability and developer experience.
|