@archetypeai/ds-cli 0.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +123 -0
  3. package/bin.js +77 -0
  4. package/commands/add.js +42 -0
  5. package/commands/create.js +238 -0
  6. package/commands/init.js +199 -0
  7. package/files/AGENTS.md +63 -0
  8. package/files/CLAUDE.md +63 -0
  9. package/files/LICENSE +21 -0
  10. package/files/rules/accessibility.md +219 -0
  11. package/files/rules/charts.md +352 -0
  12. package/files/rules/components.md +267 -0
  13. package/files/rules/design-principles.md +56 -0
  14. package/files/rules/linting.md +31 -0
  15. package/files/rules/state.md +405 -0
  16. package/files/rules/styling.md +245 -0
  17. package/files/skills/apply-ds/SKILL.md +117 -0
  18. package/files/skills/apply-ds/scripts/setup.sh +271 -0
  19. package/files/skills/build-pattern/SKILL.md +202 -0
  20. package/files/skills/create-dashboard/SKILL.md +189 -0
  21. package/files/skills/deploy-worker/SKILL.md +231 -0
  22. package/files/skills/deploy-worker/references/wrangler-commands.md +327 -0
  23. package/files/skills/fix-accessibility/SKILL.md +184 -0
  24. package/files/skills/fix-metadata/SKILL.md +118 -0
  25. package/files/skills/fix-metadata/assets/favicon.ico +0 -0
  26. package/files/skills/setup-chart/SKILL.md +225 -0
  27. package/files/skills/setup-chart/data/embedding.csv +42 -0
  28. package/files/skills/setup-chart/data/timeseries.csv +173 -0
  29. package/files/skills/setup-chart/references/scatter-chart.md +229 -0
  30. package/files/skills/setup-chart/references/sensor-chart.md +156 -0
  31. package/lib/add-ds-config-codeagent.js +154 -0
  32. package/lib/add-ds-ui-svelte.js +93 -0
  33. package/lib/scaffold-ds-svelte-project.js +272 -0
  34. package/lib/use-package-manager.js +65 -0
  35. package/lib/use-shadcn-svelte-registry.js +26 -0
  36. package/lib/validate-url.js +31 -0
  37. package/package.json +34 -0
@@ -0,0 +1,117 @@
1
+ ---
2
+ name: apply-ds
3
+ description: Sets up an existing SvelteKit project with the Archetype AI design system (@archetypeai/ds-lib-tokens). Use when initializing a new project with the design system by adding tokens to an existing project, configuring Tailwind v4 CSS imports, setting up shadcn-svelte, installing design system components and configuring eslint/prettier for Svelte projects.
4
+ ---
5
+
6
+ # Applying the Design System
7
+
8
+ Setup involves these steps:
9
+
10
+ 1. Install tokens package
11
+ 2. Install and configure Tailwind CSS
12
+ 3. Initialize shadcn-svelte
13
+ 4. Install design system components
14
+ 5. Configure CSS imports
15
+ 6. Set up linting and formatting
16
+
17
+ ## Automated Setup
18
+
19
+ Run the setup script from the project root:
20
+
21
+ ```bash
22
+ bash scripts/setup.sh
23
+ ```
24
+
25
+ The script requires:
26
+
27
+ - A global CSS file at `src/app.css`, `src/routes/layout.css`, or `src/app.pcss`
28
+
29
+ ## Manual Setup
30
+
31
+ ### Step 1: Install Tokens
32
+
33
+ ```bash
34
+ npm i @archetypeai/ds-lib-tokens
35
+ ```
36
+
37
+ ### Step 2: Install and Configure Tailwind CSS
38
+
39
+ Install Tailwind CSS v4 and its Vite plugin:
40
+
41
+ ```bash
42
+ npm i -D tailwindcss @tailwindcss/vite
43
+ ```
44
+
45
+ Then add the `@tailwindcss/vite` plugin to your `vite.config.js`:
46
+
47
+ ```js
48
+ import tailwindcss from '@tailwindcss/vite';
49
+
50
+ export default defineConfig({
51
+ plugins: [svelte(), tailwindcss()]
52
+ // ...
53
+ });
54
+ ```
55
+
56
+ The setup script handles this automatically — it detects your vite config file, adds the import, and inserts `tailwindcss()` into the plugins array.
57
+
58
+ ### Step 3: Initialize shadcn-svelte
59
+
60
+ The `--css` flag should point to your project's global CSS file:
61
+
62
+ ```bash
63
+ npx shadcn-svelte@latest init \
64
+ --base-color slate \
65
+ --css src/app.css \
66
+ --components-alias '$lib/components' \
67
+ --lib-alias '$lib' \
68
+ --utils-alias '$lib/utils' \
69
+ --hooks-alias '$lib/hooks' \
70
+ --ui-alias '$lib/components/ui' \
71
+ --skip-preflight \
72
+ --no-deps
73
+ ```
74
+
75
+ ### Step 4: Install Components
76
+
77
+ Install all components:
78
+
79
+ ```bash
80
+ npx @archetypeai/ds-cli add ds-ui-svelte
81
+ ```
82
+
83
+ Or install individually:
84
+
85
+ ```bash
86
+ npx shadcn-svelte@latest add https://design-system.archetypeai.workers.dev/r/button.json
87
+ ```
88
+
89
+ ### Step 5: Configure CSS Imports
90
+
91
+ Replace the contents of your global CSS file with:
92
+
93
+ ```css
94
+ @import '@archetypeai/ds-lib-tokens/theme.css';
95
+ @import 'tailwindcss';
96
+ ```
97
+
98
+ ### Step 6: Set Up Linting
99
+
100
+ Install dependencies:
101
+
102
+ ```bash
103
+ npm i -D eslint prettier eslint-plugin-svelte eslint-config-prettier prettier-plugin-svelte prettier-plugin-tailwindcss globals
104
+ ```
105
+
106
+ The setup script creates `eslint.config.js`, `.prettierrc`, and `.prettierignore` automatically. See `@rules/linting.md` for details.
107
+
108
+ ## Verification
109
+
110
+ Confirm setup is complete:
111
+
112
+ - [ ] `@archetypeai/ds-lib-tokens` in package.json
113
+ - [ ] `tailwindcss` and `@tailwindcss/vite` in package.json devDependencies
114
+ - [ ] `vite.config.js` includes `import tailwindcss from '@tailwindcss/vite'` and `tailwindcss()` in plugins
115
+ - [ ] `components.json` exists
116
+ - [ ] Components in `$lib/components/ui/`
117
+ - [ ] CSS file contains correct imports
@@ -0,0 +1,271 @@
1
+ #!/bin/bash
2
+ #
3
+ # Archetype AI Design System Setup Script
4
+ #
5
+ # Sets up a SvelteKit project with @archetypeai/ds-lib-tokens and design system components.
6
+ # Fully non-interactive.
7
+ #
8
+ # Usage: bash setup.sh
9
+ #
10
+
11
+ set -e
12
+
13
+ echo "═══════════════════════════════════════════════════"
14
+ echo " Archetype AI Design System Setup"
15
+ echo "═══════════════════════════════════════════════════"
16
+ echo ""
17
+
18
+ # ─────────────────────────────────────────────────────────
19
+ # Prerequisites Check
20
+ # ─────────────────────────────────────────────────────────
21
+
22
+ if ! command -v node &> /dev/null; then
23
+ echo "✗ Error: Node.js is not installed"
24
+ echo " Install Node.js 18+ and try again"
25
+ exit 1
26
+ fi
27
+
28
+ NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
29
+ if [ "$NODE_VERSION" -lt 18 ]; then
30
+ echo "✗ Error: Node.js 18+ required (found v$NODE_VERSION)"
31
+ exit 1
32
+ fi
33
+
34
+ if [ ! -f "package.json" ]; then
35
+ echo "✗ Error: No package.json found"
36
+ echo " Run this script from your project root directory"
37
+ exit 1
38
+ fi
39
+
40
+ # Detect global CSS file
41
+ CSS_FILE=""
42
+ if [ -f "src/app.css" ]; then
43
+ CSS_FILE="src/app.css"
44
+ elif [ -f "src/routes/layout.css" ]; then
45
+ CSS_FILE="src/routes/layout.css"
46
+ elif [ -f "src/app.pcss" ]; then
47
+ CSS_FILE="src/app.pcss"
48
+ fi
49
+
50
+ if [ -z "$CSS_FILE" ]; then
51
+ echo "✗ Error: No global CSS file found"
52
+ echo " Checked: src/app.css, src/routes/layout.css, src/app.pcss"
53
+ echo " Create a global CSS file and run again."
54
+ exit 1
55
+ fi
56
+
57
+ echo "✓ Prerequisites OK (Node v$NODE_VERSION, CSS: $CSS_FILE)"
58
+ echo ""
59
+
60
+ # ─────────────────────────────────────────────────────────
61
+ # Step 1: Install Tokens
62
+ # ─────────────────────────────────────────────────────────
63
+
64
+ echo "Step 1/6: Installing @archetypeai/ds-lib-tokens..."
65
+
66
+ if grep -q '"@archetypeai/ds-lib-tokens"' package.json 2>/dev/null; then
67
+ echo " → Already installed, skipping"
68
+ else
69
+ npm i @archetypeai/ds-lib-tokens || {
70
+ echo ""
71
+ echo "✗ Installation failed."
72
+ exit 1
73
+ }
74
+ echo " ✓ Tokens installed"
75
+ fi
76
+ echo ""
77
+
78
+ # ─────────────────────────────────────────────────────────
79
+ # Step 2: Install & Configure Tailwind CSS
80
+ # ─────────────────────────────────────────────────────────
81
+
82
+ echo "Step 2/6: Installing and configuring Tailwind CSS..."
83
+
84
+ # Install tailwindcss + vite plugin if not present
85
+ if grep -q '"tailwindcss"' package.json 2>/dev/null && grep -q '"@tailwindcss/vite"' package.json 2>/dev/null; then
86
+ echo " → tailwindcss already installed, skipping"
87
+ else
88
+ npm i -D tailwindcss @tailwindcss/vite || {
89
+ echo ""
90
+ echo "✗ Failed to install tailwindcss"
91
+ exit 1
92
+ }
93
+ echo " ✓ tailwindcss and @tailwindcss/vite installed"
94
+ fi
95
+
96
+ # Configure vite.config.js with @tailwindcss/vite plugin
97
+ VITE_CONFIG=""
98
+ if [ -f "vite.config.js" ]; then
99
+ VITE_CONFIG="vite.config.js"
100
+ elif [ -f "vite.config.ts" ]; then
101
+ VITE_CONFIG="vite.config.ts"
102
+ fi
103
+
104
+ if [ -z "$VITE_CONFIG" ]; then
105
+ echo " ⚠ No vite.config found — create one and add tailwindcss() to plugins manually"
106
+ elif grep -q "@tailwindcss/vite" "$VITE_CONFIG" 2>/dev/null; then
107
+ echo " → @tailwindcss/vite already configured in $VITE_CONFIG, skipping"
108
+ else
109
+ # Add import after the last import statement
110
+ LAST_IMPORT_LINE=$(grep -n '^import ' "$VITE_CONFIG" | tail -1 | cut -d: -f1)
111
+ if [ -n "$LAST_IMPORT_LINE" ]; then
112
+ sed -i.bak "${LAST_IMPORT_LINE}a\\
113
+ import tailwindcss from '@tailwindcss/vite';" "$VITE_CONFIG"
114
+ else
115
+ sed -i.bak "1i\\
116
+ import tailwindcss from '@tailwindcss/vite';" "$VITE_CONFIG"
117
+ fi
118
+
119
+ # Add tailwindcss() to plugins array
120
+ if grep -q 'plugins.*svelte()' "$VITE_CONFIG"; then
121
+ sed -i.bak 's/svelte()/svelte(), tailwindcss()/' "$VITE_CONFIG"
122
+ elif grep -q 'plugins.*\[' "$VITE_CONFIG"; then
123
+ sed -i.bak 's/plugins:[[:space:]]*\[/plugins: [tailwindcss(), /' "$VITE_CONFIG"
124
+ else
125
+ echo " ⚠ Could not find plugins array — add tailwindcss() to plugins manually"
126
+ fi
127
+
128
+ rm -f "${VITE_CONFIG}.bak"
129
+ echo " ✓ @tailwindcss/vite configured in $VITE_CONFIG"
130
+ fi
131
+ echo ""
132
+
133
+ # ─────────────────────────────────────────────────────────
134
+ # Step 3: Initialize shadcn-svelte
135
+ # ─────────────────────────────────────────────────────────
136
+
137
+ echo "Step 3/6: Initializing shadcn-svelte..."
138
+
139
+ if [ -f "components.json" ]; then
140
+ echo " → components.json exists, skipping init"
141
+ else
142
+ npx shadcn-svelte@latest init \
143
+ --base-color slate \
144
+ --css "$CSS_FILE" \
145
+ --components-alias '$lib/components' \
146
+ --lib-alias '$lib' \
147
+ --utils-alias '$lib/utils' \
148
+ --hooks-alias '$lib/hooks' \
149
+ --ui-alias '$lib/components/ui' \
150
+ --skip-preflight \
151
+ --no-deps
152
+ echo " ✓ shadcn-svelte initialized"
153
+ fi
154
+ echo ""
155
+
156
+ # ─────────────────────────────────────────────────────────
157
+ # Step 4: Install Components
158
+ # ─────────────────────────────────────────────────────────
159
+
160
+ echo "Step 4/6: Installing design system components..."
161
+ npx @archetypeai/ds-cli add ds-ui-svelte
162
+ echo " ✓ Components installed"
163
+ echo ""
164
+
165
+ # ─────────────────────────────────────────────────────────
166
+ # Step 5: Configure CSS Imports
167
+ # ─────────────────────────────────────────────────────────
168
+
169
+ echo "Step 5/6: Configuring CSS imports..."
170
+
171
+ cat > "$CSS_FILE" << 'EOF'
172
+ @import '@archetypeai/ds-lib-tokens/theme.css';
173
+ @import 'tailwindcss';
174
+ EOF
175
+
176
+ echo " ✓ CSS imports written to $CSS_FILE"
177
+ echo ""
178
+
179
+ # ─────────────────────────────────────────────────────────
180
+ # Step 6: Set Up Linting & Formatting
181
+ # ─────────────────────────────────────────────────────────
182
+
183
+ echo "Step 6/6: Setting up linting and formatting..."
184
+
185
+ npm i -D eslint prettier eslint-plugin-svelte eslint-config-prettier prettier-plugin-svelte prettier-plugin-tailwindcss globals 2>/dev/null || true
186
+ echo " ✓ Linting dependencies installed"
187
+
188
+ # Create eslint.config.js if it doesn't exist
189
+ if [ ! -f "eslint.config.js" ]; then
190
+ cat > eslint.config.js << 'ESLINT_EOF'
191
+ import js from '@eslint/js';
192
+ import svelte from 'eslint-plugin-svelte';
193
+ import globals from 'globals';
194
+ import svelteConfig from './svelte.config.js';
195
+
196
+ export default [
197
+ js.configs.recommended,
198
+ ...svelte.configs.recommended,
199
+ ...svelte.configs['flat/prettier'],
200
+ {
201
+ languageOptions: {
202
+ globals: { ...globals.browser, ...globals.node }
203
+ }
204
+ },
205
+ {
206
+ files: ['**/*.svelte', '**/*.svelte.js'],
207
+ languageOptions: {
208
+ parserOptions: { svelteConfig }
209
+ }
210
+ },
211
+ {
212
+ ignores: ['.svelte-kit/', 'build/', 'dist/', 'node_modules/']
213
+ }
214
+ ];
215
+ ESLINT_EOF
216
+ echo " ✓ eslint.config.js created"
217
+ else
218
+ echo " → eslint.config.js exists, skipping"
219
+ fi
220
+
221
+ # Create .prettierrc if it doesn't exist
222
+ if [ ! -f ".prettierrc" ]; then
223
+ cat > .prettierrc << PRETTIER_EOF
224
+ {
225
+ "useTabs": true,
226
+ "singleQuote": true,
227
+ "trailingComma": "none",
228
+ "printWidth": 100,
229
+ "plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
230
+ "tailwindStylesheet": "./$CSS_FILE"
231
+ }
232
+ PRETTIER_EOF
233
+ echo " ✓ .prettierrc created"
234
+ else
235
+ echo " → .prettierrc exists, skipping"
236
+ fi
237
+
238
+ # Create .prettierignore if it doesn't exist
239
+ if [ ! -f ".prettierignore" ]; then
240
+ cat > .prettierignore << 'IGNORE_EOF'
241
+ .svelte-kit
242
+ .claude
243
+ .cursor
244
+ build
245
+ dist
246
+ node_modules
247
+ package-lock.json
248
+ IGNORE_EOF
249
+ echo " ✓ .prettierignore created"
250
+ else
251
+ echo " → .prettierignore exists, skipping"
252
+ fi
253
+
254
+ # Add lint/format scripts to package.json
255
+ npm pkg set scripts.lint="eslint ." 2>/dev/null || true
256
+ npm pkg set scripts.lint:fix="eslint . --fix" 2>/dev/null || true
257
+ npm pkg set scripts.format="prettier --write ." 2>/dev/null || true
258
+ npm pkg set scripts.format:check="prettier --check ." 2>/dev/null || true
259
+ echo " ✓ Lint/format scripts added to package.json"
260
+ echo ""
261
+
262
+ # ─────────────────────────────────────────────────────────
263
+ # Complete
264
+ # ─────────────────────────────────────────────────────────
265
+
266
+ echo "═══════════════════════════════════════════════════"
267
+ echo " Setup Complete"
268
+ echo "═══════════════════════════════════════════════════"
269
+ echo ""
270
+ echo " Components are in \$lib/components/ui/"
271
+ echo ""
@@ -0,0 +1,202 @@
1
+ ---
2
+ name: build-pattern
3
+ description: Creates composite UI patterns by assembling design system primitives. Use when building reusable components that combine multiple primitives (Card, Button, Input, etc.), creating dashboard widgets, form groups, sensor cards, data displays, or any complex component from existing design system primitives. Also use when the user asks to create a "component" or "widget" that should follow design system conventions.
4
+ ---
5
+
6
+ # Building Patterns
7
+
8
+ Patterns are composite components assembled from design system primitives.
9
+
10
+ ## Decision: Pattern vs Extension
11
+
12
+ **Build a pattern when:**
13
+
14
+ - Combining 3+ primitives into a reusable unit
15
+ - The combination will be used in multiple places
16
+ - The component has its own props/state logic
17
+
18
+ **Extend a primitive instead when:**
19
+
20
+ - Adding variants to a single primitive
21
+ - Customizing styling without composition
22
+
23
+ ## Pattern Structure
24
+
25
+ ```svelte
26
+ <script>
27
+ import { cn } from '$lib/utils.js';
28
+ import { Card, CardHeader, CardTitle, CardContent } from '$lib/components/ui/card/index.js';
29
+ import { Button } from '$lib/components/ui/button/index.js';
30
+
31
+ let { title, class: className, children, ...restProps } = $props();
32
+ </script>
33
+
34
+ <Card class={cn('p-4', className)} {...restProps}>
35
+ <CardHeader>
36
+ <CardTitle>{title}</CardTitle>
37
+ </CardHeader>
38
+ <CardContent>
39
+ {@render children?.()}
40
+ </CardContent>
41
+ </Card>
42
+ ```
43
+
44
+ ## Key Conventions
45
+
46
+ ### Props Pattern
47
+
48
+ Always use this structure:
49
+
50
+ ```javascript
51
+ let {
52
+ ref = $bindable(null), // optional DOM reference
53
+ class: className, // rename to avoid reserved word
54
+ children, // snippet for slot content
55
+ ...restProps // pass-through attributes
56
+ } = $props();
57
+ ```
58
+
59
+ ### Class Merging
60
+
61
+ Always use `cn()` for classes:
62
+
63
+ ```svelte
64
+ <div class={cn('bg-card p-4', className)}>
65
+ ```
66
+
67
+ Never concatenate strings directly.
68
+
69
+ ### Spreading restProps
70
+
71
+ Always spread on the root element:
72
+
73
+ ```svelte
74
+ <Card class={cn('p-4', className)} {...restProps}>
75
+ ```
76
+
77
+ This ensures aria attributes, data attributes, and event handlers pass through.
78
+
79
+ ### Rendering Children
80
+
81
+ Use `{@render}` for slot content:
82
+
83
+ ```svelte
84
+ {@render children?.()}
85
+ ```
86
+
87
+ ## Available Primitives
88
+
89
+ Import from `$lib/components/ui/`. Before building, list `$lib/components/ui/` to discover all installed primitives.
90
+
91
+ ### Layout & Structure
92
+
93
+ - **card** - Card, CardHeader, CardTitle, CardContent, CardFooter, CardAction, CardDescription
94
+ - **separator** - Separator
95
+ - **resizable** - ResizablePane, ResizablePaneGroup, ResizableHandle
96
+ - **scroll-area** - ScrollArea
97
+ - **aspect-ratio** - AspectRatio
98
+ - **skeleton** - Skeleton
99
+ - **collapsible** - Collapsible.Root, Collapsible.Trigger, Collapsible.Content
100
+
101
+ ### Forms & Inputs
102
+
103
+ - **button** - Button (with variants via `buttonVariants`)
104
+ - **input** - Input
105
+ - **textarea** - Textarea
106
+ - **label** - Label
107
+ - **checkbox** - Checkbox
108
+ - **switch** - Switch
109
+ - **select** - Select.Root, Select.Trigger, Select.Content, Select.Item
110
+ - **native-select** - NativeSelect
111
+ - **radio-group** - RadioGroup.Root, RadioGroup.Item
112
+ - **slider** - Slider
113
+ - **toggle** - Toggle
114
+ - **toggle-group** - ToggleGroup.Root, ToggleGroup.Item
115
+ - **input-otp** - InputOTP
116
+ - **input-group** - InputGroup
117
+ - **field** - Field, FieldSet, FieldGroup, FieldLabel, FieldDescription, FieldError, FieldContent
118
+
119
+ ### Data Display
120
+
121
+ - **table** - Table, TableHeader, TableBody, TableRow, TableCell, TableHead, TableFooter, TableCaption
122
+ - **data-table** - createSvelteTable, FlexRender
123
+ - **chart** - Chart.Container, Chart.Tooltip
124
+ - **badge** - Badge
125
+ - **avatar** - Avatar, AvatarImage, AvatarFallback
126
+ - **kbd** - Kbd
127
+ - **empty** - Empty, EmptyHeader, EmptyMedia, EmptyTitle, EmptyDescription, EmptyContent
128
+ - **item** - Item, ItemGroup, ItemHeader, ItemContent, ItemTitle, ItemDescription, ItemActions, ItemMedia
129
+ - **spinner** - Spinner
130
+ - **progress** - Progress
131
+ - **carousel** - Carousel
132
+
133
+ ### Overlays & Dialogs
134
+
135
+ - **dialog** - Dialog.Root, Dialog.Trigger, Dialog.Content, Dialog.Header, Dialog.Title, Dialog.Description, Dialog.Footer, Dialog.Close
136
+ - **alert-dialog** - AlertDialog.Root, AlertDialog.Trigger, AlertDialog.Content, AlertDialog.Header, AlertDialog.Title, AlertDialog.Description, AlertDialog.Footer, AlertDialog.Action, AlertDialog.Cancel
137
+ - **sheet** - Sheet.Root, Sheet.Trigger, Sheet.Content, Sheet.Header, Sheet.Title, Sheet.Description, Sheet.Footer, Sheet.Close
138
+ - **drawer** - Drawer.Root, Drawer.Trigger, Drawer.Content, Drawer.Header, Drawer.Title, Drawer.Description, Drawer.Footer, Drawer.Close
139
+ - **popover** - Popover.Root, Popover.Trigger, Popover.Content
140
+ - **hover-card** - HoverCard.Root, HoverCard.Trigger, HoverCard.Content
141
+ - **tooltip** - Tooltip.Root, Tooltip.Trigger, Tooltip.Content, Tooltip.Provider
142
+ - **command** - Command.Root, Command.Input, Command.List, Command.Item, Command.Group
143
+ - **sonner** - Toaster
144
+
145
+ ### Navigation & Menus
146
+
147
+ - **tabs** - Tabs.Root, Tabs.List, Tabs.Trigger, Tabs.Content
148
+ - **accordion** - Accordion.Root, Accordion.Item, Accordion.Trigger, Accordion.Content
149
+ - **dropdown-menu** - DropdownMenu.Root, DropdownMenu.Trigger, DropdownMenu.Content, DropdownMenu.Item, DropdownMenu.Separator
150
+ - **context-menu** - ContextMenu.Root, ContextMenu.Trigger, ContextMenu.Content, ContextMenu.Item
151
+ - **menubar** - Menubar
152
+ - **navigation-menu** - NavigationMenu
153
+ - **breadcrumb** - Breadcrumb, BreadcrumbList, BreadcrumbItem, BreadcrumbLink, BreadcrumbSeparator, BreadcrumbPage
154
+ - **pagination** - Pagination
155
+ - **sidebar** - Sidebar, SidebarProvider, SidebarContent, SidebarGroup, SidebarGroupLabel, SidebarMenu, SidebarMenuItem, SidebarMenuButton, SidebarTrigger
156
+ - **button-group** - ButtonGroup, ButtonGroupText, ButtonGroupSeparator
157
+
158
+ ### Date Picking
159
+
160
+ - **calendar** - Calendar
161
+ - **range-calendar** - RangeCalendar
162
+
163
+ ### Feedback
164
+
165
+ - **alert** - Alert, AlertTitle, AlertDescription
166
+
167
+ ## Example: Sensor Card Pattern
168
+
169
+ ```svelte
170
+ <script>
171
+ import { cn } from '$lib/utils.js';
172
+ import { Card, CardHeader, CardTitle, CardContent } from '$lib/components/ui/card/index.js';
173
+ import * as Chart from '$lib/components/ui/chart/index.js';
174
+
175
+ let { title = 'SENSOR', icon: Icon, data = [], class: className, ...restProps } = $props();
176
+ </script>
177
+
178
+ <Card class={cn('p-4', className)} {...restProps}>
179
+ <CardHeader class="flex flex-row items-center justify-between p-0">
180
+ <CardTitle class="text-foreground font-mono text-base uppercase">
181
+ {title}
182
+ </CardTitle>
183
+ {#if Icon}
184
+ <Icon class="text-muted-foreground size-6" aria-hidden="true" />
185
+ {/if}
186
+ </CardHeader>
187
+ <CardContent class="p-0">
188
+ <Chart.Container config={{}} class="h-[220px] w-full">
189
+ <!-- chart content -->
190
+ </Chart.Container>
191
+ </CardContent>
192
+ </Card>
193
+ ```
194
+
195
+ ## Detailed Conventions
196
+
197
+ See `@rules/components.md` for:
198
+
199
+ - bits-ui wrapper patterns
200
+ - tailwind-variants (tv) usage
201
+ - Conditional rendering patterns
202
+ - Icon handling