dialkit 0.1.2 → 0.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 +249 -74
- package/dist/index.cjs +899 -259
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +82 -17
- package/dist/index.d.ts +82 -17
- package/dist/index.js +906 -269
- package/dist/index.js.map +1 -1
- package/dist/styles.css +620 -44
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,21 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Real-time parameter tweaking for React + Motion.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
## Installation
|
|
5
|
+
## Quick Start
|
|
8
6
|
|
|
9
7
|
```bash
|
|
10
8
|
npm install dialkit motion
|
|
11
9
|
```
|
|
12
10
|
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## Setup
|
|
16
|
-
|
|
17
|
-
Add `<DialRoot />` once in your app layout:
|
|
18
|
-
|
|
19
11
|
```tsx
|
|
12
|
+
// layout.tsx
|
|
20
13
|
import { DialRoot } from 'dialkit';
|
|
21
14
|
import 'dialkit/styles.css';
|
|
22
15
|
|
|
@@ -25,51 +18,41 @@ export default function Layout({ children }) {
|
|
|
25
18
|
<html>
|
|
26
19
|
<body>
|
|
27
20
|
{children}
|
|
28
|
-
<DialRoot
|
|
21
|
+
<DialRoot />
|
|
29
22
|
</body>
|
|
30
23
|
</html>
|
|
31
24
|
);
|
|
32
25
|
}
|
|
33
26
|
```
|
|
34
27
|
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
## Usage
|
|
38
|
-
|
|
39
28
|
```tsx
|
|
29
|
+
// component.tsx
|
|
40
30
|
import { useDialKit } from 'dialkit';
|
|
41
|
-
import { motion } from 'motion/react';
|
|
42
31
|
|
|
43
32
|
function Card() {
|
|
44
|
-
const
|
|
33
|
+
const p = useDialKit('Card', {
|
|
45
34
|
blur: [24, 0, 100],
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
type: 'spring',
|
|
50
|
-
visualDuration: 0.3,
|
|
51
|
-
bounce: 0.2,
|
|
52
|
-
},
|
|
35
|
+
scale: 1.2,
|
|
36
|
+
color: '#ff5500',
|
|
37
|
+
visible: true,
|
|
53
38
|
});
|
|
54
39
|
|
|
55
40
|
return (
|
|
56
|
-
<
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
41
|
+
<div style={{
|
|
42
|
+
filter: `blur(${p.blur}px)`,
|
|
43
|
+
transform: `scale(${p.scale})`,
|
|
44
|
+
color: p.color,
|
|
45
|
+
opacity: p.visible ? 1 : 0,
|
|
46
|
+
}}>
|
|
47
|
+
...
|
|
48
|
+
</div>
|
|
64
49
|
);
|
|
65
50
|
}
|
|
66
51
|
```
|
|
67
52
|
|
|
68
53
|
---
|
|
69
54
|
|
|
70
|
-
##
|
|
71
|
-
|
|
72
|
-
### useDialKit
|
|
55
|
+
## useDialKit
|
|
73
56
|
|
|
74
57
|
```tsx
|
|
75
58
|
const params = useDialKit(name, config, options?)
|
|
@@ -77,70 +60,262 @@ const params = useDialKit(name, config, options?)
|
|
|
77
60
|
|
|
78
61
|
| Param | Type | Description |
|
|
79
62
|
|-------|------|-------------|
|
|
80
|
-
| `name` | `string` | Panel title |
|
|
81
|
-
| `config` | `DialConfig` | Parameter definitions |
|
|
82
|
-
| `options.onAction` | `(
|
|
63
|
+
| `name` | `string` | Panel title displayed in the UI |
|
|
64
|
+
| `config` | `DialConfig` | Parameter definitions (see Control Types below) |
|
|
65
|
+
| `options.onAction` | `(path: string) => void` | Callback when action buttons are clicked |
|
|
66
|
+
|
|
67
|
+
Returns a fully typed object matching your config shape with live values. Updating a control in the UI immediately updates the returned values.
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Control Types
|
|
72
|
+
|
|
73
|
+
### Slider
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
blur: [24, 0, 100] // [default, min, max] — explicit range
|
|
77
|
+
scale: 1.2 // auto-infers range from value
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Numbers create sliders. With a tuple `[default, min, max]` you set the range explicitly. A bare number auto-infers a reasonable range:
|
|
81
|
+
|
|
82
|
+
| Value range | Inferred min/max | Step |
|
|
83
|
+
|-------------|-----------------|------|
|
|
84
|
+
| 0–1 | 0 to 1 | 0.01 |
|
|
85
|
+
| 0–10 | 0 to value × 3 | 0.1 |
|
|
86
|
+
| 0–100 | 0 to value × 3 | 1 |
|
|
87
|
+
| 100+ | 0 to value × 3 | 10 |
|
|
88
|
+
|
|
89
|
+
**Returns:** `number`
|
|
90
|
+
|
|
91
|
+
Sliders support click-to-snap (with spring animation), drag with rubber-band overflow, and direct text editing (hover the value for 800ms, then click to type).
|
|
92
|
+
|
|
93
|
+
### Toggle
|
|
83
94
|
|
|
84
|
-
|
|
95
|
+
```tsx
|
|
96
|
+
enabled: true
|
|
97
|
+
darkMode: false
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Booleans create an Off/On segmented control.
|
|
101
|
+
|
|
102
|
+
**Returns:** `boolean`
|
|
103
|
+
|
|
104
|
+
### Text
|
|
105
|
+
|
|
106
|
+
```tsx
|
|
107
|
+
title: 'Hello' // auto-detected from string
|
|
108
|
+
subtitle: { type: 'text', default: '', placeholder: 'Enter subtitle...' }
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Non-hex strings are auto-detected as text inputs. Use the explicit form for a placeholder or to set a default.
|
|
112
|
+
|
|
113
|
+
**Returns:** `string`
|
|
114
|
+
|
|
115
|
+
### Color
|
|
116
|
+
|
|
117
|
+
```tsx
|
|
118
|
+
color: '#ff5500' // auto-detected from hex string
|
|
119
|
+
bg: { type: 'color', default: '#000' } // explicit
|
|
120
|
+
```
|
|
85
121
|
|
|
86
|
-
|
|
87
|
-
|--------|---------|---------|
|
|
88
|
-
| `[default, min, max]` | Slider | `blur: [24, 0, 100]` |
|
|
89
|
-
| `number` | Slider (auto range) | `scale: 1.18` |
|
|
90
|
-
| `boolean` | Toggle | `enabled: true` |
|
|
91
|
-
| `{ type: 'spring', ... }` | Spring editor | See below |
|
|
92
|
-
| `{ type: 'action' }` | Button | `reset: { type: 'action' }` |
|
|
93
|
-
| `{ nested: ... }` | Folder | Nest any config |
|
|
122
|
+
Hex strings (`#RGB`, `#RRGGBB`, `#RRGGBBAA`) are auto-detected as color pickers. Each color control has a text display (click to edit the hex value), and a swatch button that opens the native color picker.
|
|
94
123
|
|
|
95
|
-
|
|
124
|
+
**Returns:** `string` (hex color)
|
|
96
125
|
|
|
97
|
-
|
|
126
|
+
### Select
|
|
98
127
|
|
|
99
128
|
```tsx
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
bounce: 0.2,
|
|
129
|
+
layout: {
|
|
130
|
+
type: 'select',
|
|
131
|
+
options: ['stack', 'fan', 'grid'],
|
|
132
|
+
default: 'stack',
|
|
105
133
|
}
|
|
134
|
+
```
|
|
106
135
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
136
|
+
Options can be plain strings or `{ value, label }` objects for custom display text:
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
shape: {
|
|
140
|
+
type: 'select',
|
|
141
|
+
options: [
|
|
142
|
+
{ value: 'portrait', label: 'Portrait' },
|
|
143
|
+
{ value: 'square', label: 'Square' },
|
|
144
|
+
{ value: 'landscape', label: 'Landscape' },
|
|
145
|
+
],
|
|
146
|
+
default: 'portrait',
|
|
113
147
|
}
|
|
114
148
|
```
|
|
115
149
|
|
|
116
|
-
|
|
150
|
+
If `default` is omitted, the first option is selected.
|
|
151
|
+
|
|
152
|
+
**Returns:** `string` (the selected option's value)
|
|
153
|
+
|
|
154
|
+
### Spring
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
// Time-based (simple mode)
|
|
158
|
+
spring: { type: 'spring', visualDuration: 0.3, bounce: 0.2 }
|
|
159
|
+
|
|
160
|
+
// Physics-based (advanced mode)
|
|
161
|
+
spring: { type: 'spring', stiffness: 200, damping: 25, mass: 1 }
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Creates a visual spring editor with a live animation curve preview. The editor supports two modes, toggled in the UI:
|
|
165
|
+
|
|
166
|
+
- **Time** (simple) — `visualDuration` (0.1–1s) and `bounce` (0–1). Ideal for most animations.
|
|
167
|
+
- **Physics** (advanced) — `stiffness` (1–1000), `damping` (1–100), and `mass` (0.1–10). Full control over spring dynamics.
|
|
168
|
+
|
|
169
|
+
The returned config object is passed directly to Motion's `transition` prop:
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
const p = useDialKit('Card', {
|
|
173
|
+
spring: { type: 'spring', visualDuration: 0.5, bounce: 0.04 },
|
|
174
|
+
x: [0, -200, 200],
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
<motion.div animate={{ x: p.x }} transition={p.spring} />
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
**Returns:** `SpringConfig` (pass directly to Motion)
|
|
117
181
|
|
|
118
|
-
|
|
182
|
+
### Action
|
|
119
183
|
|
|
120
184
|
```tsx
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
185
|
+
const p = useDialKit('Controls', {
|
|
186
|
+
shuffle: { type: 'action' },
|
|
187
|
+
reset: { type: 'action', label: 'Reset All' },
|
|
124
188
|
}, {
|
|
125
|
-
onAction: (
|
|
126
|
-
if (
|
|
127
|
-
if (
|
|
189
|
+
onAction: (path) => {
|
|
190
|
+
if (path === 'shuffle') shuffleItems();
|
|
191
|
+
if (path === 'reset') resetToDefaults();
|
|
128
192
|
},
|
|
129
193
|
});
|
|
130
194
|
```
|
|
131
195
|
|
|
132
|
-
|
|
196
|
+
Action buttons trigger callbacks without storing any value. The `label` defaults to the formatted key name (camelCase becomes Title Case). Multiple adjacent actions are grouped vertically.
|
|
197
|
+
|
|
198
|
+
### Folder
|
|
199
|
+
|
|
200
|
+
```tsx
|
|
201
|
+
shadow: {
|
|
202
|
+
blur: [10, 0, 50],
|
|
203
|
+
opacity: [0.25, 0, 1],
|
|
204
|
+
color: '#000000',
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Any nested plain object becomes a collapsible folder. Folders can nest arbitrarily deep. Access nested values with dot notation on the returned object:
|
|
209
|
+
|
|
210
|
+
```tsx
|
|
211
|
+
params.shadow.blur // number
|
|
212
|
+
params.shadow.color // string
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## DialRoot
|
|
133
218
|
|
|
134
219
|
```tsx
|
|
135
220
|
<DialRoot position="top-right" />
|
|
136
221
|
```
|
|
137
222
|
|
|
138
|
-
|
|
|
139
|
-
|
|
140
|
-
| `top-right` |
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
223
|
+
| Prop | Type | Default |
|
|
224
|
+
|------|------|---------|
|
|
225
|
+
| `position` | `'top-right' \| 'top-left' \| 'bottom-right' \| 'bottom-left'` | `'top-right'` |
|
|
226
|
+
|
|
227
|
+
Mount once at your app root. The panel renders via a portal on `document.body`. It collapses to a small icon button and expands to 280px wide on click.
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## Panel Toolbar
|
|
232
|
+
|
|
233
|
+
When the panel is open, the toolbar provides:
|
|
234
|
+
|
|
235
|
+
- **Presets** — A version dropdown for saving and loading parameter snapshots. Click "+" to save the current state as a new version. Select a version to load it. Changes auto-save to the active version. "Version 1" always represents the original defaults.
|
|
236
|
+
- **Copy** — Exports the current values as JSON to your clipboard.
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Full Example
|
|
241
|
+
|
|
242
|
+
```tsx
|
|
243
|
+
import { useDialKit } from 'dialkit';
|
|
244
|
+
import { motion } from 'motion/react';
|
|
245
|
+
|
|
246
|
+
function PhotoStack() {
|
|
247
|
+
const p = useDialKit('Photo Stack', {
|
|
248
|
+
// Text inputs
|
|
249
|
+
title: 'Japan',
|
|
250
|
+
subtitle: { type: 'text', default: 'December 2025', placeholder: 'Enter subtitle...' },
|
|
251
|
+
|
|
252
|
+
// Color pickers
|
|
253
|
+
accentColor: '#c41e3a',
|
|
254
|
+
shadowTint: { type: 'color', default: '#000000' },
|
|
255
|
+
|
|
256
|
+
// Select dropdown
|
|
257
|
+
layout: { type: 'select', options: ['stack', 'fan', 'grid'], default: 'stack' },
|
|
258
|
+
|
|
259
|
+
// Grouped sliders in a folder
|
|
260
|
+
backPhoto: {
|
|
261
|
+
offsetX: [239, 0, 400],
|
|
262
|
+
offsetY: [0, 0, 150],
|
|
263
|
+
scale: [0.7, 0.5, 0.95],
|
|
264
|
+
overlayOpacity: [0.6, 0, 1],
|
|
265
|
+
},
|
|
266
|
+
|
|
267
|
+
// Spring config for Motion
|
|
268
|
+
transitionSpring: { type: 'spring', visualDuration: 0.5, bounce: 0.04 },
|
|
269
|
+
|
|
270
|
+
// Toggle
|
|
271
|
+
darkMode: false,
|
|
272
|
+
|
|
273
|
+
// Action buttons
|
|
274
|
+
next: { type: 'action' },
|
|
275
|
+
previous: { type: 'action' },
|
|
276
|
+
}, {
|
|
277
|
+
onAction: (action) => {
|
|
278
|
+
if (action === 'next') goNext();
|
|
279
|
+
if (action === 'previous') goPrevious();
|
|
280
|
+
},
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
return (
|
|
284
|
+
<motion.div
|
|
285
|
+
animate={{ x: p.backPhoto.offsetX }}
|
|
286
|
+
transition={p.transitionSpring}
|
|
287
|
+
style={{ color: p.accentColor }}
|
|
288
|
+
>
|
|
289
|
+
<h1>{p.title}</h1>
|
|
290
|
+
<p>{p.subtitle}</p>
|
|
291
|
+
</motion.div>
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## Types
|
|
299
|
+
|
|
300
|
+
All config and value types are exported:
|
|
301
|
+
|
|
302
|
+
```tsx
|
|
303
|
+
import type {
|
|
304
|
+
SpringConfig,
|
|
305
|
+
ActionConfig,
|
|
306
|
+
SelectConfig,
|
|
307
|
+
ColorConfig,
|
|
308
|
+
TextConfig,
|
|
309
|
+
DialConfig,
|
|
310
|
+
DialValue,
|
|
311
|
+
ResolvedValues,
|
|
312
|
+
ControlMeta,
|
|
313
|
+
PanelConfig,
|
|
314
|
+
Preset,
|
|
315
|
+
} from 'dialkit';
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
Return values are fully typed: `params.blur` infers as `number`, `params.color` as `string`, `params.spring` as `SpringConfig`, `params.shadow` as a nested object, etc.
|
|
144
319
|
|
|
145
320
|
---
|
|
146
321
|
|