@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
package/README.md
CHANGED
|
@@ -369,7 +369,7 @@ The preset you apply last (a chip, `[` / `]`, a pan, `controls.preset(id)`, `var
|
|
|
369
369
|
- **The `?` popover says so:** "Random around Storm / Back to Storm", then "Reset all to defaults" once you're there.
|
|
370
370
|
- **Undo covers it:** applying a preset, each reset and each roll is one undo step, and undoing restores the active preset with the values. The active preset is kept with the values in storage.
|
|
371
371
|
|
|
372
|
-
`controls.activePreset()` returns `{ kind: "preset" | "variant", id }` or null, `controls.activeGroupPreset(group)` the group's index or -1, `controls.baseValues()` what Reset returns to first, and `controls.canReset(keys?)` whether a reset would change anything. A reset back to a preset reaches `onChange` with `source: "reset"` and `base: true`; remote controls send its values with `onSet` (nulls only for a reset to the defaults), or call `onPreset` again for a group whose peer applies its own presets.
|
|
372
|
+
`controls.activePreset(scope?)` returns `{ kind: "preset" | "variant", id }` or null (a tab's or group's with `scope`, see `scopedPresets` under [Tabs](#tabs-sub-headings-and-search)), `controls.activeGroupPreset(group)` the group's index or -1, `controls.baseValues()` what Reset returns to first, and `controls.canReset(keys?)` whether a reset would change anything. A reset back to a preset reaches `onChange` with `source: "reset"` and `base: true`; remote controls send its values with `onSet` (nulls only for a reset to the defaults), or call `onPreset` again for a group whose peer applies its own presets.
|
|
373
373
|
|
|
374
374
|
## Keyboard
|
|
375
375
|
|
|
@@ -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` |
|
|
@@ -431,14 +431,14 @@ Three things show which, in both renderers, on floating and inline panels and on
|
|
|
431
431
|
its hairline edge brightens a touch toward the accent and its title is at full strength. At rest
|
|
432
432
|
the title is a little quieter, so on a page with several panels the one listening is plain.
|
|
433
433
|
Focus leaving (or `Esc` out of the panel, or the window going to the background) disarms it.
|
|
434
|
-
- **The scope line
|
|
435
|
-
Cohesion`, the deepest crumb bright and its parents dim. Crumbs
|
|
436
|
-
moves, and one that changes fades out as the new one fades in. For a moment after a key below
|
|
434
|
+
- **The scope line** (opt-in: `crumbs: true` on the mount). Beside the title, a quiet trail says
|
|
435
|
+
where keys go: `Swarm › Shape › Cohesion`, the deepest crumb bright and its parents dim. Crumbs
|
|
436
|
+
glide to their places as focus moves, and one that changes fades out as the new one fades in. For a moment after a key below
|
|
437
437
|
the panel's level, a faint `esc ↑ Shape` follows it, then fades. Clicking a crumb takes focus to
|
|
438
438
|
its level; clicking the title takes it to the panel. The line lives in the room between the
|
|
439
439
|
title and the header's buttons: when it doesn't fit, the first crumbs drop off, and without room
|
|
440
440
|
for the deepest it stays empty, so it never runs under the buttons and the title never moves.
|
|
441
|
-
|
|
441
|
+
Without it the header is the title and its buttons; the lens and the armed frame show either way.
|
|
442
442
|
|
|
443
443
|
Tune them with tokens on the panel or any ancestor:
|
|
444
444
|
|
|
@@ -834,7 +834,29 @@ panel.tab("emitter") // shows a tab; panel.tab() answers the one showing
|
|
|
834
834
|
preset strip, then the tab's rows. `controls.isPinned(key)` says whether a key is pinned.
|
|
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.
|
|
842
|
+
`controls.inPresets(key)` says whether presets move a key.
|
|
843
|
+
- **Presets of a tab's own.** `scopedPresets` gives a tab (or a group) presets that belong to it:
|
|
844
|
+
`{ Sidebars: { snappy, smooth, calm } }`. Its strip shows only on that tab, and a tab without any
|
|
845
|
+
shows none. A scoped preset moves only its tab's (or group's) keys, never pinned ones or another
|
|
846
|
+
tab's, so each tab is its own experiment: it has its own active preset (Reset's base and
|
|
847
|
+
Random's centre for its keys), its own modified mark on the chip and its own saved variants
|
|
848
|
+
(`controls.scopes.Sidebars.variants`, kept apart in storage). A preset switch is one undo step.
|
|
849
|
+
A `variants: true` choice on a tab adds its options to that tab's presets. Keys belong to their
|
|
850
|
+
tab's scope first, then their group's. Plain `presets` then cover only the keys no scope holds;
|
|
851
|
+
leave them out and only the scoped strips show. One strip shows per tab: the tab's own, else the
|
|
852
|
+
first group scope on it. In a panel, any other group's presets show at the top of its own card,
|
|
853
|
+
in the strip's look without its tray, so a story's states can lead the panel while its Motion
|
|
854
|
+
group keeps Shipped, Snappy and Calm beside its knobs. Every strip's default chip reads `defaultLabel`; by scope,
|
|
855
|
+
`defaultLabel: { "": "Empty", Motion: "Shipped" }` names each on its own. In code, `controls.preset(id, { scope })`, `activePreset(scope)` and
|
|
856
|
+
`matchingPreset(scope)` take the tab or group, and `controls.scopeOf(key)` says whose presets
|
|
857
|
+
move a key (`""` for plain `presets`, undefined when pinned). An active preset saved while the
|
|
858
|
+
presets were panel-wide comes back on the scope that now has one by that id, and variants saved
|
|
859
|
+
then start out in each scope they move.
|
|
838
860
|
|
|
839
861
|
```ts
|
|
840
862
|
const motion = defineControls(
|
|
@@ -845,7 +867,12 @@ panel.tab("emitter") // shows a tab; panel.tab() answers the one showing
|
|
|
845
867
|
sidebars: spring({ duration: 0.3, bounce: 0 }, { group: "Sidebars", tab: "Sidebars" }),
|
|
846
868
|
hover: spring({ duration: 0.14, bounce: 0 }, { group: "Experiments", tab: "Experiments" }),
|
|
847
869
|
},
|
|
848
|
-
{
|
|
870
|
+
{
|
|
871
|
+
pinned: ["Global"],
|
|
872
|
+
defaultLabel: "Shipped",
|
|
873
|
+
// Only the Sidebars tab has a strip, and its presets set only its springs.
|
|
874
|
+
scopedPresets: { Sidebars: { snappy, smooth, calm } },
|
|
875
|
+
},
|
|
849
876
|
)
|
|
850
877
|
motion.mount(el, { title: "Knobs", tabs: ["Sidebars", "Experiments"] })
|
|
851
878
|
```
|
|
@@ -1187,7 +1214,7 @@ Scrolling pane bodies, trees and the command palette's list fade their content o
|
|
|
1187
1214
|
| Key | Action |
|
|
1188
1215
|
| --- | --- |
|
|
1189
1216
|
| `↑` / `↓`, `Home` / `End` | Move; type letters to jump to a label (see `typeahead`) |
|
|
1190
|
-
| `←` / `→` | Close or go up / open or go down |
|
|
1217
|
+
| `←` / `→` | Close or go up / open or go down (swapped when the tree is `dir="rtl"`) |
|
|
1191
1218
|
| `⇧` click or `⇧↑↓`, `⌘` click, `⌘A` | Extend, toggle, select all |
|
|
1192
1219
|
| `Space` | Select the active row (`⌘Space` toggles it) |
|
|
1193
1220
|
| `Enter` / `F2` | Rename in place (with `onRename`); otherwise `Enter` calls `onActivate` |
|
|
@@ -1240,7 +1267,7 @@ toast("Deleted Barrier", { action: { label: "Undo", run: undo } })
|
|
|
1240
1267
|
|
|
1241
1268
|
- **`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).
|
|
1242
1269
|
- **`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.
|
|
1243
|
-
- **`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()`.
|
|
1270
|
+
- **`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()`.
|
|
1244
1271
|
- **`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.
|
|
1245
1272
|
- **`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.
|
|
1246
1273
|
- **`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.
|
|
@@ -2007,7 +2034,7 @@ The package has two core exports selected through the standard `development` con
|
|
|
2007
2034
|
| `action(label, { run, shortcut?, global?, rebind? })` / `flatSpring({ duration, bounce }, meta)` | A button row, with a shortcut its key cap can rebind; two flat number fields drawn as one spring card. `actionShortcut(field)` reads an action's shortcut as `{ key, scope }`. |
|
|
2008
2035
|
| Field meta `random?`, `disabled?`, `readOnly?`, `folded?`, `tab?`, `subsection?` | On any field or descriptor: `random: false` stays out of Random and Mutate (switches, seeds and key combinations start out; `random: true` brings them in); `disabled` / `readOnly` (boolean or `(values) => boolean`) gate the row; `folded` makes its group foldable, starting folded; `tab` puts the row on a tab; `subsection` puts it under a sub-heading in its group. |
|
|
2009
2036
|
| Field meta `groupDescription?: string`, `sectionDescription?: string`, `sectionFolded?: boolean` | On any field or descriptor, for pages (the first field of a group or section that gives one wins): a muted line under the card's title or the section's heading; `sectionFolded` makes the section foldable, starting folded. |
|
|
2010
|
-
| `mountPanel(controls, container, options?)` (`knobs/panel`) | An inline panel. Beside theme, density, renderer and keys: `preset`, `header` (`false` or `{ title?, buttons? }`), `crumbs` (`
|
|
2037
|
+
| `mountPanel(controls, container, options?)` (`knobs/panel`) | An inline panel. Beside theme, density, renderer and keys: `preset`, `header` (`false` or `{ title?, buttons? }`), `crumbs` (`true` adds the scope line), `session`, `groupFolded`, `subsectionFolded`, `tabs`, `tab`, `onTab`, `search`, `groupRandom(group, mode)`, `rowAccessory(key)`, `marks`, `haptics`, `detents`, `sound`. The handle adds `panel.fold(group, folded?)`, `panel.tab(id?)`, `panel.search(query?, chips?)` (returns `{ query, chips }`) and `panel.updateAccessories()`. |
|
|
2011
2038
|
| `sound` (`knobs/panel`) | The page's sound effects (see **Sound**): `enabled`, `enable(on?)`, `volume`, `setVolume(v)`, `theme`, `setTheme("glass" \| "mech")`, `play(cue \| layers, detail?)`, `output()`, `subscribe(listener)`. Panels play only with `sound` on their mount. |
|
|
2012
2039
|
| `mountPage(controls, container, options?)` (`knobs/panel`) | A full page of group cards in sections under a sticky header; `page.card({ title?, section?, element?, collapsed?, summary?, description? })` adds custom cards (`card.collapse(collapsed?)`, `card.collapsed`, `card.summary(content \| null)`), and `page.highlight({ groups?, sections? } \| null, { reveal?, expand? })` marks what's on screen. Options take `groupLabels`, `sectionLabels`, `groupDescriptions`, `sectionDescriptions`, `presetLabels`, `defaultLabel`, `groupPresetDisplay` and `groupFolded` over the store's. |
|
|
2013
2040
|
| `MountPageOptions` folds | `sectionFolded?: SectionFolded` (`boolean \| Record<string, boolean>`), `foldStorage?: StoragePort \| null`, `nav?: boolean`, `groupSummary?(group, info: FoldSummaryInfo): string \| Node \| null`, `sectionSummary?(section, info: FoldSummaryInfo): string \| Node \| null`; `FoldSummaryInfo` is `{ preset: string \| null, changed: number, keys: readonly string[] }`. |
|
|
@@ -2035,10 +2062,11 @@ The package has two core exports selected through the standard `development` con
|
|
|
2035
2062
|
- `controls.randomize(keys?)` / `controls.mutate(keys?)`: skip locked fields; one undo step each
|
|
2036
2063
|
- `controls.lock(keys, locked = true)` / `controls.isLocked(key)`: locks are saved with the values (remote controls keep them in memory)
|
|
2037
2064
|
- `controls.compare(hold)` / `controls.comparing`: while held, `get()` returns the previous undo entry; no history, no storage
|
|
2038
|
-
- `controls.preset(id, { coalesce? })` / `controls.matchingPreset()`
|
|
2039
|
-
- `controls.activePreset()` / `controls.activeGroupPreset(group)` / `controls.baseValues()`: the base Reset returns to and Random explores around
|
|
2065
|
+
- `controls.preset(id, { coalesce?, scope? })` / `controls.matchingPreset(scope?)`
|
|
2066
|
+
- `controls.activePreset(scope?)` / `controls.activeGroupPreset(group)` / `controls.baseValues()`: the base Reset returns to and Random explores around
|
|
2067
|
+
- `controls.scopes` / `controls.scopeOf(key)`: the tabs and groups with presets of their own (`scopedPresets`), each `{ id, keys, presets, variants }`, and whose presets move a key
|
|
2040
2068
|
- `controls.groupPresets` / `controls.groupPreset(group, index, { coalesce? })` / `controls.matchingGroupPreset(group)` / `controls.groupPresetDisplay`
|
|
2041
|
-
- `controls.groupLabel(id)` / `controls.sectionLabel(id)` / `controls.presetLabel(id)`: display labels (`groupLabels`, `sectionLabels`, `presetLabels`, `defaultLabel`, or the fields' `groupLabel` / `sectionLabel`)
|
|
2069
|
+
- `controls.groupLabel(id)` / `controls.sectionLabel(id)` / `controls.presetLabel(id, scope?)`: display labels (`groupLabels`, `sectionLabels`, `presetLabels`, `defaultLabel`, or the fields' `groupLabel` / `sectionLabel`)
|
|
2042
2070
|
- `controls.groupDescription(group): string | undefined` / `controls.sectionDescription(section): string | undefined`: `groupDescriptions` / `sectionDescriptions`, else the fields' `groupDescription` / `sectionDescription`
|
|
2043
2071
|
- `controls.groupFolded` / `controls.sectionFolded`: how groups and a page's sections start, as given to `defineControls` or `createRemoteControls` (`groupFolded?: Record<string, boolean>`, `sectionFolded?: SectionFolded`); mounts read them under their own
|
|
2044
2072
|
- `controls.code("ts" | "json" | "jsx", values?)`
|
|
@@ -2058,7 +2086,7 @@ The package has two core exports selected through the standard `development` con
|
|
|
2058
2086
|
| `readout(field, { preset?, theme?, label? })` | A readout on its own: `{ element, push(value), value, dispose() }`. |
|
|
2059
2087
|
| `popover(anchor, content, { placement?, offset?, role?, label?, focus?, trap?, closeOnOutside?, onClose? })` | A floating layer that flips and shifts; `{ element, open, reposition(), close() }`. |
|
|
2060
2088
|
| `tooltip(el, text \| { text, shortcut?, placement?, delay? })` / `tooltips(doc)` | Delayed tooltips with instant hand-off and shortcut chips; `data-tip` attributes. |
|
|
2061
|
-
| `commandPalette({ commands, onRun?, hotkey?, recents?, placeholder? })` / `commandsFrom(controls, options?)` | `⌘K` fuzzy command search; a store's actions, presets and fields as commands. |
|
|
2089
|
+
| `commandPalette({ commands, onRun?, hotkey?, recents?, placeholder?, presence? })` / `commandsFrom(controls, options?)` | `⌘K` fuzzy command search; a store's actions, presets and fields as commands. |
|
|
2062
2090
|
| `confirm({ title, body?, confirm?, cancel?, destructive? })` | `Promise<boolean>`, modal, focus kept inside. |
|
|
2063
2091
|
| `toast(message, { tone?, linger?, action?, within? })` | A status pill at the bottom centre. |
|
|
2064
2092
|
| `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. |
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
DEFAULT_LINEAR,
|
|
11
11
|
motionCss,
|
|
12
12
|
storageKey
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-v2g91mrm.js";
|
|
14
14
|
|
|
15
15
|
// src/core/theme.ts
|
|
16
16
|
var property = (k) => k.startsWith("--") ? k : `--k-${k}`;
|
|
@@ -2396,7 +2396,7 @@ ${GRAD_PROPS}
|
|
|
2396
2396
|
|
|
2397
2397
|
/* The chip: a round cog button, or a capsule with a label beside the cog. */
|
|
2398
2398
|
.knobs-chip{position:fixed;z-index:2147480000;display:inline-flex;align-items:center;justify-content:center;gap:5px;width:26px;height:26px;padding:0;border-radius:999px;cursor:pointer;background:var(--_k-bg);border:1px solid transparent;
|
|
2399
|
-
color:var(--_k-fg-2);font-size:var(--_k-text-control);line-height:1;letter-spacing:.01em;white-space:nowrap;--k-chip-edge:var(--_k-border-subtle);box-shadow:0 0 0 var(--k-rim-width) var(--k-chip-edge),0 4px 16px rgba(0,0,0,calc(.35 * var(--_k-shadow-k,1)))
|
|
2399
|
+
color:var(--_k-fg-2);font-size:var(--_k-text-control);line-height:1;letter-spacing:.01em;white-space:nowrap;--k-chip-edge:var(--_k-border-subtle);box-shadow:0 calc(var(--k-rim-width) * -1) 0 var(--_k-rim),0 0 0 var(--k-rim-width) var(--k-chip-edge),0 4px 16px rgba(0,0,0,calc(.35 * var(--_k-shadow-k,1)));transition:color .15s,border-color .15s,transform .2s var(--k-ease),opacity .2s,scale .12s var(--k-ease),${TOKEN_TRANSITIONS};}
|
|
2400
2400
|
.knobs-chip[data-label]{width:auto;padding:0 10px 0 7px}
|
|
2401
2401
|
.knobs-chip .knobs-icon{display:block;flex:none;width:15px;height:15px}
|
|
2402
2402
|
.knobs-chip:hover{color:var(--_k-fg);--k-chip-edge:var(--_k-border-strong)}
|
|
@@ -2423,9 +2423,10 @@ ${GRAD_PROPS}
|
|
|
2423
2423
|
/* Panel material: --k-glass (0 opaque … 1 clearest) thins the surface over a blurred, saturated
|
|
2424
2424
|
backdrop, toned toward the theme (--k-glass-tone dims it under dark panels) so text keeps its
|
|
2425
2425
|
contrast. Its edge is a hairline (--k-edge, --k-rim-width wide) and a hairline of light (--k-rim)
|
|
2426
|
-
catches its top.
|
|
2426
|
+
catches its top. The light rides on the edge (a shadow raised by its width, so only its top
|
|
2427
|
+
shows), not inside the card's 1px border, where it read as a second edge. */
|
|
2427
2428
|
.knobs-panel{-webkit-user-select:none;user-select:none;transition:${TOKEN_TRANSITIONS},--k-armed ${ARMED_T};position:fixed;z-index:2147480001;width:var(--_k-width);max-width:calc(100vw - 16px);max-height:calc(100dvh - 16px);overflow:auto;padding:var(--_k-pad);
|
|
2428
|
-
background:color-mix(in srgb,var(--_k-bg) calc(100% - var(--_k-glass) * 20%),transparent);border:1px solid transparent;border-radius:var(--_k-radius-panel);box-shadow:var(--_k-shadow-overlay),0
|
|
2429
|
+
background:color-mix(in srgb,var(--_k-bg) calc(100% - var(--_k-glass) * 20%),transparent);border:1px solid transparent;border-radius:var(--_k-radius-panel);box-shadow:var(--_k-shadow-overlay),0 calc(var(--k-rim-width) * -1) 0 var(--_k-rim),0 0 0 var(--k-rim-width) var(--ka-edge),var(--ka-glow);scrollbar-width:thin;
|
|
2429
2430
|
/* Armed (focus inside: keys come here), the edge takes the accent and a faint glow lifts it. */
|
|
2430
2431
|
--ka-edge:color-mix(in srgb,var(--_k-accent) calc(var(--k-armed) * var(--k-armed-edge) * 100%),var(--_k-border-subtle));
|
|
2431
2432
|
--ka-glow:0 0 calc(var(--k-armed-glow) * 1px) color-mix(in srgb,var(--_k-accent) calc(var(--k-armed) * var(--k-armed-glow-a) * var(--k-chrome,1) * 100%),transparent);
|
|
@@ -2438,7 +2439,7 @@ ${GRAD_PROPS}
|
|
|
2438
2439
|
.knobs-panel[data-morphing]{background:transparent;border-color:transparent;box-shadow:none;-webkit-backdrop-filter:none;backdrop-filter:none;animation:none}
|
|
2439
2440
|
.knobs-morph{position:fixed;left:0;top:0;z-index:2147480001;pointer-events:none;box-sizing:border-box;--p:0;--spec:0;
|
|
2440
2441
|
background:color-mix(in srgb,var(--_k-bg) calc(100% - var(--_k-glass) * 20% * var(--p)),transparent);border:1px solid transparent;
|
|
2441
|
-
box-shadow:0
|
|
2442
|
+
box-shadow:0 calc(var(--k-rim-width) * -1) 0 color-mix(in srgb,var(--_k-rim) calc(var(--p) * 100%),transparent),0 0 0 var(--k-rim-width) var(--_k-border-subtle),inset 0 0 0 var(--k-rim-width) rgb(255 255 255/var(--spec));
|
|
2442
2443
|
--k-backdrop:blur(calc(var(--_k-glass) * 24px)) saturate(calc(1 + var(--_k-glass) * .8)) brightness(calc(1 + (var(--_k-glass-tone) - 1) * var(--_k-glass)));
|
|
2443
2444
|
-webkit-backdrop-filter:var(--k-backdrop);backdrop-filter:var(--k-backdrop)}
|
|
2444
2445
|
.knobs-morph::before,.knobs-morph::after{content:"";position:absolute;inset:-1px;border-radius:inherit;pointer-events:none}
|
|
@@ -2446,7 +2447,7 @@ ${GRAD_PROPS}
|
|
|
2446
2447
|
.knobs-morph::after{box-shadow:var(--_k-shadow-overlay);opacity:var(--p)}
|
|
2447
2448
|
/* Meanwhile the chip is just its label, fading on the shape. */
|
|
2448
2449
|
.knobs-chip.knobs-chip[data-morph]{visibility:visible;pointer-events:auto;transform:none;transition:none;background:transparent;border-color:transparent;box-shadow:none}
|
|
2449
|
-
.knobs-panel.knobs-inline{position:relative;z-index:auto;left:auto!important;top:auto!important;max-width:100%;max-height:none;box-shadow:0
|
|
2450
|
+
.knobs-panel.knobs-inline{position:relative;z-index:auto;left:auto!important;top:auto!important;max-width:100%;max-height:none;box-shadow:0 calc(var(--k-rim-width) * -1) 0 color-mix(in srgb,var(--_k-rim) calc(var(--k-chrome) * 100%),transparent),0 0 0 var(--k-rim-width) color-mix(in srgb,var(--ka-edge) calc(var(--k-chrome) * 100%),transparent),var(--ka-glow);animation:none;
|
|
2450
2451
|
/* --k-chrome 0: an embedded panel sheds its card (background, border, rim) for the host's column,
|
|
2451
2452
|
border width too, so its rows line up with the column's edges. */
|
|
2452
2453
|
border-width:calc(var(--k-chrome) * 1px);
|
|
@@ -2599,9 +2600,16 @@ ${GRAD_PROPS}
|
|
|
2599
2600
|
/* The active preset's modified mark: the values have drifted off it (a row's dot, in its corner). */
|
|
2600
2601
|
.knobs-panel .knobs-preset-chip::after{content:"";position:absolute;top:4px;right:4px;width:4px;height:4px;border-radius:50%;background:var(--_k-modified);opacity:0;transform:scale(.4);pointer-events:none;transition:opacity .16s ease-out,transform .28s cubic-bezier(.34,1.5,.64,1)}
|
|
2601
2602
|
.knobs-panel .knobs-preset-chip[data-drifted]::after{opacity:.95;transform:none}
|
|
2603
|
+
/* Digits that stay on the chips (hints: { digits: "always" }): quiet, in a column of their own. */
|
|
2604
|
+
.knobs-panel .knobs-preset-key{display:inline-block;margin-right:6px;color:var(--_k-fg-3);font-size:var(--_k-text-meta);font-weight:var(--_k-weight-label);font-variant-numeric:tabular-nums}
|
|
2605
|
+
/* A group's own presets at the top of its card: the chips sit on the card, with no tray. */
|
|
2606
|
+
.knobs-panel .knobs-card>.knobs-presets{margin:0;padding:max(4px,calc((var(--_k-row) - var(--k-button-h,var(--_k-control-h))) / 2)) var(--_k-inset);background:transparent;border-radius:0}
|
|
2607
|
+
.knobs-panel .knobs-card>.knobs-presets[data-display="list"]{padding-inline:0}
|
|
2608
|
+
.knobs-card>.knobs-presets:hover{background:transparent}
|
|
2602
2609
|
/* Naming a saved preset: a field over its chip that opens out from the middle to the chip's width;
|
|
2603
2610
|
the chip's own name hides beneath it. Leaving, it fades. */
|
|
2604
2611
|
.knobs-panel .knobs-preset-chip[data-naming]{color:transparent!important}
|
|
2612
|
+
.knobs-panel .knobs-preset-chip[data-naming] .knobs-preset-key{color:transparent}
|
|
2605
2613
|
.knobs-panel .knobs-preset-name{position:absolute;z-index:2;box-sizing:border-box;min-width:0;margin:0;padding:0 6px;border:1px solid color-mix(in srgb,var(--_k-accent) 55%,transparent);border-radius:var(--k-button-radius,var(--_k-radius-md));outline:none;background:color-mix(in srgb,var(--_k-accent) 10%,transparent);color:var(--_k-fg);caret-color:var(--_k-accent);
|
|
2606
2614
|
font-family:inherit;font-size:var(--k-button-font-size,var(--_k-text-control));font-weight:var(--_k-weight-title);letter-spacing:inherit;text-align:center;animation:knobs-name-in .25s cubic-bezier(.2,.8,.2,1);transition:opacity .11s cubic-bezier(.4,0,1,1)}
|
|
2607
2615
|
.knobs-preset-name::selection{background:color-mix(in srgb,var(--_k-accent) 24%,transparent);color:var(--_k-fg)}
|
|
@@ -3212,7 +3220,7 @@ ${POINTER_ROW} .knobs-slider.knobs-modified:not(:hover,.knobs-active) .knobs-val
|
|
|
3212
3220
|
.knobs-panel[data-gpu-active="true"] :where(header strong,header button,.knobs-tile,.knobs-section-head,.knobs-group-label,.knobs-peek,.knobs-card>*,.knobs-presets,.knobs-preset-chip,.knobs-group-head,.knobs-group-head button,.knobs-card,.knobs-row,.knobs-row>span:first-child,.knobs-slider,.knobs-track,.knobs-label,.knobs-value,.knobs-digits,.knobs-digits *,.knobs-unit,.knobs-seg,.knobs-seg button,.knobs-custom-actions button,.knobs-action,.knobs-select,.knobs-select-value,
|
|
3213
3221
|
.knobs-sub,.knobs-x-head,.knobs-x-label,.knobs-x-read,.knobs-strip-label,.knobs-strip-read,.knobs-pad,.knobs-ease,.knobs-spring-curve,.knobs-ease-chips,.knobs-ease-chip,.knobs-graph,.knobs-graph-read,
|
|
3214
3222
|
.knobs-tabs,.knobs-tab,.knobs-subhead,.knobs-subhead-label,.knobs-match,.knobs-cell,.knobs-cell-axis,.knobs-cell-read,.knobs-link,.knobs-range-read,.knobs-angle,.knobs-angle-read,.knobs-dial,
|
|
3215
|
-
.knobs-seed,.knobs-seed-read,.knobs-seed-digits,.knobs-seed-digits *,.knobs-seed-roll,.knobs-keys,.knobs-keys-text,.knobs-tool,.knobs-tool-label,.knobs-tool-key,
|
|
3223
|
+
.knobs-seed,.knobs-seed-read,.knobs-seed-digits,.knobs-seed-digits *,.knobs-seed-roll,.knobs-keys,.knobs-keys-text,.knobs-tool,.knobs-tool-label,.knobs-tool-key,.knobs-preset-key,
|
|
3216
3224
|
.knobs-section-name,.knobs-section-summary,.knobs-section-desc,.knobs-group-desc,.knobs-group-summary,.knobs-tab-count):not(.knobs-live,.knobs-live *){
|
|
3217
3225
|
background:transparent!important;color:transparent!important;border-color:transparent!important;box-shadow:none!important;
|
|
3218
3226
|
}
|
|
@@ -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-s7d5a8vb.js");
|
|
86
86
|
if (disposed || !controls.enabled || panel)
|
|
87
87
|
return;
|
|
88
88
|
if (panel = createPanel(controls, element, close, { restored, chip }), remember)
|