@kitlangton/knobs 0.4.0-next.12 → 0.4.0-next.14
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 +43 -15
- package/dist/dev/{chunk-nwfm1bfj.js → chunk-bejz4qcg.js} +15 -7
- package/dist/dev/{chunk-ab7vfghg.js → chunk-f0e5tkqg.js} +2 -2
- package/dist/dev/{chunk-9qtvxa6k.js → chunk-s7d5a8vb.js} +271 -163
- package/dist/dev/{chunk-7kns3qe6.js → chunk-v2g91mrm.js} +9 -1
- package/dist/dev/index.js +166 -57
- package/dist/index.js +170 -54
- package/dist/panel.js +339 -181
- package/dist/review-react.js +5 -3
- package/dist/review-solid.js +5 -3
- package/dist/review.js +5 -3
- package/dist/types/core/remote.d.ts +5 -1
- package/dist/types/core/schema.d.ts +12 -1
- package/dist/types/core/store.d.ts +62 -12
- package/dist/types/core/variants.d.ts +3 -1
- package/dist/types/panel/gpu/renderer.d.ts +8 -0
- package/dist/types/panel/presets.d.ts +14 -4
- package/dist/types/ui/index.d.ts +1 -1
- package/dist/types/ui/palette.d.ts +15 -0
- package/dist/types/ui/tree-model.d.ts +5 -2
- package/dist/ui-react.js +5 -3
- package/dist/ui-solid.js +5 -3
- package/dist/ui.js +28 -6
- package/package.json +1 -1
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
pushReadout,
|
|
47
47
|
READOUT,
|
|
48
48
|
storageKey
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-v2g91mrm.js";
|
|
50
50
|
import {
|
|
51
51
|
resolveLook,
|
|
52
52
|
themeOf,
|
|
@@ -119,7 +119,7 @@ import {
|
|
|
119
119
|
createHintController,
|
|
120
120
|
pageHints,
|
|
121
121
|
toggleLayer
|
|
122
|
-
} from "./chunk-
|
|
122
|
+
} from "./chunk-bejz4qcg.js";
|
|
123
123
|
|
|
124
124
|
// src/panel/die.ts
|
|
125
125
|
var ROUND = 16 * Math.sqrt(5), DIE = { half: 64 + ROUND, round: ROUND, pip: 12 }, PIPS = {
|
|
@@ -960,8 +960,8 @@ function panOptions(el, o) {
|
|
|
960
960
|
|
|
961
961
|
// src/panel/presets.ts
|
|
962
962
|
var DRIFTED_PILL = 0.5;
|
|
963
|
-
function activeEntryId(controls) {
|
|
964
|
-
let ref = controls.activePreset();
|
|
963
|
+
function activeEntryId(controls, scope = "") {
|
|
964
|
+
let ref = controls.activePreset(scope);
|
|
965
965
|
return ref ? `${ref.kind === "preset" ? "p" : "v"}:${ref.id}` : null;
|
|
966
966
|
}
|
|
967
967
|
function resolveActivePresetEntry(entries, currentValues, lastAppliedId, baseId = null) {
|
|
@@ -1012,7 +1012,7 @@ function nextPresetIndex(count, activeIndex, direction) {
|
|
|
1012
1012
|
return direction > 0 ? 0 : count - 1;
|
|
1013
1013
|
return ((activeIndex + direction) % count + count) % count;
|
|
1014
1014
|
}
|
|
1015
|
-
function createPresetStrip(doc, controls, showVariants, run, onAfterChange, presetLabel = (id) => controls.presetLabel(id), relevant) {
|
|
1015
|
+
function createPresetStrip(doc, controls, showVariants, run, onAfterChange, presetLabel = (id, scope) => controls.presetLabel(id, scope), relevant, scopeOf = () => "") {
|
|
1016
1016
|
let wake = () => onAfterChange?.(), el = (tag, cls, text) => {
|
|
1017
1017
|
let node = doc.createElement(tag);
|
|
1018
1018
|
if (cls)
|
|
@@ -1029,31 +1029,34 @@ function createPresetStrip(doc, controls, showVariants, run, onAfterChange, pres
|
|
|
1029
1029
|
saveButton.type = "button", saveButton.tabIndex = -1, saveButton.setAttribute("aria-label", "Save as variant"), saveButton.setAttribute("aria-keyshortcuts", "Shift+S"), saveButton.dataset.hint = "Save", saveButton.onclick = () => run(save);
|
|
1030
1030
|
if (track.append(pill), root.append(track), saveButton)
|
|
1031
1031
|
root.append(saveButton);
|
|
1032
|
-
let pillEdges = new Edges, pillY = new Spring(0, 28, 0.86), pillAlpha = new Spring(1, 26, 0.9), entries = [], buttons = [], signature = "", lastVariantsRef = null, lastAppliedId = null, activeState = { activeId: "p:default", activeIndex: 0, isCustom: !1 }, prevActiveId = "", prevActiveIndex = -2, prevIsCustom = !1, prevDrifted = !1, initializedPill = !1, slideUntil = 0, display = "auto", chipMin = 0, unpinned = (values) => {
|
|
1032
|
+
let pillEdges = new Edges, pillY = new Spring(0, 28, 0.86), pillAlpha = new Spring(1, 26, 0.9), entries = [], buttons = [], signature = "", lastVariantsRef = null, lastAppliedId = null, activeState = { activeId: "p:default", activeIndex: 0, isCustom: !1 }, prevActiveId = "", prevActiveIndex = -2, prevIsCustom = !1, prevDrifted = !1, initializedPill = !1, slideUntil = 0, display = "auto", digits = !1, chipMin = 0, scope = null, at = () => scope ?? "", source = () => scope === null ? void 0 : scope === "" ? { presets: controls.presets, variants: controls.variants } : controls.scopes[scope], unpinned = (values) => {
|
|
1033
1033
|
let out;
|
|
1034
1034
|
for (let k of Object.keys(values))
|
|
1035
|
-
if (controls.
|
|
1035
|
+
if (controls.scopeOf(k) !== at() && !same(values[k], controls.locked[k]))
|
|
1036
1036
|
out ??= { ...values }, out[k] = controls.locked[k];
|
|
1037
1037
|
return out ?? values;
|
|
1038
1038
|
};
|
|
1039
1039
|
function buildEntries() {
|
|
1040
|
-
let
|
|
1040
|
+
let from = source();
|
|
1041
|
+
if (!from)
|
|
1042
|
+
return [];
|
|
1043
|
+
let where = at(), presetEntries = Object.entries(from.presets).map(([id, presetValues]) => ({
|
|
1041
1044
|
id: `p:${id}`,
|
|
1042
1045
|
kind: "preset",
|
|
1043
1046
|
rawId: id,
|
|
1044
|
-
label: presetLabel(id),
|
|
1047
|
+
label: presetLabel(id, where),
|
|
1045
1048
|
values: presetValues,
|
|
1046
|
-
apply: (coalesce) => controls.preset(id, { coalesce })
|
|
1049
|
+
apply: (coalesce) => controls.preset(id, { coalesce, scope: where })
|
|
1047
1050
|
}));
|
|
1048
1051
|
if (!showVariants)
|
|
1049
1052
|
return presetEntries;
|
|
1050
|
-
let variantEntries =
|
|
1053
|
+
let variantEntries = from.variants.list().map((v) => ({
|
|
1051
1054
|
id: `v:${v.id}`,
|
|
1052
1055
|
kind: "variant",
|
|
1053
1056
|
rawId: v.id,
|
|
1054
1057
|
label: v.name ?? v.id.slice(0, 8),
|
|
1055
1058
|
values: unpinned(v.values),
|
|
1056
|
-
apply: (coalesce) =>
|
|
1059
|
+
apply: (coalesce) => from.variants.load(v.id, { coalesce })
|
|
1057
1060
|
}));
|
|
1058
1061
|
return [...presetEntries, ...variantEntries];
|
|
1059
1062
|
}
|
|
@@ -1087,7 +1090,7 @@ function createPresetStrip(doc, controls, showVariants, run, onAfterChange, pres
|
|
|
1087
1090
|
if (pill.style.left = `${left}px`, pill.style.right = `${box.trackWidth - right}px`, pill.style.top = `${top}px`, pill.style.height = `${box.height}px`, pill.style.opacity = activeState.drifted ? String(DRIFTED_PILL) : "1", pill.style.scale = "", first)
|
|
1088
1091
|
doc.defaultView?.requestAnimationFrame(() => pill.style.transition = "");
|
|
1089
1092
|
}
|
|
1090
|
-
let resolve = () => resolveActivePresetEntry(entries, unpinned(controls.get()), lastAppliedId, activeEntryId(controls)), wanted = (list) => (list.length > 1 || showVariants) && (relevant?.(list) ?? !0);
|
|
1093
|
+
let resolve = () => resolveActivePresetEntry(entries, unpinned(controls.get()), lastAppliedId, activeEntryId(controls, at())), wanted = (list) => scope !== null && (list.length > 1 || showVariants) && (relevant?.(list) ?? !0);
|
|
1091
1094
|
function syncShown() {
|
|
1092
1095
|
let show = wanted(entries);
|
|
1093
1096
|
if (root.hidden === show && root.dataset.presence === void 0)
|
|
@@ -1130,16 +1133,24 @@ function createPresetStrip(doc, controls, showVariants, run, onAfterChange, pres
|
|
|
1130
1133
|
}
|
|
1131
1134
|
function update() {
|
|
1132
1135
|
run(() => {
|
|
1133
|
-
let
|
|
1134
|
-
if (
|
|
1136
|
+
let was = scope;
|
|
1137
|
+
if (scope = scopeOf(), scope !== was)
|
|
1138
|
+
lastAppliedId = null;
|
|
1139
|
+
let variantsRef = showVariants ? source()?.variants.list() ?? null : null;
|
|
1140
|
+
if (signature !== "" && scope === was && variantsRef === lastVariantsRef) {
|
|
1135
1141
|
syncShown(), syncSelection(!1);
|
|
1136
1142
|
return;
|
|
1137
1143
|
}
|
|
1138
1144
|
lastVariantsRef = variantsRef;
|
|
1139
|
-
let nextEntries = buildEntries(), nextSig = JSON.stringify(nextEntries.map((e) => [e.id, e.label]));
|
|
1145
|
+
let nextEntries = buildEntries(), nextSig = JSON.stringify([scope, digits, nextEntries.map((e) => [e.id, e.label])]);
|
|
1140
1146
|
if (entries = nextEntries, syncShown(), nextSig !== signature)
|
|
1141
1147
|
signature = nextSig, entries = nextEntries, buttons = entries.map((entry, idx) => {
|
|
1142
|
-
let b = el("button", "knobs-preset-chip"
|
|
1148
|
+
let b = el("button", "knobs-preset-chip");
|
|
1149
|
+
if (digits && idx < 9) {
|
|
1150
|
+
let key = el("span", "knobs-preset-key", String(idx + 1));
|
|
1151
|
+
key.setAttribute("aria-hidden", "true"), b.append(key, el("span", "knobs-preset-label", entry.label)), b.setAttribute("aria-keyshortcuts", String(idx + 1));
|
|
1152
|
+
} else
|
|
1153
|
+
b.textContent = entry.label;
|
|
1143
1154
|
return b.type = "button", b.tabIndex = -1, b.dataset.presetId = entry.id, b.dataset.presetKind = entry.kind, b.dataset.presetName = entry.label, b.setAttribute("role", "radio"), b.setAttribute("aria-label", entry.label), b.onclick = (e) => {
|
|
1144
1155
|
if (e.preventDefault(), focusQuietly(), idx !== activeState.activeIndex || activeState.drifted)
|
|
1145
1156
|
selectAt(idx);
|
|
@@ -1175,11 +1186,14 @@ function createPresetStrip(doc, controls, showVariants, run, onAfterChange, pres
|
|
|
1175
1186
|
}
|
|
1176
1187
|
function save() {
|
|
1177
1188
|
finishName(!0);
|
|
1178
|
-
let
|
|
1189
|
+
let variants = source()?.variants;
|
|
1190
|
+
if (!variants)
|
|
1191
|
+
return "";
|
|
1192
|
+
let used = new Set(variants.list().map((v) => v.name)), n = 1;
|
|
1179
1193
|
while (used.has(`Variant ${n}`))
|
|
1180
1194
|
n++;
|
|
1181
|
-
let variant =
|
|
1182
|
-
return
|
|
1195
|
+
let variant = variants.save(`Variant ${n}`);
|
|
1196
|
+
return variants.load(variant.id), lastAppliedId = `v:${variant.id}`, update(), startName(entries.findIndex((e) => e.id === `v:${variant.id}`), !0), onAfterChange?.(), `Saved “Variant ${n}”. Type a name, or Enter to keep it.`;
|
|
1183
1197
|
}
|
|
1184
1198
|
let naming = null;
|
|
1185
1199
|
function placeName() {
|
|
@@ -1223,7 +1237,7 @@ function createPresetStrip(doc, controls, showVariants, run, onAfterChange, pres
|
|
|
1223
1237
|
focusQuietly();
|
|
1224
1238
|
let message;
|
|
1225
1239
|
if (keep && entry?.kind === "variant" && name && name !== was)
|
|
1226
|
-
|
|
1240
|
+
source()?.variants.rename(entry.rawId, name), update(), message = `Named “${name}”.`;
|
|
1227
1241
|
return onAfterChange?.(), message;
|
|
1228
1242
|
}
|
|
1229
1243
|
function rename() {
|
|
@@ -1239,7 +1253,7 @@ function createPresetStrip(doc, controls, showVariants, run, onAfterChange, pres
|
|
|
1239
1253
|
let entry = entries[activeState.activeIndex];
|
|
1240
1254
|
if (!entry || entry.kind !== "variant")
|
|
1241
1255
|
return;
|
|
1242
|
-
return
|
|
1256
|
+
return source()?.variants.remove(entry.rawId), lastAppliedId = null, update(), onAfterChange?.(), `Deleted “${entry.label}”.`;
|
|
1243
1257
|
}
|
|
1244
1258
|
let scrubbing = !1, scrubCommitted = !1, chipIndexAt = (clientX, clientY) => {
|
|
1245
1259
|
let best = -1, bestDist = 1 / 0;
|
|
@@ -1330,6 +1344,13 @@ function createPresetStrip(doc, controls, showVariants, run, onAfterChange, pres
|
|
|
1330
1344
|
if (display = mode, placeDisplay())
|
|
1331
1345
|
measurePill(!0);
|
|
1332
1346
|
},
|
|
1347
|
+
digits(on) {
|
|
1348
|
+
if (digits === on)
|
|
1349
|
+
return;
|
|
1350
|
+
if (digits = on, root.toggleAttribute("data-digits", on), signature === "")
|
|
1351
|
+
return;
|
|
1352
|
+
signature = "", update();
|
|
1353
|
+
},
|
|
1333
1354
|
save: () => {
|
|
1334
1355
|
let message = "";
|
|
1335
1356
|
return run(() => message = save()), message;
|
|
@@ -2971,7 +2992,8 @@ fn hash21(q: vec2f) -> f32 {
|
|
|
2971
2992
|
|
|
2972
2993
|
// kind 0: Panel card surface + elevation shadow + border + specular rim. With a hairline width
|
|
2973
2994
|
// (extra.z, whole device px) the edge is that hairline just outside the card, like CSS's
|
|
2974
|
-
// 0 0 0 w spread shadow, and the rim
|
|
2995
|
+
// 0 0 0 w spread shadow, and the rim lights its top, like CSS's 0 -w 0 (one edge, not two);
|
|
2996
|
+
// otherwise a 1px border and a 1px rim inside it.
|
|
2975
2997
|
fn shadePanel(p: Prim, local: vec2f, size: vec2f) -> vec4f {
|
|
2976
2998
|
let r = p.look.x;
|
|
2977
2999
|
let dist = roundedBox(local, size, r);
|
|
@@ -2980,6 +3002,8 @@ fn shadePanel(p: Prim, local: vec2f, size: vec2f) -> vec4f {
|
|
|
2980
3002
|
var out = vec4f(0.0);
|
|
2981
3003
|
if (hair > 0.0 && dist > -1.0) {
|
|
2982
3004
|
out = premul(p.color2) * clamp(covSd(dist - hair) - bodyCov, 0.0, 1.0);
|
|
3005
|
+
let raised = covSd(roundedBox(local + vec2f(0.0, hair), size, r));
|
|
3006
|
+
out = over(out, premul(p.aux2) * clamp(raised - bodyCov, 0.0, 1.0));
|
|
2983
3007
|
}
|
|
2984
3008
|
|
|
2985
3009
|
// Floating drop shadow when glowOrBlur (look.z) > 0; like box-shadow, never under the card.
|
|
@@ -2993,13 +3017,16 @@ fn shadePanel(p: Prim, local: vec2f, size: vec2f) -> vec4f {
|
|
|
2993
3017
|
|
|
2994
3018
|
var card = premul(p.color) * bodyCov;
|
|
2995
3019
|
|
|
2996
|
-
//
|
|
3020
|
+
// Without a hairline, the rim is CSS's inset 0 1px 0: inside the border, minus that shape
|
|
3021
|
+
// moved down.
|
|
2997
3022
|
let inner = local - vec2f(1.0);
|
|
2998
3023
|
let innerSize = size - vec2f(2.0);
|
|
2999
3024
|
let w = select(1.0, hair, hair > 0.0);
|
|
3000
3025
|
let innerCov = covSd(roundedBox(inner, innerSize, r - 1.0));
|
|
3001
|
-
|
|
3002
|
-
|
|
3026
|
+
if (hair <= 0.0) {
|
|
3027
|
+
let rimCov = innerCov * (1.0 - covSd(roundedBox(inner - vec2f(0.0, w), innerSize, r - 1.0)));
|
|
3028
|
+
card = over(card, premul(p.aux2) * rimCov);
|
|
3029
|
+
}
|
|
3003
3030
|
|
|
3004
3031
|
// A morphing card's specular ring (extra.y), w wide inside the border like CSS's inset 0 0 0 w.
|
|
3005
3032
|
if (p.extra.y > 0.001) {
|
|
@@ -4007,6 +4034,111 @@ class GpuOverlayManager {
|
|
|
4007
4034
|
let more = o.more;
|
|
4008
4035
|
d[b + 40] = more ? more[0] : 0, d[b + 41] = more ? more[1] : 0, d[b + 42] = more ? more[2] : 0, d[b + 43] = more ? more[3] : 0;
|
|
4009
4036
|
}
|
|
4037
|
+
drawPresetStrip(ps, tokens, clip, hinting, reducedMotion, dt, tray) {
|
|
4038
|
+
let moving = !1, psHovered = this.curPanelHovered && ps.element.matches(":hover");
|
|
4039
|
+
this.curSubHovered = psHovered;
|
|
4040
|
+
let psRect = this.rectOf(ps.element), trackRect = this.rectOf(ps.track);
|
|
4041
|
+
if (tray && !tokens.boxed)
|
|
4042
|
+
this.pushPrim({
|
|
4043
|
+
x: psRect.left,
|
|
4044
|
+
y: psRect.top,
|
|
4045
|
+
w: psRect.width,
|
|
4046
|
+
h: psRect.height,
|
|
4047
|
+
color: tokens.segBg,
|
|
4048
|
+
color2: tokens.accent,
|
|
4049
|
+
radius: tokens.radius,
|
|
4050
|
+
glowOrBlur: tokens.glowStrength * 8,
|
|
4051
|
+
kind: 1,
|
|
4052
|
+
p0: psHovered || this.isFocused(ps.element) ? 0.4 : 0
|
|
4053
|
+
});
|
|
4054
|
+
let stripClip = intersectClip(clip, [psRect.left, psRect.top, psRect.right, psRect.bottom]), activeState = ps.getActiveState(), chipButtons = ps.getButtons();
|
|
4055
|
+
if (tokens.boxed)
|
|
4056
|
+
for (let btn of chipButtons) {
|
|
4057
|
+
let br = this.rectOf(btn);
|
|
4058
|
+
if (br.right < stripClip[0] || br.left > stripClip[2])
|
|
4059
|
+
continue;
|
|
4060
|
+
this.drawButtonBox(btn, br, this.isHovered(btn), this.missed(btn, hinting), stripClip);
|
|
4061
|
+
}
|
|
4062
|
+
let activeBtn = activeState.activeIndex >= 0 ? chipButtons[activeState.activeIndex] : void 0, pe = ps.pillEdges, activeBtnRect = activeBtn ? this.rectOf(activeBtn) : void 0, panned = livePill(ps.track);
|
|
4063
|
+
if (activeBtn && activeBtnRect && !activeState.isCustom) {
|
|
4064
|
+
let left = activeBtnRect.left - trackRect.left, right = left + Math.max(20, activeBtnRect.width), top = activeBtnRect.top - trackRect.top;
|
|
4065
|
+
if (this.carry(pe, activeBtn, left, right, ps.pillY, top), panned)
|
|
4066
|
+
pe.snap(panned.left, panned.right), ps.pillY.snap(panned.top);
|
|
4067
|
+
else if (reducedMotion || pe.end.x - pe.start.x <= 1)
|
|
4068
|
+
pe.snap(left, right), ps.pillY.snap(top);
|
|
4069
|
+
else
|
|
4070
|
+
pe.to(left, right, 0, trailScale(tokens.blurStrength)), ps.pillY.set(top);
|
|
4071
|
+
ps.pillAlpha.set(activeState.drifted ? DRIFTED_PILL : 1);
|
|
4072
|
+
} else
|
|
4073
|
+
ps.pillAlpha.set(0);
|
|
4074
|
+
for (let sp of [pe.start, pe.end, ps.pillY, ps.pillAlpha])
|
|
4075
|
+
if (reducedMotion)
|
|
4076
|
+
sp.snap(sp.target);
|
|
4077
|
+
else if (sp.step(dt), !sp.resting)
|
|
4078
|
+
moving = !0;
|
|
4079
|
+
let pillAlpha = clamp(ps.pillAlpha.x, 0, 1);
|
|
4080
|
+
if (pillAlpha > 0.01)
|
|
4081
|
+
this.pushPrim({
|
|
4082
|
+
x: trackRect.left + pe.start.x,
|
|
4083
|
+
y: trackRect.top + ps.pillY.x,
|
|
4084
|
+
w: Math.max(18, pe.end.x - pe.start.x),
|
|
4085
|
+
h: Math.max(16, activeBtnRect?.height ?? trackRect.height),
|
|
4086
|
+
clip: stripClip,
|
|
4087
|
+
color: withAlpha(tokens.pillBg, pillAlpha),
|
|
4088
|
+
color2: withAlpha(tokens.pillBorder, pillAlpha),
|
|
4089
|
+
strokeWidth: this.hairline(tokens),
|
|
4090
|
+
aux2: withAlpha(tokens.rim, tokens.rim[3] * pillAlpha),
|
|
4091
|
+
radius: tokens.buttonRadius ?? tokens.radiusMd,
|
|
4092
|
+
glowOrBlur: tokens.glowStrength,
|
|
4093
|
+
kind: 3,
|
|
4094
|
+
blurX: reducedMotion ? 0 : clamp(pe.velocity * 0.006 * tokens.motionBlur, -8, 8)
|
|
4095
|
+
});
|
|
4096
|
+
for (let i = 0;i < chipButtons.length; i++) {
|
|
4097
|
+
let btn = chipButtons[i], br = this.rectOf(btn);
|
|
4098
|
+
if (br.right < stripClip[0] || br.left > stripClip[2])
|
|
4099
|
+
continue;
|
|
4100
|
+
let isActive = i === activeState.activeIndex, chipHovered = this.isHovered(btn);
|
|
4101
|
+
if (chipHovered)
|
|
4102
|
+
this.curSubHovered = !1;
|
|
4103
|
+
let mark = this.ease(btn, "dot", btn.hasAttribute("data-drifted") ? 1 : 0);
|
|
4104
|
+
if (mark > 0.01) {
|
|
4105
|
+
let size = 4 * (0.4 + 0.6 * mark);
|
|
4106
|
+
this.pushPrim({
|
|
4107
|
+
x: br.right - 6 - size / 2,
|
|
4108
|
+
y: br.top + 6 - size / 2,
|
|
4109
|
+
w: size,
|
|
4110
|
+
h: size,
|
|
4111
|
+
clip: stripClip,
|
|
4112
|
+
color: withAlpha(tokens.modified, 0.95 * mark),
|
|
4113
|
+
glowOrBlur: 0.5,
|
|
4114
|
+
kind: 7
|
|
4115
|
+
});
|
|
4116
|
+
}
|
|
4117
|
+
if (btn.hasAttribute("data-naming"))
|
|
4118
|
+
continue;
|
|
4119
|
+
let key = btn.querySelector(".knobs-preset-key"), name = key && btn.querySelector(".knobs-preset-label");
|
|
4120
|
+
if (key && name) {
|
|
4121
|
+
let kr = this.rectOf(key);
|
|
4122
|
+
this.drawText(key.textContent ?? "", kr.left, br.top + br.height * 0.5, withAlpha(tokens.dim, this.missed(btn, hinting)), { px: tokens.textMeta, weight: tokens.labelWeight, clip: stripClip });
|
|
4123
|
+
}
|
|
4124
|
+
let nr = name ? this.rectOf(name) : void 0;
|
|
4125
|
+
this.drawText(name ? name.textContent ?? "" : btn.textContent ?? "", nr ? nr.left : br.left + br.width * 0.5, br.top + br.height * 0.5, withAlpha(this.hot(btn, isActive || chipHovered, tokens.buttonColor ?? tokens.label), this.missed(btn, hinting)), {
|
|
4126
|
+
px: tokens.buttonFontSize ?? tokens.textControl,
|
|
4127
|
+
weight: isActive ? tokens.titleWeight : tokens.labelWeight,
|
|
4128
|
+
align: nr ? "left" : "center",
|
|
4129
|
+
clip: stripClip
|
|
4130
|
+
});
|
|
4131
|
+
}
|
|
4132
|
+
if (ps.saveButton && !ps.saveButton.hidden) {
|
|
4133
|
+
let sr = this.rectOf(ps.saveButton), hot = this.isHovered(ps.saveButton);
|
|
4134
|
+
this.drawText("+", sr.left + sr.width * 0.5, sr.top + sr.height * 0.5, this.hot(ps.saveButton, hot, tokens.dim), {
|
|
4135
|
+
px: tokens.textTitle,
|
|
4136
|
+
weight: 400,
|
|
4137
|
+
align: "center"
|
|
4138
|
+
});
|
|
4139
|
+
}
|
|
4140
|
+
return moving;
|
|
4141
|
+
}
|
|
4010
4142
|
hairline(tokens) {
|
|
4011
4143
|
return Math.max(1, Math.round(tokens.rimWidth * this.curScale)) / this.curScale;
|
|
4012
4144
|
}
|
|
@@ -5753,7 +5885,6 @@ class GpuOverlayManager {
|
|
|
5753
5885
|
this.placeBackdrop(panel);
|
|
5754
5886
|
continue;
|
|
5755
5887
|
}
|
|
5756
|
-
let pillFill = tokens.pillBg;
|
|
5757
5888
|
if (pageB)
|
|
5758
5889
|
this.placeBackdrop(panel);
|
|
5759
5890
|
let covers = drawn.some((r) => r.left < card.right && r.right > card.left && r.top < card.bottom && r.bottom > card.top);
|
|
@@ -5885,111 +6016,8 @@ class GpuOverlayManager {
|
|
|
5885
6016
|
}
|
|
5886
6017
|
}
|
|
5887
6018
|
let ps = panel.presetStrip, hinting = panel.root.classList.contains("knobs-hinting"), stripAlpha = this.curAlpha;
|
|
5888
|
-
if (!ps.element.hidden)
|
|
5889
|
-
this.curAlpha = stripAlpha * this.presence(ps.element);
|
|
5890
|
-
let psHovered = this.curPanelHovered && ps.element.matches(":hover");
|
|
5891
|
-
this.curSubHovered = psHovered;
|
|
5892
|
-
let psRect = this.rectOf(ps.element), trackRect = this.rectOf(ps.track);
|
|
5893
|
-
if (!tokens.boxed)
|
|
5894
|
-
this.pushPrim({
|
|
5895
|
-
x: psRect.left,
|
|
5896
|
-
y: psRect.top,
|
|
5897
|
-
w: psRect.width,
|
|
5898
|
-
h: psRect.height,
|
|
5899
|
-
color: tokens.segBg,
|
|
5900
|
-
color2: tokens.accent,
|
|
5901
|
-
radius: tokens.radius,
|
|
5902
|
-
glowOrBlur: tokens.glowStrength * 8,
|
|
5903
|
-
kind: 1,
|
|
5904
|
-
p0: psHovered || this.isFocused(ps.element) ? 0.4 : 0
|
|
5905
|
-
});
|
|
5906
|
-
let stripClip = intersectClip(bodyClip, [
|
|
5907
|
-
psRect.left,
|
|
5908
|
-
psRect.top,
|
|
5909
|
-
psRect.right,
|
|
5910
|
-
psRect.bottom
|
|
5911
|
-
]), activeState = ps.getActiveState(), chipButtons = ps.getButtons();
|
|
5912
|
-
if (tokens.boxed)
|
|
5913
|
-
for (let btn of chipButtons) {
|
|
5914
|
-
let br = this.rectOf(btn);
|
|
5915
|
-
if (br.right < stripClip[0] || br.left > stripClip[2])
|
|
5916
|
-
continue;
|
|
5917
|
-
this.drawButtonBox(btn, br, this.isHovered(btn), this.missed(btn, hinting), stripClip);
|
|
5918
|
-
}
|
|
5919
|
-
let activeBtn = activeState.activeIndex >= 0 ? chipButtons[activeState.activeIndex] : void 0, pe = ps.pillEdges, activeBtnRect = activeBtn ? this.rectOf(activeBtn) : void 0, panned = livePill(ps.track);
|
|
5920
|
-
if (activeBtn && activeBtnRect && !activeState.isCustom) {
|
|
5921
|
-
let left = activeBtnRect.left - trackRect.left, right = left + Math.max(20, activeBtnRect.width), top = activeBtnRect.top - trackRect.top;
|
|
5922
|
-
if (this.carry(pe, activeBtn, left, right, ps.pillY, top), panned)
|
|
5923
|
-
pe.snap(panned.left, panned.right), ps.pillY.snap(panned.top);
|
|
5924
|
-
else if (reducedMotion || pe.end.x - pe.start.x <= 1)
|
|
5925
|
-
pe.snap(left, right), ps.pillY.snap(top);
|
|
5926
|
-
else
|
|
5927
|
-
pe.to(left, right, 0, trailScale(tokens.blurStrength)), ps.pillY.set(top);
|
|
5928
|
-
ps.pillAlpha.set(activeState.drifted ? DRIFTED_PILL : 1);
|
|
5929
|
-
} else
|
|
5930
|
-
ps.pillAlpha.set(0);
|
|
5931
|
-
for (let sp of [pe.start, pe.end, ps.pillY, ps.pillAlpha])
|
|
5932
|
-
if (reducedMotion)
|
|
5933
|
-
sp.snap(sp.target);
|
|
5934
|
-
else if (sp.step(dt), !sp.resting)
|
|
5935
|
-
anyMoving = !0;
|
|
5936
|
-
let pillAlpha = clamp(ps.pillAlpha.x, 0, 1);
|
|
5937
|
-
if (pillAlpha > 0.01)
|
|
5938
|
-
this.pushPrim({
|
|
5939
|
-
x: trackRect.left + pe.start.x,
|
|
5940
|
-
y: trackRect.top + ps.pillY.x,
|
|
5941
|
-
w: Math.max(18, pe.end.x - pe.start.x),
|
|
5942
|
-
h: Math.max(16, activeBtnRect?.height ?? trackRect.height),
|
|
5943
|
-
clip: stripClip,
|
|
5944
|
-
color: withAlpha(pillFill, pillAlpha),
|
|
5945
|
-
color2: withAlpha(tokens.pillBorder, pillAlpha),
|
|
5946
|
-
strokeWidth: this.hairline(tokens),
|
|
5947
|
-
aux2: withAlpha(tokens.rim, tokens.rim[3] * pillAlpha),
|
|
5948
|
-
radius: tokens.buttonRadius ?? tokens.radiusMd,
|
|
5949
|
-
glowOrBlur: tokens.glowStrength,
|
|
5950
|
-
kind: 3,
|
|
5951
|
-
blurX: reducedMotion ? 0 : clamp(pe.velocity * 0.006 * tokens.motionBlur, -8, 8)
|
|
5952
|
-
});
|
|
5953
|
-
for (let i = 0;i < chipButtons.length; i++) {
|
|
5954
|
-
let btn = chipButtons[i], br = this.rectOf(btn);
|
|
5955
|
-
if (br.right < stripClip[0] || br.left > stripClip[2])
|
|
5956
|
-
continue;
|
|
5957
|
-
let isActive = i === activeState.activeIndex, chipHovered = this.isHovered(btn);
|
|
5958
|
-
if (chipHovered)
|
|
5959
|
-
this.curSubHovered = !1;
|
|
5960
|
-
let mark = this.ease(btn, "dot", btn.hasAttribute("data-drifted") ? 1 : 0);
|
|
5961
|
-
if (mark > 0.01) {
|
|
5962
|
-
let size = 4 * (0.4 + 0.6 * mark);
|
|
5963
|
-
this.pushPrim({
|
|
5964
|
-
x: br.right - 6 - size / 2,
|
|
5965
|
-
y: br.top + 6 - size / 2,
|
|
5966
|
-
w: size,
|
|
5967
|
-
h: size,
|
|
5968
|
-
clip: stripClip,
|
|
5969
|
-
color: withAlpha(tokens.modified, 0.95 * mark),
|
|
5970
|
-
glowOrBlur: 0.5,
|
|
5971
|
-
kind: 7
|
|
5972
|
-
});
|
|
5973
|
-
}
|
|
5974
|
-
if (btn.hasAttribute("data-naming"))
|
|
5975
|
-
continue;
|
|
5976
|
-
this.drawText(btn.textContent ?? "", br.left + br.width * 0.5, br.top + br.height * 0.5, withAlpha(this.hot(btn, isActive || chipHovered, tokens.buttonColor ?? tokens.label), this.missed(btn, hinting)), {
|
|
5977
|
-
px: tokens.buttonFontSize ?? tokens.textControl,
|
|
5978
|
-
weight: isActive ? tokens.titleWeight : tokens.labelWeight,
|
|
5979
|
-
align: "center",
|
|
5980
|
-
clip: stripClip
|
|
5981
|
-
});
|
|
5982
|
-
}
|
|
5983
|
-
if (ps.saveButton && !ps.saveButton.hidden) {
|
|
5984
|
-
let sr = this.rectOf(ps.saveButton), hot = this.isHovered(ps.saveButton);
|
|
5985
|
-
this.drawText("+", sr.left + sr.width * 0.5, sr.top + sr.height * 0.5, this.hot(ps.saveButton, hot, tokens.dim), {
|
|
5986
|
-
px: tokens.textTitle,
|
|
5987
|
-
weight: 400,
|
|
5988
|
-
align: "center"
|
|
5989
|
-
});
|
|
5990
|
-
}
|
|
5991
|
-
this.curAlpha = stripAlpha;
|
|
5992
|
-
}
|
|
6019
|
+
if (!ps.element.hidden)
|
|
6020
|
+
this.curAlpha = stripAlpha * this.presence(ps.element), anyMoving = this.drawPresetStrip(ps, tokens, bodyClip, hinting, reducedMotion, dt, !0) || anyMoving, this.curAlpha = stripAlpha;
|
|
5993
6021
|
let tabs = panel.tabs;
|
|
5994
6022
|
if (tabs && !tabs.element.hidden)
|
|
5995
6023
|
anyMoving = this.drawTabStrip(tabs, hinting, reducedMotion, dt, {
|
|
@@ -6210,6 +6238,13 @@ class GpuOverlayManager {
|
|
|
6210
6238
|
this.drawScope(card, cr, tokens.radius, 1);
|
|
6211
6239
|
}
|
|
6212
6240
|
}
|
|
6241
|
+
for (let gs of panel.groupStrips?.() ?? []) {
|
|
6242
|
+
let card = gs.element.parentElement;
|
|
6243
|
+
if (!card || gs.element.closest("[hidden]"))
|
|
6244
|
+
continue;
|
|
6245
|
+
let cr = cardRects.get(card) ?? this.rectOf(card);
|
|
6246
|
+
this.curClip = clipToTile(card, intersectClip(bodyClip, [cr.left, cr.top, cr.right, cr.bottom])), this.curAlpha = panelAlpha * this.presence(card) * fadeOf(card), anyMoving = this.drawPresetStrip(gs, tokens, this.curClip, hinting, reducedMotion, dt, !1) || anyMoving;
|
|
6247
|
+
}
|
|
6213
6248
|
this.curClip = bodyClip, this.curAlpha = panelAlpha;
|
|
6214
6249
|
let washed = /* @__PURE__ */ new Set, rowsAlpha = this.curAlpha;
|
|
6215
6250
|
for (let row of panel.rows) {
|
|
@@ -11296,7 +11331,7 @@ function presence(el, o = {}) {
|
|
|
11296
11331
|
return !1;
|
|
11297
11332
|
}), tune = (seconds, zeta) => {
|
|
11298
11333
|
let reduced = reducedMotion(win);
|
|
11299
|
-
spring.omega = 2 * Math.PI / (reduced ? FADE.duration : seconds), spring.zeta = reduced ? 1 : zeta;
|
|
11334
|
+
spring.omega = 2 * Math.PI / (reduced ? Math.min(FADE.duration, seconds) : seconds), spring.zeta = reduced ? 1 : zeta;
|
|
11300
11335
|
};
|
|
11301
11336
|
return render(), {
|
|
11302
11337
|
show() {
|
|
@@ -15047,7 +15082,7 @@ function buildPanel(controls, host, options) {
|
|
|
15047
15082
|
}
|
|
15048
15083
|
popover.append(popGrid);
|
|
15049
15084
|
let baseAt = (scope, from) => {
|
|
15050
|
-
let group = scope === "row" ? rows[rowAt(from)]?.group : scope === "group" ? cardOf(from)?.dataset.group ?? void 0 : void 0, keys = scope === "row" ? rows[rowAt(from)]?.keys ?? [] : scope === "group" ? cardKeys(cardOf(from)) : scope === "selection" ? selectionKeys() ?? [] : void 0, index = group === void 0 ? -1 : controls.activeGroupPreset(group), ref = controls.activePreset(), name = index >= 0 ? controls.groupPresets[group]?.[index]?.name : ref?.kind === "preset" ? presetLabel(ref.id) : ref ?
|
|
15085
|
+
let group = scope === "row" ? rows[rowAt(from)]?.group : scope === "group" ? cardOf(from)?.dataset.group ?? void 0 : void 0, keys = scope === "row" ? rows[rowAt(from)]?.keys ?? [] : scope === "group" ? cardKeys(cardOf(from)) : scope === "selection" ? selectionKeys() ?? [] : void 0, index = group === void 0 ? -1 : controls.activeGroupPreset(group), where = (keys?.length ? controls.scopeOf(keys[0]) : stripScope()) ?? null, ref = where === null ? null : controls.activePreset(where), name = index >= 0 ? controls.groupPresets[group]?.[index]?.name : ref?.kind === "preset" ? presetLabel(ref.id, where) : ref ? (where === "" ? controls.variants : controls.scopes[where]?.variants)?.list().find((v) => v.id === ref.id)?.name : void 0;
|
|
15051
15086
|
if (!name)
|
|
15052
15087
|
return null;
|
|
15053
15088
|
let off = keys ? keys.some((k) => controls.isModified(k)) : controls.isModified();
|
|
@@ -15141,7 +15176,7 @@ function buildPanel(controls, host, options) {
|
|
|
15141
15176
|
if (helpButton?.hidden)
|
|
15142
15177
|
titleEl.title = `${titleEl.textContent ? `${titleEl.textContent}
|
|
15143
15178
|
` : ""}Press ${show("help")} for keyboard shortcuts`;
|
|
15144
|
-
let presetLabel = (id) => options.presetLabels?.[id] ?? (id === "default" ? options.defaultLabel : void 0) ?? controls.presetLabel(id), presetStrip = createPresetStrip(doc, controls, showVariants, run, () => wakeGpu(), presetLabel, (entries) => presetsTouchTab(entries)), tabStrip = createTabStrip(doc, (id, animate) => selectTab(id, animate)), activeTab, searchOptions = typeof options.search === "object" ? options.search : {}, chipTests = /* @__PURE__ */ new Map, search = options.search && !page ? createSearch(doc, {
|
|
15179
|
+
let presetLabel = (id, scope = "") => options.presetLabels?.[id] ?? (id === "default" ? typeof options.defaultLabel === "object" ? options.defaultLabel[scope] : options.defaultLabel : void 0) ?? controls.presetLabel(id, scope), hintReach = (typeof options.hints === "object" ? options.hints.reach : options.hints) ?? "page", stripDigitsShown = typeof options.hints === "object" && options.hints.digits === "always", presetStrip = createPresetStrip(doc, controls, showVariants, run, () => wakeGpu(), presetLabel, (entries) => presetsTouchTab(entries), () => stripScope()), tabStrip = createTabStrip(doc, (id, animate) => selectTab(id, animate)), activeTab, searchOptions = typeof options.search === "object" ? options.search : {}, chipTests = /* @__PURE__ */ new Map, search = options.search && !page ? createSearch(doc, {
|
|
15145
15180
|
placeholder: searchOptions.placeholder ?? "Search",
|
|
15146
15181
|
chips: (searchOptions.chips ?? ["modified"]).map((chip) => {
|
|
15147
15182
|
if (chip === "modified")
|
|
@@ -15172,8 +15207,19 @@ function buildPanel(controls, host, options) {
|
|
|
15172
15207
|
else if ((!header.hidden && header.dataset.leaving !== "true") !== any)
|
|
15173
15208
|
reveal(header, any, () => wakeGpu());
|
|
15174
15209
|
};
|
|
15175
|
-
presetStrip.display(page ? "chips" : options.presetDisplay ?? "auto");
|
|
15176
|
-
let
|
|
15210
|
+
presetStrip.display(page ? "chips" : options.presetDisplay ?? "auto"), presetStrip.digits(stripDigitsShown);
|
|
15211
|
+
let groupStrips = /* @__PURE__ */ new Map, tabNamed = (id) => (options.tabs ?? []).some((t) => (typeof t === "string" ? t : t.id) === id) || Object.values(controls.schema).some((f) => f.tab === id), groupStripFor = (group) => {
|
|
15212
|
+
if (page || !Object.hasOwn(controls.scopes, group) || tabNamed(group))
|
|
15213
|
+
return;
|
|
15214
|
+
let strip = groupStrips.get(group);
|
|
15215
|
+
if (!strip)
|
|
15216
|
+
strip = createPresetStrip(doc, controls, showVariants, run, () => wakeGpu(), presetLabel, void 0, () => stripScope() === group ? null : group), strip.element.setAttribute("aria-label", `${groupTitle(group)} presets`), strip.display(options.presetDisplay ?? "auto"), strip.digits(stripDigitsShown), groupStrips.set(group, strip);
|
|
15217
|
+
return strip;
|
|
15218
|
+
}, updateStrips = () => {
|
|
15219
|
+
presetStrip.update();
|
|
15220
|
+
for (let strip of groupStrips.values())
|
|
15221
|
+
strip.update();
|
|
15222
|
+
}, allActions = [
|
|
15177
15223
|
...controls.actions ?? [],
|
|
15178
15224
|
...options.actions ?? []
|
|
15179
15225
|
], body = el("div"), tabMotion = tabTransition(body, root, () => wakeGpu()), pinnedBody = el("div");
|
|
@@ -15465,7 +15511,7 @@ function buildPanel(controls, host, options) {
|
|
|
15465
15511
|
}
|
|
15466
15512
|
let specs = [], placed = /* @__PURE__ */ new Set;
|
|
15467
15513
|
for (let [key, field] of entries) {
|
|
15468
|
-
if (field.kind === "choice" && field.variants &&
|
|
15514
|
+
if (field.kind === "choice" && field.variants && controls.inPresets(key))
|
|
15469
15515
|
continue;
|
|
15470
15516
|
let pair = field.kind === "knob" && field.spring ? halves.get(field.spring.id) : void 0;
|
|
15471
15517
|
if (pair?.duration && pair.bounce && field.kind === "knob" && field.spring) {
|
|
@@ -16034,7 +16080,7 @@ function buildPanel(controls, host, options) {
|
|
|
16034
16080
|
else
|
|
16035
16081
|
runs.push({ group: r.group, pinned, rows: [r] });
|
|
16036
16082
|
}
|
|
16037
|
-
let free = blocks.filter((b) => !b.leaving), chosen = [], pinnedBlocks = /* @__PURE__ */ new Set, usedSubheads = /* @__PURE__ */ new Set;
|
|
16083
|
+
let free = blocks.filter((b) => !b.leaving), chosen = [], pinnedBlocks = /* @__PURE__ */ new Set, usedSubheads = /* @__PURE__ */ new Set, stripped = /* @__PURE__ */ new Set;
|
|
16038
16084
|
for (let run of runs) {
|
|
16039
16085
|
let at = free.findIndex((b) => b.group === run.group), block = at >= 0 ? free.splice(at, 1)[0] : newBlock(run.group);
|
|
16040
16086
|
if (at < 0) {
|
|
@@ -16061,7 +16107,10 @@ function buildPanel(controls, host, options) {
|
|
|
16061
16107
|
}
|
|
16062
16108
|
under = name, nodes.push(r.row);
|
|
16063
16109
|
}
|
|
16064
|
-
|
|
16110
|
+
let strip = run.group !== void 0 && !run.pinned && !stripped.has(run.group) ? groupStripFor(run.group) : void 0;
|
|
16111
|
+
if (strip)
|
|
16112
|
+
stripped.add(run.group);
|
|
16113
|
+
if (arrange(block.card, strip ? [strip.element, ...nodes] : nodes), animate && at >= 0) {
|
|
16065
16114
|
for (let r of run.rows)
|
|
16066
16115
|
if (entering.has(r))
|
|
16067
16116
|
motion.push({ node: r.row, show: !0 });
|
|
@@ -16192,12 +16241,12 @@ function buildPanel(controls, host, options) {
|
|
|
16192
16241
|
return list;
|
|
16193
16242
|
};
|
|
16194
16243
|
function presetsTouchTab(entries) {
|
|
16195
|
-
if (page || activeTab === void 0)
|
|
16244
|
+
if (page || activeTab === void 0 || stripScope() !== "")
|
|
16196
16245
|
return !0;
|
|
16197
16246
|
let keys = rows.flatMap((r) => {
|
|
16198
16247
|
let tab = tabOf(r);
|
|
16199
|
-
return !pinnedRow(r) && (tab === void 0 || tab === activeTab) ? r.keys : [];
|
|
16200
|
-
}), v = variantsOf(controls.schema, controls.
|
|
16248
|
+
return !pinnedRow(r) && (tab === void 0 || tab === activeTab) ? r.keys.filter((k) => controls.scopeOf(k) === "") : [];
|
|
16249
|
+
}), v = variantsOf(controls.schema, (key) => !controls.inPresets(key));
|
|
16201
16250
|
if (v) {
|
|
16202
16251
|
let tab = v.field.tab ?? (v.field.group !== void 0 ? groupTab(v.field.group) : void 0);
|
|
16203
16252
|
if (tab === void 0 || tab === activeTab)
|
|
@@ -16205,6 +16254,20 @@ function buildPanel(controls, host, options) {
|
|
|
16205
16254
|
}
|
|
16206
16255
|
return presetsTouch(entries, keys, controls.locked);
|
|
16207
16256
|
}
|
|
16257
|
+
function stripScope() {
|
|
16258
|
+
let named = Object.keys(controls.scopes), panelWide = named.length === 0 || Object.keys(controls.presets).length > 1;
|
|
16259
|
+
if (page)
|
|
16260
|
+
return panelWide ? "" : null;
|
|
16261
|
+
if (activeTab === void 0)
|
|
16262
|
+
return panelWide ? "" : named[0] ?? null;
|
|
16263
|
+
if (named.includes(activeTab))
|
|
16264
|
+
return activeTab;
|
|
16265
|
+
return named.find((id) => rows.some((r) => r.group === id && tabOf(r) === activeTab)) ?? (panelWide ? "" : null);
|
|
16266
|
+
}
|
|
16267
|
+
let stripVariants = () => {
|
|
16268
|
+
let scope = stripScope();
|
|
16269
|
+
return (scope ? controls.scopes[scope]?.variants : void 0) ?? controls.variants;
|
|
16270
|
+
};
|
|
16208
16271
|
function syncTabs() {
|
|
16209
16272
|
let list = tabList(), has = (id) => id !== void 0 && list.some((t) => t.id === id);
|
|
16210
16273
|
if (!has(activeTab))
|
|
@@ -16218,7 +16281,7 @@ function buildPanel(controls, host, options) {
|
|
|
16218
16281
|
writeSession(controls.id, { tab: id });
|
|
16219
16282
|
tabStrip.select(id, animate);
|
|
16220
16283
|
let focused = doc.activeElement;
|
|
16221
|
-
if (applyVisibility(animate ? "tab" : "instant"), focused && root.contains(focused) && focused.closest("[hidden],[data-leaving]"))
|
|
16284
|
+
if (updateStrips(), applyVisibility(animate ? "tab" : "instant"), focused && root.contains(focused) && focused.closest("[hidden],[data-leaving]"))
|
|
16222
16285
|
tabStrip.focus({ preventScroll: !0, focusVisible: !1 });
|
|
16223
16286
|
options.onTab?.(id), wakeGpu();
|
|
16224
16287
|
}
|
|
@@ -16431,7 +16494,7 @@ function buildPanel(controls, host, options) {
|
|
|
16431
16494
|
}, text = el("textarea");
|
|
16432
16495
|
text.hidden = !0, text.name = "variant-json", text.spellcheck = !1, text.setAttribute("aria-label", "Import or copy text");
|
|
16433
16496
|
let apply = button("Apply import", () => {
|
|
16434
|
-
|
|
16497
|
+
stripVariants().import(text.value), say("Presets imported."), reveal(text, !1), reveal(apply, !1), positioned?.constrain();
|
|
16435
16498
|
});
|
|
16436
16499
|
apply.className = "knobs-apply-btn", apply.setAttribute("aria-label", "Import JSON"), apply.hidden = !0;
|
|
16437
16500
|
let copy = async (value, inPlace = !0) => {
|
|
@@ -16456,7 +16519,7 @@ function buildPanel(controls, host, options) {
|
|
|
16456
16519
|
}
|
|
16457
16520
|
if (showVariants && showFooter) {
|
|
16458
16521
|
let transfer = el("div");
|
|
16459
|
-
transfer.className = "knobs-transfer", transfer.append(button("Export presets", () => void copy(
|
|
16522
|
+
transfer.className = "knobs-transfer", transfer.append(button("Export presets", () => void copy(stripVariants().export(), !1)), button("Import presets", () => {
|
|
16460
16523
|
reveal(text, !0), reveal(apply, !0), text.value = "", positioned?.constrain(), text.focus();
|
|
16461
16524
|
})), popover.append(transfer);
|
|
16462
16525
|
}
|
|
@@ -16524,6 +16587,7 @@ function buildPanel(controls, host, options) {
|
|
|
16524
16587
|
}
|
|
16525
16588
|
let shownBase = "", baseSignature = () => JSON.stringify([
|
|
16526
16589
|
controls.activePreset(),
|
|
16590
|
+
Object.keys(controls.scopes).map((s) => controls.activePreset(s)),
|
|
16527
16591
|
Object.keys(controls.groupPresets).map((g) => controls.activeGroupPreset(g))
|
|
16528
16592
|
]);
|
|
16529
16593
|
function update() {
|
|
@@ -16545,7 +16609,7 @@ function buildPanel(controls, host, options) {
|
|
|
16545
16609
|
changedCount++;
|
|
16546
16610
|
}
|
|
16547
16611
|
let stagger = initialized ? cascade(changedCount) : 0, moving = initialized ? rows.filter(changed) : rows;
|
|
16548
|
-
if (
|
|
16612
|
+
if (updateStrips(), batchMeasures(() => {
|
|
16549
16613
|
for (let row of moving)
|
|
16550
16614
|
if (row.slider?.prime(), row.editor?.prime?.(), row.choice)
|
|
16551
16615
|
primeSegPill(row.choice.seg, row.choice.buttons);
|
|
@@ -16677,13 +16741,14 @@ function buildPanel(controls, host, options) {
|
|
|
16677
16741
|
if (s.label?.hasAttribute("data-foldable"))
|
|
16678
16742
|
add(s.label, sectionTitle(s.name), () => s.label.focus(), s.label.firstElementChild);
|
|
16679
16743
|
}
|
|
16680
|
-
presetStrip.
|
|
16681
|
-
|
|
16682
|
-
|
|
16683
|
-
|
|
16684
|
-
|
|
16685
|
-
|
|
16686
|
-
|
|
16744
|
+
for (let strip of [presetStrip, ...groupStrips.values()])
|
|
16745
|
+
strip.getEntries().forEach((entry, i) => {
|
|
16746
|
+
let chip = strip.getButtons()[i];
|
|
16747
|
+
if (chip)
|
|
16748
|
+
add(chip, entry.label, () => {
|
|
16749
|
+
strip.selectById(entry.id), strip.element.focus({ preventScroll: !0 });
|
|
16750
|
+
});
|
|
16751
|
+
});
|
|
16687
16752
|
for (let b of root.querySelectorAll(page ? ".knobs-head-cmd, .knobs-group-head button:not(.knobs-group-die,.knobs-group-reset,.knobs-chips button), .knobs-custom-actions button, .knobs-preset-save" : ".knobs-head-cmd, .knobs-group-head button, .knobs-custom-actions button, .knobs-preset-save, .knobs-popover button"))
|
|
16688
16753
|
add(b, b.dataset.hint ?? b.getAttribute("aria-label") ?? b.textContent ?? "", () => b.focus());
|
|
16689
16754
|
let focusedHead = page ? doc.activeElement?.closest(".knobs-tile")?.querySelector(":scope > .knobs-group-head") : null, presetUi = focusedHead ? groupChips.get(focusedHead.dataset.group ?? "") : void 0;
|
|
@@ -16699,7 +16764,7 @@ function buildPanel(controls, host, options) {
|
|
|
16699
16764
|
add(stop, label, () => stop.focus());
|
|
16700
16765
|
}
|
|
16701
16766
|
return targets;
|
|
16702
|
-
}, unregisterHints =
|
|
16767
|
+
}, unregisterHints = hintReach === "page" && bound("hint") ? pageHints(doc).register(root, () => collectHintTargets().map((t) => ({
|
|
16703
16768
|
el: t.el,
|
|
16704
16769
|
label: t.display,
|
|
16705
16770
|
...t.labelEl ? { labelEl: t.labelEl } : {},
|
|
@@ -16756,6 +16821,9 @@ function buildPanel(controls, host, options) {
|
|
|
16756
16821
|
runs.push({ at: b.head, stops: shown([b.head]) });
|
|
16757
16822
|
for (let sh of subheads.values())
|
|
16758
16823
|
runs.push({ at: sh.el, stops: shown([sh.el]) });
|
|
16824
|
+
for (let gs of groupStrips.values())
|
|
16825
|
+
if (visible(gs.element))
|
|
16826
|
+
runs.push({ at: gs.element, stops: shown([gs.element]) });
|
|
16759
16827
|
runs.push(...strips), runs.sort((a, b) => a.at.compareDocumentPosition(b.at) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1);
|
|
16760
16828
|
for (let run of runs)
|
|
16761
16829
|
list.push(...run.stops);
|
|
@@ -17134,6 +17202,9 @@ function buildPanel(controls, host, options) {
|
|
|
17134
17202
|
return { el: sub, level: "row" };
|
|
17135
17203
|
return { el: r.row.closest(".knobs-card > *") ?? r.row, level: "row" };
|
|
17136
17204
|
}
|
|
17205
|
+
let strip = active.closest(".knobs-card > .knobs-presets");
|
|
17206
|
+
if (strip)
|
|
17207
|
+
return { el: strip, level: "row" };
|
|
17137
17208
|
let card = cardOf(active);
|
|
17138
17209
|
return card ? { el: card, level: "card" } : null;
|
|
17139
17210
|
}, partName = (part, active) => part.querySelector(".knobs-strip-label")?.textContent || active?.getAttribute("aria-label") || part.getAttribute("aria-label") || "Editor", trailFor = (t, active) => {
|
|
@@ -17145,7 +17216,7 @@ function buildPanel(controls, host, options) {
|
|
|
17145
17216
|
row: rows[rowAt(active)]?.display,
|
|
17146
17217
|
editor: t.level === "editor" ? partName(t.el, active) : void 0
|
|
17147
17218
|
});
|
|
17148
|
-
}, crumbs = options.crumbs
|
|
17219
|
+
}, crumbs = options.crumbs !== !0 || header.hidden || !titleEl.isConnected ? void 0 : createCrumbs({
|
|
17149
17220
|
header,
|
|
17150
17221
|
title: titleEl,
|
|
17151
17222
|
reduced: () => reducedMotion(),
|
|
@@ -17163,7 +17234,21 @@ function buildPanel(controls, host, options) {
|
|
|
17163
17234
|
return;
|
|
17164
17235
|
let t = lensTarget(to);
|
|
17165
17236
|
jumpedTo = t && t !== "out" ? t.el : null, to.focus(quiet), queueScope();
|
|
17166
|
-
}
|
|
17237
|
+
};
|
|
17238
|
+
root.addEventListener("mousedown", (event) => {
|
|
17239
|
+
if (event.button !== 0 || event.shiftKey || event.metaKey || event.ctrlKey)
|
|
17240
|
+
return;
|
|
17241
|
+
let target = event.target instanceof Element ? event.target : null, r = rows[rowAt(target)];
|
|
17242
|
+
if (!target || !r || r.leaving || r.row.closest("[hidden]"))
|
|
17243
|
+
return;
|
|
17244
|
+
let own = target.closest("button,input,select,textarea,a[href],[tabindex],[contenteditable]");
|
|
17245
|
+
if (own && r.row.contains(own))
|
|
17246
|
+
return;
|
|
17247
|
+
event.preventDefault(), r.input.focus({ preventScroll: !0, focusVisible: !1 });
|
|
17248
|
+
let t = lensTarget(doc.activeElement);
|
|
17249
|
+
jumpedTo = t && t !== "out" ? t.el : null, queueScope();
|
|
17250
|
+
}, !0);
|
|
17251
|
+
let titleDown;
|
|
17167
17252
|
titleEl.addEventListener("pointerdown", (event) => {
|
|
17168
17253
|
titleDown = [event.clientX, event.clientY];
|
|
17169
17254
|
}), titleEl.addEventListener("click", (event) => {
|
|
@@ -17255,6 +17340,18 @@ function buildPanel(controls, host, options) {
|
|
|
17255
17340
|
if (!r || r.row.closest("[data-disabled],[data-readonly]"))
|
|
17256
17341
|
return;
|
|
17257
17342
|
return optionsOf(r);
|
|
17343
|
+
}, groupStripAt = (node) => node ? [...groupStrips.values()].find((s) => s.element.contains(node)) : void 0, groupStripOptions = /* @__PURE__ */ new Map, optionsOfStrip = (strip) => {
|
|
17344
|
+
let o = groupStripOptions.get(strip);
|
|
17345
|
+
if (!o)
|
|
17346
|
+
o = {
|
|
17347
|
+
get count() {
|
|
17348
|
+
return strip.getEntries().length;
|
|
17349
|
+
},
|
|
17350
|
+
choose: (i) => strip.select(i),
|
|
17351
|
+
shown: () => strip.getButtons(),
|
|
17352
|
+
anchor: strip.element
|
|
17353
|
+
}, groupStripOptions.set(strip, o);
|
|
17354
|
+
return o;
|
|
17258
17355
|
}, stripDigits = () => visible(presetStrip.element) && presetStrip.getEntries().length > 1, stripOptions = {
|
|
17259
17356
|
get count() {
|
|
17260
17357
|
return presetStrip.getEntries().length;
|
|
@@ -17263,7 +17360,12 @@ function buildPanel(controls, host, options) {
|
|
|
17263
17360
|
shown: () => presetStrip.getButtons(),
|
|
17264
17361
|
anchor: presetStrip.element
|
|
17265
17362
|
}, stripOptionsAt = (node) => {
|
|
17266
|
-
if (hintCtrl.isActive || !node ||
|
|
17363
|
+
if (hintCtrl.isActive || !node || stripDigitsShown)
|
|
17364
|
+
return;
|
|
17365
|
+
let own = groupStripAt(node);
|
|
17366
|
+
if (own)
|
|
17367
|
+
return visible(own.element) && own.getEntries().length > 1 && !own.nameField() ? optionsOfStrip(own) : void 0;
|
|
17368
|
+
if (!stripDigits())
|
|
17267
17369
|
return;
|
|
17268
17370
|
return (presetStrip.element.contains(node) || focusLevel(node) === "panel") && !presetStrip.nameField() ? stripOptions : void 0;
|
|
17269
17371
|
}, pickOption = (event) => {
|
|
@@ -17442,9 +17544,9 @@ function buildPanel(controls, host, options) {
|
|
|
17442
17544
|
return;
|
|
17443
17545
|
}
|
|
17444
17546
|
if (pressed("presets", event)) {
|
|
17445
|
-
let direction = key === keys.presets[0] ? -1 : 1;
|
|
17446
|
-
if (visible(
|
|
17447
|
-
|
|
17547
|
+
let direction = key === keys.presets[0] ? -1 : 1, strip = groupStripAt(target) ?? presetStrip;
|
|
17548
|
+
if (visible(strip.element) && strip.getEntries().length > 1)
|
|
17549
|
+
strip.cycle(direction);
|
|
17448
17550
|
else if (!cycleTab(direction))
|
|
17449
17551
|
return;
|
|
17450
17552
|
event.preventDefault(), event.stopPropagation();
|
|
@@ -17470,6 +17572,8 @@ function buildPanel(controls, host, options) {
|
|
|
17470
17572
|
event.preventDefault(), searchReturn = target, search.focus();
|
|
17471
17573
|
return;
|
|
17472
17574
|
}
|
|
17575
|
+
if (/^[1-9]$/.test(key) && groupStripAt(target))
|
|
17576
|
+
return;
|
|
17473
17577
|
if (/^[1-9]$/.test(key)) {
|
|
17474
17578
|
let group = page ? focusedGroup(target) : void 0;
|
|
17475
17579
|
if (Boolean(group && groupChips.has(group))) {
|
|
@@ -17518,7 +17622,7 @@ function buildPanel(controls, host, options) {
|
|
|
17518
17622
|
return;
|
|
17519
17623
|
}
|
|
17520
17624
|
if (pressed("save", event) && showVariants) {
|
|
17521
|
-
event.preventDefault(), presetStrip.save();
|
|
17625
|
+
event.preventDefault(), (groupStripAt(target) ?? presetStrip).save();
|
|
17522
17626
|
return;
|
|
17523
17627
|
}
|
|
17524
17628
|
let index = rowAt(target);
|
|
@@ -17891,6 +17995,7 @@ function buildPanel(controls, host, options) {
|
|
|
17891
17995
|
...undock ? {} : { headerDie: { button: randomButton, die } },
|
|
17892
17996
|
locks: lockIcons,
|
|
17893
17997
|
presetStrip,
|
|
17998
|
+
groupStrips: () => groupStrips.values(),
|
|
17894
17999
|
tabs: tabStrip,
|
|
17895
18000
|
groups: gpuGroups,
|
|
17896
18001
|
cards,
|
|
@@ -17997,7 +18102,10 @@ function buildPanel(controls, host, options) {
|
|
|
17997
18102
|
dropGpu(r);
|
|
17998
18103
|
for (let c of groupChips.values())
|
|
17999
18104
|
c.dispose();
|
|
18000
|
-
presetStrip.dispose()
|
|
18105
|
+
presetStrip.dispose();
|
|
18106
|
+
for (let strip of groupStrips.values())
|
|
18107
|
+
strip.dispose();
|
|
18108
|
+
tabStrip.dispose(), tabMotion.finish(), doc.removeEventListener("keydown", onGlobalKey), layout?.dispose(), tileSizes.disconnect(), headSize.disconnect(), win?.removeEventListener("scroll", onScroll), win?.removeEventListener("scrollend", onScrollEnd);
|
|
18001
18109
|
for (let type of ["wheel", "touchstart", "keydown"])
|
|
18002
18110
|
doc.removeEventListener(type, touched, !0);
|
|
18003
18111
|
doc.removeEventListener("pointerdown", onPointerDown, !0);
|