@kitlangton/knobs 0.4.0-next.11 → 0.4.0-next.12
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 +88 -12
- package/dist/dev/{chunk-mjdgzad5.js → chunk-7kns3qe6.js} +29 -25
- package/dist/dev/{chunk-bnhzf1tj.js → chunk-9qtvxa6k.js} +1378 -1066
- package/dist/dev/{chunk-75gbzbyd.js → chunk-ab7vfghg.js} +2 -5
- package/dist/dev/{chunk-j57rhjtm.js → chunk-nwfm1bfj.js} +89 -37
- package/dist/dev/index.js +41 -18
- package/dist/index.js +64 -15
- package/dist/panel.js +2788 -2294
- package/dist/review-react.js +8 -4
- package/dist/review-solid.js +10 -5
- package/dist/review.js +8 -4
- package/dist/types/core/remote.d.ts +8 -2
- package/dist/types/core/schema.d.ts +52 -4
- package/dist/types/core/store.d.ts +7 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/panel/dock.d.ts +9 -0
- package/dist/types/panel/gpu/renderer.d.ts +11 -1
- package/dist/types/panel/inspector.d.ts +11 -3
- package/dist/types/panel/presets.d.ts +14 -0
- package/dist/types/panel/scope.d.ts +15 -4
- package/dist/types/ui/canvas-css.d.ts +1 -0
- package/dist/types/ui/canvas-model.d.ts +116 -0
- package/dist/types/ui/canvas.d.ts +66 -0
- package/dist/types/ui/index.d.ts +2 -0
- package/dist/types/ui/react.d.ts +12 -0
- package/dist/types/ui/solid.d.ts +9 -0
- package/dist/ui-react.js +1020 -17
- package/dist/ui-solid.js +1032 -25
- package/dist/ui.js +986 -4
- package/package.json +1 -1
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
__preload
|
|
3
|
-
} from "./chunk-mjdgzad5.js";
|
|
4
1
|
import {
|
|
5
2
|
applyLook,
|
|
6
3
|
panelLook,
|
|
@@ -9,7 +6,7 @@ import {
|
|
|
9
6
|
writeSession,
|
|
10
7
|
injectStyles,
|
|
11
8
|
toggleLayer
|
|
12
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-nwfm1bfj.js";
|
|
13
10
|
|
|
14
11
|
// src/panel/attach.ts
|
|
15
12
|
function attach(controls, element, options = {}) {
|
|
@@ -85,7 +82,7 @@ function attach(controls, element, options = {}) {
|
|
|
85
82
|
return;
|
|
86
83
|
loading = !0;
|
|
87
84
|
try {
|
|
88
|
-
let { createPanel } = await
|
|
85
|
+
let { createPanel } = await import("./chunk-9qtvxa6k.js");
|
|
89
86
|
if (disposed || !controls.enabled || panel)
|
|
90
87
|
return;
|
|
91
88
|
if (panel = createPanel(controls, element, close, { restored, chip }), remember)
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
DEFAULT_LINEAR,
|
|
11
11
|
motionCss,
|
|
12
12
|
storageKey
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-7kns3qe6.js";
|
|
14
14
|
|
|
15
15
|
// src/core/theme.ts
|
|
16
16
|
var property = (k) => k.startsWith("--") ? k : `--k-${k}`;
|
|
@@ -631,20 +631,15 @@ function escTarget(trail, title) {
|
|
|
631
631
|
return;
|
|
632
632
|
return trail.at(-2)?.label ?? (title.trim() || "panel");
|
|
633
633
|
}
|
|
634
|
-
function fitCrumbs(widths, room, sep,
|
|
635
|
-
let n = widths.length;
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
}, from = 0;
|
|
644
|
-
while (from < n - 1 && span(from) > room)
|
|
645
|
-
from++;
|
|
646
|
-
let used = span(from);
|
|
647
|
-
return { from, hint: hint > 0 && used + sep + hint <= room };
|
|
634
|
+
function fitCrumbs(widths, room, sep, hint = 0) {
|
|
635
|
+
let n = widths.length, from = n, used = 0;
|
|
636
|
+
for (let i = n - 1;i >= 0; i--) {
|
|
637
|
+
let w = used + widths[i] + (i < n - 1 ? sep : 0);
|
|
638
|
+
if (w > room)
|
|
639
|
+
break;
|
|
640
|
+
used = w, from = i;
|
|
641
|
+
}
|
|
642
|
+
return { from, hint: from < n && hint > 0 && used + sep + hint <= room };
|
|
648
643
|
}
|
|
649
644
|
function digitOption(key, count) {
|
|
650
645
|
if (!/^[1-9]$/.test(key))
|
|
@@ -652,6 +647,15 @@ function digitOption(key, count) {
|
|
|
652
647
|
let i = Number(key) - 1;
|
|
653
648
|
return i < count ? i : void 0;
|
|
654
649
|
}
|
|
650
|
+
function digitRoute(key, at) {
|
|
651
|
+
if (!/^[1-9]$/.test(key))
|
|
652
|
+
return;
|
|
653
|
+
if (at.options)
|
|
654
|
+
return "options";
|
|
655
|
+
if (at.keeps)
|
|
656
|
+
return;
|
|
657
|
+
return digitOption(key, at.presets) === void 0 ? void 0 : "presets";
|
|
658
|
+
}
|
|
655
659
|
function digitHints(count, showing) {
|
|
656
660
|
let n = Math.min(9, count);
|
|
657
661
|
if (n <= 0)
|
|
@@ -684,9 +688,10 @@ function createCrumbs(o) {
|
|
|
684
688
|
}, build = () => {
|
|
685
689
|
if (!trail.length)
|
|
686
690
|
return { pieces: [], xs: [] };
|
|
687
|
-
let head = o.header.getBoundingClientRect(), { x, right } = titleEnd(head), sepW = width(SEP) + GAP * 2, escText = esc ? `esc ↑ ${esc}` : "", fit = fitCrumbs(trail.map((c) => width(c.label)), Math.max(0, right - x - sepW), sepW,
|
|
688
|
-
if (fit.from
|
|
689
|
-
|
|
691
|
+
let head = o.header.getBoundingClientRect(), { x, right } = titleEnd(head), sepW = width(SEP) + GAP * 2, escText = esc ? `esc ↑ ${esc}` : "", fit = fitCrumbs(trail.map((c) => width(c.label)), Math.max(0, right - x - sepW), sepW, escText ? width(escText) + HINT_GAP - sepW : 0);
|
|
692
|
+
if (fit.from >= trail.length)
|
|
693
|
+
return { pieces: [], xs: [] };
|
|
694
|
+
let pieces = [{ key: "sep:lead", text: SEP, kind: "sep" }];
|
|
690
695
|
if (trail.forEach((c, i) => {
|
|
691
696
|
if (i < fit.from)
|
|
692
697
|
return;
|
|
@@ -2374,8 +2379,8 @@ ${GRAD_PROPS}
|
|
|
2374
2379
|
.knobs-panel *:where(:not(.knobs-accessory,.knobs-accessory *,.knobs-live *)),.knobs-menu *{box-sizing:border-box;color:inherit;letter-spacing:inherit;word-spacing:inherit;line-height:inherit;text-transform:inherit;text-shadow:inherit;font-style:inherit}
|
|
2375
2380
|
/* Hover washes come in at --k-hover-in and leave at --k-hover-out (ms). Set per element, so a
|
|
2376
2381
|
hovered card doesn't hand its quick entrance to the rows inside it. */
|
|
2377
|
-
:where(.knobs-panel,.knobs-menu) *{--k-hover-t:calc(var(--_k-hover-out) * 1ms)}
|
|
2378
|
-
:where(.knobs-panel,.knobs-menu) :is(:hover,.knobs-active){--k-hover-t:calc(var(--_k-hover-in) * 1ms)}
|
|
2382
|
+
:where(.knobs-panel,.knobs-menu,.knobs-head-actions[data-docked]) *{--k-hover-t:calc(var(--_k-hover-out) * 1ms)}
|
|
2383
|
+
:where(.knobs-panel,.knobs-menu,.knobs-head-actions[data-docked]) :is(:hover,.knobs-active){--k-hover-t:calc(var(--_k-hover-in) * 1ms)}
|
|
2379
2384
|
|
|
2380
2385
|
.knobs-panel,.knobs-chip{
|
|
2381
2386
|
box-sizing:border-box;font:var(--_k-weight) var(--_k-font-size)/1.35 var(--_k-font);color:var(--_k-fg);text-align:left;
|
|
@@ -2495,7 +2500,7 @@ ${GRAD_PROPS}
|
|
|
2495
2500
|
.knobs-crumbs{position:absolute;left:0;top:50%;height:0;pointer-events:none;white-space:nowrap;font-size:var(--_k-text-meta);font-weight:var(--_k-weight-label);line-height:1.2;letter-spacing:0;text-transform:none}
|
|
2496
2501
|
.knobs-crumbs>*{position:absolute;left:0;top:0;translate:0 -50%;color:var(--_k-fg-3);transition:opacity .2s var(--k-ease),translate ${CRUMB_GLIDE},color .2s var(--k-ease)}
|
|
2497
2502
|
.knobs-crumbs>[data-leaving]{transition:opacity .14s cubic-bezier(.4,0,1,1),translate .14s cubic-bezier(.4,0,1,1)}
|
|
2498
|
-
.knobs-crumbs>.knobs-crumb-crumb{pointer-events:auto;cursor:
|
|
2503
|
+
.knobs-crumbs>.knobs-crumb-crumb{pointer-events:auto;cursor:default}
|
|
2499
2504
|
.knobs-crumbs>.knobs-crumb-crumb[data-deep]{color:var(--_k-fg)}
|
|
2500
2505
|
.knobs-crumbs>.knobs-crumb-crumb:not([data-deep]):hover{color:var(--_k-fg-2)}
|
|
2501
2506
|
.knobs-crumbs>.knobs-crumb-sep{color:color-mix(in srgb,var(--_k-fg-3) 70%,transparent)}
|
|
@@ -2512,40 +2517,53 @@ ${GRAD_PROPS}
|
|
|
2512
2517
|
.knobs-panel[data-gpu-active="true"] .knobs-die-icon>canvas{visibility:hidden}
|
|
2513
2518
|
/* The tools sit quiet (--k-dim) until the panel has the pointer or keyboard focus, then read as
|
|
2514
2519
|
labels, and as text under the pointer. */
|
|
2515
|
-
.knobs-panel header button{position:relative;width:var(--k-icon-btn);height:var(--k-icon-btn);padding:0;display:inline-flex;align-items:center;justify-content:center;color:var(--_k-fg-3);background:transparent;border-radius:var(--_k-round);cursor:
|
|
2520
|
+
.knobs-panel header button{position:relative;width:var(--k-icon-btn);height:var(--k-icon-btn);padding:0;display:inline-flex;align-items:center;justify-content:center;color:var(--_k-fg-3);background:transparent;border-radius:var(--_k-round);cursor:default;font-size:12px;line-height:1;transition:background var(--k-hover-t),color var(--k-hover-t),opacity .15s}
|
|
2516
2521
|
.knobs-panel:is(:hover,:has(:focus-visible)) header button{color:var(--_k-fg-2)}
|
|
2517
2522
|
.knobs-panel header button:is(:hover:not([disabled]),:focus-visible),.knobs-panel header button[aria-expanded="true"]{background:var(--_k-fill-selected);color:var(--_k-fg)}
|
|
2518
2523
|
.knobs-panel header button[disabled]{opacity:var(--k-disabled-opacity);cursor:default}
|
|
2519
2524
|
/* The close X's ink sits a fifth of its box in from each side, a digit's barely: nudged right, its
|
|
2520
2525
|
ink ends where the values' digits do. */
|
|
2521
2526
|
.knobs-panel header .knobs-close>.knobs-icon{translate:calc(var(--k-icon-size) * .1) 0}
|
|
2527
|
+
/* In a split pane's header (dock.ts) the buttons are the pane's: its size, ink and wash, which
|
|
2528
|
+
comes on at once and eases off. Outside the panel, they bring its resets with them. */
|
|
2529
|
+
.knobs-head-actions[data-docked]{--k-icon-size:13px;--k-icon-btn:20px;margin-right:0}
|
|
2530
|
+
.knobs-head-actions[data-docked] button{all:revert;box-sizing:border-box;position:relative;flex:none;display:inline-flex;align-items:center;justify-content:center;width:var(--k-icon-btn);height:var(--k-icon-btn);margin:0;padding:0;border:0;border-radius:var(--_k-round);
|
|
2531
|
+
background:transparent;color:var(--_k-fg-3);font:inherit;line-height:1;cursor:default;outline:none;box-shadow:none;transition:background var(--k-hover-t),color var(--k-hover-t)}
|
|
2532
|
+
.knobs-head-actions[data-docked] button:is(:hover:not([disabled]),:focus-visible){background:var(--_ku-wash-hi,var(--_k-fill-selected));color:var(--_k-fg)}
|
|
2533
|
+
.knobs-head-actions[data-docked] .knobs-icon>path{fill:currentColor}
|
|
2534
|
+
.knobs-head-actions[data-docked] button:focus-visible{--k-hover-t:calc(var(--_k-hover-in) * 1ms)}
|
|
2522
2535
|
/* Undo · Redo sit apart from Reset · Copy · Random. Undo, Redo and Reset (and a group's reset)
|
|
2523
2536
|
keep their slots while they're away and bloom in and out of them: nothing beside them moves. */
|
|
2524
2537
|
.knobs-head-history{display:flex;flex:none;margin-right:calc(var(--_k-unit) * 1.5)}
|
|
2525
|
-
.knobs-panel :is(.knobs-head-actions,.knobs-group-head) button[data-shown]{transition:background var(--k-hover-t),color var(--k-hover-t),opacity ${BLOOM_IN},scale ${BLOOM_IN},
|
|
2526
|
-
.knobs-panel :is(.knobs-head-actions,.knobs-group-head) button[data-shown="false"]{opacity:0;scale:.9;filter:blur(2.5px);visibility:hidden;
|
|
2527
|
-
transition:background var(--k-hover-t),color var(--k-hover-t),opacity ${BLOOM_OUT},scale ${BLOOM_OUT},filter ${BLOOM_OUT},visibility 0s ${snappyOut.ms}ms}
|
|
2538
|
+
:is(.knobs-panel :is(.knobs-head-actions,.knobs-group-head),.knobs-head-actions[data-docked]) button[data-shown]{transition:background var(--k-hover-t),color var(--k-hover-t),opacity ${BLOOM_IN},scale ${BLOOM_IN},width ${BLOOM_IN}}
|
|
2539
|
+
:is(.knobs-panel :is(.knobs-head-actions,.knobs-group-head),.knobs-head-actions[data-docked]) button[data-shown="false"]{opacity:0;scale:.9;filter:blur(2.5px);visibility:hidden;
|
|
2540
|
+
transition:background var(--k-hover-t),color var(--k-hover-t),opacity ${BLOOM_OUT},scale ${BLOOM_OUT},filter ${BLOOM_OUT},width ${BLOOM_OUT},visibility 0s ${snappyOut.ms}ms}
|
|
2541
|
+
/* Docked, a slot opens and closes with its button (the width above) rather than waiting: the
|
|
2542
|
+
pane's title keeps the room. */
|
|
2543
|
+
.knobs-head-actions[data-docked] button[data-shown="false"]{width:0}
|
|
2544
|
+
.knobs-head-actions[data-docked]>.knobs-head-history{transition:margin ${BLOOM_IN}}
|
|
2545
|
+
.knobs-head-actions[data-docked]>.knobs-head-history:not(:has(>[data-shown="true"]:not([hidden]))){margin-right:0}
|
|
2528
2546
|
@media(prefers-reduced-motion:reduce){
|
|
2529
|
-
.knobs-panel :is(.knobs-head-actions,.knobs-group-head) button[data-shown]{transition:opacity .15s
|
|
2530
|
-
.knobs-panel :is(.knobs-head-actions,.knobs-group-head) button[data-shown="false"]{scale:1;filter:none;transition:opacity .15s,visibility 0s .15s!important}}
|
|
2547
|
+
:is(.knobs-panel :is(.knobs-head-actions,.knobs-group-head),.knobs-head-actions[data-docked]) button[data-shown]{transition:opacity .15s!important}
|
|
2548
|
+
:is(.knobs-panel :is(.knobs-head-actions,.knobs-group-head),.knobs-head-actions[data-docked]) button[data-shown="false"]{scale:1;filter:none;transition:opacity .15s,visibility 0s .15s!important}}
|
|
2531
2549
|
/* A press flash (flash.ts): from a key or a click, the button's wash brightens at once and eases
|
|
2532
2550
|
back to its own, its ink with it. Two names, so a second press restarts it. */
|
|
2533
2551
|
@keyframes knobs-flash-a{from{background-color:var(--k-flash-bg);color:var(--_k-fg)}}
|
|
2534
2552
|
@keyframes knobs-flash-b{from{background-color:var(--k-flash-bg);color:var(--_k-fg)}}
|
|
2535
|
-
.knobs-panel :is(header,.knobs-group-head) button{--k-flash-bg:color-mix(in srgb,var(--_k-fill-selected),var(--_k-fg) 10%)}
|
|
2536
|
-
.knobs-panel :is(header,.knobs-group-head) button[data-k-flash="a"]{animation:knobs-flash-a ${FLASH_MS}ms cubic-bezier(.33,1,.68,1)}
|
|
2537
|
-
.knobs-panel :is(header,.knobs-group-head) button[data-k-flash="b"]{animation:knobs-flash-b ${FLASH_MS}ms cubic-bezier(.33,1,.68,1)}
|
|
2553
|
+
.knobs-panel :is(header,.knobs-group-head) button,.knobs-head-actions[data-docked] button{--k-flash-bg:color-mix(in srgb,var(--_k-fill-selected),var(--_k-fg) 10%)}
|
|
2554
|
+
.knobs-panel :is(header,.knobs-group-head) button[data-k-flash="a"],.knobs-head-actions[data-docked] button[data-k-flash="a"]{animation:knobs-flash-a ${FLASH_MS}ms cubic-bezier(.33,1,.68,1)}
|
|
2555
|
+
.knobs-panel :is(header,.knobs-group-head) button[data-k-flash="b"],.knobs-head-actions[data-docked] button[data-k-flash="b"]{animation:knobs-flash-b ${FLASH_MS}ms cubic-bezier(.33,1,.68,1)}
|
|
2538
2556
|
/* Copied: the glyph shrinks away and a check draws itself in its place, held, then they trade
|
|
2539
2557
|
back (the check fading). Driven by --k-copy (the glyph), --k-check (how much of the check is
|
|
2540
2558
|
drawn) and --k-check-a (its opacity), which the GPU renderer reads too. */
|
|
2541
|
-
.knobs-panel header .knobs-copy{--k-copy:1;--k-check:0;--k-check-a:0;
|
|
2559
|
+
.knobs-panel header .knobs-copy,.knobs-head-actions[data-docked] .knobs-copy{--k-copy:1;--k-check:0;--k-check-a:0;
|
|
2542
2560
|
transition:background var(--k-hover-t),color var(--k-hover-t),opacity .15s,--k-copy ${BLOOM_IN} .04s,--k-check 0s .1s,--k-check-a .1s cubic-bezier(.4,0,1,1)}
|
|
2543
|
-
.knobs-panel header .knobs-copy[data-copied]{--k-copy:0;--k-check:1;--k-check-a:1;color:var(--_k-fg);
|
|
2561
|
+
.knobs-panel header .knobs-copy[data-copied],.knobs-head-actions[data-docked] .knobs-copy[data-copied]{--k-copy:0;--k-check:1;--k-check-a:1;color:var(--_k-fg);
|
|
2544
2562
|
transition:background var(--k-hover-t),color var(--k-hover-t),opacity .15s,--k-copy .1s cubic-bezier(.4,0,1,1),--k-check .18s cubic-bezier(.2,.8,.2,1) .03s,--k-check-a .04s linear .03s}
|
|
2545
2563
|
.knobs-copy>.knobs-icon:not(.knobs-check){opacity:var(--k-copy);scale:calc(.5 + .5 * var(--k-copy))}
|
|
2546
2564
|
.knobs-copy>.knobs-check{position:absolute;inset:0;margin:auto;opacity:var(--k-check-a)}
|
|
2547
2565
|
/* (Over .knobs-icon>path's fill: the check is a stroke, 16 of 256 wide like Phosphor's regular icons.) */
|
|
2548
|
-
.knobs-panel .knobs-icon.knobs-check>path{fill:none;stroke:currentColor;stroke-width:16;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:1 2;stroke-dashoffset:calc(1 - var(--k-check))}
|
|
2566
|
+
.knobs-panel .knobs-icon.knobs-check>path,.knobs-head-actions[data-docked] .knobs-icon.knobs-check>path{fill:none;stroke:currentColor;stroke-width:16;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:1 2;stroke-dashoffset:calc(1 - var(--k-check))}
|
|
2549
2567
|
.knobs-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}
|
|
2550
2568
|
|
|
2551
2569
|
/* Shortcuts Popover */
|
|
@@ -2567,6 +2585,15 @@ ${GRAD_PROPS}
|
|
|
2567
2585
|
.knobs-panel[data-buttons] .knobs-preset-chip:hover{background:var(--k-button-hover-bg,var(--_k-fill-selected))!important;box-shadow:inset 0 0 0 1px var(--k-button-hover-line,var(--k-button-line,transparent))}
|
|
2568
2586
|
.knobs-panel .knobs-preset-chip:hover{color:var(--_k-fg)}
|
|
2569
2587
|
.knobs-panel .knobs-preset-chip[aria-checked="true"]{color:var(--_k-fg);font-weight:var(--_k-weight-title)}
|
|
2588
|
+
/* A list (presetDisplay "list", or chips that would take more than two lines): rows like a
|
|
2589
|
+
menu's, their names on the rows' text edge and each wash bleeding 8 px past it, the selection a
|
|
2590
|
+
quiet wash that glides between them. Hover is a wash too, on at once. */
|
|
2591
|
+
.knobs-presets[data-display="list"]{padding:0;background:transparent}
|
|
2592
|
+
.knobs-presets[data-display="list"]>.knobs-presets-track{grid-template-columns:minmax(0,1fr);gap:0;margin:0 calc(var(--_k-inset) - 8px)}
|
|
2593
|
+
.knobs-panel .knobs-presets[data-display="list"] .knobs-preset-chip{height:var(--_k-control-h);padding:0 16px 0 8px;text-align:left;cursor:default;font-weight:var(--_k-weight-label);transition:color var(--k-hover-t),background var(--k-hover-t)}
|
|
2594
|
+
.knobs-panel .knobs-presets[data-display="list"] .knobs-preset-chip:hover:not([aria-checked="true"]){background:var(--_k-row-hover)!important}
|
|
2595
|
+
.knobs-panel .knobs-presets[data-display="list"] .knobs-preset-chip::after{top:50%;right:8px;margin-top:-2px}
|
|
2596
|
+
.knobs-presets[data-display="list"] .knobs-presets-pill{background:var(--_k-fill-selected);box-shadow:none}
|
|
2570
2597
|
.knobs-panel .knobs-preset-save{flex:none;width:calc((var(--_k-inset) - var(--_k-tray-pad)) * 2 + 8px);padding:0!important;color:var(--_k-fg-3)!important;font-weight:400!important;font-size:var(--_k-text-title)!important}
|
|
2571
2598
|
.knobs-panel .knobs-preset-save:hover{color:var(--_k-fg)!important}
|
|
2572
2599
|
/* The active preset's modified mark: the values have drifted off it (a row's dot, in its corner). */
|
|
@@ -2911,6 +2938,14 @@ ${POINTER_ROW} .knobs-slider.knobs-modified:not(:hover,.knobs-active) .knobs-val
|
|
|
2911
2938
|
:where(.knobs-panel)[data-frame="flat"]{--k-group-divider:var(--_k-border);--k-group-divider-gap:var(--_k-gap)}
|
|
2912
2939
|
:where(.knobs-panel.knobs-inline:not(.knobs-page))[data-frame="flat"]{--k-chrome:0;--k-pad:0px}
|
|
2913
2940
|
.knobs-panel[data-frame="flat"] .knobs-card{background:transparent;border-radius:0}
|
|
2941
|
+
/* One surface: an inline panel on another card (a split's pane, anything .knobs-surface, or in
|
|
2942
|
+
[data-nested]) takes the flat frame by itself: no padding (its rows keep their inset, so their
|
|
2943
|
+
text sits on the card's, and its preset chips line up with them), groups as plain sections,
|
|
2944
|
+
rows on hairlines. */
|
|
2945
|
+
:where(.knobs-surface,.knobs-pane:not([data-nested])>.knobs-pane-clip,[data-nested]) :where(.knobs-panel.knobs-inline:not(.knobs-page)){--k-chrome:0;--k-group-divider:var(--_k-border);--k-group-divider-gap:var(--_k-gap)}
|
|
2946
|
+
:where(.knobs-surface,.knobs-pane:not([data-nested])>.knobs-pane-clip,[data-nested]) .knobs-panel.knobs-inline:not(.knobs-page){padding:0}
|
|
2947
|
+
:where(.knobs-surface,.knobs-pane:not([data-nested])>.knobs-pane-clip,[data-nested]) .knobs-panel.knobs-inline:not(.knobs-page) .knobs-card{background:transparent;border-radius:0}
|
|
2948
|
+
:where(.knobs-surface,.knobs-pane:not([data-nested])>.knobs-pane-clip,[data-nested]) .knobs-panel.knobs-inline:not(.knobs-page) .knobs-presets:not([data-display="list"]){margin-inline:var(--_k-inset)}
|
|
2914
2949
|
.knobs-panel[data-frame="flat"][data-rows] .knobs-card>*,.knobs-panel[data-frame="flat"][data-rows] .knobs-sub{background:transparent;border-radius:0}
|
|
2915
2950
|
|
|
2916
2951
|
/* Disabled rows dim and take no edits (focus still reaches them, to read); read-only rows keep
|
|
@@ -3063,6 +3098,10 @@ ${POINTER_ROW} .knobs-slider.knobs-modified:not(:hover,.knobs-active) .knobs-val
|
|
|
3063
3098
|
.knobs-panel .knobs-tool[disabled]{opacity:var(--k-disabled-opacity);cursor:default}
|
|
3064
3099
|
.knobs-tool .knobs-icon{flex:none;width:var(--k-icon-sm);height:var(--k-icon-sm)}
|
|
3065
3100
|
.knobs-tool-label{min-width:0;overflow:hidden;text-overflow:ellipsis}
|
|
3101
|
+
/* Icons only (labels that don't fit one row, or labels: false): one row of equal buttons, each
|
|
3102
|
+
its icon centred, its label and shortcut in its tooltip. */
|
|
3103
|
+
.knobs-panel .knobs-toolbar[data-icons] .knobs-tool{justify-content:center;padding:0;cursor:default}
|
|
3104
|
+
.knobs-panel .knobs-toolbar[data-icons] :is(.knobs-tool-label,.knobs-tool-key){display:none}
|
|
3066
3105
|
/* The shortcut sits at the button's end, so a column of buttons lines their chips up. */
|
|
3067
3106
|
.knobs-panel .knobs-tool-key{flex:none;margin-left:auto;padding-left:4px;font:inherit;font-size:var(--_k-text-cap);font-variant-numeric:tabular-nums;color:var(--_k-fg-3);letter-spacing:.06em}
|
|
3068
3107
|
.knobs-panel :is([data-disabled],[data-readonly]) :is(.knobs-cell,.knobs-range-track,.knobs-angle,.knobs-dial,.knobs-seed,.knobs-keys,.knobs-tool){cursor:default}
|
|
@@ -3108,7 +3147,7 @@ ${POINTER_ROW} .knobs-slider.knobs-modified:not(:hover,.knobs-active) .knobs-val
|
|
|
3108
3147
|
|
|
3109
3148
|
/* A focused row's options: tiny digits in hint mode's look, once focus settles (optkeys.ts). */
|
|
3110
3149
|
.knobs-optkeys{position:absolute;left:0;top:0;width:0;height:0;pointer-events:none;z-index:5}
|
|
3111
|
-
.knobs-panel .knobs-optkey{position:absolute;transform:translateY(-50%);display:inline-flex;align-items:center;height:12px;padding:0 3px;border-radius:var(--_k-radius-sm);background:var(--_k-accent);color:var(--_k-bg);box-shadow:0 1px 3px rgba(0,0,0,calc(.35 * var(--k-lift)));
|
|
3150
|
+
.knobs-panel .knobs-optkey{position:absolute;transform:translateY(-50%);display:inline-flex;white-space:nowrap;align-items:center;height:12px;padding:0 3px;border-radius:var(--_k-radius-sm);background:var(--_k-accent);color:var(--_k-bg);box-shadow:0 1px 3px rgba(0,0,0,calc(.35 * var(--k-lift)));
|
|
3112
3151
|
font:700 calc(var(--_k-text-cap) * .85)/1 var(--_k-mono);letter-spacing:.04em;pointer-events:none;opacity:0;transition:opacity .12s var(--k-ease)}
|
|
3113
3152
|
.knobs-panel .knobs-optkey-range{transform:translate(-100%,-50%)}
|
|
3114
3153
|
.knobs-panel .knobs-optkey[data-shown]{opacity:.85;transition-duration:.15s}
|
|
@@ -3150,7 +3189,18 @@ ${POINTER_ROW} .knobs-slider.knobs-modified:not(:hover,.knobs-active) .knobs-val
|
|
|
3150
3189
|
.knobs-menu-item[data-separated]{margin-top:calc(var(--_k-unit) * 2 + 1px)}
|
|
3151
3190
|
.knobs-menu-item[data-separated]::before{content:"";position:absolute;left:8px;right:8px;top:calc(var(--_k-unit) * -1 - 1px);height:1px;transform:scaleY(.5);background:var(--_k-border)}
|
|
3152
3191
|
|
|
3192
|
+
/* Text: a field beside its label, or (multiline) a box under it that grows with its lines */
|
|
3193
|
+
.knobs-panel .knobs-text{flex:1 1 auto;min-width:0;max-width:62%;height:var(--_k-control-h);margin:0;padding:0 8px;border:0;border-radius:var(--_k-radius-md);outline:none;background:var(--_k-segmented-track);color:var(--_k-fg);caret-color:var(--_k-accent);font:inherit;font-size:var(--_k-text-control);-webkit-user-select:text;user-select:text;cursor:text}
|
|
3194
|
+
.knobs-panel .knobs-text::placeholder{color:var(--_k-fg-3);opacity:1}
|
|
3195
|
+
.knobs-panel .knobs-text:is(:hover,:focus){background:color-mix(in srgb,var(--_k-fill-selected) 70%,var(--_k-segmented-track))}
|
|
3196
|
+
.knobs-panel .knobs-text::selection{background:color-mix(in srgb,var(--_k-accent) 24%,transparent);color:var(--_k-fg)}
|
|
3197
|
+
.knobs-panel .knobs-insp[data-multiline]{flex-direction:column;align-items:stretch;justify-content:flex-start;gap:calc(var(--_k-unit) * 1.5);height:auto;padding-block:calc(var(--_k-unit) * 2)}
|
|
3198
|
+
.knobs-panel .knobs-insp[data-multiline]>span:first-child{align-self:flex-start;max-width:100%}
|
|
3199
|
+
.knobs-panel textarea.knobs-text{max-width:none;height:auto;min-height:calc(2lh + 12px);max-height:calc(8lh + 12px);margin:0;padding:6px 8px;resize:none;field-sizing:content;font:inherit;font-size:var(--_k-text-control);line-height:1.4}
|
|
3200
|
+
.knobs-panel :is([data-disabled],[data-readonly]) .knobs-text{cursor:default}
|
|
3201
|
+
|
|
3153
3202
|
/* Status & Transfer Textarea */
|
|
3203
|
+
.knobs-panel .knobs-empty{margin:0;padding:calc(var(--_k-unit) * 2) var(--_k-inset);color:var(--_k-fg-3);font-size:var(--_k-text-control);overflow-wrap:anywhere}
|
|
3154
3204
|
.knobs-panel .knobs-status{margin:6px 0 0;padding:0 var(--_k-inset);color:var(--_k-fg-2);font-size:var(--_k-text-meta);overflow-wrap:anywhere}
|
|
3155
3205
|
|
|
3156
3206
|
.knobs-panel textarea{width:100%;min-height:84px;margin-top:6px;padding:6px var(--_k-inset);resize:vertical;font:var(--_k-text-meta)/1.4 var(--_k-mono)}
|
|
@@ -3182,11 +3232,11 @@ ${POINTER_ROW} .knobs-slider.knobs-modified:not(:hover,.knobs-active) .knobs-val
|
|
|
3182
3232
|
.knobs-panel[data-gpu-active="true"] .knobs-preset-chip::after,
|
|
3183
3233
|
.knobs-panel[data-gpu-active="true"] :is(.knobs-tile:not(.knobs-live)>.knobs-veil,.knobs-tile:not(.knobs-live)>.knobs-mark,.knobs-section-head>.knobs-mark){opacity:0!important}
|
|
3184
3234
|
/* Parts the canvas doesn't draw (shortcuts, status, editors) sit above it. */
|
|
3185
|
-
.knobs-panel[data-gpu-active="true"] :where(.knobs-popover,.knobs-status,textarea,.knobs-apply-btn){position:relative;z-index:2147480003}
|
|
3235
|
+
.knobs-panel[data-gpu-active="true"] :where(.knobs-popover,.knobs-status,textarea,.knobs-text,.knobs-apply-btn){position:relative;z-index:2147480003}
|
|
3186
3236
|
.knobs-panel[data-gpu-active="true"] :is(.knobs-number,.knobs-preset-name){z-index:2147480003}
|
|
3187
3237
|
/* A row accessory is the host's own DOM, so it sits above the canvas too (its row then can't
|
|
3188
3238
|
contain its layout, which would trap it in a stacking context under the canvas). */
|
|
3189
|
-
.knobs-panel[data-gpu-active="true"] .knobs-row[data-accessory]{contain:style}
|
|
3239
|
+
.knobs-panel[data-gpu-active="true"] :is(.knobs-row[data-accessory],.knobs-insp[data-kind="text"]){contain:style}
|
|
3190
3240
|
:where(.knobs-panel[data-gpu-active="true"] .knobs-row>.knobs-accessory){position:relative}
|
|
3191
3241
|
.knobs-panel[data-gpu-active="true"] .knobs-row>.knobs-accessory{z-index:2147480003}
|
|
3192
3242
|
|
|
@@ -3568,6 +3618,8 @@ function changeCue(field, before, after) {
|
|
|
3568
3618
|
let options = field.options ?? [];
|
|
3569
3619
|
return { cue: "select", detail: { direction: options.indexOf(after) - options.indexOf(before) }, detents: 1, at: 1, was: 0 };
|
|
3570
3620
|
}
|
|
3621
|
+
if (field.kind === "text")
|
|
3622
|
+
return null;
|
|
3571
3623
|
if (field.kind === "keybind")
|
|
3572
3624
|
return after ? { cue: "capture", detail: {}, detents: 1, at: 1, was: 0 } : { cue: "select", detail: { direction: -1 }, detents: 1, at: 1, was: 0 };
|
|
3573
3625
|
let { min, max, step } = field, a = numbers(before), b = numbers(after);
|
|
@@ -4393,4 +4445,4 @@ function createLayer(doc) {
|
|
|
4393
4445
|
};
|
|
4394
4446
|
}
|
|
4395
4447
|
|
|
4396
|
-
export { resolveLook, themeOf, applyLook, panelLook, CHECK_POINTS, CHECK_PATH, iconPath, iconSvg, readSession, writeSession, rolling_css_default, FILL, LEAD, trailScale, Edges, POP_MS, popScale, settleScale, VelocityTracker, clamp, Roll, rollTarget, numeral, entranceOffset, FLASH_MS, flash, flashOf, offRow, precisionRate, RULER, RULER_NEAR, RULER_FADE, rulerLevels, rulerAlpha, rulerDepth, THIN, THINNEST, thinOf, roundOf, stretchOf, stretchAt, giveRoom, detentScale, detentsOf, roundValues, unwarp, Notches, escapeTo, commandScope, scopeLabel, crumbTrail, escTarget, digitOption, digitHints, createCrumbs, TOKENS, knobs, aliased, injectTokens, DELAYED, injectStyles, resolveSound, sound, SOUND_PREF, soundPanel, changed, cue, createHintController, pageHints, toggleLayer };
|
|
4448
|
+
export { resolveLook, themeOf, applyLook, panelLook, CHECK_POINTS, CHECK_PATH, iconPath, iconSvg, readSession, writeSession, rolling_css_default, FILL, LEAD, trailScale, Edges, POP_MS, popScale, settleScale, VelocityTracker, clamp, Roll, rollTarget, numeral, entranceOffset, FLASH_MS, flash, flashOf, offRow, precisionRate, RULER, RULER_NEAR, RULER_FADE, rulerLevels, rulerAlpha, rulerDepth, THIN, THINNEST, thinOf, roundOf, stretchOf, stretchAt, giveRoom, detentScale, detentsOf, roundValues, unwarp, Notches, escapeTo, commandScope, scopeLabel, crumbTrail, escTarget, digitOption, digitRoute, digitHints, createCrumbs, TOKENS, knobs, aliased, injectTokens, DELAYED, injectStyles, resolveSound, sound, SOUND_PREF, soundPanel, changed, cue, createHintController, pageHints, toggleLayer };
|
package/dist/dev/index.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
__preload,
|
|
3
|
-
__chunks,
|
|
4
2
|
maxChroma,
|
|
5
3
|
oklchToRgb,
|
|
6
4
|
parseColor2,
|
|
@@ -27,6 +25,7 @@ import {
|
|
|
27
25
|
pickMeta,
|
|
28
26
|
isReadout2,
|
|
29
27
|
hasValue2,
|
|
28
|
+
variantsOf,
|
|
30
29
|
pinnedKeys,
|
|
31
30
|
SPRING2,
|
|
32
31
|
valueKeys,
|
|
@@ -45,6 +44,7 @@ import {
|
|
|
45
44
|
angle2,
|
|
46
45
|
seed2,
|
|
47
46
|
keybind2,
|
|
47
|
+
text2,
|
|
48
48
|
gradient2,
|
|
49
49
|
curve2,
|
|
50
50
|
toolbarShortcut2,
|
|
@@ -76,8 +76,7 @@ import {
|
|
|
76
76
|
browserStorage,
|
|
77
77
|
urlFlag2,
|
|
78
78
|
storageKey
|
|
79
|
-
} from "./chunk-
|
|
80
|
-
__chunks(import.meta.url,["js6xfzn6","bnhzf1tj","75gbzbyd","mjdgzad5","j57rhjtm"],[["./index.js",3],["./chunk-bnhzf1tj.js",3,4],["./chunk-75gbzbyd.js",3,4],["./chunk-mjdgzad5.js"],["./chunk-j57rhjtm.js",3]],0);
|
|
79
|
+
} from "./chunk-7kns3qe6.js";
|
|
81
80
|
// src/core/random.ts
|
|
82
81
|
var lattice = (min, max, step, r) => min + Math.floor(r * (Math.floor((max - min) / step + 0.000000001) + 1)) * step, between = (min, max, r) => min + (max - min) * r;
|
|
83
82
|
function pick(field, random) {
|
|
@@ -120,6 +119,7 @@ function pick(field, random) {
|
|
|
120
119
|
case "seed":
|
|
121
120
|
return lattice(field.min, field.max, 1, r());
|
|
122
121
|
case "keybind":
|
|
122
|
+
case "text":
|
|
123
123
|
return field.value;
|
|
124
124
|
case "gradient":
|
|
125
125
|
return randomStops(field.value.length, r);
|
|
@@ -205,6 +205,7 @@ function around(field, base, random) {
|
|
|
205
205
|
]);
|
|
206
206
|
case "seed":
|
|
207
207
|
case "keybind":
|
|
208
|
+
case "text":
|
|
208
209
|
return pick(field, random);
|
|
209
210
|
}
|
|
210
211
|
}
|
|
@@ -304,6 +305,7 @@ function shift(field, value, random) {
|
|
|
304
305
|
case "seed":
|
|
305
306
|
return nudge(value, field.min, field.max, 1, random);
|
|
306
307
|
case "keybind":
|
|
308
|
+
case "text":
|
|
307
309
|
return value;
|
|
308
310
|
case "gradient":
|
|
309
311
|
return mutateStops(value, random, MUTATE.hue, MUTATE.lightness);
|
|
@@ -599,7 +601,7 @@ function defineControls(id, input, options = {}) {
|
|
|
599
601
|
if (pinnedOf?.schema !== schema)
|
|
600
602
|
pinnedOf = { schema, keys: pinnedKeys(schema, options.pinned) };
|
|
601
603
|
return pinnedOf.keys;
|
|
602
|
-
}, unpinned = (values) => {
|
|
604
|
+
}, variantsChoice = () => variantsOf(schema, (key) => pinned().has(key)), unpinned = (values) => {
|
|
603
605
|
let keys = pinned();
|
|
604
606
|
if (keys.size === 0)
|
|
605
607
|
return values;
|
|
@@ -613,14 +615,24 @@ function defineControls(id, input, options = {}) {
|
|
|
613
615
|
if (keys.size === 0)
|
|
614
616
|
return values;
|
|
615
617
|
return Object.fromEntries(Object.entries(values).filter(([k]) => !keys.has(k)));
|
|
616
|
-
}, buildPresets = () =>
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
618
|
+
}, buildPresets = () => {
|
|
619
|
+
let own = options.presets ?? {}, v = variantsChoice();
|
|
620
|
+
if (v && Object.hasOwn(own, v.field.value))
|
|
621
|
+
throw Error(`The default variant (${v.field.value}) is the schema's defaults; set its values there.`);
|
|
622
|
+
let ids = [
|
|
623
|
+
...v ? v.field.options.filter((o) => o !== v.field.value) : [],
|
|
624
|
+
...Object.keys(own).filter((id) => !v?.field.options.includes(id))
|
|
625
|
+
];
|
|
626
|
+
return Object.freeze(Object.fromEntries([
|
|
627
|
+
["default", locked],
|
|
628
|
+
...ids.map((id) => {
|
|
629
|
+
if (id === "default" || id === "custom")
|
|
630
|
+
throw Error(`Reserved preset id: ${id}`);
|
|
631
|
+
let variant = v?.field.options.includes(id) ? { [v.key]: id } : {};
|
|
632
|
+
return [id, unpinned(normalize(schema, { ...locked, ...variant, ...own[id] }))];
|
|
633
|
+
})
|
|
634
|
+
]));
|
|
635
|
+
}, presets = buildPresets(), buildGroupPresets = () => Object.freeze(Object.fromEntries(Object.entries(options.groupPresets ?? {}).map(([group, list]) => {
|
|
624
636
|
let named = list.flatMap((p) => Object.keys(p.values).filter((k) => Object.hasOwn(schema, k))), covered = new Set((named.length ? named : Object.keys(schema).filter((k) => schema[k].group === group)).filter((k) => hasValue2(schema[k])));
|
|
625
637
|
return [
|
|
626
638
|
group,
|
|
@@ -1088,7 +1100,10 @@ function defineControls(id, input, options = {}) {
|
|
|
1088
1100
|
sectionDescription: (section) => options.sectionDescriptions?.[section] ?? fieldLabels().sectionText.get(section),
|
|
1089
1101
|
groupFolded: options.groupFolded,
|
|
1090
1102
|
sectionFolded: options.sectionFolded,
|
|
1091
|
-
presetLabel: (presetId) =>
|
|
1103
|
+
presetLabel: (presetId) => {
|
|
1104
|
+
let v = variantsChoice(), option = presetId === "default" ? v?.field.value : presetId;
|
|
1105
|
+
return options.presetLabels?.[presetId] ?? (presetId === "default" ? options.defaultLabel : void 0) ?? (v && option !== void 0 && v.field.options.includes(option) ? v.field.labels?.[option] ?? option : presetId);
|
|
1106
|
+
},
|
|
1092
1107
|
isPinned: (key) => pinned().has(key),
|
|
1093
1108
|
get,
|
|
1094
1109
|
set,
|
|
@@ -1400,11 +1415,11 @@ function defineControls(id, input, options = {}) {
|
|
|
1400
1415
|
code: (format, values) => formatCode(values ?? get(), format),
|
|
1401
1416
|
variants,
|
|
1402
1417
|
attach(element, chip) {
|
|
1403
|
-
let load = options.ship ? () => options.ship().then((m) => m.attach) : () =>
|
|
1418
|
+
let load = options.ship ? () => options.ship().then((m) => m.attach) : () => import("./chunk-ab7vfghg.js").then((m) => m.attach);
|
|
1404
1419
|
return live(load, (attach) => attach(controls, element, chip), (detach) => detach());
|
|
1405
1420
|
},
|
|
1406
1421
|
mount(container, mountOptions) {
|
|
1407
|
-
let load = options.ship ? () => options.ship().then((m) => m.mountPanel) : () =>
|
|
1422
|
+
let load = options.ship ? () => options.ship().then((m) => m.mountPanel) : () => import("./chunk-9qtvxa6k.js").then((m) => m.mountPanel);
|
|
1408
1423
|
return live(load, (mountPanel) => {
|
|
1409
1424
|
let panel = mountPanel(controls, container, mountOptions);
|
|
1410
1425
|
return mountOptions?.onReady?.(panel), panel;
|
|
@@ -1441,7 +1456,7 @@ function descriptorToField(d) {
|
|
|
1441
1456
|
if (readoutDescriptor(d))
|
|
1442
1457
|
return readoutField(d);
|
|
1443
1458
|
if (d.kind === "toolbar")
|
|
1444
|
-
return toolbar2(d.items.map(({ key, ...item }) => ({ ...item, id: key })), meta);
|
|
1459
|
+
return toolbar2(d.items.map(({ key, ...item }) => ({ ...item, id: key })), d.labels !== void 0 ? { ...meta, labels: d.labels } : meta);
|
|
1445
1460
|
if (d.bind)
|
|
1446
1461
|
return flatSpring2({}, { ...meta, id: d.key }).duration;
|
|
1447
1462
|
if (d.kind === "knob" || d.kind === "number") {
|
|
@@ -1516,6 +1531,12 @@ function descriptorToField(d) {
|
|
|
1516
1531
|
});
|
|
1517
1532
|
if (d.kind === "keybind")
|
|
1518
1533
|
return keybind2(typeof d.default === "string" ? d.default : "", meta);
|
|
1534
|
+
if (d.kind === "text")
|
|
1535
|
+
return text2(typeof d.default === "string" ? d.default : "", {
|
|
1536
|
+
...d.multiline ? { multiline: !0 } : {},
|
|
1537
|
+
...d.placeholder ? { placeholder: d.placeholder } : {},
|
|
1538
|
+
...meta
|
|
1539
|
+
});
|
|
1519
1540
|
if (d.kind === "gradient") {
|
|
1520
1541
|
let fallback = [
|
|
1521
1542
|
{ at: 0, color: "#000000" },
|
|
@@ -1594,7 +1615,7 @@ var decimal = (n) => String(Math.round(n * 1e4) / 1e4), swiftLiteral = (d, v) =>
|
|
|
1594
1615
|
let [a, b] = v;
|
|
1595
1616
|
return `${decimal(a)}...${decimal(b)}`;
|
|
1596
1617
|
}
|
|
1597
|
-
if (d.kind === "keybind")
|
|
1618
|
+
if (d.kind === "keybind" || d.kind === "text")
|
|
1598
1619
|
return JSON.stringify(v);
|
|
1599
1620
|
if (d.kind === "gradient")
|
|
1600
1621
|
return `Gradient(stops: [${(Array.isArray(v) ? v : []).map((s) => {
|
|
@@ -1623,6 +1644,7 @@ var decimal = (n) => String(Math.round(n * 1e4) / 1e4), swiftLiteral = (d, v) =>
|
|
|
1623
1644
|
range: "ClosedRange<Double>",
|
|
1624
1645
|
seed: "Int",
|
|
1625
1646
|
keybind: "String",
|
|
1647
|
+
text: "String",
|
|
1626
1648
|
gradient: "Gradient",
|
|
1627
1649
|
curve: "[CGPoint]"
|
|
1628
1650
|
};
|
|
@@ -1832,6 +1854,7 @@ export {
|
|
|
1832
1854
|
springCss2 as springCss,
|
|
1833
1855
|
springMotion2 as springMotion,
|
|
1834
1856
|
table2 as table,
|
|
1857
|
+
text2 as text,
|
|
1835
1858
|
toggle2 as toggle,
|
|
1836
1859
|
toolbar2 as toolbar,
|
|
1837
1860
|
toolbarShortcut2 as toolbarShortcut,
|
package/dist/index.js
CHANGED
|
@@ -473,6 +473,16 @@ function pickMeta(source, skip = []) {
|
|
|
473
473
|
return out;
|
|
474
474
|
}
|
|
475
475
|
var READOUT_KINDS = /* @__PURE__ */ new Set(["watch", "sparkline", "graph", "meter", "table", "log"]), isReadout = (field) => READOUT_KINDS.has(field.kind), hasValue = (field) => field.kind !== "action" && field.kind !== "toolbar" && !READOUT_KINDS.has(field.kind);
|
|
476
|
+
function variantsOf(schema, isPinned = () => !1) {
|
|
477
|
+
let found;
|
|
478
|
+
for (let [key, field] of Object.entries(schema))
|
|
479
|
+
if (field.kind === "choice" && field.variants && !isPinned(key)) {
|
|
480
|
+
if (found)
|
|
481
|
+
throw Error(`Only one choice can hold the variants (${found.key}, ${key}).`);
|
|
482
|
+
found = { key, field };
|
|
483
|
+
}
|
|
484
|
+
return found;
|
|
485
|
+
}
|
|
476
486
|
function pinnedKeys(schema, groups = []) {
|
|
477
487
|
let byGroup = new Map(groups.map((g) => [g, !0]));
|
|
478
488
|
for (let f of Object.values(schema))
|
|
@@ -515,8 +525,9 @@ function choice(value, options, meta) {
|
|
|
515
525
|
value,
|
|
516
526
|
options: Object.freeze([...options]),
|
|
517
527
|
...labels && Object.keys(labels).length ? { labels } : {},
|
|
518
|
-
...meta?.display ? { display: meta.display } : {}
|
|
519
|
-
|
|
528
|
+
...meta?.display ? { display: meta.display } : {},
|
|
529
|
+
...meta?.variants ? { variants: !0 } : {}
|
|
530
|
+
}, meta?.variants ? { ...meta, random: meta.random ?? !1 } : meta);
|
|
520
531
|
}
|
|
521
532
|
function action(label, meta) {
|
|
522
533
|
let { shortcut, global, rebind, run, ...rest } = meta ?? {}, key = shortcutOf({ ...shortcut ? { shortcut } : {}, ...global ? { global } : {} }), combo = key ? normalizeCombo(key.key) : "";
|
|
@@ -661,6 +672,17 @@ function keybind(value = "", meta) {
|
|
|
661
672
|
let field = { kind: "keybind", value: normalizeCombo(value) };
|
|
662
673
|
return withMeta(field, { random: !1, ...meta });
|
|
663
674
|
}
|
|
675
|
+
function text(value = "", options) {
|
|
676
|
+
let { multiline, placeholder, ...meta } = options ?? {}, field = {
|
|
677
|
+
kind: "text",
|
|
678
|
+
value: "",
|
|
679
|
+
...multiline ? { multiline: !0 } : {},
|
|
680
|
+
...placeholder ? { placeholder } : {}
|
|
681
|
+
};
|
|
682
|
+
return withMeta({ ...field, value: normalizeText(field, value) }, { random: !1, ...meta });
|
|
683
|
+
}
|
|
684
|
+
var normalizeText = (field, input) => field.multiline ? input.replace(/\r\n?/g, `
|
|
685
|
+
`) : input.replace(/\r\n?|\n/g, " ");
|
|
664
686
|
function gradient(stops, options = {}) {
|
|
665
687
|
let value = normalizeStops(stops);
|
|
666
688
|
if (!value)
|
|
@@ -715,7 +737,8 @@ function toolbar(items, meta) {
|
|
|
715
737
|
throw Error("A toolbar needs at least one item.");
|
|
716
738
|
return withMeta({
|
|
717
739
|
kind: "toolbar",
|
|
718
|
-
items: Object.freeze(items.map((item) => Object.freeze({ ...item })))
|
|
740
|
+
items: Object.freeze(items.map((item) => Object.freeze({ ...item }))),
|
|
741
|
+
...meta?.labels !== void 0 ? { labels: meta.labels } : {}
|
|
719
742
|
}, meta);
|
|
720
743
|
}
|
|
721
744
|
var readoutMeta = (o) => {
|
|
@@ -859,6 +882,8 @@ function normalizeField(field, input) {
|
|
|
859
882
|
return typeof input === "number" && Number.isFinite(input) ? Math.round(Math.min(field.max, Math.max(field.min, input))) : field.value;
|
|
860
883
|
case "keybind":
|
|
861
884
|
return typeof input === "string" ? normalizeCombo(input) : field.value;
|
|
885
|
+
case "text":
|
|
886
|
+
return typeof input === "string" ? normalizeText(field, input) : field.value;
|
|
862
887
|
case "gradient":
|
|
863
888
|
return normalizeStops(input) ?? field.value;
|
|
864
889
|
case "curve":
|
|
@@ -1009,6 +1034,7 @@ function pick(field, random) {
|
|
|
1009
1034
|
case "seed":
|
|
1010
1035
|
return lattice(field.min, field.max, 1, r());
|
|
1011
1036
|
case "keybind":
|
|
1037
|
+
case "text":
|
|
1012
1038
|
return field.value;
|
|
1013
1039
|
case "gradient":
|
|
1014
1040
|
return randomStops(field.value.length, r);
|
|
@@ -1094,6 +1120,7 @@ function around(field, base, random) {
|
|
|
1094
1120
|
]);
|
|
1095
1121
|
case "seed":
|
|
1096
1122
|
case "keybind":
|
|
1123
|
+
case "text":
|
|
1097
1124
|
return pick(field, random);
|
|
1098
1125
|
}
|
|
1099
1126
|
}
|
|
@@ -1193,6 +1220,7 @@ function shift(field, value, random) {
|
|
|
1193
1220
|
case "seed":
|
|
1194
1221
|
return nudge(value, field.min, field.max, 1, random);
|
|
1195
1222
|
case "keybind":
|
|
1223
|
+
case "text":
|
|
1196
1224
|
return value;
|
|
1197
1225
|
case "gradient":
|
|
1198
1226
|
return mutateStops(value, random, MUTATE.hue, MUTATE.lightness);
|
|
@@ -1629,7 +1657,7 @@ function defineControls(id, input, options = {}) {
|
|
|
1629
1657
|
if (pinnedOf?.schema !== schema)
|
|
1630
1658
|
pinnedOf = { schema, keys: pinnedKeys(schema, options.pinned) };
|
|
1631
1659
|
return pinnedOf.keys;
|
|
1632
|
-
}, unpinned = (values) => {
|
|
1660
|
+
}, variantsChoice = () => variantsOf(schema, (key) => pinned().has(key)), unpinned = (values) => {
|
|
1633
1661
|
let keys = pinned();
|
|
1634
1662
|
if (keys.size === 0)
|
|
1635
1663
|
return values;
|
|
@@ -1643,14 +1671,24 @@ function defineControls(id, input, options = {}) {
|
|
|
1643
1671
|
if (keys.size === 0)
|
|
1644
1672
|
return values;
|
|
1645
1673
|
return Object.fromEntries(Object.entries(values).filter(([k]) => !keys.has(k)));
|
|
1646
|
-
}, buildPresets = () =>
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1674
|
+
}, buildPresets = () => {
|
|
1675
|
+
let own = options.presets ?? {}, v = variantsChoice();
|
|
1676
|
+
if (v && Object.hasOwn(own, v.field.value))
|
|
1677
|
+
throw Error(`The default variant (${v.field.value}) is the schema's defaults; set its values there.`);
|
|
1678
|
+
let ids = [
|
|
1679
|
+
...v ? v.field.options.filter((o) => o !== v.field.value) : [],
|
|
1680
|
+
...Object.keys(own).filter((id) => !v?.field.options.includes(id))
|
|
1681
|
+
];
|
|
1682
|
+
return Object.freeze(Object.fromEntries([
|
|
1683
|
+
["default", locked],
|
|
1684
|
+
...ids.map((id) => {
|
|
1685
|
+
if (id === "default" || id === "custom")
|
|
1686
|
+
throw Error(`Reserved preset id: ${id}`);
|
|
1687
|
+
let variant = v?.field.options.includes(id) ? { [v.key]: id } : {};
|
|
1688
|
+
return [id, unpinned(normalize(schema, { ...locked, ...variant, ...own[id] }))];
|
|
1689
|
+
})
|
|
1690
|
+
]));
|
|
1691
|
+
}, presets = buildPresets(), buildGroupPresets = () => Object.freeze(Object.fromEntries(Object.entries(options.groupPresets ?? {}).map(([group, list]) => {
|
|
1654
1692
|
let named = list.flatMap((p) => Object.keys(p.values).filter((k) => Object.hasOwn(schema, k))), covered = new Set((named.length ? named : Object.keys(schema).filter((k) => schema[k].group === group)).filter((k) => hasValue(schema[k])));
|
|
1655
1693
|
return [
|
|
1656
1694
|
group,
|
|
@@ -2118,7 +2156,10 @@ function defineControls(id, input, options = {}) {
|
|
|
2118
2156
|
sectionDescription: (section) => options.sectionDescriptions?.[section] ?? fieldLabels().sectionText.get(section),
|
|
2119
2157
|
groupFolded: options.groupFolded,
|
|
2120
2158
|
sectionFolded: options.sectionFolded,
|
|
2121
|
-
presetLabel: (presetId) =>
|
|
2159
|
+
presetLabel: (presetId) => {
|
|
2160
|
+
let v = variantsChoice(), option = presetId === "default" ? v?.field.value : presetId;
|
|
2161
|
+
return options.presetLabels?.[presetId] ?? (presetId === "default" ? options.defaultLabel : void 0) ?? (v && option !== void 0 && v.field.options.includes(option) ? v.field.labels?.[option] ?? option : presetId);
|
|
2162
|
+
},
|
|
2122
2163
|
isPinned: (key) => pinned().has(key),
|
|
2123
2164
|
get,
|
|
2124
2165
|
set,
|
|
@@ -2471,7 +2512,7 @@ function descriptorToField(d) {
|
|
|
2471
2512
|
if (readoutDescriptor(d))
|
|
2472
2513
|
return readoutField(d);
|
|
2473
2514
|
if (d.kind === "toolbar")
|
|
2474
|
-
return toolbar(d.items.map(({ key, ...item }) => ({ ...item, id: key })), meta);
|
|
2515
|
+
return toolbar(d.items.map(({ key, ...item }) => ({ ...item, id: key })), d.labels !== void 0 ? { ...meta, labels: d.labels } : meta);
|
|
2475
2516
|
if (d.bind)
|
|
2476
2517
|
return flatSpring({}, { ...meta, id: d.key }).duration;
|
|
2477
2518
|
if (d.kind === "knob" || d.kind === "number") {
|
|
@@ -2546,6 +2587,12 @@ function descriptorToField(d) {
|
|
|
2546
2587
|
});
|
|
2547
2588
|
if (d.kind === "keybind")
|
|
2548
2589
|
return keybind(typeof d.default === "string" ? d.default : "", meta);
|
|
2590
|
+
if (d.kind === "text")
|
|
2591
|
+
return text(typeof d.default === "string" ? d.default : "", {
|
|
2592
|
+
...d.multiline ? { multiline: !0 } : {},
|
|
2593
|
+
...d.placeholder ? { placeholder: d.placeholder } : {},
|
|
2594
|
+
...meta
|
|
2595
|
+
});
|
|
2549
2596
|
if (d.kind === "gradient") {
|
|
2550
2597
|
let fallback = [
|
|
2551
2598
|
{ at: 0, color: "#000000" },
|
|
@@ -2624,7 +2671,7 @@ var decimal = (n) => String(Math.round(n * 1e4) / 1e4), swiftLiteral = (d, v) =>
|
|
|
2624
2671
|
let [a, b] = v;
|
|
2625
2672
|
return `${decimal(a)}...${decimal(b)}`;
|
|
2626
2673
|
}
|
|
2627
|
-
if (d.kind === "keybind")
|
|
2674
|
+
if (d.kind === "keybind" || d.kind === "text")
|
|
2628
2675
|
return JSON.stringify(v);
|
|
2629
2676
|
if (d.kind === "gradient")
|
|
2630
2677
|
return `Gradient(stops: [${(Array.isArray(v) ? v : []).map((s) => {
|
|
@@ -2653,6 +2700,7 @@ var decimal = (n) => String(Math.round(n * 1e4) / 1e4), swiftLiteral = (d, v) =>
|
|
|
2653
2700
|
range: "ClosedRange<Double>",
|
|
2654
2701
|
seed: "Int",
|
|
2655
2702
|
keybind: "String",
|
|
2703
|
+
text: "String",
|
|
2656
2704
|
gradient: "Gradient",
|
|
2657
2705
|
curve: "[CGPoint]"
|
|
2658
2706
|
};
|
|
@@ -2862,6 +2910,7 @@ export {
|
|
|
2862
2910
|
springCss,
|
|
2863
2911
|
springMotion,
|
|
2864
2912
|
table,
|
|
2913
|
+
text,
|
|
2865
2914
|
toggle,
|
|
2866
2915
|
toolbar,
|
|
2867
2916
|
toolbarShortcut,
|