@kitlangton/knobs 0.4.0-next.0 → 0.4.0-next.10

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 (74) hide show
  1. package/README.md +451 -54
  2. package/dist/dev/{chunk-7xgkerd2.js → chunk-3ygqgy1x.js} +23 -1
  3. package/dist/dev/{chunk-stbcgz1y.js → chunk-5pb7ymrd.js} +567 -471
  4. package/dist/dev/{chunk-t68smqkc.js → chunk-a7cjgy8x.js} +13 -11
  5. package/dist/dev/{chunk-pmkvb9ep.js → chunk-dyq4m24m.js} +2081 -507
  6. package/dist/dev/index.js +10 -5
  7. package/dist/index.js +25 -1
  8. package/dist/panel.js +3187 -1341
  9. package/dist/react.js +294 -6
  10. package/dist/review-react.js +18580 -0
  11. package/dist/review-solid.js +18482 -0
  12. package/dist/review.js +18488 -0
  13. package/dist/solid.js +292 -4
  14. package/dist/themes.js +1767 -7
  15. package/dist/types/core/adapter.d.ts +6 -2
  16. package/dist/types/core/appearance.d.ts +44 -0
  17. package/dist/types/core/glide.d.ts +7 -0
  18. package/dist/types/core/motion.d.ts +66 -0
  19. package/dist/types/core/root.d.ts +13 -0
  20. package/dist/types/core/store.d.ts +18 -5
  21. package/dist/types/core/theme.d.ts +10 -3
  22. package/dist/types/index.d.ts +2 -1
  23. package/dist/types/panel/gpu/color.d.ts +6 -0
  24. package/dist/types/panel/motion.d.ts +1 -1
  25. package/dist/types/panel/styles.d.ts +2 -3
  26. package/dist/types/review/font.d.ts +13 -0
  27. package/dist/types/review/foundations.d.ts +175 -0
  28. package/dist/types/review/index.d.ts +13 -0
  29. package/dist/types/review/react.d.ts +1 -0
  30. package/dist/types/review/solid.d.ts +1 -0
  31. package/dist/types/themes/define.d.ts +104 -0
  32. package/dist/types/themes/index.d.ts +16 -0
  33. package/dist/types/themes/knobs.d.ts +5 -0
  34. package/dist/types/themes/review.d.ts +8 -0
  35. package/dist/types/themes/void.d.ts +8 -0
  36. package/dist/types/tokens/color.d.ts +42 -0
  37. package/dist/types/tokens/css.d.ts +13 -0
  38. package/dist/types/tokens/evaluate.d.ts +8 -0
  39. package/dist/types/tokens/index.d.ts +4 -0
  40. package/dist/types/tokens/schema.d.ts +1280 -0
  41. package/dist/types/ui/bento-css.d.ts +1 -1
  42. package/dist/types/ui/compare-css.d.ts +1 -1
  43. package/dist/types/ui/compare-gpu.d.ts +6 -6
  44. package/dist/types/ui/compare-model.d.ts +85 -2
  45. package/dist/types/ui/compare.d.ts +18 -4
  46. package/dist/types/ui/diff.d.ts +4 -5
  47. package/dist/types/ui/history-css.d.ts +1 -0
  48. package/dist/types/ui/history-model.d.ts +249 -0
  49. package/dist/types/ui/history.d.ts +38 -0
  50. package/dist/types/ui/icons.d.ts +40 -0
  51. package/dist/types/ui/index.d.ts +9 -5
  52. package/dist/types/ui/look.d.ts +18 -13
  53. package/dist/types/ui/overlay-css.d.ts +1 -1
  54. package/dist/types/ui/player-css.d.ts +1 -0
  55. package/dist/types/ui/player.d.ts +51 -0
  56. package/dist/types/ui/readout-css.d.ts +1 -1
  57. package/dist/types/ui/readout-model.d.ts +5 -1
  58. package/dist/types/ui/review-look.d.ts +6 -0
  59. package/dist/types/ui/review-options.d.ts +28 -0
  60. package/dist/types/ui/rgba.d.ts +11 -0
  61. package/dist/types/ui/selection-pill-css.d.ts +1 -0
  62. package/dist/types/ui/selection-pill.d.ts +106 -0
  63. package/dist/types/ui/timeline-model.d.ts +27 -0
  64. package/dist/types/ui/timeline.d.ts +16 -1
  65. package/dist/types/ui/tree.d.ts +3 -2
  66. package/dist/types/ui/walkthrough-annotations.d.ts +42 -0
  67. package/dist/types/ui/walkthrough-blocks.d.ts +87 -0
  68. package/dist/types/ui/walkthrough-media.d.ts +30 -1
  69. package/dist/types/ui/walkthrough-model.d.ts +469 -5
  70. package/dist/types/ui/walkthrough.d.ts +27 -5
  71. package/dist/ui-react.js +8087 -2350
  72. package/dist/ui-solid.js +8100 -2363
  73. package/dist/ui.js +9751 -3963
  74. package/package.json +13 -1
package/dist/react.js CHANGED
@@ -22,12 +22,299 @@ import {
22
22
  useSyncExternalStore as useSyncExternalStore2
23
23
  } from "react";
24
24
 
25
+ // src/core/spring.ts
26
+ class Spring {
27
+ x;
28
+ omega;
29
+ zeta;
30
+ eps;
31
+ v = 0;
32
+ target;
33
+ next;
34
+ constructor(x, omega = 24, zeta = 0.86, eps = 0.005) {
35
+ this.x = x;
36
+ this.omega = omega;
37
+ this.zeta = zeta;
38
+ this.eps = eps;
39
+ this.target = x;
40
+ }
41
+ set(target, delay = 0) {
42
+ if (delay > 0) {
43
+ if (target !== (this.next?.target ?? this.target))
44
+ this.next = { target, at: performance.now() + delay };
45
+ return this;
46
+ }
47
+ this.next = undefined;
48
+ this.target = target;
49
+ return this;
50
+ }
51
+ snap(x) {
52
+ this.next = undefined;
53
+ this.x = this.target = x;
54
+ this.v = 0;
55
+ return this;
56
+ }
57
+ step(dt) {
58
+ if (this.next && performance.now() >= this.next.at) {
59
+ this.target = this.next.target;
60
+ this.next = undefined;
61
+ }
62
+ if (this.x === this.target && this.v === 0)
63
+ return this.x;
64
+ const clampedDt = Math.min(dt, 0.1);
65
+ const h = 1 / 480;
66
+ for (let t = 0;t < clampedDt; t += h) {
67
+ const k = Math.min(h, clampedDt - t);
68
+ const a = -this.omega * this.omega * (this.x - this.target) - 2 * this.zeta * this.omega * this.v;
69
+ this.v += a * k;
70
+ this.x += this.v * k;
71
+ }
72
+ if (this.resting) {
73
+ this.x = this.target;
74
+ this.v = 0;
75
+ }
76
+ return this.x;
77
+ }
78
+ get resting() {
79
+ return !this.next && Math.abs(this.x - this.target) < this.eps && Math.abs(this.v) < this.eps * 4;
80
+ }
81
+ }
82
+ function springMotion({ duration, bounce }) {
83
+ return {
84
+ omega: 2 * Math.PI / Math.max(0.01, duration),
85
+ zeta: bounce >= 0 ? 1 - bounce : 1 / (1 + bounce)
86
+ };
87
+ }
88
+ function springEasing(omega, zeta) {
89
+ const s = new Spring(0, omega, zeta).set(1);
90
+ const points = ["0"];
91
+ const dt = 1 / 60;
92
+ let t = 0;
93
+ while (t < 4 && !(Math.abs(s.x - 1) < 0.002 && Math.abs(s.v) < 0.05)) {
94
+ s.step(dt);
95
+ t += dt;
96
+ points.push(String(Math.round(s.x * 1000) / 1000));
97
+ }
98
+ points[points.length - 1] = "1";
99
+ return { easing: `linear(${points.join(",")})`, ms: Math.round(t * 1000) };
100
+ }
101
+ function springCss(value) {
102
+ const { omega, zeta } = springMotion(value);
103
+ const { easing, ms } = springEasing(omega, zeta);
104
+ return { easing, duration: ms };
105
+ }
106
+
107
+ // src/core/theme.ts
108
+ var property = (k) => k.startsWith("--") ? k : `--k-${k}`;
109
+ function presetCss(preset) {
110
+ if (!/^[\w-]+$/.test(preset.name))
111
+ throw new Error(`Invalid preset name: ${preset.name}`);
112
+ const at = `.knobs-root[data-preset="${preset.name}"]`;
113
+ const light = preset.light ?? {};
114
+ const decls = Object.entries(preset.dark).map(([k, dark]) => {
115
+ const l = light[k];
116
+ return l === undefined || String(l) === String(dark) ? `${property(k)}:${dark}` : `${property(k)}:light-dark(${l},${dark})`;
117
+ });
118
+ for (const [k, l] of Object.entries(light))
119
+ if (!(k in preset.dark) && k !== "color-scheme")
120
+ decls.push(`${property(k)}:${l}`);
121
+ return `${at}{${decls.join(";")}}${(preset.css ?? "").replaceAll("&", at)}`;
122
+ }
123
+ var glide = /* @__PURE__ */ springCss({ duration: 0.185, bounce: 0.14 });
124
+ var problemsPreset = {
125
+ name: "problems",
126
+ dark: {
127
+ bg: "#161618",
128
+ surface: "rgba(255,255,255,.055)",
129
+ "surface-hi": "rgba(255,255,255,.11)",
130
+ line: "rgba(255,255,255,.075)",
131
+ "line-hi": "rgba(255,255,255,.12)",
132
+ text: "#f5f5f7",
133
+ label: "rgba(235,235,245,.62)",
134
+ dim: "rgba(235,235,245,.36)",
135
+ accent: "#0091ff",
136
+ modified: "#0091ff",
137
+ "seg-bg": "rgba(120,120,128,.16)",
138
+ "seg-active": "rgba(120,120,128,.24)",
139
+ "toggle-track": "rgba(120,120,128,.32)",
140
+ "toggle-thumb": "#fff",
141
+ rim: "transparent",
142
+ font: 'system-ui,-apple-system,BlinkMacSystemFont,"Helvetica Neue",sans-serif',
143
+ mono: '"Kit SF Mono",ui-monospace,Menlo,monospace',
144
+ "font-size": "13px",
145
+ "label-weight": 500,
146
+ row: "34px",
147
+ radius: "8px",
148
+ "panel-radius": "12px",
149
+ pad: "0px",
150
+ inset: "10px",
151
+ gap: "4px",
152
+ "row-gap": "4px",
153
+ glass: 0,
154
+ glow: 0,
155
+ blur: 0.6,
156
+ "hover-in": 0,
157
+ "hover-out": 100,
158
+ "handle-rest": 0.55,
159
+ handle: "var(--k-text)",
160
+ "handle-inset": "7.5px",
161
+ "fill-base": "transparent",
162
+ "fill-rest-mix": "24%",
163
+ "fill-hover-mix": "36%",
164
+ "fill-active-mix": "36%",
165
+ chrome: 0,
166
+ "group-transform": "none",
167
+ "value-font": "var(--k-mono)",
168
+ "unit-gap": "0px",
169
+ "unit-color": "currentColor",
170
+ "readout-mark": 1,
171
+ "group-size": "12px",
172
+ "group-color": "rgba(235,235,245,.62)",
173
+ "group-inset": "0px",
174
+ "group-tracking": "-.01em",
175
+ "group-divider": "rgba(255,255,255,.075)",
176
+ "group-divider-gap": "8px",
177
+ "curve-inset": "0px",
178
+ "curve-guide": "dashed",
179
+ "curve-dot": 0,
180
+ spring: "0.185 0.14",
181
+ "fill-ease": glide.easing,
182
+ "fill-ms": glide.duration
183
+ },
184
+ light: {
185
+ bg: "#fff",
186
+ surface: "rgba(0,0,0,.045)",
187
+ "surface-hi": "rgba(0,0,0,.09)",
188
+ line: "rgba(0,0,0,.07)",
189
+ "line-hi": "rgba(0,0,0,.11)",
190
+ text: "#000",
191
+ label: "rgba(60,60,67,.66)",
192
+ dim: "rgba(60,60,67,.38)",
193
+ accent: "#0088ff",
194
+ modified: "#0088ff",
195
+ "seg-bg": "rgba(120,120,128,.11)",
196
+ "seg-active": "#fff",
197
+ "toggle-track": "rgba(120,120,128,.2)",
198
+ "toggle-thumb": "#fff",
199
+ rim: "transparent",
200
+ "group-color": "rgba(60,60,67,.66)",
201
+ "group-divider": "rgba(0,0,0,.07)"
202
+ }
203
+ };
204
+
205
+ // src/core/appearance.ts
206
+ var MODES = {
207
+ dark: "dark",
208
+ light: "light",
209
+ auto: "system"
210
+ };
211
+ function resolveLook(options = {}, base) {
212
+ const t = options.theme;
213
+ const mode = typeof t === "string" ? MODES[t] : undefined;
214
+ const theme = typeof t === "object" ? t : base?.theme;
215
+ const preset = options.preset ?? base?.preset;
216
+ return {
217
+ ...theme ? { theme } : {},
218
+ appearance: options.appearance ?? mode ?? base?.appearance ?? "inherit",
219
+ ...preset ? { preset } : {}
220
+ };
221
+ }
222
+ var themes = new Map;
223
+ var themeSelector = (name) => `:where(.knobs-root)[data-knobs-theme="${name}"]`;
224
+ function upsertStyle(doc, key, value, content) {
225
+ const existing = doc.querySelector(`style[${key}="${value}"]`);
226
+ if (existing) {
227
+ if (existing.textContent !== content)
228
+ existing.textContent = content;
229
+ return;
230
+ }
231
+ const style = doc.createElement("style");
232
+ style.setAttribute(key, value);
233
+ style.textContent = content;
234
+ doc.head.append(style);
235
+ }
236
+ function injectTheme(doc, theme) {
237
+ themes.set(theme.name, theme);
238
+ upsertStyle(doc, "data-knobs-theme-css", theme.name, theme.css({ selector: themeSelector(theme.name) }));
239
+ }
240
+ var presets = new Map;
241
+ function injectPreset(doc, preset) {
242
+ presets.set(preset.name, preset);
243
+ upsertStyle(doc, "data-knobs-preset", preset.name, presetCss(preset));
244
+ }
245
+ var setAttr = (el, name, value) => {
246
+ if (value === undefined)
247
+ el.removeAttribute(name);
248
+ else if (el.getAttribute(name) !== value)
249
+ el.setAttribute(name, value);
250
+ };
251
+ function applyLook(el, look) {
252
+ const doc = el.ownerDocument;
253
+ if (look.theme)
254
+ injectTheme(doc, look.theme);
255
+ if (look.preset)
256
+ injectPreset(doc, look.preset);
257
+ setAttr(el, "data-knobs-theme", look.theme?.name);
258
+ setAttr(el, "data-preset", look.preset?.name);
259
+ setAttr(el, "data-appearance", look.appearance === "inherit" ? undefined : look.appearance);
260
+ if (look.appearance === "inherit")
261
+ followPage(el);
262
+ else
263
+ clearInherited(el);
264
+ }
265
+ var clearInherited = (el) => {
266
+ el.style.removeProperty("color-scheme");
267
+ el.style.removeProperty("--_k-light");
268
+ };
269
+ function resolveInherited(el) {
270
+ const parent = el.parentElement;
271
+ const win = el.ownerDocument.defaultView;
272
+ if (!parent || !win || el.hasAttribute("data-appearance"))
273
+ return;
274
+ if (parent.closest(".knobs-root"))
275
+ return clearInherited(el);
276
+ const scheme = win.getComputedStyle(parent).colorScheme.trim();
277
+ const dark = /\bdark\b/.test(scheme);
278
+ const light = /\blight\b/.test(scheme);
279
+ if (!dark && !light)
280
+ return clearInherited(el);
281
+ const isLight = dark && light ? win.matchMedia?.("(prefers-color-scheme: light)").matches ?? false : light;
282
+ el.style.setProperty("color-scheme", "inherit");
283
+ el.style.setProperty("--_k-light", isLight ? "1" : "0");
284
+ }
285
+ var watched = new WeakSet;
286
+ function followPage(el) {
287
+ const doc = el.ownerDocument;
288
+ const win = doc.defaultView;
289
+ if (!win)
290
+ return;
291
+ const run = () => resolveInherited(el);
292
+ if (el.isConnected)
293
+ run();
294
+ queueMicrotask(run);
295
+ win.requestAnimationFrame?.(run);
296
+ if (watched.has(doc))
297
+ return;
298
+ watched.add(doc);
299
+ const all = () => {
300
+ for (const root of doc.querySelectorAll(".knobs-root:not([data-appearance])"))
301
+ resolveInherited(root);
302
+ };
303
+ const observer = new MutationObserver(all);
304
+ const attributeFilter = ["class", "data-theme", "data-appearance"];
305
+ observer.observe(doc.documentElement, { attributes: true, attributeFilter });
306
+ if (doc.body)
307
+ observer.observe(doc.body, { attributes: true, attributeFilter });
308
+ win.matchMedia?.("(prefers-color-scheme: light)").addEventListener?.("change", all);
309
+ }
310
+
25
311
  // src/core/adapter.ts
26
- function syncPanelLook(host, controls, theme, density) {
312
+ var panelLook = (controls, look = {}) => resolveLook(look, resolveLook({ theme: controls.theme, appearance: controls.appearance }));
313
+ function syncPanelLook(host, controls, look = {}, density) {
27
314
  const panel = host?.firstElementChild;
28
315
  if (!panel)
29
316
  return;
30
- panel.dataset.theme = theme ?? controls.theme;
317
+ applyLook(panel, panelLook(controls, look));
31
318
  panel.dataset.density = density ?? controls.density;
32
319
  }
33
320
  function syncPanelValues(controls, descriptors, values, land = false) {
@@ -43,6 +330,7 @@ function mountPanelAdapter(host, controls, getProps) {
43
330
  return controls.mount(host, {
44
331
  title: p.title,
45
332
  theme: p.theme,
333
+ appearance: p.appearance,
46
334
  density: p.density,
47
335
  renderer: p.renderer,
48
336
  variants: p.variants,
@@ -57,7 +345,7 @@ function mountPanelAdapter(host, controls, getProps) {
57
345
  onClose: p.onClose ? () => getProps().onClose?.() : undefined,
58
346
  onReady(panel) {
59
347
  const cur = getProps();
60
- syncPanelLook(host, controls, cur.theme, cur.density);
348
+ syncPanelLook(host, controls, cur, cur.density);
61
349
  cur.onReady?.(panel);
62
350
  }
63
351
  });
@@ -89,7 +377,7 @@ function Knobs({
89
377
  return cloneElement(children, { ref });
90
378
  }
91
379
  function KnobsPanel(props) {
92
- const { controls, descriptors, values, land, theme, density } = props;
380
+ const { controls, descriptors, values, land, theme, appearance, preset, density } = props;
93
381
  const enabled = useSyncExternalStore2(controls.subscribe, () => controls.enabled, () => false);
94
382
  const ref = useRef(null);
95
383
  const latest = useRef(props);
@@ -105,8 +393,8 @@ function KnobsPanel(props) {
105
393
  syncPanelValues(controls, descriptors, values, Boolean(land));
106
394
  }, [enabled, controls, descriptors, values, land]);
107
395
  useEffect(() => {
108
- syncPanelLook(ref.current, controls, theme, density);
109
- }, [controls, theme, density]);
396
+ syncPanelLook(ref.current, controls, { theme, appearance, preset }, density);
397
+ }, [controls, theme, appearance, preset, density]);
110
398
  if (!enabled)
111
399
  return null;
112
400
  return /* @__PURE__ */ jsx("div", {