From d7626fd483884322a7d274ec37e65ba1bad796ff Mon Sep 17 00:00:00 2001 From: h Date: Fri, 16 Oct 2026 03:41:12 +0200 Subject: [PATCH] feat(*): init --- .claude/rules/svelte.md | 23 + .claude/rules/ultracite.md | 123 +++ .claude/settings.json | 15 + .copier/caddy.yml | 5 + .copier/frontend.yml | 9 + .copier/infra.yml | 9 + .dockerignore | 7 + .env.example | 4 + .gitignore | 18 + .lodge | 6 + .mcp.json | 12 + .npmrc | 1 + .pre-commit-config.yaml | 13 + CLAUDE.md | 16 + Dockerfile | 34 + Makefile | 42 + README.md | 8 + biome.jsonc | 45 + bun.lock | 520 ++++++++++ caddy/.env.example | 2 + caddy/.gitignore | 2 + caddy/Caddyfile.example | 14 + caddy/README.md | 3 + caddy/docker-compose.yml | 23 + caddy/site.caddy | 5 + components.json | 20 + docker-compose.override.yml.example | 22 + docker-compose.yml | 30 + docs/agents/decisions.md | 15 + docs/agents/kickoff.md | 116 +++ package.json | 46 + renovate.jsonc | 4 + serve.ts | 36 + src/app.d.ts | 13 + src/app.html | 13 + src/env.ts | 5 + src/lib/api/client.ts | 56 ++ .../ui/avatar/avatar-fallback.svelte | 20 + .../components/ui/avatar/avatar-image.svelte | 17 + src/lib/components/ui/avatar/avatar.svelte | 22 + src/lib/components/ui/avatar/index.ts | 13 + src/lib/components/ui/badge/badge.svelte | 61 ++ src/lib/components/ui/badge/index.ts | 2 + .../ui/breadcrumb/breadcrumb-ellipsis.svelte | 25 + .../ui/breadcrumb/breadcrumb-item.svelte | 20 + .../ui/breadcrumb/breadcrumb-link.svelte | 29 + .../ui/breadcrumb/breadcrumb-list.svelte | 23 + .../ui/breadcrumb/breadcrumb-page.svelte | 23 + .../ui/breadcrumb/breadcrumb-separator.svelte | 27 + .../ui/breadcrumb/breadcrumb.svelte | 21 + src/lib/components/ui/breadcrumb/index.ts | 25 + src/lib/components/ui/button/button.svelte | 131 +++ src/lib/components/ui/button/index.ts | 21 + src/lib/components/ui/card/card-action.svelte | 23 + .../components/ui/card/card-content.svelte | 20 + .../ui/card/card-description.svelte | 20 + src/lib/components/ui/card/card-footer.svelte | 20 + src/lib/components/ui/card/card-header.svelte | 23 + src/lib/components/ui/card/card-title.svelte | 20 + src/lib/components/ui/card/card.svelte | 23 + src/lib/components/ui/card/index.ts | 25 + .../components/ui/checkbox/checkbox.svelte | 49 + src/lib/components/ui/checkbox/index.ts | 6 + .../ui/collapsible/collapsible-content.svelte | 14 + .../ui/collapsible/collapsible-trigger.svelte | 14 + .../ui/collapsible/collapsible.svelte | 16 + src/lib/components/ui/collapsible/index.ts | 13 + .../context-menu-checkbox-item.svelte | 42 + .../context-menu/context-menu-content.svelte | 30 + .../context-menu-group-heading.svelte | 24 + .../ui/context-menu/context-menu-group.svelte | 12 + .../ui/context-menu/context-menu-item.svelte | 27 + .../ui/context-menu/context-menu-label.svelte | 27 + .../context-menu/context-menu-portal.svelte | 7 + .../context-menu-radio-group.svelte | 16 + .../context-menu-radio-item.svelte | 35 + .../context-menu-separator.svelte | 17 + .../context-menu/context-menu-shortcut.svelte | 23 + .../context-menu-sub-content.svelte | 20 + .../context-menu-sub-trigger.svelte | 29 + .../ui/context-menu/context-menu-sub.svelte | 8 + .../context-menu/context-menu-trigger.svelte | 14 + .../ui/context-menu/context-menu.svelte | 10 + src/lib/components/ui/context-menu/index.ts | 52 + .../components/ui/dialog/dialog-close.svelte | 8 + .../ui/dialog/dialog-content.svelte | 45 + .../ui/dialog/dialog-description.svelte | 17 + .../components/ui/dialog/dialog-footer.svelte | 23 + .../components/ui/dialog/dialog-header.svelte | 20 + .../ui/dialog/dialog-overlay.svelte | 17 + .../components/ui/dialog/dialog-portal.svelte | 7 + .../components/ui/dialog/dialog-title.svelte | 17 + .../ui/dialog/dialog-trigger.svelte | 8 + src/lib/components/ui/dialog/dialog.svelte | 8 + src/lib/components/ui/dialog/index.ts | 34 + .../dropdown-menu-checkbox-group.svelte | 16 + .../dropdown-menu-checkbox-item.svelte | 46 + .../dropdown-menu-content.svelte | 31 + .../dropdown-menu-group-heading.svelte | 25 + .../dropdown-menu/dropdown-menu-group.svelte | 14 + .../dropdown-menu/dropdown-menu-item.svelte | 28 + .../dropdown-menu/dropdown-menu-label.svelte | 27 + .../dropdown-menu/dropdown-menu-portal.svelte | 7 + .../dropdown-menu-radio-group.svelte | 16 + .../dropdown-menu-radio-item.svelte | 35 + .../dropdown-menu-separator.svelte | 17 + .../dropdown-menu-shortcut.svelte | 23 + .../dropdown-menu-sub-content.svelte | 20 + .../dropdown-menu-sub-trigger.svelte | 29 + .../ui/dropdown-menu/dropdown-menu-sub.svelte | 10 + .../dropdown-menu-trigger.svelte | 14 + .../ui/dropdown-menu/dropdown-menu.svelte | 10 + src/lib/components/ui/dropdown-menu/index.ts | 54 + src/lib/components/ui/input/index.ts | 7 + src/lib/components/ui/input/input.svelte | 54 + src/lib/components/ui/label/index.ts | 3 + src/lib/components/ui/label/label.svelte | 27 + src/lib/components/ui/progress/index.ts | 7 + .../components/ui/progress/progress.svelte | 30 + src/lib/components/ui/select/index.ts | 37 + .../ui/select/select-content.svelte | 45 + .../ui/select/select-group-heading.svelte | 24 + .../components/ui/select/select-group.svelte | 8 + .../components/ui/select/select-item.svelte | 41 + .../components/ui/select/select-label.svelte | 23 + .../components/ui/select/select-portal.svelte | 7 + .../select/select-scroll-down-button.svelte | 23 + .../ui/select/select-scroll-up-button.svelte | 23 + .../ui/select/select-separator.svelte | 21 + .../ui/select/select-trigger.svelte | 29 + src/lib/components/ui/select/select.svelte | 11 + src/lib/components/ui/separator/index.ts | 7 + .../components/ui/separator/separator.svelte | 21 + src/lib/components/ui/sheet/index.ts | 34 + .../components/ui/sheet/sheet-close.svelte | 8 + .../components/ui/sheet/sheet-content.svelte | 62 ++ .../ui/sheet/sheet-description.svelte | 17 + .../components/ui/sheet/sheet-footer.svelte | 20 + .../components/ui/sheet/sheet-header.svelte | 20 + .../components/ui/sheet/sheet-overlay.svelte | 17 + .../components/ui/sheet/sheet-portal.svelte | 7 + .../components/ui/sheet/sheet-title.svelte | 17 + .../components/ui/sheet/sheet-trigger.svelte | 8 + src/lib/components/ui/sheet/sheet.svelte | 8 + src/lib/components/ui/slider/index.ts | 7 + src/lib/components/ui/slider/slider.svelte | 54 + src/lib/components/ui/sonner/index.ts | 1 + src/lib/components/ui/sonner/sonner.svelte | 55 ++ src/lib/components/ui/surface/index.ts | 5 + .../components/ui/surface/surface-cut.svelte | 38 + src/lib/components/ui/surface/surface.svelte | 66 ++ src/lib/components/ui/switch/index.ts | 7 + src/lib/components/ui/switch/switch.svelte | 63 ++ src/lib/components/ui/table/index.ts | 28 + src/lib/components/ui/table/table-body.svelte | 20 + .../components/ui/table/table-caption.svelte | 20 + src/lib/components/ui/table/table-cell.svelte | 23 + .../components/ui/table/table-footer.svelte | 23 + src/lib/components/ui/table/table-head.svelte | 23 + .../components/ui/table/table-header.svelte | 23 + src/lib/components/ui/table/table-row.svelte | 23 + src/lib/components/ui/table/table.svelte | 22 + src/lib/components/ui/tabs/index.ts | 16 + .../components/ui/tabs/tabs-content.svelte | 17 + src/lib/components/ui/tabs/tabs-list.svelte | 20 + .../components/ui/tabs/tabs-trigger.svelte | 20 + src/lib/components/ui/tabs/tabs.svelte | 19 + src/lib/components/ui/textarea/index.ts | 7 + .../components/ui/textarea/textarea.svelte | 23 + src/lib/components/ui/tooltip/index.ts | 19 + .../ui/tooltip/tooltip-content.svelte | 35 + .../ui/tooltip/tooltip-portal.svelte | 7 + .../ui/tooltip/tooltip-provider.svelte | 7 + .../ui/tooltip/tooltip-trigger.svelte | 8 + src/lib/components/ui/tooltip/tooltip.svelte | 8 + src/lib/index.ts | 2 + src/lib/utils.ts | 58 ++ src/routes/+layout.svelte | 10 + src/routes/+layout.ts | 2 + src/routes/+page.svelte | 13 + src/routes/claddcn.css | 922 ++++++++++++++++++ src/routes/layout.css | 15 + tsconfig.json | 9 + vite.config.ts | 34 + 184 files changed, 5558 insertions(+) create mode 100644 .claude/rules/svelte.md create mode 100644 .claude/rules/ultracite.md create mode 100644 .claude/settings.json create mode 100644 .copier/caddy.yml create mode 100644 .copier/frontend.yml create mode 100644 .copier/infra.yml create mode 100644 .dockerignore create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 .lodge create mode 100644 .mcp.json create mode 100644 .npmrc create mode 100644 .pre-commit-config.yaml create mode 100644 CLAUDE.md create mode 100644 Dockerfile create mode 100644 Makefile create mode 100644 README.md create mode 100644 biome.jsonc create mode 100644 bun.lock create mode 100644 caddy/.env.example create mode 100644 caddy/.gitignore create mode 100644 caddy/Caddyfile.example create mode 100644 caddy/README.md create mode 100644 caddy/docker-compose.yml create mode 100644 caddy/site.caddy create mode 100644 components.json create mode 100644 docker-compose.override.yml.example create mode 100644 docker-compose.yml create mode 100644 docs/agents/decisions.md create mode 100644 docs/agents/kickoff.md create mode 100644 package.json create mode 100644 renovate.jsonc create mode 100644 serve.ts create mode 100644 src/app.d.ts create mode 100644 src/app.html create mode 100644 src/env.ts create mode 100644 src/lib/api/client.ts create mode 100644 src/lib/components/ui/avatar/avatar-fallback.svelte create mode 100644 src/lib/components/ui/avatar/avatar-image.svelte create mode 100644 src/lib/components/ui/avatar/avatar.svelte create mode 100644 src/lib/components/ui/avatar/index.ts create mode 100644 src/lib/components/ui/badge/badge.svelte create mode 100644 src/lib/components/ui/badge/index.ts create mode 100644 src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte create mode 100644 src/lib/components/ui/breadcrumb/breadcrumb-item.svelte create mode 100644 src/lib/components/ui/breadcrumb/breadcrumb-link.svelte create mode 100644 src/lib/components/ui/breadcrumb/breadcrumb-list.svelte create mode 100644 src/lib/components/ui/breadcrumb/breadcrumb-page.svelte create mode 100644 src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte create mode 100644 src/lib/components/ui/breadcrumb/breadcrumb.svelte create mode 100644 src/lib/components/ui/breadcrumb/index.ts create mode 100644 src/lib/components/ui/button/button.svelte create mode 100644 src/lib/components/ui/button/index.ts create mode 100644 src/lib/components/ui/card/card-action.svelte create mode 100644 src/lib/components/ui/card/card-content.svelte create mode 100644 src/lib/components/ui/card/card-description.svelte create mode 100644 src/lib/components/ui/card/card-footer.svelte create mode 100644 src/lib/components/ui/card/card-header.svelte create mode 100644 src/lib/components/ui/card/card-title.svelte create mode 100644 src/lib/components/ui/card/card.svelte create mode 100644 src/lib/components/ui/card/index.ts create mode 100644 src/lib/components/ui/checkbox/checkbox.svelte create mode 100644 src/lib/components/ui/checkbox/index.ts create mode 100644 src/lib/components/ui/collapsible/collapsible-content.svelte create mode 100644 src/lib/components/ui/collapsible/collapsible-trigger.svelte create mode 100644 src/lib/components/ui/collapsible/collapsible.svelte create mode 100644 src/lib/components/ui/collapsible/index.ts create mode 100644 src/lib/components/ui/context-menu/context-menu-checkbox-item.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-content.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-group-heading.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-group.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-item.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-label.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-portal.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-radio-group.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-radio-item.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-separator.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-shortcut.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-sub-content.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-sub-trigger.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-sub.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu-trigger.svelte create mode 100644 src/lib/components/ui/context-menu/context-menu.svelte create mode 100644 src/lib/components/ui/context-menu/index.ts create mode 100644 src/lib/components/ui/dialog/dialog-close.svelte create mode 100644 src/lib/components/ui/dialog/dialog-content.svelte create mode 100644 src/lib/components/ui/dialog/dialog-description.svelte create mode 100644 src/lib/components/ui/dialog/dialog-footer.svelte create mode 100644 src/lib/components/ui/dialog/dialog-header.svelte create mode 100644 src/lib/components/ui/dialog/dialog-overlay.svelte create mode 100644 src/lib/components/ui/dialog/dialog-portal.svelte create mode 100644 src/lib/components/ui/dialog/dialog-title.svelte create mode 100644 src/lib/components/ui/dialog/dialog-trigger.svelte create mode 100644 src/lib/components/ui/dialog/dialog.svelte create mode 100644 src/lib/components/ui/dialog/index.ts create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte create mode 100644 src/lib/components/ui/dropdown-menu/dropdown-menu.svelte create mode 100644 src/lib/components/ui/dropdown-menu/index.ts create mode 100644 src/lib/components/ui/input/index.ts create mode 100644 src/lib/components/ui/input/input.svelte create mode 100644 src/lib/components/ui/label/index.ts create mode 100644 src/lib/components/ui/label/label.svelte create mode 100644 src/lib/components/ui/progress/index.ts create mode 100644 src/lib/components/ui/progress/progress.svelte create mode 100644 src/lib/components/ui/select/index.ts create mode 100644 src/lib/components/ui/select/select-content.svelte create mode 100644 src/lib/components/ui/select/select-group-heading.svelte create mode 100644 src/lib/components/ui/select/select-group.svelte create mode 100644 src/lib/components/ui/select/select-item.svelte create mode 100644 src/lib/components/ui/select/select-label.svelte create mode 100644 src/lib/components/ui/select/select-portal.svelte create mode 100644 src/lib/components/ui/select/select-scroll-down-button.svelte create mode 100644 src/lib/components/ui/select/select-scroll-up-button.svelte create mode 100644 src/lib/components/ui/select/select-separator.svelte create mode 100644 src/lib/components/ui/select/select-trigger.svelte create mode 100644 src/lib/components/ui/select/select.svelte create mode 100644 src/lib/components/ui/separator/index.ts create mode 100644 src/lib/components/ui/separator/separator.svelte create mode 100644 src/lib/components/ui/sheet/index.ts create mode 100644 src/lib/components/ui/sheet/sheet-close.svelte create mode 100644 src/lib/components/ui/sheet/sheet-content.svelte create mode 100644 src/lib/components/ui/sheet/sheet-description.svelte create mode 100644 src/lib/components/ui/sheet/sheet-footer.svelte create mode 100644 src/lib/components/ui/sheet/sheet-header.svelte create mode 100644 src/lib/components/ui/sheet/sheet-overlay.svelte create mode 100644 src/lib/components/ui/sheet/sheet-portal.svelte create mode 100644 src/lib/components/ui/sheet/sheet-title.svelte create mode 100644 src/lib/components/ui/sheet/sheet-trigger.svelte create mode 100644 src/lib/components/ui/sheet/sheet.svelte create mode 100644 src/lib/components/ui/slider/index.ts create mode 100644 src/lib/components/ui/slider/slider.svelte create mode 100644 src/lib/components/ui/sonner/index.ts create mode 100644 src/lib/components/ui/sonner/sonner.svelte create mode 100644 src/lib/components/ui/surface/index.ts create mode 100644 src/lib/components/ui/surface/surface-cut.svelte create mode 100644 src/lib/components/ui/surface/surface.svelte create mode 100644 src/lib/components/ui/switch/index.ts create mode 100644 src/lib/components/ui/switch/switch.svelte create mode 100644 src/lib/components/ui/table/index.ts create mode 100644 src/lib/components/ui/table/table-body.svelte create mode 100644 src/lib/components/ui/table/table-caption.svelte create mode 100644 src/lib/components/ui/table/table-cell.svelte create mode 100644 src/lib/components/ui/table/table-footer.svelte create mode 100644 src/lib/components/ui/table/table-head.svelte create mode 100644 src/lib/components/ui/table/table-header.svelte create mode 100644 src/lib/components/ui/table/table-row.svelte create mode 100644 src/lib/components/ui/table/table.svelte create mode 100644 src/lib/components/ui/tabs/index.ts create mode 100644 src/lib/components/ui/tabs/tabs-content.svelte create mode 100644 src/lib/components/ui/tabs/tabs-list.svelte create mode 100644 src/lib/components/ui/tabs/tabs-trigger.svelte create mode 100644 src/lib/components/ui/tabs/tabs.svelte create mode 100644 src/lib/components/ui/textarea/index.ts create mode 100644 src/lib/components/ui/textarea/textarea.svelte create mode 100644 src/lib/components/ui/tooltip/index.ts create mode 100644 src/lib/components/ui/tooltip/tooltip-content.svelte create mode 100644 src/lib/components/ui/tooltip/tooltip-portal.svelte create mode 100644 src/lib/components/ui/tooltip/tooltip-provider.svelte create mode 100644 src/lib/components/ui/tooltip/tooltip-trigger.svelte create mode 100644 src/lib/components/ui/tooltip/tooltip.svelte create mode 100644 src/lib/index.ts create mode 100644 src/lib/utils.ts create mode 100644 src/routes/+layout.svelte create mode 100644 src/routes/+layout.ts create mode 100644 src/routes/+page.svelte create mode 100644 src/routes/claddcn.css create mode 100644 src/routes/layout.css create mode 100644 tsconfig.json create mode 100644 vite.config.ts diff --git a/.claude/rules/svelte.md b/.claude/rules/svelte.md new file mode 100644 index 0000000..4711cd0 --- /dev/null +++ b/.claude/rules/svelte.md @@ -0,0 +1,23 @@ +You are able to use the Svelte MCP server, where you have access to comprehensive Svelte 5 and SvelteKit documentation. Here's how to use the available tools effectively: + +## Available Svelte MCP Tools: + +### 1. list-sections + +Use this FIRST to discover all available documentation sections. Returns a structured list with titles, use_cases, and paths. +When asked about Svelte or SvelteKit topics, ALWAYS use this tool at the start of the chat to find relevant sections. + +### 2. get-documentation + +Retrieves full documentation content for specific sections. Accepts single or multiple sections. +After calling the list-sections tool, you MUST analyze the returned documentation sections (especially the use_cases field) and then use the get-documentation tool to fetch ALL documentation sections that are relevant for the user's task. + +### 3. svelte-autofixer + +Analyzes Svelte code and returns issues and suggestions. +You MUST use this tool whenever writing Svelte code before sending it to the user. Keep calling it until no issues or suggestions are returned. + +### 4. playground-link + +Generates a Svelte Playground link with the provided code. +After completing the code, ask the user if they want a playground link. Only call this tool after user confirmation and NEVER if code was written to files in their project. diff --git a/.claude/rules/ultracite.md b/.claude/rules/ultracite.md new file mode 100644 index 0000000..05ab812 --- /dev/null +++ b/.claude/rules/ultracite.md @@ -0,0 +1,123 @@ +# Ultracite Code Standards + +This project uses **Ultracite**, a zero-config preset that enforces strict code quality standards through automated formatting and linting. + +## Quick Reference + +- **Format code**: `bun x ultracite fix` +- **Check for issues**: `bun x ultracite check` +- **Diagnose setup**: `bun x ultracite doctor` + +Biome (the underlying engine) provides robust linting and formatting. Most issues are automatically fixable. + +--- + +## Core Principles + +Write code that is **accessible, performant, type-safe, and maintainable**. Focus on clarity and explicit intent over brevity. + +### Type Safety & Explicitness + +- Use explicit types for function parameters and return values when they enhance clarity +- Prefer `unknown` over `any` when the type is genuinely unknown +- Use const assertions (`as const`) for immutable values and literal types +- Leverage TypeScript's type narrowing instead of type assertions +- Use meaningful variable names instead of magic numbers - extract constants with descriptive names + +### Modern JavaScript/TypeScript + +- Use arrow functions for callbacks and short functions +- Prefer `for...of` loops over `.forEach()` and indexed `for` loops +- Use optional chaining (`?.`) and nullish coalescing (`??`) for safer property access +- Prefer template literals over string concatenation +- Use destructuring for object and array assignments +- Use `const` by default, `let` only when reassignment is needed, never `var` + +### Async & Promises + +- Always `await` promises in async functions - don't forget to use the return value +- Use `async/await` syntax instead of promise chains for better readability +- Handle errors appropriately in async code with try-catch blocks +- Don't use async functions as Promise executors + +### React & JSX + +- Use function components over class components +- Call hooks at the top level only, never conditionally +- Specify all dependencies in hook dependency arrays correctly +- Use the `key` prop for elements in iterables (prefer unique IDs over array indices) +- Nest children between opening and closing tags instead of passing as props +- Don't define components inside other components +- Use semantic HTML and ARIA attributes for accessibility: + - Provide meaningful alt text for images + - Use proper heading hierarchy + - Add labels for form inputs + - Include keyboard event handlers alongside mouse events + - Use semantic elements (` +{/if} diff --git a/src/lib/components/ui/button/index.ts b/src/lib/components/ui/button/index.ts new file mode 100644 index 0000000..761edcf --- /dev/null +++ b/src/lib/components/ui/button/index.ts @@ -0,0 +1,21 @@ +import Root, { + type ButtonProps, + type ButtonSize, + type ButtonVariant, + type CladdColor, + buttonVariants, + withColor, +} from "./button.svelte"; + +export { + Root, + type ButtonProps as Props, + // + Root as Button, + buttonVariants, + withColor, + type CladdColor, + type ButtonProps, + type ButtonSize, + type ButtonVariant, +}; diff --git a/src/lib/components/ui/card/card-action.svelte b/src/lib/components/ui/card/card-action.svelte new file mode 100644 index 0000000..5ac9b13 --- /dev/null +++ b/src/lib/components/ui/card/card-action.svelte @@ -0,0 +1,23 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/card/card-content.svelte b/src/lib/components/ui/card/card-content.svelte new file mode 100644 index 0000000..1d29484 --- /dev/null +++ b/src/lib/components/ui/card/card-content.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/card/card-description.svelte b/src/lib/components/ui/card/card-description.svelte new file mode 100644 index 0000000..d7f82db --- /dev/null +++ b/src/lib/components/ui/card/card-description.svelte @@ -0,0 +1,20 @@ + + +

+ {@render children?.()} +

diff --git a/src/lib/components/ui/card/card-footer.svelte b/src/lib/components/ui/card/card-footer.svelte new file mode 100644 index 0000000..e1ed303 --- /dev/null +++ b/src/lib/components/ui/card/card-footer.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/card/card-header.svelte b/src/lib/components/ui/card/card-header.svelte new file mode 100644 index 0000000..4a89145 --- /dev/null +++ b/src/lib/components/ui/card/card-header.svelte @@ -0,0 +1,23 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/card/card-title.svelte b/src/lib/components/ui/card/card-title.svelte new file mode 100644 index 0000000..ae4668a --- /dev/null +++ b/src/lib/components/ui/card/card-title.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/card/card.svelte b/src/lib/components/ui/card/card.svelte new file mode 100644 index 0000000..5297ab8 --- /dev/null +++ b/src/lib/components/ui/card/card.svelte @@ -0,0 +1,23 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/card/index.ts b/src/lib/components/ui/card/index.ts new file mode 100644 index 0000000..406a5ce --- /dev/null +++ b/src/lib/components/ui/card/index.ts @@ -0,0 +1,25 @@ +import Root from "./card.svelte"; +import Content from "./card-content.svelte"; +import Description from "./card-description.svelte"; +import Footer from "./card-footer.svelte"; +import Header from "./card-header.svelte"; +import Title from "./card-title.svelte"; +import Action from "./card-action.svelte"; + +export { + Root, + Content, + Description, + Footer, + Header, + Title, + Action, + // + Root as Card, + Content as CardContent, + Description as CardDescription, + Footer as CardFooter, + Header as CardHeader, + Title as CardTitle, + Action as CardAction, +}; diff --git a/src/lib/components/ui/checkbox/checkbox.svelte b/src/lib/components/ui/checkbox/checkbox.svelte new file mode 100644 index 0000000..d7de6e1 --- /dev/null +++ b/src/lib/components/ui/checkbox/checkbox.svelte @@ -0,0 +1,49 @@ + + + + {#snippet children({ + checked, + indeterminate, + })} + + {#if indeterminate} + + {:else} + + {/if} + + {/snippet} + diff --git a/src/lib/components/ui/checkbox/index.ts b/src/lib/components/ui/checkbox/index.ts new file mode 100644 index 0000000..d1b2485 --- /dev/null +++ b/src/lib/components/ui/checkbox/index.ts @@ -0,0 +1,6 @@ +import Root from "./checkbox.svelte"; +export { + Root, + // + Root as Checkbox, +}; diff --git a/src/lib/components/ui/collapsible/collapsible-content.svelte b/src/lib/components/ui/collapsible/collapsible-content.svelte new file mode 100644 index 0000000..6c9f34e --- /dev/null +++ b/src/lib/components/ui/collapsible/collapsible-content.svelte @@ -0,0 +1,14 @@ + + + diff --git a/src/lib/components/ui/collapsible/collapsible-trigger.svelte b/src/lib/components/ui/collapsible/collapsible-trigger.svelte new file mode 100644 index 0000000..ab2ce1f --- /dev/null +++ b/src/lib/components/ui/collapsible/collapsible-trigger.svelte @@ -0,0 +1,14 @@ + + + diff --git a/src/lib/components/ui/collapsible/collapsible.svelte b/src/lib/components/ui/collapsible/collapsible.svelte new file mode 100644 index 0000000..ac14155 --- /dev/null +++ b/src/lib/components/ui/collapsible/collapsible.svelte @@ -0,0 +1,16 @@ + + + diff --git a/src/lib/components/ui/collapsible/index.ts b/src/lib/components/ui/collapsible/index.ts new file mode 100644 index 0000000..296a91b --- /dev/null +++ b/src/lib/components/ui/collapsible/index.ts @@ -0,0 +1,13 @@ +import Root from "./collapsible.svelte"; +import Trigger from "./collapsible-trigger.svelte"; +import Content from "./collapsible-content.svelte"; + +export { + Root, + Content, + Trigger, + // + Root as Collapsible, + Content as CollapsibleContent, + Trigger as CollapsibleTrigger, +}; diff --git a/src/lib/components/ui/context-menu/context-menu-checkbox-item.svelte b/src/lib/components/ui/context-menu/context-menu-checkbox-item.svelte new file mode 100644 index 0000000..487dbf8 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-checkbox-item.svelte @@ -0,0 +1,42 @@ + + + + {#snippet children({ + checked, + })} + + {#if checked} + + {/if} + + {@render childrenProp?.()} + {/snippet} + diff --git a/src/lib/components/ui/context-menu/context-menu-content.svelte b/src/lib/components/ui/context-menu/context-menu-content.svelte new file mode 100644 index 0000000..6d1555c --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-content.svelte @@ -0,0 +1,30 @@ + + + + + diff --git a/src/lib/components/ui/context-menu/context-menu-group-heading.svelte b/src/lib/components/ui/context-menu/context-menu-group-heading.svelte new file mode 100644 index 0000000..78b70e1 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-group-heading.svelte @@ -0,0 +1,24 @@ + + + diff --git a/src/lib/components/ui/context-menu/context-menu-group.svelte b/src/lib/components/ui/context-menu/context-menu-group.svelte new file mode 100644 index 0000000..7b769f3 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-group.svelte @@ -0,0 +1,12 @@ + + + diff --git a/src/lib/components/ui/context-menu/context-menu-item.svelte b/src/lib/components/ui/context-menu/context-menu-item.svelte new file mode 100644 index 0000000..b2ff4b9 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-item.svelte @@ -0,0 +1,27 @@ + + + diff --git a/src/lib/components/ui/context-menu/context-menu-label.svelte b/src/lib/components/ui/context-menu/context-menu-label.svelte new file mode 100644 index 0000000..db20296 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-label.svelte @@ -0,0 +1,27 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/context-menu/context-menu-portal.svelte b/src/lib/components/ui/context-menu/context-menu-portal.svelte new file mode 100644 index 0000000..8674d44 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-portal.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/context-menu/context-menu-radio-group.svelte b/src/lib/components/ui/context-menu/context-menu-radio-group.svelte new file mode 100644 index 0000000..f043063 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-radio-group.svelte @@ -0,0 +1,16 @@ + + + diff --git a/src/lib/components/ui/context-menu/context-menu-radio-item.svelte b/src/lib/components/ui/context-menu/context-menu-radio-item.svelte new file mode 100644 index 0000000..12672a6 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-radio-item.svelte @@ -0,0 +1,35 @@ + + + + {#snippet children({ + checked, + })} + + {#if checked} + + {/if} + + {@render childrenProp?.({ checked })} + {/snippet} + diff --git a/src/lib/components/ui/context-menu/context-menu-separator.svelte b/src/lib/components/ui/context-menu/context-menu-separator.svelte new file mode 100644 index 0000000..788533e --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-separator.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/context-menu/context-menu-shortcut.svelte b/src/lib/components/ui/context-menu/context-menu-shortcut.svelte new file mode 100644 index 0000000..1ce50a0 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-shortcut.svelte @@ -0,0 +1,23 @@ + + + + {@render children?.()} + diff --git a/src/lib/components/ui/context-menu/context-menu-sub-content.svelte b/src/lib/components/ui/context-menu/context-menu-sub-content.svelte new file mode 100644 index 0000000..665a417 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-sub-content.svelte @@ -0,0 +1,20 @@ + + + diff --git a/src/lib/components/ui/context-menu/context-menu-sub-trigger.svelte b/src/lib/components/ui/context-menu/context-menu-sub-trigger.svelte new file mode 100644 index 0000000..592a080 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-sub-trigger.svelte @@ -0,0 +1,29 @@ + + + + {@render children?.()} + + diff --git a/src/lib/components/ui/context-menu/context-menu-sub.svelte b/src/lib/components/ui/context-menu/context-menu-sub.svelte new file mode 100644 index 0000000..ddd0575 --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-sub.svelte @@ -0,0 +1,8 @@ + + + diff --git a/src/lib/components/ui/context-menu/context-menu-trigger.svelte b/src/lib/components/ui/context-menu/context-menu-trigger.svelte new file mode 100644 index 0000000..e73751c --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu-trigger.svelte @@ -0,0 +1,14 @@ + + + diff --git a/src/lib/components/ui/context-menu/context-menu.svelte b/src/lib/components/ui/context-menu/context-menu.svelte new file mode 100644 index 0000000..c24489e --- /dev/null +++ b/src/lib/components/ui/context-menu/context-menu.svelte @@ -0,0 +1,10 @@ + + + diff --git a/src/lib/components/ui/context-menu/index.ts b/src/lib/components/ui/context-menu/index.ts new file mode 100644 index 0000000..1bca4fa --- /dev/null +++ b/src/lib/components/ui/context-menu/index.ts @@ -0,0 +1,52 @@ +import Root from "./context-menu.svelte"; +import Sub from "./context-menu-sub.svelte"; +import Portal from "./context-menu-portal.svelte"; +import Trigger from "./context-menu-trigger.svelte"; +import Group from "./context-menu-group.svelte"; +import RadioGroup from "./context-menu-radio-group.svelte"; +import Item from "./context-menu-item.svelte"; +import GroupHeading from "./context-menu-group-heading.svelte"; +import Content from "./context-menu-content.svelte"; +import Shortcut from "./context-menu-shortcut.svelte"; +import RadioItem from "./context-menu-radio-item.svelte"; +import Separator from "./context-menu-separator.svelte"; +import SubContent from "./context-menu-sub-content.svelte"; +import SubTrigger from "./context-menu-sub-trigger.svelte"; +import CheckboxItem from "./context-menu-checkbox-item.svelte"; +import Label from "./context-menu-label.svelte"; + +export { + Root, + Sub, + Portal, + Item, + GroupHeading, + Label, + Group, + Trigger, + Content, + Shortcut, + Separator, + RadioItem, + SubContent, + SubTrigger, + RadioGroup, + CheckboxItem, + // + Root as ContextMenu, + Sub as ContextMenuSub, + Portal as ContextMenuPortal, + Item as ContextMenuItem, + GroupHeading as ContextMenuGroupHeading, + Group as ContextMenuGroup, + Content as ContextMenuContent, + Trigger as ContextMenuTrigger, + Shortcut as ContextMenuShortcut, + RadioItem as ContextMenuRadioItem, + Separator as ContextMenuSeparator, + RadioGroup as ContextMenuRadioGroup, + SubContent as ContextMenuSubContent, + SubTrigger as ContextMenuSubTrigger, + CheckboxItem as ContextMenuCheckboxItem, + Label as ContextMenuLabel, +}; diff --git a/src/lib/components/ui/dialog/dialog-close.svelte b/src/lib/components/ui/dialog/dialog-close.svelte new file mode 100644 index 0000000..a0b8586 --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-close.svelte @@ -0,0 +1,8 @@ + + + diff --git a/src/lib/components/ui/dialog/dialog-content.svelte b/src/lib/components/ui/dialog/dialog-content.svelte new file mode 100644 index 0000000..d15e5ea --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-content.svelte @@ -0,0 +1,45 @@ + + + + + + {@render children?.()} + {#if showCloseButton} + + + Close + + {/if} + + diff --git a/src/lib/components/ui/dialog/dialog-description.svelte b/src/lib/components/ui/dialog/dialog-description.svelte new file mode 100644 index 0000000..e3d422e --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-description.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/dialog/dialog-footer.svelte b/src/lib/components/ui/dialog/dialog-footer.svelte new file mode 100644 index 0000000..67b9fcb --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-footer.svelte @@ -0,0 +1,23 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/dialog/dialog-header.svelte b/src/lib/components/ui/dialog/dialog-header.svelte new file mode 100644 index 0000000..450edae --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-header.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/dialog/dialog-overlay.svelte b/src/lib/components/ui/dialog/dialog-overlay.svelte new file mode 100644 index 0000000..ddc342b --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-overlay.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/dialog/dialog-portal.svelte b/src/lib/components/ui/dialog/dialog-portal.svelte new file mode 100644 index 0000000..d208462 --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-portal.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/dialog/dialog-title.svelte b/src/lib/components/ui/dialog/dialog-title.svelte new file mode 100644 index 0000000..c5c8ccd --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-title.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/dialog/dialog-trigger.svelte b/src/lib/components/ui/dialog/dialog-trigger.svelte new file mode 100644 index 0000000..f7ae9b4 --- /dev/null +++ b/src/lib/components/ui/dialog/dialog-trigger.svelte @@ -0,0 +1,8 @@ + + + diff --git a/src/lib/components/ui/dialog/dialog.svelte b/src/lib/components/ui/dialog/dialog.svelte new file mode 100644 index 0000000..84ecf31 --- /dev/null +++ b/src/lib/components/ui/dialog/dialog.svelte @@ -0,0 +1,8 @@ + + + diff --git a/src/lib/components/ui/dialog/index.ts b/src/lib/components/ui/dialog/index.ts new file mode 100644 index 0000000..e366157 --- /dev/null +++ b/src/lib/components/ui/dialog/index.ts @@ -0,0 +1,34 @@ +import Root from "./dialog.svelte"; +import Portal from "./dialog-portal.svelte"; +import Title from "./dialog-title.svelte"; +import Footer from "./dialog-footer.svelte"; +import Header from "./dialog-header.svelte"; +import Overlay from "./dialog-overlay.svelte"; +import Content from "./dialog-content.svelte"; +import Description from "./dialog-description.svelte"; +import Trigger from "./dialog-trigger.svelte"; +import Close from "./dialog-close.svelte"; + +export { + Root, + Title, + Portal, + Footer, + Header, + Trigger, + Overlay, + Content, + Description, + Close, + // + Root as Dialog, + Title as DialogTitle, + Portal as DialogPortal, + Footer as DialogFooter, + Header as DialogHeader, + Trigger as DialogTrigger, + Overlay as DialogOverlay, + Content as DialogContent, + Description as DialogDescription, + Close as DialogClose, +}; diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte new file mode 100644 index 0000000..442ee4f --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte @@ -0,0 +1,16 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte new file mode 100644 index 0000000..319b15d --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte @@ -0,0 +1,46 @@ + + + + {#snippet children({ + checked, + indeterminate, + })} + + {#if indeterminate} + + {:else} + + {/if} + + {@render childrenProp?.()} + {/snippet} + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte new file mode 100644 index 0000000..ee559c2 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte @@ -0,0 +1,31 @@ + + + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte new file mode 100644 index 0000000..a47760f --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte @@ -0,0 +1,25 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte new file mode 100644 index 0000000..2473b77 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte @@ -0,0 +1,14 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte new file mode 100644 index 0000000..94138ae --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte @@ -0,0 +1,28 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte new file mode 100644 index 0000000..92bfb38 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte @@ -0,0 +1,27 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte new file mode 100644 index 0000000..f9e1e2a --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte new file mode 100644 index 0000000..d4bbe25 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte @@ -0,0 +1,16 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte new file mode 100644 index 0000000..14cf302 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte @@ -0,0 +1,35 @@ + + + + {#snippet children({ + checked, + })} + + {#if checked} + + {/if} + + {@render childrenProp?.({ checked })} + {/snippet} + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte new file mode 100644 index 0000000..2c18432 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte new file mode 100644 index 0000000..e3f7567 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte @@ -0,0 +1,23 @@ + + + + {@render children?.()} + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte new file mode 100644 index 0000000..0ac92c0 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte @@ -0,0 +1,20 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte new file mode 100644 index 0000000..016e670 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte @@ -0,0 +1,29 @@ + + + + {@render children?.()} + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte new file mode 100644 index 0000000..2ab8a41 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte @@ -0,0 +1,10 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte new file mode 100644 index 0000000..a52fb99 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte @@ -0,0 +1,14 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte b/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte new file mode 100644 index 0000000..40b84e0 --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte @@ -0,0 +1,10 @@ + + + diff --git a/src/lib/components/ui/dropdown-menu/index.ts b/src/lib/components/ui/dropdown-menu/index.ts new file mode 100644 index 0000000..5c4fe0c --- /dev/null +++ b/src/lib/components/ui/dropdown-menu/index.ts @@ -0,0 +1,54 @@ +import Root from "./dropdown-menu.svelte"; +import Sub from "./dropdown-menu-sub.svelte"; +import CheckboxGroup from "./dropdown-menu-checkbox-group.svelte"; +import CheckboxItem from "./dropdown-menu-checkbox-item.svelte"; +import Content from "./dropdown-menu-content.svelte"; +import Group from "./dropdown-menu-group.svelte"; +import Item from "./dropdown-menu-item.svelte"; +import Label from "./dropdown-menu-label.svelte"; +import RadioGroup from "./dropdown-menu-radio-group.svelte"; +import RadioItem from "./dropdown-menu-radio-item.svelte"; +import Separator from "./dropdown-menu-separator.svelte"; +import Shortcut from "./dropdown-menu-shortcut.svelte"; +import Trigger from "./dropdown-menu-trigger.svelte"; +import SubContent from "./dropdown-menu-sub-content.svelte"; +import SubTrigger from "./dropdown-menu-sub-trigger.svelte"; +import GroupHeading from "./dropdown-menu-group-heading.svelte"; +import Portal from "./dropdown-menu-portal.svelte"; + +export { + CheckboxGroup, + CheckboxItem, + Content, + Portal, + Root as DropdownMenu, + CheckboxGroup as DropdownMenuCheckboxGroup, + CheckboxItem as DropdownMenuCheckboxItem, + Content as DropdownMenuContent, + Portal as DropdownMenuPortal, + Group as DropdownMenuGroup, + Item as DropdownMenuItem, + Label as DropdownMenuLabel, + RadioGroup as DropdownMenuRadioGroup, + RadioItem as DropdownMenuRadioItem, + Separator as DropdownMenuSeparator, + Shortcut as DropdownMenuShortcut, + Sub as DropdownMenuSub, + SubContent as DropdownMenuSubContent, + SubTrigger as DropdownMenuSubTrigger, + Trigger as DropdownMenuTrigger, + GroupHeading as DropdownMenuGroupHeading, + Group, + GroupHeading, + Item, + Label, + RadioGroup, + RadioItem, + Root, + Separator, + Shortcut, + Sub, + SubContent, + SubTrigger, + Trigger, +}; diff --git a/src/lib/components/ui/input/index.ts b/src/lib/components/ui/input/index.ts new file mode 100644 index 0000000..ceb4b16 --- /dev/null +++ b/src/lib/components/ui/input/index.ts @@ -0,0 +1,7 @@ +import Root from "./input.svelte"; + +export { + Root, + // + Root as Input, +}; diff --git a/src/lib/components/ui/input/input.svelte b/src/lib/components/ui/input/input.svelte new file mode 100644 index 0000000..7e2715b --- /dev/null +++ b/src/lib/components/ui/input/input.svelte @@ -0,0 +1,54 @@ + + +{#if type === "file"} + +{:else} + +{/if} diff --git a/src/lib/components/ui/label/index.ts b/src/lib/components/ui/label/index.ts new file mode 100644 index 0000000..0a67dab --- /dev/null +++ b/src/lib/components/ui/label/index.ts @@ -0,0 +1,3 @@ +import Label from "./label.svelte"; + +export { Label }; diff --git a/src/lib/components/ui/label/label.svelte b/src/lib/components/ui/label/label.svelte new file mode 100644 index 0000000..3775e58 --- /dev/null +++ b/src/lib/components/ui/label/label.svelte @@ -0,0 +1,27 @@ + + + + {@render children?.()} + diff --git a/src/lib/components/ui/progress/index.ts b/src/lib/components/ui/progress/index.ts new file mode 100644 index 0000000..1e415fc --- /dev/null +++ b/src/lib/components/ui/progress/index.ts @@ -0,0 +1,7 @@ +import Root from "./progress.svelte"; + +export { + Root, + // + Root as Progress, +}; diff --git a/src/lib/components/ui/progress/progress.svelte b/src/lib/components/ui/progress/progress.svelte new file mode 100644 index 0000000..ac3a563 --- /dev/null +++ b/src/lib/components/ui/progress/progress.svelte @@ -0,0 +1,30 @@ + + + +
+
diff --git a/src/lib/components/ui/select/index.ts b/src/lib/components/ui/select/index.ts new file mode 100644 index 0000000..222d568 --- /dev/null +++ b/src/lib/components/ui/select/index.ts @@ -0,0 +1,37 @@ +import Root from "./select.svelte"; +import Group from "./select-group.svelte"; +import Label from "./select-label.svelte"; +import Item from "./select-item.svelte"; +import Content from "./select-content.svelte"; +import Trigger from "./select-trigger.svelte"; +import Separator from "./select-separator.svelte"; +import ScrollDownButton from "./select-scroll-down-button.svelte"; +import ScrollUpButton from "./select-scroll-up-button.svelte"; +import GroupHeading from "./select-group-heading.svelte"; +import Portal from "./select-portal.svelte"; + +export { + Root, + Group, + Label, + Item, + Content, + Trigger, + Separator, + ScrollDownButton, + ScrollUpButton, + GroupHeading, + Portal, + // + Root as Select, + Group as SelectGroup, + Label as SelectLabel, + Item as SelectItem, + Content as SelectContent, + Trigger as SelectTrigger, + Separator as SelectSeparator, + ScrollDownButton as SelectScrollDownButton, + ScrollUpButton as SelectScrollUpButton, + GroupHeading as SelectGroupHeading, + Portal as SelectPortal, +}; diff --git a/src/lib/components/ui/select/select-content.svelte b/src/lib/components/ui/select/select-content.svelte new file mode 100644 index 0000000..d47b90a --- /dev/null +++ b/src/lib/components/ui/select/select-content.svelte @@ -0,0 +1,45 @@ + + + + + + + {@render children?.()} + + + + diff --git a/src/lib/components/ui/select/select-group-heading.svelte b/src/lib/components/ui/select/select-group-heading.svelte new file mode 100644 index 0000000..4c9be11 --- /dev/null +++ b/src/lib/components/ui/select/select-group-heading.svelte @@ -0,0 +1,24 @@ + + + + {@render children?.()} + diff --git a/src/lib/components/ui/select/select-group.svelte b/src/lib/components/ui/select/select-group.svelte new file mode 100644 index 0000000..d7d49b1 --- /dev/null +++ b/src/lib/components/ui/select/select-group.svelte @@ -0,0 +1,8 @@ + + + diff --git a/src/lib/components/ui/select/select-item.svelte b/src/lib/components/ui/select/select-item.svelte new file mode 100644 index 0000000..46b7877 --- /dev/null +++ b/src/lib/components/ui/select/select-item.svelte @@ -0,0 +1,41 @@ + + + + {#snippet children({ + selected, + highlighted, + })} + + {#if selected} + + {/if} + + {#if childrenProp} + {@render childrenProp({ selected, highlighted })} + {:else} + {label || value} + {/if} + {/snippet} + diff --git a/src/lib/components/ui/select/select-label.svelte b/src/lib/components/ui/select/select-label.svelte new file mode 100644 index 0000000..e7c9633 --- /dev/null +++ b/src/lib/components/ui/select/select-label.svelte @@ -0,0 +1,23 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/select/select-portal.svelte b/src/lib/components/ui/select/select-portal.svelte new file mode 100644 index 0000000..de6004b --- /dev/null +++ b/src/lib/components/ui/select/select-portal.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/select/select-scroll-down-button.svelte b/src/lib/components/ui/select/select-scroll-down-button.svelte new file mode 100644 index 0000000..8724ce0 --- /dev/null +++ b/src/lib/components/ui/select/select-scroll-down-button.svelte @@ -0,0 +1,23 @@ + + + + + diff --git a/src/lib/components/ui/select/select-scroll-up-button.svelte b/src/lib/components/ui/select/select-scroll-up-button.svelte new file mode 100644 index 0000000..f4984e3 --- /dev/null +++ b/src/lib/components/ui/select/select-scroll-up-button.svelte @@ -0,0 +1,23 @@ + + + + + diff --git a/src/lib/components/ui/select/select-separator.svelte b/src/lib/components/ui/select/select-separator.svelte new file mode 100644 index 0000000..f0e1439 --- /dev/null +++ b/src/lib/components/ui/select/select-separator.svelte @@ -0,0 +1,21 @@ + + + diff --git a/src/lib/components/ui/select/select-trigger.svelte b/src/lib/components/ui/select/select-trigger.svelte new file mode 100644 index 0000000..77abd88 --- /dev/null +++ b/src/lib/components/ui/select/select-trigger.svelte @@ -0,0 +1,29 @@ + + + + {@render children?.()} + + diff --git a/src/lib/components/ui/select/select.svelte b/src/lib/components/ui/select/select.svelte new file mode 100644 index 0000000..e5fb6b2 --- /dev/null +++ b/src/lib/components/ui/select/select.svelte @@ -0,0 +1,11 @@ + + + diff --git a/src/lib/components/ui/separator/index.ts b/src/lib/components/ui/separator/index.ts new file mode 100644 index 0000000..d66644e --- /dev/null +++ b/src/lib/components/ui/separator/index.ts @@ -0,0 +1,7 @@ +import Root from "./separator.svelte"; + +export { + Root, + // + Root as Separator, +}; diff --git a/src/lib/components/ui/separator/separator.svelte b/src/lib/components/ui/separator/separator.svelte new file mode 100644 index 0000000..7aafcd5 --- /dev/null +++ b/src/lib/components/ui/separator/separator.svelte @@ -0,0 +1,21 @@ + + + diff --git a/src/lib/components/ui/sheet/index.ts b/src/lib/components/ui/sheet/index.ts new file mode 100644 index 0000000..c779a6e --- /dev/null +++ b/src/lib/components/ui/sheet/index.ts @@ -0,0 +1,34 @@ +import Root from "./sheet.svelte"; +import Portal from "./sheet-portal.svelte"; +import Trigger from "./sheet-trigger.svelte"; +import Close from "./sheet-close.svelte"; +import Overlay from "./sheet-overlay.svelte"; +import Content from "./sheet-content.svelte"; +import Header from "./sheet-header.svelte"; +import Footer from "./sheet-footer.svelte"; +import Title from "./sheet-title.svelte"; +import Description from "./sheet-description.svelte"; + +export { + Root, + Close, + Trigger, + Portal, + Overlay, + Content, + Header, + Footer, + Title, + Description, + // + Root as Sheet, + Close as SheetClose, + Trigger as SheetTrigger, + Portal as SheetPortal, + Overlay as SheetOverlay, + Content as SheetContent, + Header as SheetHeader, + Footer as SheetFooter, + Title as SheetTitle, + Description as SheetDescription, +}; diff --git a/src/lib/components/ui/sheet/sheet-close.svelte b/src/lib/components/ui/sheet/sheet-close.svelte new file mode 100644 index 0000000..3edf368 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-close.svelte @@ -0,0 +1,8 @@ + + + diff --git a/src/lib/components/ui/sheet/sheet-content.svelte b/src/lib/components/ui/sheet/sheet-content.svelte new file mode 100644 index 0000000..8db01fd --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-content.svelte @@ -0,0 +1,62 @@ + + + + + + + + {@render children?.()} + + + Закрыть + + + diff --git a/src/lib/components/ui/sheet/sheet-description.svelte b/src/lib/components/ui/sheet/sheet-description.svelte new file mode 100644 index 0000000..aff2a7e --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-description.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/sheet/sheet-footer.svelte b/src/lib/components/ui/sheet/sheet-footer.svelte new file mode 100644 index 0000000..cfd1d11 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-footer.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/sheet/sheet-header.svelte b/src/lib/components/ui/sheet/sheet-header.svelte new file mode 100644 index 0000000..12df1f7 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-header.svelte @@ -0,0 +1,20 @@ + + +
+ {@render children?.()} +
diff --git a/src/lib/components/ui/sheet/sheet-overlay.svelte b/src/lib/components/ui/sheet/sheet-overlay.svelte new file mode 100644 index 0000000..8fa17a8 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-overlay.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/sheet/sheet-portal.svelte b/src/lib/components/ui/sheet/sheet-portal.svelte new file mode 100644 index 0000000..27812f0 --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-portal.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/sheet/sheet-title.svelte b/src/lib/components/ui/sheet/sheet-title.svelte new file mode 100644 index 0000000..833997e --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-title.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/sheet/sheet-trigger.svelte b/src/lib/components/ui/sheet/sheet-trigger.svelte new file mode 100644 index 0000000..417d73f --- /dev/null +++ b/src/lib/components/ui/sheet/sheet-trigger.svelte @@ -0,0 +1,8 @@ + + + diff --git a/src/lib/components/ui/sheet/sheet.svelte b/src/lib/components/ui/sheet/sheet.svelte new file mode 100644 index 0000000..40537ae --- /dev/null +++ b/src/lib/components/ui/sheet/sheet.svelte @@ -0,0 +1,8 @@ + + + diff --git a/src/lib/components/ui/slider/index.ts b/src/lib/components/ui/slider/index.ts new file mode 100644 index 0000000..b3c90f9 --- /dev/null +++ b/src/lib/components/ui/slider/index.ts @@ -0,0 +1,7 @@ +import Root from "./slider.svelte"; + +export { + Root, + // + Root as Slider, +}; diff --git a/src/lib/components/ui/slider/slider.svelte b/src/lib/components/ui/slider/slider.svelte new file mode 100644 index 0000000..559acd7 --- /dev/null +++ b/src/lib/components/ui/slider/slider.svelte @@ -0,0 +1,54 @@ + + + + + {#snippet children({ + thumbs, + })} + + + + {#each thumbs as thumb (thumb)} + + {/each} + {/snippet} + diff --git a/src/lib/components/ui/sonner/index.ts b/src/lib/components/ui/sonner/index.ts new file mode 100644 index 0000000..1ad9f4a --- /dev/null +++ b/src/lib/components/ui/sonner/index.ts @@ -0,0 +1 @@ +export { default as Toaster } from "./sonner.svelte"; diff --git a/src/lib/components/ui/sonner/sonner.svelte b/src/lib/components/ui/sonner/sonner.svelte new file mode 100644 index 0000000..51bf42c --- /dev/null +++ b/src/lib/components/ui/sonner/sonner.svelte @@ -0,0 +1,55 @@ + + +{#snippet loadingIcon()} + + {/snippet} + {#snippet successIcon()} + + {/snippet} + {#snippet errorIcon()} + + {/snippet} + {#snippet infoIcon()} + + {/snippet} + {#snippet warningIcon()} + + {/snippet} + diff --git a/src/lib/components/ui/surface/index.ts b/src/lib/components/ui/surface/index.ts new file mode 100644 index 0000000..de74349 --- /dev/null +++ b/src/lib/components/ui/surface/index.ts @@ -0,0 +1,5 @@ +import Root from "./surface.svelte"; +import Cut from "./surface-cut.svelte"; + +export { Root, Cut, Root as Surface, Cut as SurfaceCut }; +export type { SurfaceProps, SurfaceVariant } from "./surface.svelte"; diff --git a/src/lib/components/ui/surface/surface-cut.svelte b/src/lib/components/ui/surface/surface-cut.svelte new file mode 100644 index 0000000..5ca6061 --- /dev/null +++ b/src/lib/components/ui/surface/surface-cut.svelte @@ -0,0 +1,38 @@ + + + + + {@render children?.()} + diff --git a/src/lib/components/ui/surface/surface.svelte b/src/lib/components/ui/surface/surface.svelte new file mode 100644 index 0000000..5a53fdd --- /dev/null +++ b/src/lib/components/ui/surface/surface.svelte @@ -0,0 +1,66 @@ + + + + + + + {@render children?.()} + diff --git a/src/lib/components/ui/switch/index.ts b/src/lib/components/ui/switch/index.ts new file mode 100644 index 0000000..99620eb --- /dev/null +++ b/src/lib/components/ui/switch/index.ts @@ -0,0 +1,7 @@ +import Root from "./switch.svelte"; + +export { + Root, + // + Root as Switch, +}; diff --git a/src/lib/components/ui/switch/switch.svelte b/src/lib/components/ui/switch/switch.svelte new file mode 100644 index 0000000..342e547 --- /dev/null +++ b/src/lib/components/ui/switch/switch.svelte @@ -0,0 +1,63 @@ + + + + + {#snippet child({ + props, + })} + + + + + + + + {/snippet} + + diff --git a/src/lib/components/ui/table/index.ts b/src/lib/components/ui/table/index.ts new file mode 100644 index 0000000..3fe1e39 --- /dev/null +++ b/src/lib/components/ui/table/index.ts @@ -0,0 +1,28 @@ +import Root from "./table.svelte"; +import Body from "./table-body.svelte"; +import Caption from "./table-caption.svelte"; +import Cell from "./table-cell.svelte"; +import Footer from "./table-footer.svelte"; +import Head from "./table-head.svelte"; +import Header from "./table-header.svelte"; +import Row from "./table-row.svelte"; + +export { + Root, + Body, + Caption, + Cell, + Footer, + Head, + Header, + Row, + // + Root as Table, + Body as TableBody, + Caption as TableCaption, + Cell as TableCell, + Footer as TableFooter, + Head as TableHead, + Header as TableHeader, + Row as TableRow, +}; diff --git a/src/lib/components/ui/table/table-body.svelte b/src/lib/components/ui/table/table-body.svelte new file mode 100644 index 0000000..676c4ef --- /dev/null +++ b/src/lib/components/ui/table/table-body.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/src/lib/components/ui/table/table-caption.svelte b/src/lib/components/ui/table/table-caption.svelte new file mode 100644 index 0000000..10b0f71 --- /dev/null +++ b/src/lib/components/ui/table/table-caption.svelte @@ -0,0 +1,20 @@ + + + + {@render children?.()} + diff --git a/src/lib/components/ui/table/table-cell.svelte b/src/lib/components/ui/table/table-cell.svelte new file mode 100644 index 0000000..487aec1 --- /dev/null +++ b/src/lib/components/ui/table/table-cell.svelte @@ -0,0 +1,23 @@ + + + + {@render children?.()} + diff --git a/src/lib/components/ui/table/table-footer.svelte b/src/lib/components/ui/table/table-footer.svelte new file mode 100644 index 0000000..488de35 --- /dev/null +++ b/src/lib/components/ui/table/table-footer.svelte @@ -0,0 +1,23 @@ + + +tr]:last:border-b-0", + className + )} + {...restProps} +> + {@render children?.()} + diff --git a/src/lib/components/ui/table/table-head.svelte b/src/lib/components/ui/table/table-head.svelte new file mode 100644 index 0000000..e666755 --- /dev/null +++ b/src/lib/components/ui/table/table-head.svelte @@ -0,0 +1,23 @@ + + + + {@render children?.()} + diff --git a/src/lib/components/ui/table/table-header.svelte b/src/lib/components/ui/table/table-header.svelte new file mode 100644 index 0000000..5642919 --- /dev/null +++ b/src/lib/components/ui/table/table-header.svelte @@ -0,0 +1,23 @@ + + + + {@render children?.()} + diff --git a/src/lib/components/ui/table/table-row.svelte b/src/lib/components/ui/table/table-row.svelte new file mode 100644 index 0000000..877f890 --- /dev/null +++ b/src/lib/components/ui/table/table-row.svelte @@ -0,0 +1,23 @@ + + +svelte-css-wrapper]:[&>th,td]:bg-cladd-surface-hover", + className + )} + {...restProps} +> + {@render children?.()} + diff --git a/src/lib/components/ui/table/table.svelte b/src/lib/components/ui/table/table.svelte new file mode 100644 index 0000000..b392c69 --- /dev/null +++ b/src/lib/components/ui/table/table.svelte @@ -0,0 +1,22 @@ + + +
+ + {@render children?.()} +
+
diff --git a/src/lib/components/ui/tabs/index.ts b/src/lib/components/ui/tabs/index.ts new file mode 100644 index 0000000..4c728b6 --- /dev/null +++ b/src/lib/components/ui/tabs/index.ts @@ -0,0 +1,16 @@ +import Root from "./tabs.svelte"; +import Content from "./tabs-content.svelte"; +import List from "./tabs-list.svelte"; +import Trigger from "./tabs-trigger.svelte"; + +export { + Root, + Content, + List, + Trigger, + // + Root as Tabs, + Content as TabsContent, + List as TabsList, + Trigger as TabsTrigger, +}; diff --git a/src/lib/components/ui/tabs/tabs-content.svelte b/src/lib/components/ui/tabs/tabs-content.svelte new file mode 100644 index 0000000..8233c31 --- /dev/null +++ b/src/lib/components/ui/tabs/tabs-content.svelte @@ -0,0 +1,17 @@ + + + diff --git a/src/lib/components/ui/tabs/tabs-list.svelte b/src/lib/components/ui/tabs/tabs-list.svelte new file mode 100644 index 0000000..2549dfa --- /dev/null +++ b/src/lib/components/ui/tabs/tabs-list.svelte @@ -0,0 +1,20 @@ + + + diff --git a/src/lib/components/ui/tabs/tabs-trigger.svelte b/src/lib/components/ui/tabs/tabs-trigger.svelte new file mode 100644 index 0000000..43ad6a0 --- /dev/null +++ b/src/lib/components/ui/tabs/tabs-trigger.svelte @@ -0,0 +1,20 @@ + + + diff --git a/src/lib/components/ui/tabs/tabs.svelte b/src/lib/components/ui/tabs/tabs.svelte new file mode 100644 index 0000000..b7d7ae5 --- /dev/null +++ b/src/lib/components/ui/tabs/tabs.svelte @@ -0,0 +1,19 @@ + + + diff --git a/src/lib/components/ui/textarea/index.ts b/src/lib/components/ui/textarea/index.ts new file mode 100644 index 0000000..c14b903 --- /dev/null +++ b/src/lib/components/ui/textarea/index.ts @@ -0,0 +1,7 @@ +import Root from "./textarea.svelte"; + +export { + Root, + // + Root as Textarea, +}; diff --git a/src/lib/components/ui/textarea/textarea.svelte b/src/lib/components/ui/textarea/textarea.svelte new file mode 100644 index 0000000..3c3af54 --- /dev/null +++ b/src/lib/components/ui/textarea/textarea.svelte @@ -0,0 +1,23 @@ + + + diff --git a/src/lib/components/ui/tooltip/index.ts b/src/lib/components/ui/tooltip/index.ts new file mode 100644 index 0000000..9822ce1 --- /dev/null +++ b/src/lib/components/ui/tooltip/index.ts @@ -0,0 +1,19 @@ +import Root from "./tooltip.svelte"; +import Trigger from "./tooltip-trigger.svelte"; +import Content from "./tooltip-content.svelte"; +import Provider from "./tooltip-provider.svelte"; +import Portal from "./tooltip-portal.svelte"; + +export { + Root, + Trigger, + Content, + Provider, + Portal, + // + Root as Tooltip, + Content as TooltipContent, + Trigger as TooltipTrigger, + Provider as TooltipProvider, + Portal as TooltipPortal, +}; diff --git a/src/lib/components/ui/tooltip/tooltip-content.svelte b/src/lib/components/ui/tooltip/tooltip-content.svelte new file mode 100644 index 0000000..f2b5421 --- /dev/null +++ b/src/lib/components/ui/tooltip/tooltip-content.svelte @@ -0,0 +1,35 @@ + + + + + {@render children?.()} + + diff --git a/src/lib/components/ui/tooltip/tooltip-portal.svelte b/src/lib/components/ui/tooltip/tooltip-portal.svelte new file mode 100644 index 0000000..bd0b125 --- /dev/null +++ b/src/lib/components/ui/tooltip/tooltip-portal.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/tooltip/tooltip-provider.svelte b/src/lib/components/ui/tooltip/tooltip-provider.svelte new file mode 100644 index 0000000..1c97e95 --- /dev/null +++ b/src/lib/components/ui/tooltip/tooltip-provider.svelte @@ -0,0 +1,7 @@ + + + diff --git a/src/lib/components/ui/tooltip/tooltip-trigger.svelte b/src/lib/components/ui/tooltip/tooltip-trigger.svelte new file mode 100644 index 0000000..5fac3c6 --- /dev/null +++ b/src/lib/components/ui/tooltip/tooltip-trigger.svelte @@ -0,0 +1,8 @@ + + + diff --git a/src/lib/components/ui/tooltip/tooltip.svelte b/src/lib/components/ui/tooltip/tooltip.svelte new file mode 100644 index 0000000..ccc3719 --- /dev/null +++ b/src/lib/components/ui/tooltip/tooltip.svelte @@ -0,0 +1,8 @@ + + + diff --git a/src/lib/index.ts b/src/lib/index.ts new file mode 100644 index 0000000..0aa8ff8 --- /dev/null +++ b/src/lib/index.ts @@ -0,0 +1,2 @@ +// place files you want to import through the `#lib` alias in this folder. +// biome-ignore-all lint/suspicious/noEmptySource: temporary diff --git a/src/lib/utils.ts b/src/lib/utils.ts new file mode 100644 index 0000000..d706b5e --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,58 @@ +import { type ClassValue, clsx } from "clsx"; +import { extendTailwindMerge } from "tailwind-merge"; + +const cladd = (...names: string[]) => names.map((n) => `cladd-${n}`); + +const twMerge = extendTailwindMerge({ + extend: { + theme: { + radius: cladd( + "3xs", + "2xs", + "xs", + "sm", + "md", + "lg", + "xl", + "2xl", + "wrap-md", + "panel", + "popover", + "dialog", + "toast", + "tooltip" + ), + shadow: cladd("outline", "outline-fill", "cut-outline", "popover"), + spacing: cladd( + "3xs", + "2xs", + "xs", + "sm", + "md", + "lg", + "xl", + "2xl", + "thumb-xs", + "thumb-sm", + "thumb-md", + "nested-sm", + "nested-md", + "nested-lg" + ), + text: cladd("md", "sm", "xs", "2xs", "3xs"), + }, + }, +}); + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} + +export type WithoutChild = T extends { child?: any } ? Omit : T; +export type WithoutChildren = T extends { children?: any } + ? Omit + : T; +export type WithoutChildrenOrChild = WithoutChildren>; +export type WithElementRef = T & { + ref?: U | null; +}; diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte new file mode 100644 index 0000000..c7742e0 --- /dev/null +++ b/src/routes/+layout.svelte @@ -0,0 +1,10 @@ + + + + +{@render children()} diff --git a/src/routes/+layout.ts b/src/routes/+layout.ts new file mode 100644 index 0000000..83addb7 --- /dev/null +++ b/src/routes/+layout.ts @@ -0,0 +1,2 @@ +export const ssr = false; +export const prerender = false; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte new file mode 100644 index 0000000..85a2c65 --- /dev/null +++ b/src/routes/+page.svelte @@ -0,0 +1,13 @@ + + Firefly UI + + +
+

Firefly UI

+

+ Edit + src/routes/+page.svelte. +

+
diff --git a/src/routes/claddcn.css b/src/routes/claddcn.css new file mode 100644 index 0000000..4bf74b7 --- /dev/null +++ b/src/routes/claddcn.css @@ -0,0 +1,922 @@ +/* +claddcn — the cladd.io visual system as a shadcn-svelte theme. +Tokens, surfaces and color math ported from cladd (MIT, © 2026 cladd-ui, +https://github.com/cladd-ui/cladd). Adapted to the shadcn convention: +light on :root, dark under `.dark`. + +Import after tailwindcss: + @import 'tailwindcss'; + @import 'tw-animate-css'; + @import './claddcn.css'; +*/ + +@import "@fontsource-variable/geist/index.css"; +@import "@fontsource-variable/geist-mono/index.css"; + +@property --cladd-overlay { + syntax: ""; + inherits: false; + initial-value: transparent; +} + +/* ───────────────────────── accents ───────────────────────── */ + +:root, +.cladd-color-neutral { + --cladd-theme: #fff; +} +.cladd-color-brand { + --cladd-theme: #388aff; +} +.cladd-color-red { + --cladd-theme: #ff0b0b; +} +.cladd-color-pink { + --cladd-theme: #ff0bac; +} +.cladd-color-purple { + --cladd-theme: #a20bff; +} +.cladd-color-blue { + --cladd-theme: #0047ff; +} +.cladd-color-cyan { + --cladd-theme: #00f9ff; +} +.cladd-color-lime { + --cladd-theme: #7dff0b; +} +.cladd-color-green { + --cladd-theme: #0bff23; +} +.cladd-color-yellow { + --cladd-theme: #fff800; +} +.cladd-color-orange { + --cladd-theme: #ff7a00; +} + +/* ───────────────────────── neutral light ───────────────────────── */ + +:root, +.cladd-color-neutral { + --cladd-bg: #fff; + --cladd-backdrop: oklch(0.91 0 0); + --cladd-primary: oklch(0.1 0 0); + --cladd-on-primary: oklch(0.96 0 0); + --cladd-surface: oklch(0.97 0 0); + --cladd-surface-cut: oklch(0.93 0 0); + --cladd-fg: oklch(0.32 0 0); + --cladd-fg-soft: oklch(0.5 0 0); + --cladd-fg-softer: oklch(0.65 0 0); + --cladd-fg-softest: oklch(0.75 0 0); + --cladd-surface-white: oklch(1 0 0); + --cladd-surface-black: oklch(0 0 0); + --cladd-bg-outline: oklch(0.89 0 0); + --cladd-outline: oklch(0.89 0 0); + --cladd-surface-hover: color-mix( + in oklab, + var(--cladd-surface-black) 3%, + transparent + ); + --cladd-surface-pressed: color-mix( + in oklab, + var(--cladd-surface-white) 6%, + transparent + ); + --cladd-surface-hover-fill: color-mix( + in oklab, + var(--cladd-surface-white) 20%, + transparent + ); + --cladd-surface-mix-color: var(--cladd-surface-black); + --cladd-surface-mix-amount: 4%; + --cladd-highlight-mix: 50%; + --cladd-fill-fade: 20%; + + --shadow-cladd-cut-outline: + 0.5px 0.5px 0px 0px + color-mix(in oklab, var(--cladd-surface-black) 10%, transparent) inset, + 0px 0px 0px 0.5px + color-mix(in oklab, var(--cladd-surface-black) 5%, transparent) inset; + --shadow-cladd-outline-fill: + 0px 0px 0px 0.5px + color-mix(in oklab, var(--cladd-surface-black) 20%, transparent) inset, + 1px 1px 0px 0px + color-mix(in oklab, var(--cladd-surface-white) 30%, transparent) inset; + --shadow-cladd-outline: + 0px 0px 0px 1px var(--color-cladd-outline) inset, + 1.5px 1.5px 0px 0px + color-mix(in oklab, var(--cladd-surface-white) 60%, transparent) inset; + --shadow-cladd-popover: 0 24px 64px -12px rgb(0 0 0 / 0.18); +} + +/* ───────────────────────── neutral dark ───────────────────────── */ + +.dark, +.dark .cladd-color-neutral { + --cladd-bg: #0f0f0f; + --cladd-backdrop: #000; + --cladd-primary: oklch(0.95 0 0); + --cladd-on-primary: oklch(0.2 0 0); + --cladd-surface: oklch(0.21 0 0); + --cladd-surface-cut: oklch(0.19 0 0); + --cladd-fg: oklch(0.9 0 0); + --cladd-fg-soft: oklch(0.65 0 0); + --cladd-fg-softer: oklch(0.5 0 0); + --cladd-fg-softest: oklch(0.4 0 0); + --cladd-surface-white: oklch(1 0 0); + --cladd-surface-black: oklch(0 0 0); + --cladd-bg-outline: oklch(0.23 0 0); + --cladd-outline: oklch(0.3 0 0); + --cladd-surface-hover: color-mix( + in oklab, + var(--cladd-surface-white) 5%, + transparent + ); + --cladd-surface-pressed: color-mix( + in oklab, + var(--cladd-surface-white) 3%, + transparent + ); + --cladd-surface-hover-fill: color-mix( + in oklab, + var(--cladd-surface-white) 20%, + transparent + ); + --cladd-surface-mix-color: var(--cladd-surface-white); + --cladd-surface-mix-amount: 6%; + --cladd-highlight-mix: 3%; + --cladd-fill-fade: 15%; + + --shadow-cladd-cut-outline: + -1px -1px 0px 0px + color-mix(in oklab, var(--cladd-surface-white) 2%, transparent) inset, + 0px 0px 0px 1px + color-mix(in oklab, var(--cladd-surface-white) 7%, transparent) inset; + --shadow-cladd-outline: + 1px 1px 0px 0px + color-mix(in oklab, var(--cladd-surface-white) 8%, transparent) inset, + -1px -1px 0px 0px + color-mix(in oklab, var(--cladd-surface-white) 7%, transparent) inset; + --shadow-cladd-outline-fill: + 1px 1px 0px 0px + color-mix(in oklab, var(--cladd-surface-white) 20%, transparent) inset, + -1px -1px 0px 0px + color-mix(in oklab, var(--cladd-surface-white) 20%, transparent) inset; + --shadow-cladd-popover: 0 24px 64px -12px rgb(0 0 0 / 0.5); +} + +/* ───────────────────────── colored light ───────────────────────── */ + +[class*="cladd-color-"]:not(.cladd-color-neutral) { + --cladd-bg: oklch(from var(--cladd-theme) 1 0.015 h); + --cladd-backdrop: oklch(0.74 0.018 100); + --cladd-primary: oklch(from var(--cladd-theme) 0.5 0.18 h); + --cladd-on-primary: oklch(from var(--cladd-theme) 0.97 0.04 h); + --cladd-surface: oklch(from var(--cladd-theme) 0.97 0.015 h); + --cladd-surface-cut: oklch(from var(--cladd-theme) 0.93 0.02 h); + --cladd-fg: oklch(from var(--cladd-theme) 0.25 0.015 h); + --cladd-fg-soft: oklch(from var(--cladd-theme) 0.5 0.025 h); + --cladd-fg-softer: oklch(from var(--cladd-theme) 0.65 0.025 h); + --cladd-fg-softest: oklch(from var(--cladd-theme) 0.75 0.025 h); + --cladd-surface-white: oklch(from var(--cladd-theme) 0.98 0.04 h); + --cladd-surface-black: oklch(from var(--cladd-theme) 0.4 0.07 h); + --cladd-bg-outline: oklch(from var(--cladd-theme) 0.74 0.03 h); + --cladd-outline: oklch(from var(--cladd-theme) 0.88 0.025 h); + --cladd-surface-hover: color-mix( + in oklab, + var(--cladd-surface-black) 6%, + transparent + ); + --cladd-surface-hover-fill: color-mix( + in oklab, + var(--cladd-surface-white) 10%, + transparent + ); + --cladd-surface-pressed: color-mix( + in oklab, + var(--cladd-surface-white) 6%, + transparent + ); + --cladd-surface-mix-amount: 5%; + --cladd-surface-mix-color: var(--cladd-surface-black); + + --shadow-cladd-cut-outline: + 0.5px 0.5px 0px 0px + color-mix(in oklab, var(--cladd-surface-black) 10%, transparent) inset, + 0px 0px 0px 0.5px + color-mix(in oklab, var(--cladd-surface-black) 5%, transparent) inset; + --shadow-cladd-outline-fill: + 0px 0px 0px 1px + color-mix(in oklab, var(--cladd-surface-black) 40%, transparent) inset, + 1px 1px 0px 0.25px + color-mix(in oklab, var(--cladd-surface-white) 30%, transparent) inset; + --shadow-cladd-outline: + 0px 0px 0px 1px var(--color-cladd-outline) inset, + 1.5px 1.5px 0px 0px + color-mix(in oklab, var(--cladd-surface-white) 80%, transparent) inset; +} + +/* ───────────────────────── colored dark ───────────────────────── */ + +.dark [class*="cladd-color-"]:not(.cladd-color-neutral), +.dark[class*="cladd-color-"]:not(.cladd-color-neutral) { + --cladd-bg: oklch(from var(--cladd-theme) 0.18 0.02 h); + --cladd-backdrop: #000; + --cladd-primary: oklch(from var(--cladd-theme) 0.95 0.18 h); + --cladd-on-primary: oklch(from var(--cladd-theme) 0.2 0.05 h); + --cladd-surface: oklch(from var(--cladd-theme) 0.23 0.027 h); + --cladd-surface-cut: oklch(from var(--cladd-theme) 0.19 0.027 h); + --cladd-fg: oklch(from var(--cladd-theme) 0.9 0.04 h); + --cladd-fg-soft: oklch(from var(--cladd-theme) 0.65 0.04 h); + --cladd-fg-softer: oklch(from var(--cladd-theme) 0.5 0.04 h); + --cladd-fg-softest: oklch(from var(--cladd-theme) 0.4 0.04 h); + --cladd-surface-white: oklch(from var(--cladd-theme) 0.92 0.05 h); + --cladd-surface-black: oklch(from var(--cladd-theme) 0.08 0.02 h); + --cladd-bg-outline: oklch(from var(--cladd-theme) 0.25 0.02 h); + --cladd-outline: oklch(from var(--cladd-theme) 0.28 0.025 h); + --cladd-surface-hover: color-mix( + in oklab, + var(--cladd-surface-white) 5%, + transparent + ); + --cladd-surface-pressed: color-mix( + in oklab, + var(--cladd-surface-white) 3%, + transparent + ); + --cladd-surface-hover-fill: color-mix( + in oklab, + var(--cladd-surface-white) 40%, + transparent + ); + --cladd-surface-mix-color: var(--cladd-surface-white); + --cladd-surface-mix-amount: 6%; + + --shadow-cladd-cut-outline: + -1px -1px 0px 0px + color-mix(in oklab, var(--cladd-surface-white) 2%, transparent) inset, + 0px 0px 0px 1px + color-mix(in oklab, var(--cladd-surface-white) 7%, transparent) inset; + --shadow-cladd-outline: + 1px 1px 0px 0px + color-mix(in oklab, var(--cladd-surface-white) 8%, transparent) inset, + -1px -1px 0px 0px + color-mix(in oklab, var(--cladd-surface-white) 7%, transparent) inset; + --shadow-cladd-outline-fill: + 1px 1px 0px 0px + color-mix(in oklab, var(--cladd-surface-white) 30%, transparent) inset, + -1px -1px 0px 0px + color-mix(in oklab, var(--cladd-surface-white) 30%, transparent) inset; +} + +/* ───────────────────────── surface levels ───────────────────────── +Every .cladd-surface nested inside another bumps one level (up to 5), the same +auto-nesting cladd does with React context, done here with selector depth. */ + +.cladd-surface { + --cladd-surface-multiplier: 0; +} +.cladd-surface .cladd-surface { + --cladd-surface-multiplier: 1; +} +.cladd-surface .cladd-surface .cladd-surface { + --cladd-surface-multiplier: 2; +} +.cladd-surface .cladd-surface .cladd-surface .cladd-surface { + --cladd-surface-multiplier: 3; +} +.cladd-surface .cladd-surface .cladd-surface .cladd-surface .cladd-surface { + --cladd-surface-multiplier: 4; +} +.cladd-level-1.cladd-level-1.cladd-level-1.cladd-level-1.cladd-level-1.cladd-level-1 { + --cladd-surface-multiplier: 0; +} +.cladd-level-2.cladd-level-2.cladd-level-2.cladd-level-2.cladd-level-2.cladd-level-2 { + --cladd-surface-multiplier: 1; +} +.cladd-level-3.cladd-level-3.cladd-level-3.cladd-level-3.cladd-level-3.cladd-level-3 { + --cladd-surface-multiplier: 2; +} +.cladd-level-4.cladd-level-4.cladd-level-4.cladd-level-4.cladd-level-4.cladd-level-4 { + --cladd-surface-multiplier: 3; +} +.cladd-level-5.cladd-level-5.cladd-level-5.cladd-level-5.cladd-level-5.cladd-level-5 { + --cladd-surface-multiplier: 4; +} + +:root, +.dark, +.cladd-surface, +.cladd-cut, +[class*="cladd-level-"], +[class*="cladd-color-"] { + --cladd-step: calc( + var(--cladd-surface-mix-amount) * + var(--cladd-surface-multiplier, 0) + ); + --color-cladd-bg: var(--cladd-bg); + --color-cladd-backdrop: var(--cladd-backdrop); + --color-cladd-primary: var(--cladd-primary); + --color-cladd-on-primary: var(--cladd-on-primary); + --color-cladd-surface-white: var(--cladd-surface-white); + --color-cladd-surface-black: var(--cladd-surface-black); + --color-cladd-surface-hover: var(--cladd-surface-hover); + --color-cladd-surface-hover-fill: var(--cladd-surface-hover-fill); + --color-cladd-surface-pressed: var(--cladd-surface-pressed); + --color-cladd-bg-outline: var(--cladd-bg-outline); + --color-cladd-surface: color-mix( + in oklab, + var(--cladd-surface-mix-color) var(--cladd-step), + var(--cladd-surface) + ); + --color-cladd-surface-prev: color-mix( + in oklab, + var(--cladd-surface-mix-color) + calc( + var(--cladd-surface-mix-amount) * + (var(--cladd-surface-multiplier, 0) - 1) + ), + var(--cladd-surface) + ); + --color-cladd-surface-next: color-mix( + in oklab, + var(--cladd-surface-mix-color) + calc( + var(--cladd-surface-mix-amount) * + (var(--cladd-surface-multiplier, 0) + 1) + ), + var(--cladd-surface) + ); + --color-cladd-surface-cut: color-mix( + in oklab, + var(--cladd-surface-mix-color) var(--cladd-step), + var(--cladd-surface-cut) + ); + --color-cladd-outline: color-mix( + in oklab, + var(--cladd-surface-mix-color) var(--cladd-step), + var(--cladd-outline) + ); + --color-cladd-fg: var(--cladd-fg); + --color-cladd-fg-soft: color-mix( + in oklab, + var(--cladd-surface-mix-color) var(--cladd-step), + var(--cladd-fg-soft) + ); + --color-cladd-fg-softer: color-mix( + in oklab, + var(--cladd-surface-mix-color) var(--cladd-step), + var(--cladd-fg-softer) + ); + --color-cladd-fg-softest: color-mix( + in oklab, + var(--cladd-surface-mix-color) var(--cladd-step), + var(--cladd-fg-softest) + ); + --color-cladd-surface-highlight: color-mix( + in oklab, + var(--cladd-surface-white) var(--cladd-highlight-mix), + var(--color-cladd-surface) + ); +} + +/* ───────────────────────── tailwind tokens ───────────────────────── */ + +@theme { + --color-cladd-bg: var(--cladd-bg); + --color-cladd-backdrop: var(--cladd-backdrop); + --color-cladd-primary: var(--cladd-primary); + --color-cladd-on-primary: var(--cladd-on-primary); + --color-cladd-surface: var(--cladd-surface); + --color-cladd-surface-cut: var(--cladd-surface-cut); + --color-cladd-surface-prev: var(--cladd-surface); + --color-cladd-surface-next: var(--cladd-surface); + --color-cladd-surface-highlight: var(--cladd-surface); + --color-cladd-surface-white: var(--cladd-surface-white); + --color-cladd-surface-black: var(--cladd-surface-black); + --color-cladd-surface-hover: var(--cladd-surface-hover); + --color-cladd-surface-hover-fill: var(--cladd-surface-hover-fill); + --color-cladd-surface-pressed: var(--cladd-surface-pressed); + --color-cladd-fg: var(--cladd-fg); + --color-cladd-fg-soft: var(--cladd-fg-soft); + --color-cladd-fg-softer: var(--cladd-fg-softer); + --color-cladd-fg-softest: var(--cladd-fg-softest); + --color-cladd-bg-outline: var(--cladd-bg-outline); + --color-cladd-outline: var(--cladd-outline); + + --shadow-cladd-outline: var(--shadow-cladd-outline); + --shadow-cladd-outline-fill: var(--shadow-cladd-outline-fill); + --shadow-cladd-cut-outline: var(--shadow-cladd-cut-outline); + --shadow-cladd-popover: var(--shadow-cladd-popover); + + --spacing-cladd-3xs: 12px; + --spacing-cladd-2xs: 16px; + --spacing-cladd-xs: 20px; + --spacing-cladd-sm: 24px; + --spacing-cladd-md: 28px; + --spacing-cladd-lg: 32px; + --spacing-cladd-xl: 40px; + --spacing-cladd-2xl: 48px; + --spacing-cladd-thumb-xs: 16px; + --spacing-cladd-thumb-sm: 20px; + --spacing-cladd-thumb-md: 24px; + --spacing-cladd-nested-sm: 16px; + --spacing-cladd-nested-md: 20px; + --spacing-cladd-nested-lg: 24px; + + --cladd-radius: 8px; + --radius-cladd: var(--cladd-radius); + --radius-cladd-3xs: calc(var(--cladd-radius) * 12 / 28); + --radius-cladd-2xs: calc(var(--cladd-radius) * 16 / 28); + --radius-cladd-xs: calc(var(--cladd-radius) * 20 / 28); + --radius-cladd-sm: calc(var(--cladd-radius) * 24 / 28); + --radius-cladd-md: var(--cladd-radius); + --radius-cladd-lg: calc(var(--cladd-radius) * 32 / 28); + --radius-cladd-xl: calc(var(--cladd-radius) * 40 / 28); + --radius-cladd-2xl: calc(var(--cladd-radius) * 48 / 28); + --radius-cladd-wrap-md: calc(var(--cladd-radius) + 4px); + --radius-cladd-panel: 24px; + --radius-cladd-popover: 24px; + --radius-cladd-dialog: 24px; + --radius-cladd-toast: 24px; + --radius-cladd-tooltip: 12px; + + --text-cladd-md: 16px; + --text-cladd-sm: 14px; + --text-cladd-xs: 12px; + --text-cladd-2xs: 10px; + --text-cladd-3xs: 8px; + + --ease-cladd-spring: cubic-bezier(0, 1, 0.2, 1.1); + --ease-cladd-pop: cubic-bezier(0, 1, 0, 1.025); + --animate-cladd-spinner: cladd-spinner 1.5s infinite linear; + + @keyframes cladd-spinner { + to { + transform: rotate(360deg); + } + } +} + +/* ───────────────────────── shadcn mapping ───────────────────────── +Every shadcn-svelte token resolves to a cladd token, so plain shadcn markup +(bg-card, text-muted-foreground, border…) picks up the cladd palette too. */ + +:root { + --radius: 8px; + --background: var(--cladd-bg); + --foreground: var(--cladd-fg); + --card: var(--cladd-surface); + --card-foreground: var(--cladd-fg); + --popover: color-mix( + in oklab, + var(--cladd-surface-white) 50%, + var(--cladd-surface) + ); + --popover-foreground: var(--cladd-fg); + --primary: var(--cladd-primary); + --primary-foreground: var(--cladd-on-primary); + --secondary: var(--cladd-surface); + --secondary-foreground: var(--cladd-fg); + --muted: var(--cladd-surface-cut); + --muted-foreground: var(--cladd-fg-soft); + --accent: color-mix( + in oklab, + var(--cladd-surface-mix-color) var(--cladd-surface-mix-amount), + var(--cladd-surface) + ); + --accent-foreground: var(--cladd-fg); + --border: var(--cladd-bg-outline); + --input: var(--cladd-outline); + + --brand: oklch(from #388aff 0.5 0.18 h); + --brand-foreground: oklch(from #388aff 0.97 0.04 h); + --brand-soft: oklch(from #388aff 0.95 0.03 h); + --destructive: oklch(from #ff0b0b 0.55 0.2 h); + --destructive-foreground: oklch(from #ff0b0b 0.97 0.04 h); + --success: oklch(from #0bff23 0.5 0.15 h); + --success-soft: oklch(from #0bff23 0.95 0.04 h); + --warning: oklch(from #ff7a00 0.58 0.15 h); + --warning-soft: oklch(from #fff800 0.96 0.05 h); + --ring: var(--brand); + + --chart-1: var(--brand); + --chart-2: var(--success); + --chart-3: var(--cladd-fg-soft); + --chart-4: oklch(from #00f9ff 0.6 0.12 h); + --chart-5: var(--destructive); + + --sidebar: var(--cladd-surface); + --sidebar-foreground: var(--cladd-fg); + --sidebar-primary: var(--brand); + --sidebar-primary-foreground: var(--brand-foreground); + --sidebar-accent: color-mix( + in oklab, + var(--cladd-surface-mix-color) var(--cladd-surface-mix-amount), + var(--cladd-surface) + ); + --sidebar-accent-foreground: var(--cladd-fg); + --sidebar-border: var(--cladd-bg-outline); + --sidebar-ring: var(--brand); +} + +.dark { + --popover: color-mix( + in oklab, + var(--cladd-surface-white) 12%, + var(--cladd-surface) + ); + --brand: oklch(from #388aff 0.85 0.13 h); + --brand-foreground: oklch(from #388aff 0.2 0.05 h); + --brand-soft: oklch(from #388aff 0.23 0.027 h); + --destructive: oklch(from #ff0b0b 0.75 0.16 h); + --destructive-foreground: oklch(from #ff0b0b 0.2 0.05 h); + --success: oklch(from #0bff23 0.82 0.17 h); + --success-soft: oklch(from #0bff23 0.23 0.027 h); + --warning: oklch(from #fff800 0.88 0.16 h); + --warning-soft: oklch(from #fff800 0.23 0.027 h); +} + +@theme inline { + --font-sans: + "Geist Variable", "Geist", system-ui, -apple-system, "Segoe UI", Roboto, + sans-serif; + --font-mono: + "Geist Mono Variable", "Geist Mono", ui-monospace, "SF Mono", Menlo, + monospace; + --radius-sm: calc(var(--radius) - 4px); + --radius-md: calc(var(--radius) - 2px); + --radius-lg: var(--radius); + --radius-xl: calc(var(--radius) + 4px); + --color-background: var(--background); + --color-foreground: var(--foreground); + --color-card: var(--card); + --color-card-foreground: var(--card-foreground); + --color-popover: var(--popover); + --color-popover-foreground: var(--popover-foreground); + --color-primary: var(--primary); + --color-primary-foreground: var(--primary-foreground); + --color-secondary: var(--secondary); + --color-secondary-foreground: var(--secondary-foreground); + --color-muted: var(--muted); + --color-muted-foreground: var(--muted-foreground); + --color-accent: var(--accent); + --color-accent-foreground: var(--accent-foreground); + --color-destructive: var(--destructive); + --color-destructive-foreground: var(--destructive-foreground); + --color-border: var(--border); + --color-input: var(--input); + --color-ring: var(--ring); + --color-brand: var(--brand); + --color-brand-foreground: var(--brand-foreground); + --color-brand-soft: var(--brand-soft); + --color-success: var(--success); + --color-success-soft: var(--success-soft); + --color-warning: var(--warning); + --color-warning-soft: var(--warning-soft); + --color-chart-1: var(--chart-1); + --color-chart-2: var(--chart-2); + --color-chart-3: var(--chart-3); + --color-chart-4: var(--chart-4); + --color-chart-5: var(--chart-5); + --color-sidebar: var(--sidebar); + --color-sidebar-foreground: var(--sidebar-foreground); + --color-sidebar-primary: var(--sidebar-primary); + --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); + --color-sidebar-accent: var(--sidebar-accent); + --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); + --color-sidebar-border: var(--sidebar-border); + --color-sidebar-ring: var(--sidebar-ring); +} + +/* ───────────────────────── surfaces ───────────────────────── +Background is two layers over a base color: the hover/press overlay on top and +the diagonal sheen below it. Base color stays a plain background-color, so a +`bg-*` utility on a component recolors it without losing the cladd finish. */ + +@layer components { + .cladd-surface, + .cladd-cut, + .cladd-ghost { + --cladd-sheen: linear-gradient(transparent, transparent); + background-color: var(--color-cladd-surface); + background-image: + linear-gradient(var(--cladd-overlay), var(--cladd-overlay)), + var(--cladd-sheen); + transition-timing-function: ease; + transition-duration: 200ms; + transition-property: + --cladd-overlay, background-color, color, box-shadow, opacity, scale, + outline-color, outline-offset; + } + + .cladd-gradient { + --cladd-sheen: linear-gradient( + to bottom right, + color-mix( + in oklab, + var(--cladd-surface-white) var(--cladd-highlight-mix), + transparent + ), + transparent + ); + } + + /* `cladd-fill-checked` turns into a gradient fill while bits-ui marks it checked/on. */ + .cladd-fill, + .cladd-gradient-fill, + .cladd-fill-checked:is([data-state="checked"], [data-state="indeterminate"]) { + color: var(--color-cladd-on-primary); + background-color: var(--color-cladd-primary); + } + .cladd-gradient-fill, + .cladd-fill-checked:is([data-state="checked"], [data-state="indeterminate"]) { + --cladd-sheen: linear-gradient( + to bottom right, + transparent, + color-mix( + in oklab, + var(--color-cladd-surface) var(--cladd-fill-fade), + transparent + ) + ); + } + :root:not(.dark) + :is( + .cladd-gradient-fill, + .cladd-fill-checked:is( + [data-state="checked"], + [data-state="indeterminate"] + ) + ) { + --cladd-sheen: linear-gradient( + to bottom right, + color-mix( + in oklab, + var(--cladd-surface-white) var(--cladd-fill-fade), + transparent + ), + transparent + ); + } + + .cladd-outline { + box-shadow: var(--shadow-cladd-outline); + } + .cladd-outline:is(.cladd-fill, .cladd-gradient-fill), + .cladd-outline.cladd-fill-checked:is( + [data-state="checked"], + [data-state="indeterminate"] + ) { + box-shadow: var(--shadow-cladd-outline-fill); + } + + .cladd-cut { + background-color: var(--color-cladd-surface-cut); + box-shadow: var(--shadow-cladd-cut-outline); + } + + .cladd-ghost { + background-color: transparent; + box-shadow: none; + } + + @media (hover: hover) { + .cladd-hoverable:hover { + --cladd-overlay: var(--color-cladd-surface-hover); + } + .cladd-hoverable:is(.cladd-fill, .cladd-gradient-fill):hover, + .cladd-hoverable.cladd-fill-checked:is( + [data-state="checked"], + [data-state="indeterminate"] + ):hover { + --cladd-overlay: var(--color-cladd-surface-hover-fill); + } + .cladd-ghost.cladd-hoverable:hover { + --cladd-overlay: transparent; + background-color: var(--color-cladd-surface); + } + } + + .cladd-clickable:active:not(:has(.cladd-clickable:active)), + .cladd-pressed { + --cladd-overlay: var(--color-cladd-surface-pressed); + } + .cladd-ghost.cladd-pressed, + .cladd-ghost.cladd-clickable:active { + background-color: var(--color-cladd-surface); + } + .cladd-clickable:active:not(:has(.cladd-clickable:active)) > *, + .cladd-press-content:active > * { + opacity: 0.75; + scale: 0.95; + } + .cladd-clickable > * { + transition: + scale 200ms ease, + opacity 200ms ease; + } + + /* Button content inherits the host's flex layout, so `justify-between`, `gap-*` + and friends on