dialkit 1.1.0 → 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.
Files changed (67) hide show
  1. package/README.md +171 -1
  2. package/dist/index.cjs +876 -337
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +41 -6
  5. package/dist/index.d.ts +41 -6
  6. package/dist/index.js +878 -341
  7. package/dist/index.js.map +1 -1
  8. package/dist/solid/index.cjs +1011 -544
  9. package/dist/solid/index.cjs.map +1 -1
  10. package/dist/solid/index.d.cts +33 -3
  11. package/dist/solid/index.d.ts +33 -3
  12. package/dist/solid/index.js +864 -398
  13. package/dist/solid/index.js.map +1 -1
  14. package/dist/store/index.cjs +52 -12
  15. package/dist/store/index.cjs.map +1 -1
  16. package/dist/store/index.d.cts +25 -3
  17. package/dist/store/index.d.ts +25 -3
  18. package/dist/store/index.js +52 -12
  19. package/dist/store/index.js.map +1 -1
  20. package/dist/styles.css +256 -25
  21. package/dist/svelte/components/ControlRenderer.svelte +12 -0
  22. package/dist/svelte/components/ControlRenderer.svelte.d.ts.map +1 -1
  23. package/dist/svelte/components/DialRoot.svelte +22 -8
  24. package/dist/svelte/components/DialRoot.svelte.d.ts +3 -0
  25. package/dist/svelte/components/DialRoot.svelte.d.ts.map +1 -1
  26. package/dist/svelte/components/Folder.svelte +17 -8
  27. package/dist/svelte/components/Folder.svelte.d.ts.map +1 -1
  28. package/dist/svelte/components/Panel.svelte +14 -9
  29. package/dist/svelte/components/Panel.svelte.d.ts.map +1 -1
  30. package/dist/svelte/components/PresetManager.svelte +7 -6
  31. package/dist/svelte/components/PresetManager.svelte.d.ts.map +1 -1
  32. package/dist/svelte/components/SegmentedControl.svelte +30 -74
  33. package/dist/svelte/components/SegmentedControl.svelte.d.ts.map +1 -1
  34. package/dist/svelte/components/SelectControl.svelte +2 -1
  35. package/dist/svelte/components/SelectControl.svelte.d.ts.map +1 -1
  36. package/dist/svelte/components/ShortcutListener.svelte +265 -0
  37. package/dist/svelte/components/ShortcutListener.svelte.d.ts +13 -0
  38. package/dist/svelte/components/ShortcutListener.svelte.d.ts.map +1 -0
  39. package/dist/svelte/components/ShortcutsMenu.svelte +128 -0
  40. package/dist/svelte/components/ShortcutsMenu.svelte.d.ts +7 -0
  41. package/dist/svelte/components/ShortcutsMenu.svelte.d.ts.map +1 -0
  42. package/dist/svelte/components/Slider.svelte +16 -29
  43. package/dist/svelte/components/Slider.svelte.d.ts +3 -0
  44. package/dist/svelte/components/Slider.svelte.d.ts.map +1 -1
  45. package/dist/svelte/components/SpringControl.svelte +17 -15
  46. package/dist/svelte/components/SpringControl.svelte.d.ts.map +1 -1
  47. package/dist/svelte/components/Toggle.svelte +13 -2
  48. package/dist/svelte/components/Toggle.svelte.d.ts +3 -0
  49. package/dist/svelte/components/Toggle.svelte.d.ts.map +1 -1
  50. package/dist/svelte/components/TransitionControl.svelte +28 -25
  51. package/dist/svelte/components/TransitionControl.svelte.d.ts.map +1 -1
  52. package/dist/svelte/createDialKit.svelte.d.ts +2 -1
  53. package/dist/svelte/createDialKit.svelte.d.ts.map +1 -1
  54. package/dist/svelte/createDialKit.svelte.js +1 -1
  55. package/dist/svelte/index.d.ts +6 -2
  56. package/dist/svelte/index.d.ts.map +1 -1
  57. package/dist/svelte/index.js +4 -0
  58. package/dist/svelte/theme-css.d.ts +1 -1
  59. package/dist/svelte/theme-css.d.ts.map +1 -1
  60. package/dist/svelte/theme-css.js +257 -26
  61. package/dist/vue/index.cjs +3056 -0
  62. package/dist/vue/index.cjs.map +1 -0
  63. package/dist/vue/index.d.cts +675 -0
  64. package/dist/vue/index.d.ts +675 -0
  65. package/dist/vue/index.js +3014 -0
  66. package/dist/vue/index.js.map +1 -0
  67. package/package.json +24 -4
package/README.md CHANGED
@@ -1,6 +1,14 @@
1
1
  # dialkit
2
2
 
3
- Real-time parameter tweaking for React, Solid, and Svelte.
3
+ Real-time parameter tweaking for React, Solid, Svelte, and Vue, created by Josh Puckett.
4
+
5
+ To learn more about how I use DialKit, and approach design in general, feel free to check out [Interface Craft](http://interfacecraft.dev/).
6
+
7
+ ## Contributing
8
+
9
+ - **Open an issue first.** All pull requests should reference an existing issue. PRs without a corresponding issue will be closed.
10
+ - **Keep PRs small and focused.** Each pull request should address a single change — one bug fix, one feature, or one refactor. Avoid bundling unrelated changes together.
11
+ - **No unnecessary dependencies.** If your change can be accomplished without adding a new dependency, it should be. Any new dependency needs justification in the PR description.
4
12
 
5
13
  ## Quick Start
6
14
 
@@ -63,6 +71,7 @@ const params = useDialKit(name, config, options?)
63
71
  | `name` | `string` | Panel title displayed in the UI |
64
72
  | `config` | `DialConfig` | Parameter definitions (see Control Types below) |
65
73
  | `options.onAction` | `(path: string) => void` | Callback when action buttons are clicked |
74
+ | `options.shortcuts` | `Record<string, ShortcutConfig>` | Keyboard shortcuts for controls (see [Keyboard Shortcuts](#keyboard-shortcuts)) |
66
75
 
67
76
  Returns a fully typed object matching your config shape with live values. Updating a control in the UI immediately updates the returned values.
68
77
 
@@ -257,9 +266,20 @@ const values = useDialKit('Controls', {
257
266
  | `position` | `'top-right' \| 'top-left' \| 'bottom-right' \| 'bottom-left'` | `'top-right'` |
258
267
  | `defaultOpen` | `boolean` | `true` |
259
268
  | `mode` | `'popover' \| 'inline'` | `'popover'` |
269
+ | `productionEnabled` | `boolean` | `false` in production, `true` otherwise |
260
270
 
261
271
  Mount once at your app root. In the default `popover` mode, the panel renders via a portal on `document.body`. It collapses to a small icon button and expands to 280px wide on click.
262
272
 
273
+ DialKit is automatically hidden in production builds. To enable it in production, pass `productionEnabled`:
274
+
275
+ ```tsx
276
+ <DialRoot productionEnabled />
277
+ ```
278
+
279
+ ### Draggable panel
280
+
281
+ In popover mode, the collapsed panel bubble can be dragged to any position on the screen. When you click to open the panel, it snaps to the nearest side — top-left if the bubble is on the left half of the screen, top-right if on the right half. When the panel is closed again, it returns to where you last dragged it.
282
+
263
283
  ### Inline mode
264
284
 
265
285
  Use `mode="inline"` to render DialKit directly in your layout instead of as a floating popover. The panel fills its container and scrolls internally, which is useful for embedding in a sidebar or resizable panel. Inline mode works across all frameworks:
@@ -298,6 +318,88 @@ When the panel is open, the toolbar provides:
298
318
 
299
319
  ---
300
320
 
321
+ ## Keyboard Shortcuts
322
+
323
+ Assign keyboard shortcuts to controls so you can adjust values without touching the panel. Pass a `shortcuts` map in the options object:
324
+
325
+ ```tsx
326
+ const p = useDialKit('Card', {
327
+ blur: [24, 0, 100],
328
+ scale: 1.2,
329
+ opacity: [1, 0, 1],
330
+ borderRadius: [16, 0, 64],
331
+ darkMode: true,
332
+ shadow: {
333
+ blur: [10, 0, 50],
334
+ },
335
+ }, {
336
+ shortcuts: {
337
+ blur: { key: 'b', mode: 'fine' }, // B+Scroll
338
+ scale: { key: 's', interaction: 'drag', mode: 'coarse' }, // S+Drag
339
+ opacity: { key: 'o', interaction: 'move' }, // O+Move
340
+ borderRadius: { interaction: 'scroll-only' }, // Scroll (no key)
341
+ darkMode: { key: 'm' }, // press M
342
+ 'shadow.blur': { key: 'd', mode: 'fine' }, // D+Scroll
343
+ },
344
+ });
345
+ ```
346
+
347
+ ### ShortcutConfig
348
+
349
+ ```tsx
350
+ type ShortcutConfig = {
351
+ key?: string; // trigger key (e.g. 'b', 's') — optional for scroll-only
352
+ modifier?: 'alt' | 'shift' | 'meta'; // optional modifier key
353
+ mode?: 'fine' | 'normal' | 'coarse'; // precision level (default: 'normal')
354
+ interaction?: 'scroll' | 'drag' | 'move' | 'scroll-only'; // input method (default: 'scroll')
355
+ };
356
+ ```
357
+
358
+ ### Interaction types
359
+
360
+ | Interaction | Description | Example pill |
361
+ |-------------|-------------|-------------|
362
+ | `scroll` | Hold key + scroll wheel to adjust (default) | `B+Scroll` |
363
+ | `drag` | Hold key + click and drag horizontally | `S+Drag` |
364
+ | `move` | Hold key + move mouse (no click needed) | `O+Move` |
365
+ | `scroll-only` | Just scroll anywhere, no key needed | `Scroll` |
366
+
367
+ ### Supported controls
368
+
369
+ | Control | Interactions | Description |
370
+ |---------|-------------|-------------|
371
+ | **Slider** | `scroll`, `drag`, `move`, `scroll-only` | Adjust value with chosen input method |
372
+ | **Toggle** | key press | Press the assigned key to flip on/off |
373
+
374
+ ### Precision modes
375
+
376
+ For sliders, the `mode` controls how much each scroll tick or drag pixel changes the value:
377
+
378
+ | Mode | Step multiplier | Use case |
379
+ |------|----------------|----------|
380
+ | `fine` | step &divide; 10 | Precision tweaking |
381
+ | `normal` | step &times; 1 | Default behavior |
382
+ | `coarse` | step &times; 10 | Big sweeps |
383
+
384
+ ### Nested paths
385
+
386
+ For controls inside folders, use dot notation:
387
+
388
+ ```tsx
389
+ shortcuts: {
390
+ 'shadow.blur': { key: 'd' },
391
+ 'shadow.opacity': { key: 'a', interaction: 'drag', mode: 'fine' },
392
+ }
393
+ ```
394
+
395
+ ### UI indicators
396
+
397
+ Each control with a shortcut displays a pill badge next to its label showing the key and interaction (e.g. `B+Scroll`, `S+Drag`, `O+Move`, `Scroll`). The pill highlights when the shortcut key is actively held.
398
+
399
+ Shortcuts are automatically disabled when a text input is focused.
400
+
401
+ ---
402
+
301
403
  ## Full Example
302
404
 
303
405
  ```tsx
@@ -335,6 +437,11 @@ function PhotoStack() {
335
437
  next: { type: 'action' },
336
438
  previous: { type: 'action' },
337
439
  }, {
440
+ shortcuts: {
441
+ 'backPhoto.offsetX': { key: 'x', interaction: 'drag', mode: 'coarse' },
442
+ 'backPhoto.scale': { key: 's', interaction: 'move', mode: 'fine' },
443
+ darkMode: { key: 'm' },
444
+ },
338
445
  onAction: (action) => {
339
446
  if (action === 'next') goNext();
340
447
  if (action === 'previous') goPrevious();
@@ -449,6 +556,67 @@ npm install dialkit
449
556
 
450
557
  ---
451
558
 
559
+ ## Vue
560
+
561
+ DialKit works with Vue 3 (≥3.3.0). Import from `dialkit/vue`.
562
+
563
+ ```bash
564
+ npm install dialkit motion-v vue
565
+ ```
566
+
567
+ ```ts
568
+ // main.ts
569
+ import { createApp } from 'vue';
570
+ import { DialRoot } from 'dialkit/vue';
571
+ import 'dialkit/styles.css';
572
+ import App from './App.vue';
573
+
574
+ const app = createApp(App);
575
+ app.mount('#app');
576
+ ```
577
+
578
+ ```vue
579
+ <!-- App.vue -->
580
+ <script setup>
581
+ import { DialRoot } from 'dialkit/vue';
582
+ import Card from './Card.vue';
583
+ </script>
584
+
585
+ <template>
586
+ <Card />
587
+ <DialRoot />
588
+ </template>
589
+ ```
590
+
591
+ ```vue
592
+ <!-- Card.vue -->
593
+ <script setup>
594
+ import { useDialKit } from 'dialkit/vue';
595
+
596
+ const params = useDialKit('Card', {
597
+ blur: [24, 0, 100],
598
+ scale: 1.2,
599
+ color: '#ff5500',
600
+ visible: true,
601
+ });
602
+ </script>
603
+
604
+ <template>
605
+ <div :style="{
606
+ filter: `blur(${params.blur}px)`,
607
+ transform: `scale(${params.scale})`,
608
+ color: params.color,
609
+ opacity: params.visible ? 1 : 0,
610
+ }">
611
+ ...
612
+ </div>
613
+ </template>
614
+ ```
615
+
616
+ `useDialKit` returns a reactive object. All control types, presets, folders, keyboard shortcuts, and transitions work identically to the other frameworks.
617
+
618
+ ---
619
+
452
620
  ## Types
453
621
 
454
622
  All config and value types are exported:
@@ -460,6 +628,8 @@ import type {
460
628
  SelectConfig,
461
629
  ColorConfig,
462
630
  TextConfig,
631
+ ShortcutConfig,
632
+ ShortcutMode,
463
633
  DialConfig,
464
634
  DialValue,
465
635
  ResolvedValues,