dialkit 1.0.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.
- package/README.md +293 -2
- package/dist/index.cjs +905 -363
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +46 -9
- package/dist/index.d.ts +46 -9
- package/dist/index.js +910 -370
- package/dist/index.js.map +1 -1
- package/dist/solid/index.cjs +1042 -532
- package/dist/solid/index.cjs.map +1 -1
- package/dist/solid/index.d.cts +36 -3
- package/dist/solid/index.d.ts +36 -3
- package/dist/solid/index.js +911 -402
- package/dist/solid/index.js.map +1 -1
- package/dist/store/index.cjs +490 -0
- package/dist/store/index.cjs.map +1 -0
- package/dist/store/index.d.cts +146 -0
- package/dist/store/index.d.ts +146 -0
- package/dist/store/index.js +465 -0
- package/dist/store/index.js.map +1 -0
- package/dist/styles.css +287 -25
- package/dist/svelte/Portal.svelte +30 -0
- package/dist/svelte/Portal.svelte.d.ts +9 -0
- package/dist/svelte/Portal.svelte.d.ts.map +1 -0
- package/dist/svelte/components/ButtonGroup.svelte +16 -0
- package/dist/svelte/components/ButtonGroup.svelte.d.ts +11 -0
- package/dist/svelte/components/ButtonGroup.svelte.d.ts.map +1 -0
- package/dist/svelte/components/ColorControl.svelte +81 -0
- package/dist/svelte/components/ColorControl.svelte.d.ts +9 -0
- package/dist/svelte/components/ColorControl.svelte.d.ts.map +1 -0
- package/dist/svelte/components/ControlRenderer.svelte +96 -0
- package/dist/svelte/components/ControlRenderer.svelte.d.ts +11 -0
- package/dist/svelte/components/ControlRenderer.svelte.d.ts.map +1 -0
- package/dist/svelte/components/DialRoot.svelte +79 -0
- package/dist/svelte/components/DialRoot.svelte.d.ts +14 -0
- package/dist/svelte/components/DialRoot.svelte.d.ts.map +1 -0
- package/dist/svelte/components/EasingVisualization.svelte +50 -0
- package/dist/svelte/components/EasingVisualization.svelte.d.ts +10 -0
- package/dist/svelte/components/EasingVisualization.svelte.d.ts.map +1 -0
- package/dist/svelte/components/Folder.svelte +213 -0
- package/dist/svelte/components/Folder.svelte.d.ts +14 -0
- package/dist/svelte/components/Folder.svelte.d.ts.map +1 -0
- package/dist/svelte/components/Panel.svelte +149 -0
- package/dist/svelte/components/Panel.svelte.d.ts +10 -0
- package/dist/svelte/components/Panel.svelte.d.ts.map +1 -0
- package/dist/svelte/components/PresetManager.svelte +157 -0
- package/dist/svelte/components/PresetManager.svelte.d.ts +10 -0
- package/dist/svelte/components/PresetManager.svelte.d.ts.map +1 -0
- package/dist/svelte/components/SegmentedControl.svelte +62 -0
- package/dist/svelte/components/SegmentedControl.svelte.d.ts +13 -0
- package/dist/svelte/components/SegmentedControl.svelte.d.ts.map +1 -0
- package/dist/svelte/components/SelectControl.svelte +152 -0
- package/dist/svelte/components/SelectControl.svelte.d.ts +14 -0
- package/dist/svelte/components/SelectControl.svelte.d.ts.map +1 -0
- package/dist/svelte/components/ShortcutListener.svelte +265 -0
- package/dist/svelte/components/ShortcutListener.svelte.d.ts +13 -0
- package/dist/svelte/components/ShortcutListener.svelte.d.ts.map +1 -0
- package/dist/svelte/components/ShortcutsMenu.svelte +128 -0
- package/dist/svelte/components/ShortcutsMenu.svelte.d.ts +7 -0
- package/dist/svelte/components/ShortcutsMenu.svelte.d.ts.map +1 -0
- package/dist/svelte/components/Slider.svelte +332 -0
- package/dist/svelte/components/Slider.svelte.d.ts +16 -0
- package/dist/svelte/components/Slider.svelte.d.ts.map +1 -0
- package/dist/svelte/components/SpringControl.svelte +126 -0
- package/dist/svelte/components/SpringControl.svelte.d.ts +12 -0
- package/dist/svelte/components/SpringControl.svelte.d.ts.map +1 -0
- package/dist/svelte/components/SpringVisualization.svelte +115 -0
- package/dist/svelte/components/SpringVisualization.svelte.d.ts +9 -0
- package/dist/svelte/components/SpringVisualization.svelte.d.ts.map +1 -0
- package/dist/svelte/components/TextControl.svelte +19 -0
- package/dist/svelte/components/TextControl.svelte.d.ts +10 -0
- package/dist/svelte/components/TextControl.svelte.d.ts.map +1 -0
- package/dist/svelte/components/Toggle.svelte +32 -0
- package/dist/svelte/components/Toggle.svelte.d.ts +12 -0
- package/dist/svelte/components/Toggle.svelte.d.ts.map +1 -0
- package/dist/svelte/components/TransitionControl.svelte +203 -0
- package/dist/svelte/components/TransitionControl.svelte.d.ts +12 -0
- package/dist/svelte/components/TransitionControl.svelte.d.ts.map +1 -0
- package/dist/svelte/components/transitions.d.ts +6 -0
- package/dist/svelte/components/transitions.d.ts.map +1 -0
- package/dist/svelte/components/transitions.js +14 -0
- package/dist/svelte/createDialKit.svelte.d.ts +8 -0
- package/dist/svelte/createDialKit.svelte.d.ts.map +1 -0
- package/dist/svelte/createDialKit.svelte.js +82 -0
- package/dist/svelte/index.d.ts +23 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +23 -0
- package/dist/svelte/shims.d.ts +9 -0
- package/dist/svelte/theme-css.d.ts +2 -0
- package/dist/svelte/theme-css.d.ts.map +1 -0
- package/dist/svelte/theme-css.js +1328 -0
- package/dist/vue/index.cjs +3056 -0
- package/dist/vue/index.cjs.map +1 -0
- package/dist/vue/index.d.cts +675 -0
- package/dist/vue/index.d.ts +675 -0
- package/dist/vue/index.js +3014 -0
- package/dist/vue/index.js.map +1 -0
- package/package.json +50 -6
package/README.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# dialkit
|
|
2
2
|
|
|
3
|
-
Real-time parameter tweaking for React
|
|
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
|
|
|
@@ -256,8 +265,47 @@ const values = useDialKit('Controls', {
|
|
|
256
265
|
|------|------|---------|
|
|
257
266
|
| `position` | `'top-right' \| 'top-left' \| 'bottom-right' \| 'bottom-left'` | `'top-right'` |
|
|
258
267
|
| `defaultOpen` | `boolean` | `true` |
|
|
268
|
+
| `mode` | `'popover' \| 'inline'` | `'popover'` |
|
|
269
|
+
| `productionEnabled` | `boolean` | `false` in production, `true` otherwise |
|
|
270
|
+
|
|
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.
|
|
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
|
+
|
|
283
|
+
### Inline mode
|
|
284
|
+
|
|
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:
|
|
286
|
+
|
|
287
|
+
**React:**
|
|
288
|
+
```tsx
|
|
289
|
+
<aside style={{ width: 300, height: '100vh', overflow: 'hidden' }}>
|
|
290
|
+
<DialRoot mode="inline" />
|
|
291
|
+
</aside>
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
**Solid:**
|
|
295
|
+
```tsx
|
|
296
|
+
<aside style={{ width: '300px', height: '100vh', overflow: 'hidden' }}>
|
|
297
|
+
<DialRoot mode="inline" />
|
|
298
|
+
</aside>
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
**Svelte:**
|
|
302
|
+
```svelte
|
|
303
|
+
<aside style:width="300px" style:height="100vh" style:overflow="hidden">
|
|
304
|
+
<DialRoot mode="inline" />
|
|
305
|
+
</aside>
|
|
306
|
+
```
|
|
259
307
|
|
|
260
|
-
|
|
308
|
+
In inline mode, the `position` prop is ignored and the collapse-to-icon behavior is disabled.
|
|
261
309
|
|
|
262
310
|
---
|
|
263
311
|
|
|
@@ -270,6 +318,88 @@ When the panel is open, the toolbar provides:
|
|
|
270
318
|
|
|
271
319
|
---
|
|
272
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 ÷ 10 | Precision tweaking |
|
|
381
|
+
| `normal` | step × 1 | Default behavior |
|
|
382
|
+
| `coarse` | step × 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
|
+
|
|
273
403
|
## Full Example
|
|
274
404
|
|
|
275
405
|
```tsx
|
|
@@ -307,6 +437,11 @@ function PhotoStack() {
|
|
|
307
437
|
next: { type: 'action' },
|
|
308
438
|
previous: { type: 'action' },
|
|
309
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
|
+
},
|
|
310
445
|
onAction: (action) => {
|
|
311
446
|
if (action === 'next') goNext();
|
|
312
447
|
if (action === 'previous') goPrevious();
|
|
@@ -328,6 +463,160 @@ function PhotoStack() {
|
|
|
328
463
|
|
|
329
464
|
---
|
|
330
465
|
|
|
466
|
+
## Solid
|
|
467
|
+
|
|
468
|
+
DialKit also works with Solid. Import from `dialkit/solid` instead of `dialkit` — the API mirrors the React version, with `createDialKit` replacing `useDialKit` and `DialRoot` as a Solid component.
|
|
469
|
+
|
|
470
|
+
```bash
|
|
471
|
+
npm install dialkit solid-js
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
```tsx
|
|
475
|
+
// App.tsx
|
|
476
|
+
import { DialRoot } from 'dialkit/solid';
|
|
477
|
+
import 'dialkit/styles.css';
|
|
478
|
+
|
|
479
|
+
export default function App() {
|
|
480
|
+
return (
|
|
481
|
+
<>
|
|
482
|
+
<MyComponent />
|
|
483
|
+
<DialRoot />
|
|
484
|
+
</>
|
|
485
|
+
);
|
|
486
|
+
}
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
```tsx
|
|
490
|
+
// component.tsx
|
|
491
|
+
import { createDialKit } from 'dialkit/solid';
|
|
492
|
+
|
|
493
|
+
function Card() {
|
|
494
|
+
const params = createDialKit('Card', {
|
|
495
|
+
blur: [24, 0, 100],
|
|
496
|
+
scale: 1.2,
|
|
497
|
+
color: '#ff5500',
|
|
498
|
+
visible: true,
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
return (
|
|
502
|
+
<div style={{
|
|
503
|
+
filter: `blur(${params().blur}px)`,
|
|
504
|
+
transform: `scale(${params().scale})`,
|
|
505
|
+
color: params().color,
|
|
506
|
+
opacity: params().visible ? 1 : 0,
|
|
507
|
+
}}>
|
|
508
|
+
...
|
|
509
|
+
</div>
|
|
510
|
+
);
|
|
511
|
+
}
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
`createDialKit` returns an accessor — call `params()` to read the current values. All control types, config shapes, and panel features (presets, copy, folders) work identically to the React version.
|
|
515
|
+
|
|
516
|
+
---
|
|
517
|
+
|
|
518
|
+
## Svelte
|
|
519
|
+
|
|
520
|
+
DialKit works with Svelte 5 (≥5.8.0). Import from `dialkit/svelte` — no extra dependencies needed.
|
|
521
|
+
|
|
522
|
+
```bash
|
|
523
|
+
npm install dialkit
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
```svelte
|
|
527
|
+
<!-- +layout.svelte -->
|
|
528
|
+
<script>
|
|
529
|
+
import { DialRoot } from 'dialkit/svelte';
|
|
530
|
+
let { children } = $props();
|
|
531
|
+
</script>
|
|
532
|
+
|
|
533
|
+
{@render children()}
|
|
534
|
+
<DialRoot />
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
```svelte
|
|
538
|
+
<!-- Card.svelte -->
|
|
539
|
+
<script>
|
|
540
|
+
import { createDialKit } from 'dialkit/svelte';
|
|
541
|
+
|
|
542
|
+
const params = createDialKit('Card', {
|
|
543
|
+
blur: [24, 0, 100],
|
|
544
|
+
scale: 1.2,
|
|
545
|
+
color: '#ff5500',
|
|
546
|
+
visible: true
|
|
547
|
+
});
|
|
548
|
+
</script>
|
|
549
|
+
|
|
550
|
+
<div style:filter={`blur(${params.blur}px)`} style:color={params.color}>
|
|
551
|
+
...
|
|
552
|
+
</div>
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
`createDialKit` returns a reactive object — access values directly (e.g. `params.blur`). Styles are injected automatically by `DialRoot` (no CSS import needed). Cleanup is automatic when the component unmounts. All control types, presets, folders, and transitions match the React/Solid entries.
|
|
556
|
+
|
|
557
|
+
---
|
|
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
|
+
|
|
331
620
|
## Types
|
|
332
621
|
|
|
333
622
|
All config and value types are exported:
|
|
@@ -339,6 +628,8 @@ import type {
|
|
|
339
628
|
SelectConfig,
|
|
340
629
|
ColorConfig,
|
|
341
630
|
TextConfig,
|
|
631
|
+
ShortcutConfig,
|
|
632
|
+
ShortcutMode,
|
|
342
633
|
DialConfig,
|
|
343
634
|
DialValue,
|
|
344
635
|
ResolvedValues,
|