@kitlangton/knobs 0.4.0-next.13 → 0.4.0-next.15
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 +20 -6
- package/dist/dev/{chunk-mbhy4jg5.js → chunk-49hkdggk.js} +199 -135
- package/dist/dev/{chunk-44r02asc.js → chunk-902v1jgd.js} +2 -2
- package/dist/dev/{chunk-pdf3zy95.js → chunk-bejz4qcg.js} +9 -2
- package/dist/dev/{chunk-7kns3qe6.js → chunk-v2g91mrm.js} +9 -1
- package/dist/dev/index.js +19 -8
- package/dist/index.js +23 -5
- package/dist/panel.js +249 -147
- 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 +3 -1
- package/dist/types/core/schema.d.ts +12 -1
- package/dist/types/core/store.d.ts +30 -5
- package/dist/types/panel/gpu/renderer.d.ts +8 -0
- package/dist/types/panel/presets.d.ts +2 -0
- 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
package/README.md
CHANGED
|
@@ -384,7 +384,7 @@ Panels and switchers are keyboard-first:
|
|
|
384
384
|
| Arrows on a pad or curve handle | Move the puck or handle (`⇧` ×10, `⌥` finest); `j` / `k` or `Tab` move on |
|
|
385
385
|
| On a gradient strip or curve graph | Arrows move the selected stop or point; `Tab` / `⇧Tab` and `[` / `]` pick another; `n` adds one, `Delete` removes it; `Enter` edits a stop's colour (`Esc` returns) |
|
|
386
386
|
| `[` / `]` | Cycle presets and saved variants from anywhere in the panel; with no preset strip, cycle tabs |
|
|
387
|
-
| `1`–`9` | Pick the focused row's Nth option: a choice (segmented or menu) or a curve's, easing's or gradient's presets. Anywhere else in the panel, pick the preset strip's Nth chip (a design's variants). While you use keys, tiny digit hints show on the options once focus settles, and on the strip's chips while focus is on the strip or the panel. A number row keeps its digits for inline edits, and a page's card for its group presets |
|
|
387
|
+
| `1`–`9` | Pick the focused row's Nth option: a choice (segmented or menu) or a curve's, easing's or gradient's presets. Anywhere else in the panel, pick the preset strip's Nth chip (a design's variants). While you use keys, tiny digit hints show on the options once focus settles, and on the strip's chips while focus is on the strip or the panel (`hints: { digits: "always" }` on the mount keeps them on the chips all the time, small and dim before each name). A number row keeps its digits for inline edits, and a page's card for its group presets |
|
|
388
388
|
| `⌥1`–`⌥9` | Show tab 1–9 |
|
|
389
389
|
| `/` | Focus the search field (`Esc` clears it, then hands focus back; `↓` or `Enter` go to the first row left) |
|
|
390
390
|
| `Home` / `End` | Jump slider to `min` or `max` |
|
|
@@ -835,6 +835,16 @@ panel.tab("emitter") // shows a tab; panel.tab() answers the one showing
|
|
|
835
835
|
A pinned `variants: true` choice is an ordinary choice with a row: pinned wins, and its options
|
|
836
836
|
make no presets. A tab whose rows no preset moves shows no preset strip; a variants choice moves
|
|
837
837
|
its own tab (or every tab, if it has none).
|
|
838
|
+
- **Keys presets leave alone, in place.** `inPresets: false` on a field, or `inPresets: { Motion:
|
|
839
|
+
false }` on the store for a whole group, keeps presets, scoped presets and saved variants off
|
|
840
|
+
those keys exactly as they stay off pinned ones (and a preset's chip stays lit when they move),
|
|
841
|
+
but the rows stay where they are. A pinned key is one of these, moved to the top. The rule, for
|
|
842
|
+
`inPresets: false` and `pinned` groups alike: presets and variants from *other* scopes (the
|
|
843
|
+
panel-wide presets, tab scopes, other groups') leave the group alone, but a scope keyed by the
|
|
844
|
+
group's own name still moves it. So `inPresets: { Motion: false }` with
|
|
845
|
+
`scopedPresets: { Motion: { Snappy } }` gives Motion its own strip that state presets never
|
|
846
|
+
touch; its chips apply, save, match and mark only Motion. A field's own `inPresets: false` stays
|
|
847
|
+
out of every scope. `controls.inPresets(key)` says whether presets from other scopes move a key.
|
|
838
848
|
- **Presets of a tab's own.** `scopedPresets` gives a tab (or a group) presets that belong to it:
|
|
839
849
|
`{ Sidebars: { snappy, smooth, calm } }`. Its strip shows only on that tab, and a tab without any
|
|
840
850
|
shows none. A scoped preset moves only its tab's (or group's) keys, never pinned ones or another
|
|
@@ -844,9 +854,13 @@ panel.tab("emitter") // shows a tab; panel.tab() answers the one showing
|
|
|
844
854
|
A `variants: true` choice on a tab adds its options to that tab's presets. Keys belong to their
|
|
845
855
|
tab's scope first, then their group's. Plain `presets` then cover only the keys no scope holds;
|
|
846
856
|
leave them out and only the scoped strips show. One strip shows per tab: the tab's own, else the
|
|
847
|
-
first group scope on it. In
|
|
857
|
+
first group scope on it. In a panel, any other group's presets show at the top of its own card,
|
|
858
|
+
in the strip's look without its tray, so a story's states can lead the panel while its Motion
|
|
859
|
+
group keeps Shipped, Snappy and Calm beside its knobs. Every strip's default chip reads `defaultLabel`; by scope,
|
|
860
|
+
`defaultLabel: { "": "Empty", Motion: "Shipped" }` names each on its own. In code, `controls.preset(id, { scope })`, `activePreset(scope)` and
|
|
848
861
|
`matchingPreset(scope)` take the tab or group, and `controls.scopeOf(key)` says whose presets
|
|
849
|
-
move a key (`""` for plain `presets`,
|
|
862
|
+
move a key (`""` for plain `presets`, the group's id for a pinned or `inPresets: false`
|
|
863
|
+
group with a scope of its own, else undefined when pinned). An active preset saved while the
|
|
850
864
|
presets were panel-wide comes back on the scope that now has one by that id, and variants saved
|
|
851
865
|
then start out in each scope they move.
|
|
852
866
|
|
|
@@ -1206,7 +1220,7 @@ Scrolling pane bodies, trees and the command palette's list fade their content o
|
|
|
1206
1220
|
| Key | Action |
|
|
1207
1221
|
| --- | --- |
|
|
1208
1222
|
| `↑` / `↓`, `Home` / `End` | Move; type letters to jump to a label (see `typeahead`) |
|
|
1209
|
-
| `←` / `→` | Close or go up / open or go down |
|
|
1223
|
+
| `←` / `→` | Close or go up / open or go down (swapped when the tree is `dir="rtl"`) |
|
|
1210
1224
|
| `⇧` click or `⇧↑↓`, `⌘` click, `⌘A` | Extend, toggle, select all |
|
|
1211
1225
|
| `Space` | Select the active row (`⌘Space` toggles it) |
|
|
1212
1226
|
| `Enter` / `F2` | Rename in place (with `onRename`); otherwise `Enter` calls `onActivate` |
|
|
@@ -1259,7 +1273,7 @@ toast("Deleted Barrier", { action: { label: "Undo", run: undo } })
|
|
|
1259
1273
|
|
|
1260
1274
|
- **`popover(anchor, content, options?)`** places `content` beside an element, a rect or a point. `placement` is `top`, `bottom`, `left` or `right`, each with `-start` or `-end`; it flips when its side is short and the other has more room, then shifts to stay 8px inside the view, and follows its anchor through scrolls and resizes. It grows from the anchor's edge. It takes focus (`focus: "first" | "layer" | "none"`) and gives it back when it closes; Esc, a click outside or focus leaving closes it (`closeOnOutside: false` keeps it), and `trap: true` keeps Tab inside. The handle has `element`, `open`, `reposition()` and `close()` (a promise that resolves once it's gone).
|
|
1261
1275
|
- **`tooltip(el, content, options?)`** shows after a 500ms pause over the element, or on keyboard focus (not a click's). While one is up, or just after, moving to a neighbour shows its tip at once, with no entrance. A press hides it until the pointer leaves; Esc hides it. `shortcut` shows as key chips (`⌘K` on Apple platforms, `Ctrl+K` elsewhere) and sets `aria-keyshortcuts`; the target gets `aria-describedby` while it shows. Content can be a function, read each time it shows. Split panes use these for their buttons and rails.
|
|
1262
|
-
- **`commandPalette({ commands, onRun?, hotkey?, recents?, placeholder? })`** opens on `⌘K` (`hotkey`, `"Mod+K"` by default; `false` for none). With no query it shows recent commands (remembered in localStorage under `recents`; `false` for none), then each `section`. Typing ranks commands by a fuzzy match: letters in order, best at the start, at word starts and in runs. The matched letters light up in the accent while the rest of the label dims, and letters strewn thinly across words don't count. A command answers to its `keywords` and section too. `↑`/`↓` move a highlight that glides (`PgUp`/`PgDn`, `⌘↑`/`⌘↓`), disabled commands are passed over, `Enter` runs, `Esc` or a click outside closes. A `run` that returns a string (or a promise of one) shows it as a toast; a throw shows as an error toast. The handle has `open(query?)`, `close()`, `toggle()`, `isOpen` and `dispose()`.
|
|
1276
|
+
- **`commandPalette({ commands, onRun?, hotkey?, recents?, placeholder?, presence? })`** opens on `⌘K` (`hotkey`, `"Mod+K"` by default; `false` for none). A key summons it, so it fades in and out in about 80ms (`presence: "fade"`); `presence: "none"` (or `false`) shows and hides it at once, and `{ duration?, scale?, blur?, dy? }` gives it the full entrance (from .96, 8px blur and 8px above, over .34s), with any of those changed. With no query it shows recent commands (remembered in localStorage under `recents`; `false` for none), then each `section`. Typing ranks commands by a fuzzy match: letters in order, best at the start, at word starts and in runs. The matched letters light up in the accent while the rest of the label dims, and letters strewn thinly across words don't count. A command answers to its `keywords` and section too. `↑`/`↓` move a highlight that glides (`PgUp`/`PgDn`, `⌘↑`/`⌘↓`), disabled commands are passed over, `Enter` runs, `Esc` or a click outside closes. A `run` that returns a string (or a promise of one) shows it as a toast; a throw shows as an error toast. The handle has `open(query?)`, `close()`, `toggle()`, `isOpen` and `dispose()`.
|
|
1263
1277
|
- **`commandsFrom(controls, { title?, fields?, reveal? })`** lists a store as commands: its actions and toolbar buttons (with their shortcuts), presets and group presets (the current one marked), toggles ("Turn on …"), one command per choice option, "Reset …" for modified fields, and, with `reveal(key)`, every other field (its current value as the hint) to go to.
|
|
1264
1278
|
- **`confirm({ title, body?, confirm?, cancel?, destructive? })`** returns `Promise<boolean>`. It's modal over a scrim, keeps Tab inside, and Esc or a click outside cancels. `destructive` puts the button in `--k-critical` and focus on Cancel; otherwise focus starts on the confirming button.
|
|
1265
1279
|
- **`toast(message, { tone?, linger?, action?, within? })`** shows a pill at the bottom centre for 3.2s (6s for `tone: "error"`). A new message replaces the one showing, and hovering keeps it. Pages show their status (Copied, errors) this way.
|
|
@@ -2078,7 +2092,7 @@ The package has two core exports selected through the standard `development` con
|
|
|
2078
2092
|
| `readout(field, { preset?, theme?, label? })` | A readout on its own: `{ element, push(value), value, dispose() }`. |
|
|
2079
2093
|
| `popover(anchor, content, { placement?, offset?, role?, label?, focus?, trap?, closeOnOutside?, onClose? })` | A floating layer that flips and shifts; `{ element, open, reposition(), close() }`. |
|
|
2080
2094
|
| `tooltip(el, text \| { text, shortcut?, placement?, delay? })` / `tooltips(doc)` | Delayed tooltips with instant hand-off and shortcut chips; `data-tip` attributes. |
|
|
2081
|
-
| `commandPalette({ commands, onRun?, hotkey?, recents?, placeholder? })` / `commandsFrom(controls, options?)` | `⌘K` fuzzy command search; a store's actions, presets and fields as commands. |
|
|
2095
|
+
| `commandPalette({ commands, onRun?, hotkey?, recents?, placeholder?, presence? })` / `commandsFrom(controls, options?)` | `⌘K` fuzzy command search; a store's actions, presets and fields as commands. |
|
|
2082
2096
|
| `confirm({ title, body?, confirm?, cancel?, destructive? })` | `Promise<boolean>`, modal, focus kept inside. |
|
|
2083
2097
|
| `toast(message, { tone?, linger?, action?, within? })` | A status pill at the bottom centre. |
|
|
2084
2098
|
| `menu(anchor, items, { placement?, label?, onSelect?, onClose? })` / `contextMenu(target, items, options?)` | Menus with icons, shortcut chips, checks, radios and submenus; a right-click or menu-key menu. |
|
|
@@ -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 = {
|
|
@@ -1029,7 +1029,7 @@ 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, scope = null, at = () => scope ?? "", source = () => scope === null ? void 0 : scope === "" ? { presets: controls.presets, variants: controls.variants } : controls.scopes[scope], 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
1035
|
if (controls.scopeOf(k) !== at() && !same(values[k], controls.locked[k]))
|
|
@@ -1142,10 +1142,15 @@ function createPresetStrip(doc, controls, showVariants, run, onAfterChange, pres
|
|
|
1142
1142
|
return;
|
|
1143
1143
|
}
|
|
1144
1144
|
lastVariantsRef = variantsRef;
|
|
1145
|
-
let nextEntries = buildEntries(), nextSig = JSON.stringify([scope, nextEntries.map((e) => [e.id, e.label])]);
|
|
1145
|
+
let nextEntries = buildEntries(), nextSig = JSON.stringify([scope, digits, nextEntries.map((e) => [e.id, e.label])]);
|
|
1146
1146
|
if (entries = nextEntries, syncShown(), nextSig !== signature)
|
|
1147
1147
|
signature = nextSig, entries = nextEntries, buttons = entries.map((entry, idx) => {
|
|
1148
|
-
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;
|
|
1149
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) => {
|
|
1150
1155
|
if (e.preventDefault(), focusQuietly(), idx !== activeState.activeIndex || activeState.drifted)
|
|
1151
1156
|
selectAt(idx);
|
|
@@ -1339,6 +1344,13 @@ function createPresetStrip(doc, controls, showVariants, run, onAfterChange, pres
|
|
|
1339
1344
|
if (display = mode, placeDisplay())
|
|
1340
1345
|
measurePill(!0);
|
|
1341
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
|
+
},
|
|
1342
1354
|
save: () => {
|
|
1343
1355
|
let message = "";
|
|
1344
1356
|
return run(() => message = save()), message;
|
|
@@ -4022,6 +4034,111 @@ class GpuOverlayManager {
|
|
|
4022
4034
|
let more = o.more;
|
|
4023
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;
|
|
4024
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
|
+
}
|
|
4025
4142
|
hairline(tokens) {
|
|
4026
4143
|
return Math.max(1, Math.round(tokens.rimWidth * this.curScale)) / this.curScale;
|
|
4027
4144
|
}
|
|
@@ -5768,7 +5885,6 @@ class GpuOverlayManager {
|
|
|
5768
5885
|
this.placeBackdrop(panel);
|
|
5769
5886
|
continue;
|
|
5770
5887
|
}
|
|
5771
|
-
let pillFill = tokens.pillBg;
|
|
5772
5888
|
if (pageB)
|
|
5773
5889
|
this.placeBackdrop(panel);
|
|
5774
5890
|
let covers = drawn.some((r) => r.left < card.right && r.right > card.left && r.top < card.bottom && r.bottom > card.top);
|
|
@@ -5900,111 +6016,8 @@ class GpuOverlayManager {
|
|
|
5900
6016
|
}
|
|
5901
6017
|
}
|
|
5902
6018
|
let ps = panel.presetStrip, hinting = panel.root.classList.contains("knobs-hinting"), stripAlpha = this.curAlpha;
|
|
5903
|
-
if (!ps.element.hidden)
|
|
5904
|
-
this.curAlpha = stripAlpha * this.presence(ps.element);
|
|
5905
|
-
let psHovered = this.curPanelHovered && ps.element.matches(":hover");
|
|
5906
|
-
this.curSubHovered = psHovered;
|
|
5907
|
-
let psRect = this.rectOf(ps.element), trackRect = this.rectOf(ps.track);
|
|
5908
|
-
if (!tokens.boxed)
|
|
5909
|
-
this.pushPrim({
|
|
5910
|
-
x: psRect.left,
|
|
5911
|
-
y: psRect.top,
|
|
5912
|
-
w: psRect.width,
|
|
5913
|
-
h: psRect.height,
|
|
5914
|
-
color: tokens.segBg,
|
|
5915
|
-
color2: tokens.accent,
|
|
5916
|
-
radius: tokens.radius,
|
|
5917
|
-
glowOrBlur: tokens.glowStrength * 8,
|
|
5918
|
-
kind: 1,
|
|
5919
|
-
p0: psHovered || this.isFocused(ps.element) ? 0.4 : 0
|
|
5920
|
-
});
|
|
5921
|
-
let stripClip = intersectClip(bodyClip, [
|
|
5922
|
-
psRect.left,
|
|
5923
|
-
psRect.top,
|
|
5924
|
-
psRect.right,
|
|
5925
|
-
psRect.bottom
|
|
5926
|
-
]), activeState = ps.getActiveState(), chipButtons = ps.getButtons();
|
|
5927
|
-
if (tokens.boxed)
|
|
5928
|
-
for (let btn of chipButtons) {
|
|
5929
|
-
let br = this.rectOf(btn);
|
|
5930
|
-
if (br.right < stripClip[0] || br.left > stripClip[2])
|
|
5931
|
-
continue;
|
|
5932
|
-
this.drawButtonBox(btn, br, this.isHovered(btn), this.missed(btn, hinting), stripClip);
|
|
5933
|
-
}
|
|
5934
|
-
let activeBtn = activeState.activeIndex >= 0 ? chipButtons[activeState.activeIndex] : void 0, pe = ps.pillEdges, activeBtnRect = activeBtn ? this.rectOf(activeBtn) : void 0, panned = livePill(ps.track);
|
|
5935
|
-
if (activeBtn && activeBtnRect && !activeState.isCustom) {
|
|
5936
|
-
let left = activeBtnRect.left - trackRect.left, right = left + Math.max(20, activeBtnRect.width), top = activeBtnRect.top - trackRect.top;
|
|
5937
|
-
if (this.carry(pe, activeBtn, left, right, ps.pillY, top), panned)
|
|
5938
|
-
pe.snap(panned.left, panned.right), ps.pillY.snap(panned.top);
|
|
5939
|
-
else if (reducedMotion || pe.end.x - pe.start.x <= 1)
|
|
5940
|
-
pe.snap(left, right), ps.pillY.snap(top);
|
|
5941
|
-
else
|
|
5942
|
-
pe.to(left, right, 0, trailScale(tokens.blurStrength)), ps.pillY.set(top);
|
|
5943
|
-
ps.pillAlpha.set(activeState.drifted ? DRIFTED_PILL : 1);
|
|
5944
|
-
} else
|
|
5945
|
-
ps.pillAlpha.set(0);
|
|
5946
|
-
for (let sp of [pe.start, pe.end, ps.pillY, ps.pillAlpha])
|
|
5947
|
-
if (reducedMotion)
|
|
5948
|
-
sp.snap(sp.target);
|
|
5949
|
-
else if (sp.step(dt), !sp.resting)
|
|
5950
|
-
anyMoving = !0;
|
|
5951
|
-
let pillAlpha = clamp(ps.pillAlpha.x, 0, 1);
|
|
5952
|
-
if (pillAlpha > 0.01)
|
|
5953
|
-
this.pushPrim({
|
|
5954
|
-
x: trackRect.left + pe.start.x,
|
|
5955
|
-
y: trackRect.top + ps.pillY.x,
|
|
5956
|
-
w: Math.max(18, pe.end.x - pe.start.x),
|
|
5957
|
-
h: Math.max(16, activeBtnRect?.height ?? trackRect.height),
|
|
5958
|
-
clip: stripClip,
|
|
5959
|
-
color: withAlpha(pillFill, pillAlpha),
|
|
5960
|
-
color2: withAlpha(tokens.pillBorder, pillAlpha),
|
|
5961
|
-
strokeWidth: this.hairline(tokens),
|
|
5962
|
-
aux2: withAlpha(tokens.rim, tokens.rim[3] * pillAlpha),
|
|
5963
|
-
radius: tokens.buttonRadius ?? tokens.radiusMd,
|
|
5964
|
-
glowOrBlur: tokens.glowStrength,
|
|
5965
|
-
kind: 3,
|
|
5966
|
-
blurX: reducedMotion ? 0 : clamp(pe.velocity * 0.006 * tokens.motionBlur, -8, 8)
|
|
5967
|
-
});
|
|
5968
|
-
for (let i = 0;i < chipButtons.length; i++) {
|
|
5969
|
-
let btn = chipButtons[i], br = this.rectOf(btn);
|
|
5970
|
-
if (br.right < stripClip[0] || br.left > stripClip[2])
|
|
5971
|
-
continue;
|
|
5972
|
-
let isActive = i === activeState.activeIndex, chipHovered = this.isHovered(btn);
|
|
5973
|
-
if (chipHovered)
|
|
5974
|
-
this.curSubHovered = !1;
|
|
5975
|
-
let mark = this.ease(btn, "dot", btn.hasAttribute("data-drifted") ? 1 : 0);
|
|
5976
|
-
if (mark > 0.01) {
|
|
5977
|
-
let size = 4 * (0.4 + 0.6 * mark);
|
|
5978
|
-
this.pushPrim({
|
|
5979
|
-
x: br.right - 6 - size / 2,
|
|
5980
|
-
y: br.top + 6 - size / 2,
|
|
5981
|
-
w: size,
|
|
5982
|
-
h: size,
|
|
5983
|
-
clip: stripClip,
|
|
5984
|
-
color: withAlpha(tokens.modified, 0.95 * mark),
|
|
5985
|
-
glowOrBlur: 0.5,
|
|
5986
|
-
kind: 7
|
|
5987
|
-
});
|
|
5988
|
-
}
|
|
5989
|
-
if (btn.hasAttribute("data-naming"))
|
|
5990
|
-
continue;
|
|
5991
|
-
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)), {
|
|
5992
|
-
px: tokens.buttonFontSize ?? tokens.textControl,
|
|
5993
|
-
weight: isActive ? tokens.titleWeight : tokens.labelWeight,
|
|
5994
|
-
align: "center",
|
|
5995
|
-
clip: stripClip
|
|
5996
|
-
});
|
|
5997
|
-
}
|
|
5998
|
-
if (ps.saveButton && !ps.saveButton.hidden) {
|
|
5999
|
-
let sr = this.rectOf(ps.saveButton), hot = this.isHovered(ps.saveButton);
|
|
6000
|
-
this.drawText("+", sr.left + sr.width * 0.5, sr.top + sr.height * 0.5, this.hot(ps.saveButton, hot, tokens.dim), {
|
|
6001
|
-
px: tokens.textTitle,
|
|
6002
|
-
weight: 400,
|
|
6003
|
-
align: "center"
|
|
6004
|
-
});
|
|
6005
|
-
}
|
|
6006
|
-
this.curAlpha = stripAlpha;
|
|
6007
|
-
}
|
|
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;
|
|
6008
6021
|
let tabs = panel.tabs;
|
|
6009
6022
|
if (tabs && !tabs.element.hidden)
|
|
6010
6023
|
anyMoving = this.drawTabStrip(tabs, hinting, reducedMotion, dt, {
|
|
@@ -6225,6 +6238,13 @@ class GpuOverlayManager {
|
|
|
6225
6238
|
this.drawScope(card, cr, tokens.radius, 1);
|
|
6226
6239
|
}
|
|
6227
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
|
+
}
|
|
6228
6248
|
this.curClip = bodyClip, this.curAlpha = panelAlpha;
|
|
6229
6249
|
let washed = /* @__PURE__ */ new Set, rowsAlpha = this.curAlpha;
|
|
6230
6250
|
for (let row of panel.rows) {
|
|
@@ -11311,7 +11331,7 @@ function presence(el, o = {}) {
|
|
|
11311
11331
|
return !1;
|
|
11312
11332
|
}), tune = (seconds, zeta) => {
|
|
11313
11333
|
let reduced = reducedMotion(win);
|
|
11314
|
-
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;
|
|
11315
11335
|
};
|
|
11316
11336
|
return render(), {
|
|
11317
11337
|
show() {
|
|
@@ -15156,7 +15176,7 @@ function buildPanel(controls, host, options) {
|
|
|
15156
15176
|
if (helpButton?.hidden)
|
|
15157
15177
|
titleEl.title = `${titleEl.textContent ? `${titleEl.textContent}
|
|
15158
15178
|
` : ""}Press ${show("help")} for keyboard shortcuts`;
|
|
15159
|
-
let presetLabel = (id, scope = "") => options.presetLabels?.[id] ?? (id === "default" ? options.defaultLabel : void 0) ?? controls.presetLabel(id, scope), 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, {
|
|
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, {
|
|
15160
15180
|
placeholder: searchOptions.placeholder ?? "Search",
|
|
15161
15181
|
chips: (searchOptions.chips ?? ["modified"]).map((chip) => {
|
|
15162
15182
|
if (chip === "modified")
|
|
@@ -15187,8 +15207,19 @@ function buildPanel(controls, host, options) {
|
|
|
15187
15207
|
else if ((!header.hidden && header.dataset.leaving !== "true") !== any)
|
|
15188
15208
|
reveal(header, any, () => wakeGpu());
|
|
15189
15209
|
};
|
|
15190
|
-
presetStrip.display(page ? "chips" : options.presetDisplay ?? "auto");
|
|
15191
|
-
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 = [
|
|
15192
15223
|
...controls.actions ?? [],
|
|
15193
15224
|
...options.actions ?? []
|
|
15194
15225
|
], body = el("div"), tabMotion = tabTransition(body, root, () => wakeGpu()), pinnedBody = el("div");
|
|
@@ -15480,7 +15511,7 @@ function buildPanel(controls, host, options) {
|
|
|
15480
15511
|
}
|
|
15481
15512
|
let specs = [], placed = /* @__PURE__ */ new Set;
|
|
15482
15513
|
for (let [key, field] of entries) {
|
|
15483
|
-
if (field.kind === "choice" && field.variants &&
|
|
15514
|
+
if (field.kind === "choice" && field.variants && controls.inPresets(key))
|
|
15484
15515
|
continue;
|
|
15485
15516
|
let pair = field.kind === "knob" && field.spring ? halves.get(field.spring.id) : void 0;
|
|
15486
15517
|
if (pair?.duration && pair.bounce && field.kind === "knob" && field.spring) {
|
|
@@ -16049,7 +16080,7 @@ function buildPanel(controls, host, options) {
|
|
|
16049
16080
|
else
|
|
16050
16081
|
runs.push({ group: r.group, pinned, rows: [r] });
|
|
16051
16082
|
}
|
|
16052
|
-
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;
|
|
16053
16084
|
for (let run of runs) {
|
|
16054
16085
|
let at = free.findIndex((b) => b.group === run.group), block = at >= 0 ? free.splice(at, 1)[0] : newBlock(run.group);
|
|
16055
16086
|
if (at < 0) {
|
|
@@ -16076,7 +16107,10 @@ function buildPanel(controls, host, options) {
|
|
|
16076
16107
|
}
|
|
16077
16108
|
under = name, nodes.push(r.row);
|
|
16078
16109
|
}
|
|
16079
|
-
|
|
16110
|
+
let strip = run.group !== void 0 && !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) {
|
|
16080
16114
|
for (let r of run.rows)
|
|
16081
16115
|
if (entering.has(r))
|
|
16082
16116
|
motion.push({ node: r.row, show: !0 });
|
|
@@ -16212,7 +16246,7 @@ function buildPanel(controls, host, options) {
|
|
|
16212
16246
|
let keys = rows.flatMap((r) => {
|
|
16213
16247
|
let tab = tabOf(r);
|
|
16214
16248
|
return !pinnedRow(r) && (tab === void 0 || tab === activeTab) ? r.keys.filter((k) => controls.scopeOf(k) === "") : [];
|
|
16215
|
-
}), v = variantsOf(controls.schema, controls.
|
|
16249
|
+
}), v = variantsOf(controls.schema, (key) => !controls.inPresets(key));
|
|
16216
16250
|
if (v) {
|
|
16217
16251
|
let tab = v.field.tab ?? (v.field.group !== void 0 ? groupTab(v.field.group) : void 0);
|
|
16218
16252
|
if (tab === void 0 || tab === activeTab)
|
|
@@ -16247,7 +16281,7 @@ function buildPanel(controls, host, options) {
|
|
|
16247
16281
|
writeSession(controls.id, { tab: id });
|
|
16248
16282
|
tabStrip.select(id, animate);
|
|
16249
16283
|
let focused = doc.activeElement;
|
|
16250
|
-
if (
|
|
16284
|
+
if (updateStrips(), applyVisibility(animate ? "tab" : "instant"), focused && root.contains(focused) && focused.closest("[hidden],[data-leaving]"))
|
|
16251
16285
|
tabStrip.focus({ preventScroll: !0, focusVisible: !1 });
|
|
16252
16286
|
options.onTab?.(id), wakeGpu();
|
|
16253
16287
|
}
|
|
@@ -16575,7 +16609,7 @@ function buildPanel(controls, host, options) {
|
|
|
16575
16609
|
changedCount++;
|
|
16576
16610
|
}
|
|
16577
16611
|
let stagger = initialized ? cascade(changedCount) : 0, moving = initialized ? rows.filter(changed) : rows;
|
|
16578
|
-
if (
|
|
16612
|
+
if (updateStrips(), batchMeasures(() => {
|
|
16579
16613
|
for (let row of moving)
|
|
16580
16614
|
if (row.slider?.prime(), row.editor?.prime?.(), row.choice)
|
|
16581
16615
|
primeSegPill(row.choice.seg, row.choice.buttons);
|
|
@@ -16707,13 +16741,14 @@ function buildPanel(controls, host, options) {
|
|
|
16707
16741
|
if (s.label?.hasAttribute("data-foldable"))
|
|
16708
16742
|
add(s.label, sectionTitle(s.name), () => s.label.focus(), s.label.firstElementChild);
|
|
16709
16743
|
}
|
|
16710
|
-
presetStrip.
|
|
16711
|
-
|
|
16712
|
-
|
|
16713
|
-
|
|
16714
|
-
|
|
16715
|
-
|
|
16716
|
-
|
|
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
|
+
});
|
|
16717
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"))
|
|
16718
16753
|
add(b, b.dataset.hint ?? b.getAttribute("aria-label") ?? b.textContent ?? "", () => b.focus());
|
|
16719
16754
|
let focusedHead = page ? doc.activeElement?.closest(".knobs-tile")?.querySelector(":scope > .knobs-group-head") : null, presetUi = focusedHead ? groupChips.get(focusedHead.dataset.group ?? "") : void 0;
|
|
@@ -16729,7 +16764,7 @@ function buildPanel(controls, host, options) {
|
|
|
16729
16764
|
add(stop, label, () => stop.focus());
|
|
16730
16765
|
}
|
|
16731
16766
|
return targets;
|
|
16732
|
-
}, unregisterHints =
|
|
16767
|
+
}, unregisterHints = hintReach === "page" && bound("hint") ? pageHints(doc).register(root, () => collectHintTargets().map((t) => ({
|
|
16733
16768
|
el: t.el,
|
|
16734
16769
|
label: t.display,
|
|
16735
16770
|
...t.labelEl ? { labelEl: t.labelEl } : {},
|
|
@@ -16786,6 +16821,9 @@ function buildPanel(controls, host, options) {
|
|
|
16786
16821
|
runs.push({ at: b.head, stops: shown([b.head]) });
|
|
16787
16822
|
for (let sh of subheads.values())
|
|
16788
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]) });
|
|
16789
16827
|
runs.push(...strips), runs.sort((a, b) => a.at.compareDocumentPosition(b.at) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1);
|
|
16790
16828
|
for (let run of runs)
|
|
16791
16829
|
list.push(...run.stops);
|
|
@@ -17164,6 +17202,9 @@ function buildPanel(controls, host, options) {
|
|
|
17164
17202
|
return { el: sub, level: "row" };
|
|
17165
17203
|
return { el: r.row.closest(".knobs-card > *") ?? r.row, level: "row" };
|
|
17166
17204
|
}
|
|
17205
|
+
let strip = active.closest(".knobs-card > .knobs-presets");
|
|
17206
|
+
if (strip)
|
|
17207
|
+
return { el: strip, level: "row" };
|
|
17167
17208
|
let card = cardOf(active);
|
|
17168
17209
|
return card ? { el: card, level: "card" } : null;
|
|
17169
17210
|
}, partName = (part, active) => part.querySelector(".knobs-strip-label")?.textContent || active?.getAttribute("aria-label") || part.getAttribute("aria-label") || "Editor", trailFor = (t, active) => {
|
|
@@ -17299,6 +17340,18 @@ function buildPanel(controls, host, options) {
|
|
|
17299
17340
|
if (!r || r.row.closest("[data-disabled],[data-readonly]"))
|
|
17300
17341
|
return;
|
|
17301
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;
|
|
17302
17355
|
}, stripDigits = () => visible(presetStrip.element) && presetStrip.getEntries().length > 1, stripOptions = {
|
|
17303
17356
|
get count() {
|
|
17304
17357
|
return presetStrip.getEntries().length;
|
|
@@ -17307,7 +17360,12 @@ function buildPanel(controls, host, options) {
|
|
|
17307
17360
|
shown: () => presetStrip.getButtons(),
|
|
17308
17361
|
anchor: presetStrip.element
|
|
17309
17362
|
}, stripOptionsAt = (node) => {
|
|
17310
|
-
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())
|
|
17311
17369
|
return;
|
|
17312
17370
|
return (presetStrip.element.contains(node) || focusLevel(node) === "panel") && !presetStrip.nameField() ? stripOptions : void 0;
|
|
17313
17371
|
}, pickOption = (event) => {
|
|
@@ -17486,9 +17544,9 @@ function buildPanel(controls, host, options) {
|
|
|
17486
17544
|
return;
|
|
17487
17545
|
}
|
|
17488
17546
|
if (pressed("presets", event)) {
|
|
17489
|
-
let direction = key === keys.presets[0] ? -1 : 1;
|
|
17490
|
-
if (visible(
|
|
17491
|
-
|
|
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);
|
|
17492
17550
|
else if (!cycleTab(direction))
|
|
17493
17551
|
return;
|
|
17494
17552
|
event.preventDefault(), event.stopPropagation();
|
|
@@ -17514,6 +17572,8 @@ function buildPanel(controls, host, options) {
|
|
|
17514
17572
|
event.preventDefault(), searchReturn = target, search.focus();
|
|
17515
17573
|
return;
|
|
17516
17574
|
}
|
|
17575
|
+
if (/^[1-9]$/.test(key) && groupStripAt(target))
|
|
17576
|
+
return;
|
|
17517
17577
|
if (/^[1-9]$/.test(key)) {
|
|
17518
17578
|
let group = page ? focusedGroup(target) : void 0;
|
|
17519
17579
|
if (Boolean(group && groupChips.has(group))) {
|
|
@@ -17562,7 +17622,7 @@ function buildPanel(controls, host, options) {
|
|
|
17562
17622
|
return;
|
|
17563
17623
|
}
|
|
17564
17624
|
if (pressed("save", event) && showVariants) {
|
|
17565
|
-
event.preventDefault(), presetStrip.save();
|
|
17625
|
+
event.preventDefault(), (groupStripAt(target) ?? presetStrip).save();
|
|
17566
17626
|
return;
|
|
17567
17627
|
}
|
|
17568
17628
|
let index = rowAt(target);
|
|
@@ -17935,6 +17995,7 @@ function buildPanel(controls, host, options) {
|
|
|
17935
17995
|
...undock ? {} : { headerDie: { button: randomButton, die } },
|
|
17936
17996
|
locks: lockIcons,
|
|
17937
17997
|
presetStrip,
|
|
17998
|
+
groupStrips: () => groupStrips.values(),
|
|
17938
17999
|
tabs: tabStrip,
|
|
17939
18000
|
groups: gpuGroups,
|
|
17940
18001
|
cards,
|
|
@@ -18041,7 +18102,10 @@ function buildPanel(controls, host, options) {
|
|
|
18041
18102
|
dropGpu(r);
|
|
18042
18103
|
for (let c of groupChips.values())
|
|
18043
18104
|
c.dispose();
|
|
18044
|
-
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);
|
|
18045
18109
|
for (let type of ["wheel", "touchstart", "keydown"])
|
|
18046
18110
|
doc.removeEventListener(type, touched, !0);
|
|
18047
18111
|
doc.removeEventListener("pointerdown", onPointerDown, !0);
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
writeSession,
|
|
7
7
|
injectStyles,
|
|
8
8
|
toggleLayer
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-bejz4qcg.js";
|
|
10
10
|
|
|
11
11
|
// src/panel/attach.ts
|
|
12
12
|
function attach(controls, element, options = {}) {
|
|
@@ -82,7 +82,7 @@ function attach(controls, element, options = {}) {
|
|
|
82
82
|
return;
|
|
83
83
|
loading = !0;
|
|
84
84
|
try {
|
|
85
|
-
let { createPanel } = await import("./chunk-
|
|
85
|
+
let { createPanel } = await import("./chunk-49hkdggk.js");
|
|
86
86
|
if (disposed || !controls.enabled || panel)
|
|
87
87
|
return;
|
|
88
88
|
if (panel = createPanel(controls, element, close, { restored, chip }), remember)
|