@dheme/react 2.2.0 → 2.3.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.
Files changed (4) hide show
  1. package/README.md +133 -0
  2. package/dist/index.js +656 -413
  3. package/dist/index.mjs +657 -413
  4. package/package.json +3 -3
package/README.md CHANGED
@@ -274,6 +274,139 @@ The provider sets 19 CSS variables + `--radius` on `:root`:
274
274
 
275
275
  Values are in shadcn/ui format (`h s% l%`), directly compatible with Tailwind CSS `hsl()` usage.
276
276
 
277
+ ## ThemeGenerator
278
+
279
+ A floating FAB (Floating Action Button) that lets users generate and preview themes in real time — directly inside your app. No external dependencies beyond React itself.
280
+
281
+ ```tsx
282
+ import { DhemeProvider, ThemeGenerator } from '@dheme/react';
283
+
284
+ function App() {
285
+ return (
286
+ <DhemeProvider apiKey="..." theme="#3b82f6">
287
+ <MyApp />
288
+ <ThemeGenerator />
289
+ </DhemeProvider>
290
+ );
291
+ }
292
+ ```
293
+
294
+ The component renders as a pill in the corner of the screen. Clicking it expands a panel with color pickers, sliders, and toggles that call `generateTheme()` in real time with per-parameter debounce.
295
+
296
+ ### Props
297
+
298
+ ```tsx
299
+ <ThemeGenerator
300
+ defaultTheme="#4332f6" // Initial primary color
301
+ defaultSecondaryColor="#ab67f1" // Initial secondary color
302
+ defaultSaturation={10} // Initial saturation adjust (-100 to 100)
303
+ defaultLightness={2} // Initial lightness adjust (-100 to 100)
304
+ defaultRadius={0} // Initial border radius (0 to 2 rem)
305
+ position="bottom-right" // 'bottom-right' | 'bottom-left'
306
+ open={isOpen} // Controlled open state (optional)
307
+ onOpenChange={setIsOpen} // Controlled open callback (optional)
308
+ labels={{ // i18n overrides (all optional)
309
+ title: 'Theme Generator',
310
+ primary: 'Primary Color',
311
+ secondary: 'Secondary Color',
312
+ saturation: 'Vibrancy',
313
+ lightness: 'Brightness',
314
+ reset: 'Restore defaults',
315
+ }}
316
+ className="my-fab" // Extra class on the container (optional)
317
+ />
318
+ ```
319
+
320
+ | Prop | Type | Default | Description |
321
+ | --- | --- | --- | --- |
322
+ | `defaultTheme` | `string` | `'#4332f6'` | Initial primary HEX color. |
323
+ | `defaultSecondaryColor` | `string` | `'#ab67f1'` | Initial secondary HEX color. |
324
+ | `defaultSaturation` | `number` | `10` | Initial saturation adjust (-100–100). |
325
+ | `defaultLightness` | `number` | `2` | Initial lightness adjust (-100–100). |
326
+ | `defaultRadius` | `number` | `0` | Initial border radius (0–2 rem). |
327
+ | `position` | `'bottom-right' \| 'bottom-left'` | `'bottom-right'` | Corner to anchor the FAB. |
328
+ | `open` | `boolean` | — | Controlled open state. Omit for uncontrolled. |
329
+ | `onOpenChange` | `(open: boolean) => void` | — | Called when open state changes. |
330
+ | `labels` | `ThemeGeneratorLabels` | See below | Override any UI text for i18n. |
331
+ | `className` | `string` | — | Extra CSS class on the fixed container. |
332
+
333
+ #### Default labels
334
+
335
+ | Key | Default |
336
+ | --- | --- |
337
+ | `title` | `'Theme Generator'` |
338
+ | `description` | `'Generate complete themes from a single color. Changes apply in real time.'` |
339
+ | `baseColors` | `'Base Colors'` |
340
+ | `primary` | `'Primary'` |
341
+ | `secondary` | `'Secondary'` |
342
+ | `optional` | `'Optional'` |
343
+ | `fineTuning` | `'Fine Tuning'` |
344
+ | `saturation` | `'Saturation'` |
345
+ | `lightness` | `'Lightness'` |
346
+ | `borderRadius` | `'Border Radius'` |
347
+ | `advancedOptions` | `'Advanced Options'` |
348
+ | `colorfulCard` | `'Colorful Card'` |
349
+ | `colorfulBackground` | `'Colorful Background'` |
350
+ | `colorfulBorder` | `'Colorful Border'` |
351
+ | `reset` | `'Reset'` |
352
+ | `fabPrimaryLabel` | `'Primary'` |
353
+
354
+ ### How it works
355
+
356
+ **Real-time generation with debounce**
357
+
358
+ Each parameter has its own debounce timer. Dragging the saturation slider fires an API call 200ms after the user stops — not on every frame. Color pickers debounce at 150ms.
359
+
360
+ | Control | Debounce |
361
+ | --- | --- |
362
+ | Color pickers | 150ms |
363
+ | Sliders (saturation, lightness, radius) | 200ms |
364
+ | Boolean toggles (card, background, border) | None — fires immediately |
365
+ | Secondary color enable/disable | None — fires immediately |
366
+
367
+ **No re-render loops**
368
+
369
+ State local to the component (`localPrimary`, `localSaturation`, …) is the source of truth for the controls. The component does **not** read back from `useTheme()`. This prevents a loop where `generateTheme()` → theme state update → re-render → re-initialize state → `generateTheme()` again.
370
+
371
+ **Zero external dependencies**
372
+
373
+ - Icons: inline SVG (no `lucide-react`)
374
+ - Color picker: built-in gradient + hue slider using pointer events (no `react-colorful`)
375
+ - Styling: inline styles using `hsl(var(--...))` CSS variables — automatically matches the active theme
376
+
377
+ **Controlled vs uncontrolled**
378
+
379
+ Omit `open` / `onOpenChange` for fully uncontrolled behavior. Provide both for external control:
380
+
381
+ ```tsx
382
+ const [open, setOpen] = useState(false);
383
+
384
+ <ThemeGenerator open={open} onOpenChange={setOpen} />
385
+ <button onClick={() => setOpen(true)}>Open Theme Editor</button>
386
+ ```
387
+
388
+ ### Placement
389
+
390
+ `ThemeGenerator` must be a **descendant** of `<DhemeProvider>` — it consumes `useThemeActions()` internally.
391
+
392
+ ```tsx
393
+ // ✅ Correct
394
+ <DhemeProvider ...>
395
+ <App />
396
+ <ThemeGenerator />
397
+ </DhemeProvider>
398
+
399
+ // ❌ Wrong — outside the provider
400
+ <>
401
+ <ThemeGenerator />
402
+ <DhemeProvider ...>
403
+ <App />
404
+ </DhemeProvider>
405
+ </>
406
+ ```
407
+
408
+ ---
409
+
277
410
  ## Utilities
278
411
 
279
412
  ### `themeToCSS(theme, mode)`