unplugin-docubook 1.1.2 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # 📚 DocuBook
1
+ # <img src="./docu.svg" width="32" height="32" valign="middle" /> @DocuBook/content
2
2
 
3
3
  The Universal Documentation Engine for any JavaScript Framework.
4
4
 
@@ -33,62 +33,349 @@ npm install lucide-vue-next
33
33
  npm install lucide-svelte
34
34
  ```
35
35
 
36
- ### 3. Setup Tailwind CSS
37
- DocuBook components are styled with Tailwind. Ensure Tailwind is installed in your project, then import the DocuBook theme in your entry file (`main.ts`, `App.tsx`, etc.):
36
+ ---
38
37
 
39
- ```typescript
40
- import 'unplugin-docubook/theme.css';
38
+ ## 🔌 Integration
39
+
40
+ DocuBook is not a replacement for your MDX compiler; it is a **transformer** that works alongside your favorite compiler. DocuBook handles automatic component imports (auto-import) before the MDX is compiled.
41
+
42
+ You still need an MDX compiler/bundler based on your framework:
43
+
44
+ ```bash
45
+ # For Vite (React)
46
+ npm install @mdx-js/rollup @mdx-js/react
47
+
48
+ # For Vite (Vue)
49
+ npm install @mdx-js/rollup @mdx-js/vue
50
+
51
+ # For Next.js
52
+ npm install @next/mdx @mdx-js/loader @mdx-js/react
53
+
54
+ # For Svelte
55
+ npm install mdsvex
56
+
57
+ # For Astro
58
+ npm install @astrojs/mdx
59
+
60
+ # For Nuxt
61
+ npm install @nuxtjs/mdc
41
62
  ```
42
63
 
64
+ > [!NOTE]
65
+ > **What's the difference with `next-mdx-remote`?**
66
+ > `next-mdx-remote` compiles MDX at runtime. DocuBook (via Webpack/Vite) processes your MDX files at build-time. If you are using local MDX files, DocuBook eliminates the need to write manual imports in every file or repeatedly register components in a provider.
67
+
43
68
  ---
44
69
 
45
- ## ⚙️ Configuration
70
+ > [!TIP]
71
+ > DocuBook supports all major bundlers via `unplugin`. Select your bundler below to see the configuration.
72
+
73
+ <details>
74
+ <summary><b>Vite (React)</b></summary>
75
+
76
+ ```typescript
77
+ // vite.config.ts
78
+ import { defineConfig } from 'vite';
79
+ import react from '@vitejs/plugin-react';
80
+ import mdx from '@mdx-js/rollup';
81
+ import DocuBook from 'unplugin-docubook/vite';
82
+
83
+ export default defineConfig({
84
+ plugins: [
85
+ react(),
86
+ mdx(),
87
+ DocuBook({
88
+ framework: 'react',
89
+ }),
90
+ ],
91
+ });
92
+ ```
93
+ </details>
46
94
 
47
- Docubook supports all major bundlers via `unplugin`.
95
+ <details>
96
+ <summary><b>Vite (Vue)</b></summary>
48
97
 
49
- ### Vite (React/Vue/Svelte/Astro)
50
98
  ```typescript
51
99
  // vite.config.ts
52
100
  import { defineConfig } from 'vite';
101
+ import vue from '@vitejs/plugin-vue';
102
+ import mdx from '@mdx-js/rollup';
53
103
  import DocuBook from 'unplugin-docubook/vite';
54
104
 
55
105
  export default defineConfig({
56
106
  plugins: [
107
+ vue(),
108
+ mdx({ providerImportSource: '@mdx-js/vue' }),
57
109
  DocuBook({
58
- framework: 'react', // or 'vue' | 'svelte'
110
+ framework: 'vue',
59
111
  }),
60
112
  ],
61
113
  });
62
114
  ```
115
+ </details>
116
+
117
+ <details>
118
+ <summary><b>Next.js (App Router / Pages Router)</b></summary>
63
119
 
64
- ### Next.js
65
120
  ```javascript
66
121
  // next.config.mjs
67
122
  import DocuBook from 'unplugin-docubook/webpack';
123
+ import createMDX from '@next/mdx';
124
+
125
+ const withMDX = createMDX({});
68
126
 
69
127
  /** @type {import('next').NextConfig} */
70
128
  const nextConfig = {
129
+ pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'],
71
130
  webpack(config) {
72
131
  config.plugins.push(DocuBook({ framework: 'react' }));
73
132
  return config;
74
133
  },
75
134
  };
76
135
 
77
- export default nextConfig;
136
+ export default withMDX(nextConfig);
137
+ ```
138
+ </details>
139
+
140
+ <details>
141
+ <summary><b>Svelte (Vite)</b></summary>
142
+
143
+ ```typescript
144
+ // vite.config.ts
145
+ import { defineConfig } from 'vite';
146
+ import { svelte } from '@sveltejs/vite-plugin-svelte';
147
+ import mdsvex from 'mdsvex';
148
+ import DocuBook from 'unplugin-docubook/vite';
149
+
150
+ export default defineConfig({
151
+ plugins: [
152
+ svelte({
153
+ extensions: ['.md', '.mdx'],
154
+ }),
155
+ mdsvex({
156
+ extensions: ['.md', '.mdx'],
157
+ }),
158
+ DocuBook({
159
+ framework: 'svelte',
160
+ }),
161
+ ],
162
+ });
163
+ ```
164
+ </details>
165
+
166
+ <details>
167
+ <summary><b>Astro</b></summary>
168
+
169
+ ```javascript
170
+ // astro.config.mjs
171
+ import { defineConfig } from 'astro/config';
172
+ import mdx from '@astrojs/mdx';
173
+ import DocuBook from 'unplugin-docubook/vite';
174
+
175
+ export default defineConfig({
176
+ integrations: [mdx()],
177
+ vite: {
178
+ plugins: [
179
+ DocuBook({
180
+ framework: 'svelte', // or 'react' if using React in Astro
181
+ }),
182
+ ],
183
+ },
184
+ });
185
+ ```
186
+ </details>
187
+
188
+ <details>
189
+ <summary><b>Nuxt (Vue)</b></summary>
190
+
191
+ ```typescript
192
+ // nuxt.config.ts
193
+ export default defineNuxtConfig({
194
+ modules: ['@nuxtjs/mdc'],
195
+ docubook: {
196
+ framework: 'vue'
197
+ }
198
+ })
78
199
  ```
79
200
 
80
- ### Nuxt (Vue)
201
+ Or use the DocuBook Nuxt module directly:
81
202
  ```typescript
82
203
  // nuxt.config.ts
83
204
  export default defineNuxtConfig({
84
- modules: [
85
- ['unplugin-docubook/nuxt', { framework: 'vue' }]
86
- ]
205
+ modules: ['unplugin-docubook/nuxt'],
206
+ docubook: {
207
+ framework: 'vue'
208
+ }
87
209
  })
88
210
  ```
211
+ </details>
212
+
213
+ <details>
214
+ <summary><b>Webpack / Rollup / Others</b></summary>
89
215
 
90
- ### Webpack/Rollup
91
216
  Import from `unplugin-docubook/webpack` or `unplugin-docubook/rollup` and add to your plugins array.
217
+ </details>
218
+
219
+ ---
220
+
221
+ ## 🎨 Theming & Customization
222
+
223
+ DocuBook uses CSS variables for theming. You can override these variables to customize the appearance of components.
224
+
225
+ ### Quick Start
226
+
227
+ > [!NOTE]
228
+ > Import the DocuBook theme in your entry file (`main.ts`, `App.tsx`, etc.)
229
+
230
+ ```typescript
231
+ import 'unplugin-docubook/theme.css';
232
+ ```
233
+
234
+ ### Override CSS Variables
235
+
236
+ <details>
237
+ <summary><b>Base Colors</b></summary>
238
+
239
+ ```css
240
+ :root {
241
+ /* Background & Foreground */
242
+ --background: 210 40% 98%;
243
+ --foreground: 220 30% 15%;
244
+
245
+ /* Card */
246
+ --card: 0 0% 100%;
247
+ --card-foreground: 220 30% 15%;
248
+
249
+ /* Popover */
250
+ --popover: 0 0% 100%;
251
+ --popover-foreground: 220 30% 15%;
252
+ }
253
+ ```
254
+ </details>
255
+
256
+ <details>
257
+ <summary><b>Primary & Accent Colors</b></summary>
258
+
259
+ ```css
260
+ :root {
261
+ /* Primary - main brand color */
262
+ --primary: 210 81% 56%;
263
+ --primary-foreground: 0 0% 100%;
264
+
265
+ /* Secondary */
266
+ --secondary: 210 30% 90%;
267
+ --secondary-foreground: 220 30% 15%;
268
+
269
+ /* Accent */
270
+ --accent: 200 100% 40%;
271
+ --accent-foreground: 0 0% 100%;
272
+ }
273
+ ```
274
+ </details>
275
+
276
+ <details>
277
+ <summary><b>Muted & UI Colors</b></summary>
278
+
279
+ ```css
280
+ :root {
281
+ /* Muted */
282
+ --muted: 210 20% 92%;
283
+ --muted-foreground: 220 15% 50%;
284
+
285
+ /* Status */
286
+ --destructive: 0 85% 60%;
287
+ --destructive-foreground: 0 0% 100%;
288
+ --success: 142 70% 50%;
289
+ --success-foreground: 0 0% 100%;
290
+
291
+ /* Border & Input */
292
+ --border: 210 20% 85%;
293
+ --input: 210 20% 85%;
294
+ --ring: 210 81% 56%;
295
+
296
+ /* Radius */
297
+ --radius: 0.5rem;
298
+ }
299
+ ```
300
+ </details>
301
+
302
+ <details>
303
+ <summary><b>Note / Alert Variants</b></summary>
304
+
305
+ ```css
306
+ :root {
307
+ /* Note (info) */
308
+ --note-bg: 214 100% 97%;
309
+ --note-border: 214 100% 90%;
310
+ --note-accent: 210 81% 56%;
311
+ --note-text: 220 50% 30%;
312
+
313
+ /* Danger */
314
+ --danger-bg: 0 100% 97%;
315
+ --danger-border: 0 100% 90%;
316
+ --danger-accent: 0 85% 60%;
317
+ --danger-text: 0 50% 30%;
318
+
319
+ /* Warning */
320
+ --warning-bg: 38 100% 97%;
321
+ --warning-border: 38 100% 90%;
322
+ --warning-accent: 38 100% 50%;
323
+ --warning-text: 38 50% 30%;
324
+
325
+ /* Success */
326
+ --success-bg: 142 100% 97%;
327
+ --success-border: 142 100% 90%;
328
+ --success-accent: 142 70% 50%;
329
+ --success-text: 142 50% 25%;
330
+ }
331
+ ```
332
+ </details>
333
+
334
+ <details>
335
+ <summary><b>Dark Mode</b></summary>
336
+
337
+ Override colors for dark mode by adding `.dark` class:
338
+
339
+ ```css
340
+ .dark {
341
+ --background: 220 25% 10%;
342
+ --foreground: 210 30% 96%;
343
+ --card: 220 25% 15%;
344
+ --card-foreground: 210 30% 96%;
345
+ --primary: 210 100% 65%;
346
+ --primary-foreground: 220 25% 10%;
347
+ --accent: 200 100% 60%;
348
+ --muted: 215 20% 25%;
349
+ --muted-foreground: 215 20% 65%;
350
+ --border: 215 20% 25%;
351
+ --destructive: 0 85% 70%;
352
+ --success: 142 70% 55%;
353
+
354
+ /* Note variants - dark */
355
+ --note-bg: 217 50% 20%;
356
+ --note-border: 217 50% 30%;
357
+ --note-text: 210 30% 90%;
358
+ /* ... etc */
359
+ }
360
+ ```
361
+ </details>
362
+
363
+ <details>
364
+ <summary><b>Shadows & Animations</b></summary>
365
+
366
+ ```css
367
+ :root {
368
+ /* Shadows */
369
+ --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
370
+ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
371
+ --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
372
+
373
+ /* Animations */
374
+ --animate-accordion-down: accordion-down 0.2s ease-out;
375
+ --animate-accordion-up: accordion-up 0.2s ease-out;
376
+ }
377
+ ```
378
+ </details>
92
379
 
93
380
  ---
94
381
 
@@ -1,4 +1,6 @@
1
+ 'use client'
1
2
  "use strict";
3
+ "use client";
2
4
  var __create = Object.create;
3
5
  var __defProp = Object.defineProperty;
4
6
  var __defProps = Object.defineProperties;
@@ -262,37 +264,38 @@ var themeTokens = {
262
264
  var componentStyles = {
263
265
  // Button variations
264
266
  button: {
265
- base: "inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
267
+ base: "inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))] focus-visible:ring-offset-2 focus-visible:ring-offset-[hsl(var(--background))] disabled:pointer-events-none disabled:opacity-50",
266
268
  sizes: {
267
269
  sm: "h-8 px-3 text-xs",
268
270
  md: "h-9 px-4 py-2 text-sm",
269
271
  lg: "h-10 px-6 text-base"
270
272
  },
271
273
  variations: {
272
- primary: "bg-primary text-primary-foreground hover:bg-primary/90",
273
- accent: "bg-accent text-accent-foreground hover:bg-accent/90",
274
- outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
275
- ghost: "hover:bg-accent hover:text-accent-foreground",
276
- link: "text-primary underline-offset-4 hover:underline"
274
+ primary: "bg-[hsl(var(--primary))] text-[hsl(var(--primary-foreground))] hover:bg-[hsl(var(--primary))]/90",
275
+ accent: "bg-[hsl(var(--accent))] text-[hsl(var(--accent-foreground))] hover:bg-[hsl(var(--accent))]/90",
276
+ outline: "border border-[hsl(var(--input))] bg-[hsl(var(--background))] hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--accent-foreground))]",
277
+ ghost: "hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--accent-foreground))]",
278
+ link: "text-[hsl(var(--primary))] underline-offset-4 hover:underline"
277
279
  }
278
280
  },
279
281
  // Card variations
280
282
  card: {
281
- base: "rounded-lg border bg-card text-card-foreground shadow-sm",
283
+ base: "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--card))] text-[hsl(var(--card-foreground))] shadow-sm",
282
284
  header: "flex flex-col space-y-1.5 p-6",
283
285
  content: "p-6 pt-0",
284
286
  footer: "flex items-center p-6 pt-0",
285
287
  title: "text-2xl font-semibold leading-none tracking-tight",
286
- description: "text-sm text-muted-foreground"
288
+ description: "text-sm text-[hsl(var(--muted-foreground))]"
287
289
  },
288
290
  // Note/Alert variations
291
+ // Using HSL variables with proper semantic color classes
289
292
  note: {
290
- base: "relative w-full rounded-lg border p-4",
293
+ base: "relative w-full rounded-lg border p-4 border-l-4",
291
294
  variants: {
292
- note: "bg-[var(--color-note-bg)] border-[var(--color-note-border)] border-l-4 border-l-[var(--color-note-accent)] text-[var(--color-note-text)] dark:bg-[var(--color-dark-note-bg)] dark:border-[var(--color-dark-note-border)] dark:text-[var(--color-dark-note-text)]",
293
- danger: "bg-[var(--color-danger-bg)] border-[var(--color-danger-border)] border-l-4 border-l-[var(--color-danger-accent)] text-[var(--color-danger-text)] dark:bg-[var(--color-dark-danger-bg)] dark:border-[var(--color-dark-danger-border)] dark:text-[var(--color-dark-danger-text)]",
294
- warning: "bg-[var(--color-warning-bg)] border-[var(--color-warning-border)] border-l-4 border-l-[var(--color-warning-accent)] text-[var(--color-warning-text)] dark:bg-[var(--color-dark-warning-bg)] dark:border-[var(--color-dark-warning-border)] dark:text-[var(--color-dark-warning-text)]",
295
- success: "bg-[var(--color-success-bg)] border-[var(--color-success-border)] border-l-4 border-l-[var(--color-success-accent)] text-[var(--color-success-text)] dark:bg-[var(--color-dark-success-bg)] dark:border-[var(--color-dark-success-border)] dark:text-[var(--color-dark-success-text)]"
295
+ note: "bg-[hsl(var(--note-bg))] border-[hsl(var(--note-border))] border-l-[hsl(var(--note-accent))] text-[hsl(var(--note-text))]",
296
+ danger: "bg-[hsl(var(--danger-bg))] border-[hsl(var(--danger-border))] border-l-[hsl(var(--danger-accent))] text-[hsl(var(--danger-text))]",
297
+ warning: "bg-[hsl(var(--warning-bg))] border-[hsl(var(--warning-border))] border-l-[hsl(var(--warning-accent))] text-[hsl(var(--warning-text))]",
298
+ success: "bg-[hsl(var(--success-bg))] border-[hsl(var(--success-border))] border-l-[hsl(var(--success-accent))] text-[hsl(var(--success-text))]"
296
299
  },
297
300
  icon: "absolute left-4 top-4 h-5 w-5",
298
301
  content: "pl-8",
@@ -301,133 +304,133 @@ var componentStyles = {
301
304
  },
302
305
  // Accordion
303
306
  accordion: {
304
- base: "rounded-lg border bg-card",
305
- item: "border-b last:border-b-0",
306
- trigger: "flex w-full items-center justify-between p-4 font-medium transition-all hover:bg-muted [&[data-state=open]>svg]:rotate-180",
307
+ base: "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--card))]",
308
+ item: "border-b border-[hsl(var(--border))] last:border-b-0",
309
+ trigger: "flex w-full items-center justify-between p-4 font-medium transition-all hover:bg-[hsl(var(--muted))] [&[data-state=open]>svg]:rotate-180",
307
310
  content: "overflow-hidden transition-all data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down",
308
311
  contentInner: "p-4 pt-0"
309
312
  },
310
313
  // Tooltip
311
314
  tooltip: {
312
- content: "z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2"
315
+ content: "z-50 overflow-hidden rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--popover))] text-[hsl(var(--popover-foreground))] shadow-md px-3 py-1.5 text-sm animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2"
313
316
  },
314
317
  // Kbd
315
318
  kbd: {
316
- base: "pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground opacity-100"
319
+ base: "pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border border-[hsl(var(--border))] bg-[hsl(var(--muted))] px-1.5 font-mono text-[10px] font-medium text-[hsl(var(--muted-foreground))] opacity-100"
317
320
  },
318
321
  // Stepper
319
322
  stepper: {
320
323
  base: "flex w-full items-start gap-2",
321
324
  item: "flex-1",
322
325
  trigger: "flex items-center gap-2",
323
- indicator: "flex h-8 w-8 items-center justify-center rounded-full border text-sm font-medium",
326
+ indicator: "flex h-8 w-8 items-center justify-center rounded-full border border-[hsl(var(--border))] text-sm font-medium",
324
327
  title: "text-sm font-medium",
325
- description: "text-xs text-muted-foreground",
326
- separator: "flex-1 h-[1px] bg-border mt-4"
328
+ description: "text-xs text-[hsl(var(--muted-foreground))]",
329
+ separator: "flex-1 h-[1px] bg-[hsl(var(--border))] mt-4"
327
330
  },
328
331
  // File Tree
329
332
  fileTree: {
330
- base: "rounded-lg border bg-card p-4",
333
+ base: "rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--card))] p-4",
331
334
  folder: "font-medium",
332
- file: "text-muted-foreground",
333
- indent: "ml-4 pl-4 border-l"
335
+ file: "text-[hsl(var(--muted-foreground))]",
336
+ indent: "ml-4 pl-4 border-l border-[hsl(var(--border))]"
334
337
  },
335
338
  // Copy button
336
339
  copy: {
337
- base: "absolute right-4 top-4 inline-flex h-6 w-6 items-center justify-center rounded-md border bg-background text-foreground opacity-0 transition-opacity hover:bg-muted focus:outline-none group-hover:opacity-100",
340
+ base: "absolute right-4 top-4 inline-flex h-6 w-6 items-center justify-center rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--background))] text-[hsl(var(--foreground))] opacity-0 transition-opacity hover:bg-[hsl(var(--muted))] focus:outline-none group-hover:opacity-100",
338
341
  icon: "h-3 w-3"
339
342
  },
340
343
  // Pre (code block)
341
344
  pre: {
342
- base: "relative mb-4 mt-6 overflow-x-auto rounded-lg border bg-muted p-4 font-mono text-sm",
345
+ base: "relative mb-4 mt-6 overflow-x-auto rounded-lg border border-[hsl(var(--border))] bg-[hsl(var(--muted))] p-4 font-mono text-sm",
343
346
  withCopy: "pr-12"
344
347
  },
345
348
  // Release
346
349
  release: {
347
350
  base: "space-y-4",
348
351
  version: "text-2xl font-bold",
349
- date: "text-sm text-muted-foreground",
352
+ date: "text-sm text-[hsl(var(--muted-foreground))]",
350
353
  changes: "space-y-2",
351
354
  changeItem: "flex items-start gap-2",
352
- badge: "inline-flex items-center rounded-full border px-2 py-0.5 text-xs font-semibold transition-colors",
355
+ badge: "inline-flex items-center rounded-full border border-[hsl(var(--border))] px-2 py-0.5 text-xs font-semibold transition-colors",
353
356
  badgeVariants: {
354
- major: "bg-red-100 text-red-800 border-red-200 dark:bg-red-900/30 dark:text-red-200 dark:border-red-800",
355
- minor: "bg-blue-100 text-blue-800 border-blue-200 dark:bg-blue-900/30 dark:text-blue-200 dark:border-blue-800",
356
- patch: "bg-green-100 text-green-800 border-green-200 dark:bg-green-900/30 dark:text-green-200 dark:border-green-800"
357
+ major: "bg-[hsl(var(--destructive))]/10 text-[hsl(var(--destructive))] border-[hsl(var(--destructive))]/20",
358
+ minor: "bg-[hsl(var(--primary))]/10 text-[hsl(var(--primary))] border-[hsl(var(--primary))]/20",
359
+ patch: "bg-[hsl(var(--success))]/10 text-[hsl(var(--success))] border-[hsl(var(--success))]/20"
357
360
  }
358
361
  },
359
362
  // YouTube
360
363
  youtube: {
361
- container: "relative aspect-video w-full overflow-hidden rounded-lg border",
364
+ container: "relative aspect-video w-full overflow-hidden rounded-lg border border-[hsl(var(--border))]",
362
365
  iframe: "absolute inset-0 h-full w-full"
363
366
  },
364
367
  // Image
365
368
  image: {
366
- base: "rounded-lg border",
367
- caption: "mt-2 text-center text-sm text-muted-foreground"
369
+ base: "rounded-lg border border-[hsl(var(--border))]",
370
+ caption: "mt-2 text-center text-sm text-[hsl(var(--muted-foreground))]"
368
371
  },
369
372
  // Link
370
373
  link: {
371
- base: "font-medium text-primary underline underline-offset-4 hover:text-primary/80"
374
+ base: "font-medium text-[hsl(var(--primary))] underline underline-offset-4 hover:text-[hsl(var(--primary))]/80"
372
375
  },
373
376
  // Tabs (Radix UI)
374
377
  tabs: {
375
378
  root: "w-full",
376
- list: "inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
377
- trigger: "inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",
378
- content: "mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
379
+ list: "inline-flex h-9 items-center justify-center rounded-lg bg-[hsl(var(--muted))] p-1 text-[hsl(var(--muted-foreground))]",
380
+ trigger: "inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-[hsl(var(--background))] transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))] focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-[hsl(var(--background))] data-[state=active]:text-[hsl(var(--foreground))] data-[state=active]:shadow-sm",
381
+ content: "mt-2 ring-offset-[hsl(var(--background))] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))] focus-visible:ring-offset-2"
379
382
  },
380
383
  // Collapsible
381
384
  collapsible: {
382
385
  base: "",
383
- trigger: "flex w-full items-center justify-between p-4 font-medium transition-all hover:bg-muted [&[data-state=open]>svg]:rotate-180",
386
+ trigger: "flex w-full items-center justify-between p-4 font-medium transition-all hover:bg-[hsl(var(--muted))] [&[data-state=open]>svg]:rotate-180",
384
387
  content: "overflow-hidden transition-all data-[state=closed]:animate-collapse-up data-[state=open]:animate-collapse-down"
385
388
  },
386
389
  // Dialog
387
390
  dialog: {
388
391
  overlay: "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
389
- content: "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
392
+ content: "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border border-[hsl(var(--border))] bg-[hsl(var(--background))] p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
390
393
  header: "flex flex-col space-y-1.5 text-center sm:text-left",
391
394
  footer: "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
392
395
  title: "text-lg font-semibold leading-none tracking-tight",
393
- description: "text-sm text-muted-foreground",
394
- close: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground"
396
+ description: "text-sm text-[hsl(var(--muted-foreground))]",
397
+ close: "absolute right-4 top-4 rounded-sm opacity-70 ring-offset-[hsl(var(--background))] transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-[hsl(var(--ring))] focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-[hsl(var(--accent))] data-[state=open]:text-[hsl(var(--muted-foreground))]"
395
398
  },
396
399
  // Dropdown Menu
397
400
  dropdownMenu: {
398
- content: "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
399
- item: "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
400
- separator: "-mx-1 my-1 h-px bg-muted",
401
+ content: "z-50 min-w-[8rem] overflow-hidden rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--popover))] text-[hsl(var(--popover-foreground))] shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
402
+ item: "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-[hsl(var(--accent))] focus:text-[hsl(var(--accent-foreground))] data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
403
+ separator: "-mx-1 my-1 h-px bg-[hsl(var(--border))]",
401
404
  label: "px-2 py-1.5 text-sm font-semibold"
402
405
  },
403
406
  // Select
404
407
  select: {
405
- trigger: "flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
406
- content: "relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
408
+ trigger: "flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-[hsl(var(--input))] bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-[hsl(var(--background))] placeholder:text-[hsl(var(--muted-foreground))] focus:outline-none focus:ring-1 focus:ring-[hsl(var(--ring))] disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
409
+ content: "relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border border-[hsl(var(--border))] bg-[hsl(var(--popover))] text-[hsl(var(--popover-foreground))] shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
407
410
  viewport: "p-1",
408
- item: "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
411
+ item: "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-[hsl(var(--accent))] focus:text-[hsl(var(--accent-foreground))] data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
409
412
  itemIndicator: "absolute right-2 flex h-3.5 w-3.5 items-center justify-center",
410
413
  groupLabel: "px-2 py-1.5 text-sm font-semibold"
411
414
  },
412
415
  // Checkbox
413
416
  checkbox: {
414
- base: "peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
417
+ base: "peer h-4 w-4 shrink-0 rounded-sm border border-[hsl(var(--primary))] ring-offset-[hsl(var(--background))] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))] focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-[hsl(var(--primary))] data-[state=checked]:text-[hsl(var(--primary-foreground))]",
415
418
  indicator: "flex items-center justify-center text-current"
416
419
  },
417
420
  // Switch
418
421
  switch: {
419
- base: "peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
420
- thumb: "pointer-events-none block h-4 w-4 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0"
422
+ base: "peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))] focus-visible:ring-offset-2 focus-visible:ring-offset-[hsl(var(--background))] disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-[hsl(var(--primary))] data-[state=unchecked]:bg-[hsl(var(--input))]",
423
+ thumb: "pointer-events-none block h-4 w-4 rounded-full bg-[hsl(var(--background))] shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0"
421
424
  },
422
425
  // Radio Group
423
426
  radioGroup: {
424
427
  root: "grid gap-2",
425
- item: "aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
428
+ item: "aspect-square h-4 w-4 rounded-full border border-[hsl(var(--primary))] text-[hsl(var(--primary))] ring-offset-[hsl(var(--background))] focus:outline-none focus-visible:ring-2 focus-visible:ring-[hsl(var(--ring))] focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
426
429
  indicator: "flex items-center justify-center"
427
430
  },
428
431
  // Separator
429
432
  separator: {
430
- base: "bg-border shrink-0",
433
+ base: "bg-[hsl(var(--border))] shrink-0",
431
434
  horizontal: "h-[1px] w-full",
432
435
  vertical: "h-full w-[1px]"
433
436
  }