@kitlangton/knobs 0.4.0-next.11 → 0.4.0-next.13
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 +117 -21
- package/dist/dev/{chunk-75gbzbyd.js → chunk-44r02asc.js} +2 -5
- package/dist/dev/{chunk-mjdgzad5.js → chunk-7kns3qe6.js} +29 -25
- package/dist/dev/{chunk-bnhzf1tj.js → chunk-mbhy4jg5.js} +1453 -1097
- package/dist/dev/{chunk-j57rhjtm.js → chunk-pdf3zy95.js} +95 -42
- package/dist/dev/index.js +188 -63
- package/dist/index.js +211 -60
- package/dist/panel.js +2699 -2149
- package/dist/review-react.js +8 -4
- package/dist/review-solid.js +10 -5
- package/dist/review.js +8 -4
- package/dist/types/core/remote.d.ts +10 -2
- package/dist/types/core/schema.d.ts +52 -4
- package/dist/types/core/store.d.ts +45 -8
- package/dist/types/core/variants.d.ts +3 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/panel/dock.d.ts +9 -0
- package/dist/types/panel/gpu/renderer.d.ts +11 -1
- package/dist/types/panel/inspector.d.ts +11 -3
- package/dist/types/panel/presets.d.ts +26 -4
- package/dist/types/panel/scope.d.ts +15 -4
- package/dist/types/ui/canvas-css.d.ts +1 -0
- package/dist/types/ui/canvas-model.d.ts +116 -0
- package/dist/types/ui/canvas.d.ts +66 -0
- package/dist/types/ui/index.d.ts +2 -0
- package/dist/types/ui/react.d.ts +12 -0
- package/dist/types/ui/solid.d.ts +9 -0
- package/dist/ui-react.js +1020 -17
- package/dist/ui-solid.js +1032 -25
- package/dist/ui.js +986 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -473,6 +473,16 @@ function pickMeta(source, skip = []) {
|
|
|
473
473
|
return out;
|
|
474
474
|
}
|
|
475
475
|
var READOUT_KINDS = /* @__PURE__ */ new Set(["watch", "sparkline", "graph", "meter", "table", "log"]), isReadout = (field) => READOUT_KINDS.has(field.kind), hasValue = (field) => field.kind !== "action" && field.kind !== "toolbar" && !READOUT_KINDS.has(field.kind);
|
|
476
|
+
function variantsOf(schema, isPinned = () => !1) {
|
|
477
|
+
let found;
|
|
478
|
+
for (let [key, field] of Object.entries(schema))
|
|
479
|
+
if (field.kind === "choice" && field.variants && !isPinned(key)) {
|
|
480
|
+
if (found)
|
|
481
|
+
throw Error(`Only one choice can hold the variants (${found.key}, ${key}).`);
|
|
482
|
+
found = { key, field };
|
|
483
|
+
}
|
|
484
|
+
return found;
|
|
485
|
+
}
|
|
476
486
|
function pinnedKeys(schema, groups = []) {
|
|
477
487
|
let byGroup = new Map(groups.map((g) => [g, !0]));
|
|
478
488
|
for (let f of Object.values(schema))
|
|
@@ -515,8 +525,9 @@ function choice(value, options, meta) {
|
|
|
515
525
|
value,
|
|
516
526
|
options: Object.freeze([...options]),
|
|
517
527
|
...labels && Object.keys(labels).length ? { labels } : {},
|
|
518
|
-
...meta?.display ? { display: meta.display } : {}
|
|
519
|
-
|
|
528
|
+
...meta?.display ? { display: meta.display } : {},
|
|
529
|
+
...meta?.variants ? { variants: !0 } : {}
|
|
530
|
+
}, meta?.variants ? { ...meta, random: meta.random ?? !1 } : meta);
|
|
520
531
|
}
|
|
521
532
|
function action(label, meta) {
|
|
522
533
|
let { shortcut, global, rebind, run, ...rest } = meta ?? {}, key = shortcutOf({ ...shortcut ? { shortcut } : {}, ...global ? { global } : {} }), combo = key ? normalizeCombo(key.key) : "";
|
|
@@ -661,6 +672,17 @@ function keybind(value = "", meta) {
|
|
|
661
672
|
let field = { kind: "keybind", value: normalizeCombo(value) };
|
|
662
673
|
return withMeta(field, { random: !1, ...meta });
|
|
663
674
|
}
|
|
675
|
+
function text(value = "", options) {
|
|
676
|
+
let { multiline, placeholder, ...meta } = options ?? {}, field = {
|
|
677
|
+
kind: "text",
|
|
678
|
+
value: "",
|
|
679
|
+
...multiline ? { multiline: !0 } : {},
|
|
680
|
+
...placeholder ? { placeholder } : {}
|
|
681
|
+
};
|
|
682
|
+
return withMeta({ ...field, value: normalizeText(field, value) }, { random: !1, ...meta });
|
|
683
|
+
}
|
|
684
|
+
var normalizeText = (field, input) => field.multiline ? input.replace(/\r\n?/g, `
|
|
685
|
+
`) : input.replace(/\r\n?|\n/g, " ");
|
|
664
686
|
function gradient(stops, options = {}) {
|
|
665
687
|
let value = normalizeStops(stops);
|
|
666
688
|
if (!value)
|
|
@@ -715,7 +737,8 @@ function toolbar(items, meta) {
|
|
|
715
737
|
throw Error("A toolbar needs at least one item.");
|
|
716
738
|
return withMeta({
|
|
717
739
|
kind: "toolbar",
|
|
718
|
-
items: Object.freeze(items.map((item) => Object.freeze({ ...item })))
|
|
740
|
+
items: Object.freeze(items.map((item) => Object.freeze({ ...item }))),
|
|
741
|
+
...meta?.labels !== void 0 ? { labels: meta.labels } : {}
|
|
719
742
|
}, meta);
|
|
720
743
|
}
|
|
721
744
|
var readoutMeta = (o) => {
|
|
@@ -859,6 +882,8 @@ function normalizeField(field, input) {
|
|
|
859
882
|
return typeof input === "number" && Number.isFinite(input) ? Math.round(Math.min(field.max, Math.max(field.min, input))) : field.value;
|
|
860
883
|
case "keybind":
|
|
861
884
|
return typeof input === "string" ? normalizeCombo(input) : field.value;
|
|
885
|
+
case "text":
|
|
886
|
+
return typeof input === "string" ? normalizeText(field, input) : field.value;
|
|
862
887
|
case "gradient":
|
|
863
888
|
return normalizeStops(input) ?? field.value;
|
|
864
889
|
case "curve":
|
|
@@ -1009,6 +1034,7 @@ function pick(field, random) {
|
|
|
1009
1034
|
case "seed":
|
|
1010
1035
|
return lattice(field.min, field.max, 1, r());
|
|
1011
1036
|
case "keybind":
|
|
1037
|
+
case "text":
|
|
1012
1038
|
return field.value;
|
|
1013
1039
|
case "gradient":
|
|
1014
1040
|
return randomStops(field.value.length, r);
|
|
@@ -1094,6 +1120,7 @@ function around(field, base, random) {
|
|
|
1094
1120
|
]);
|
|
1095
1121
|
case "seed":
|
|
1096
1122
|
case "keybind":
|
|
1123
|
+
case "text":
|
|
1097
1124
|
return pick(field, random);
|
|
1098
1125
|
}
|
|
1099
1126
|
}
|
|
@@ -1193,6 +1220,7 @@ function shift(field, value, random) {
|
|
|
1193
1220
|
case "seed":
|
|
1194
1221
|
return nudge(value, field.min, field.max, 1, random);
|
|
1195
1222
|
case "keybind":
|
|
1223
|
+
case "text":
|
|
1196
1224
|
return value;
|
|
1197
1225
|
case "gradient":
|
|
1198
1226
|
return mutateStops(value, random, MUTATE.hue, MUTATE.lightness);
|
|
@@ -1509,7 +1537,7 @@ function unlock(options) {
|
|
|
1509
1537
|
}
|
|
1510
1538
|
|
|
1511
1539
|
// src/core/variants.ts
|
|
1512
|
-
function createVariants(schema, id, key, storage, get, set, notify, enabled) {
|
|
1540
|
+
function createVariants(schema, id, key, storage, get, set, notify, enabled, seed) {
|
|
1513
1541
|
let ready = !1, list = Object.freeze([]);
|
|
1514
1542
|
function parse(json) {
|
|
1515
1543
|
let data = JSON.parse(json);
|
|
@@ -1538,7 +1566,7 @@ function createVariants(schema, id, key, storage, get, set, notify, enabled) {
|
|
|
1538
1566
|
if (ready || !enabled())
|
|
1539
1567
|
return;
|
|
1540
1568
|
let json = storage()?.getItem(key);
|
|
1541
|
-
list = json ? parse(json) : Object.freeze([]), ready = !0;
|
|
1569
|
+
list = json ? parse(json) : Object.freeze([...seed?.() ?? []]), ready = !0;
|
|
1542
1570
|
}
|
|
1543
1571
|
function persist(next) {
|
|
1544
1572
|
if (!enabled())
|
|
@@ -1625,32 +1653,69 @@ function defineControls(id, input, options = {}) {
|
|
|
1625
1653
|
let schema = Object.freeze({ ...input }), locked = normalize(schema, {}), actions = Object.freeze([...options.actions ?? []]), { theme, appearance } = options, density = options.density ?? "default", renderer = options.renderer ?? "auto", enabled = () => (Boolean(options.ship) || isUnlocked()) && (typeof options.enabled === "function" ? options.enabled() : options.enabled ?? (Boolean(options.ship) || isUnlocked() || typeof location < "u" && ["localhost", "127.0.0.1", "[::1]"].includes(location.hostname))), storage = () => options.storage === void 0 ? browserStorage() : options.storage, persistMode = options.persist ?? "all", valueStorage = () => persistMode === "all" ? storage() : null, variantStorage = () => persistMode === "none" ? null : storage(), draw = options.random ?? Math.random, hostHistory = options.history, unsubscribeHistory, unsubscribeUnlock, listeners = /* @__PURE__ */ new Set, refreshes = 0, notify = () => {
|
|
1626
1654
|
for (let cb of [...listeners])
|
|
1627
1655
|
cb();
|
|
1628
|
-
}, mixed = /* @__PURE__ */ new Set, current = locked, read = !1, error = null, locks = /* @__PURE__ */ new Set, bindings = /* @__PURE__ */ new Map, comparing = null, landing = !1, echo = Math.max(0, options.echo ?? 0), grabbed = /* @__PURE__ */ new Set, changedAt = /* @__PURE__ */ new Map, sent = /* @__PURE__ */ new Map, pending = /* @__PURE__ */ new Map, echoTimer, now = () => typeof performance < "u" ? performance.now() : Date.now(), isHeld = (key) => grabbed.has(key) || echo > 0 && now() - (changedAt.get(key) ?? -1 / 0) < echo, NO_BASE = Object.freeze({
|
|
1656
|
+
}, mixed = /* @__PURE__ */ new Set, current = locked, read = !1, error = null, locks = /* @__PURE__ */ new Set, bindings = /* @__PURE__ */ new Map, comparing = null, landing = !1, echo = Math.max(0, options.echo ?? 0), grabbed = /* @__PURE__ */ new Set, changedAt = /* @__PURE__ */ new Map, sent = /* @__PURE__ */ new Map, pending = /* @__PURE__ */ new Map, echoTimer, now = () => typeof performance < "u" ? performance.now() : Date.now(), isHeld = (key) => grabbed.has(key) || echo > 0 && now() - (changedAt.get(key) ?? -1 / 0) < echo, NO_BASE = Object.freeze({
|
|
1657
|
+
preset: null,
|
|
1658
|
+
groups: Object.freeze({}),
|
|
1659
|
+
scopes: Object.freeze({})
|
|
1660
|
+
}), base = NO_BASE, past = [], future = [], HISTORY = 100, stateKey = storageKey(id, "state"), pinnedOf, pinned = () => {
|
|
1629
1661
|
if (pinnedOf?.schema !== schema)
|
|
1630
1662
|
pinnedOf = { schema, keys: pinnedKeys(schema, options.pinned) };
|
|
1631
1663
|
return pinnedOf.keys;
|
|
1632
|
-
},
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
let
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
let
|
|
1643
|
-
if (
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
}
|
|
1653
|
-
|
|
1664
|
+
}, variantsChoice = () => variantsOf(schema, (key) => pinned().has(key)), scopingOf, scoping = () => {
|
|
1665
|
+
if (scopingOf?.schema === schema)
|
|
1666
|
+
return scopingOf;
|
|
1667
|
+
let fields = schema, groupTab = /* @__PURE__ */ new Map;
|
|
1668
|
+
for (let f of Object.values(fields))
|
|
1669
|
+
if (f.group !== void 0 && f.tab !== void 0 && !groupTab.has(f.group))
|
|
1670
|
+
groupTab.set(f.group, f.tab);
|
|
1671
|
+
let tabOf = (f) => f.tab ?? (f.group !== void 0 ? groupTab.get(f.group) : void 0), named = new Set(Object.keys(options.scopedPresets ?? {}));
|
|
1672
|
+
if (named.has(""))
|
|
1673
|
+
throw Error("A scope needs a nonempty tab or group id.");
|
|
1674
|
+
let v = variantsChoice(), group = v?.field.group, variants = v ? tabOf(v.field) ?? (group !== void 0 && named.has(group) ? group : "") : void 0;
|
|
1675
|
+
if (variants)
|
|
1676
|
+
named.add(variants);
|
|
1677
|
+
let of = /* @__PURE__ */ new Map;
|
|
1678
|
+
for (let k of valueKeys(schema)) {
|
|
1679
|
+
if (pinned().has(k))
|
|
1680
|
+
continue;
|
|
1681
|
+
let f = fields[k], tab = tabOf(f);
|
|
1682
|
+
of.set(k, tab !== void 0 && named.has(tab) ? tab : f.group !== void 0 && named.has(f.group) ? f.group : "");
|
|
1683
|
+
}
|
|
1684
|
+
return scopingOf = { schema, of, named: [...named], variants }, scopingOf;
|
|
1685
|
+
}, within = (values, scope) => {
|
|
1686
|
+
let of = scoping().of, out;
|
|
1687
|
+
for (let k of Object.keys(locked))
|
|
1688
|
+
if (of.get(k) !== scope && !same(values[k], locked[k]))
|
|
1689
|
+
out ??= { ...values }, out[k] = locked[k];
|
|
1690
|
+
return out ? Object.freeze(out) : values;
|
|
1691
|
+
}, unpinned = (values) => within(values, ""), patchIn = (values, scope) => {
|
|
1692
|
+
let of = scoping().of;
|
|
1693
|
+
return Object.fromEntries(Object.entries(values).filter(([k]) => of.get(k) === scope));
|
|
1694
|
+
}, buildPresets = (scope) => {
|
|
1695
|
+
let own = (scope === "" ? options.presets : options.scopedPresets?.[scope]) ?? {}, v = scoping().variants === scope ? variantsChoice() : void 0;
|
|
1696
|
+
if (v && Object.hasOwn(own, v.field.value))
|
|
1697
|
+
throw Error(`The default variant (${v.field.value}) is the schema's defaults; set its values there.`);
|
|
1698
|
+
let ids = [
|
|
1699
|
+
...v ? v.field.options.filter((o) => o !== v.field.value) : [],
|
|
1700
|
+
...Object.keys(own).filter((id) => !v?.field.options.includes(id))
|
|
1701
|
+
];
|
|
1702
|
+
return Object.freeze(Object.fromEntries([
|
|
1703
|
+
["default", locked],
|
|
1704
|
+
...ids.map((id) => {
|
|
1705
|
+
if (id === "default" || id === "custom")
|
|
1706
|
+
throw Error(`Reserved preset id: ${id}`);
|
|
1707
|
+
let variant = v?.field.options.includes(id) ? { [v.key]: id } : {};
|
|
1708
|
+
return [id, within(normalize(schema, { ...locked, ...variant, ...own[id] }), scope)];
|
|
1709
|
+
})
|
|
1710
|
+
]));
|
|
1711
|
+
}, buildScopePresets = () => new Map(scoping().named.map((scope) => [scope, buildPresets(scope)])), presets = buildPresets(""), scopePresets = buildScopePresets(), presetsIn = (scope) => {
|
|
1712
|
+
if (scope === "")
|
|
1713
|
+
return presets;
|
|
1714
|
+
let found = scopePresets.get(scope);
|
|
1715
|
+
if (!found)
|
|
1716
|
+
throw Error(`Unknown preset scope: ${scope}`);
|
|
1717
|
+
return found;
|
|
1718
|
+
}, buildGroupPresets = () => Object.freeze(Object.fromEntries(Object.entries(options.groupPresets ?? {}).map(([group, list]) => {
|
|
1654
1719
|
let named = list.flatMap((p) => Object.keys(p.values).filter((k) => Object.hasOwn(schema, k))), covered = new Set((named.length ? named : Object.keys(schema).filter((k) => schema[k].group === group)).filter((k) => hasValue(schema[k])));
|
|
1655
1720
|
return [
|
|
1656
1721
|
group,
|
|
@@ -1715,22 +1780,54 @@ function defineControls(id, input, options = {}) {
|
|
|
1715
1780
|
function commit(next) {
|
|
1716
1781
|
current = next, persist(), notify();
|
|
1717
1782
|
}
|
|
1718
|
-
let makeBase = (preset, groups) => preset === null && Object.keys(groups).length === 0
|
|
1783
|
+
let makeBase = (preset, groups, scopes = {}) => preset === null && Object.keys(groups).length === 0 && Object.keys(scopes).length === 0 ? NO_BASE : Object.freeze({
|
|
1784
|
+
preset,
|
|
1785
|
+
groups: Object.freeze({ ...groups }),
|
|
1786
|
+
scopes: Object.freeze({ ...scopes })
|
|
1787
|
+
}), withScope = (scopes, scope, ref) => {
|
|
1788
|
+
let { [scope]: _, ...others } = scopes;
|
|
1789
|
+
return ref ? { ...others, [scope]: ref } : others;
|
|
1790
|
+
}, sameRef = (a, b) => a?.kind === b?.kind && a?.id === b?.id, sameBase = (a, b) => a === b || sameRef(a.preset, b.preset) && Object.keys(a.groups).length === Object.keys(b.groups).length && Object.entries(a.groups).every(([g, i]) => b.groups[g] === i) && Object.keys(a.scopes).length === Object.keys(b.scopes).length && Object.entries(a.scopes).every(([s, ref]) => sameRef(ref, b.scopes[s])), seedsScopes = () => scopePresets.size > 0 && Object.keys(options.presets ?? {}).length === 0, groupsOutside = (groups, scope) => {
|
|
1791
|
+
let of = scoping().of;
|
|
1792
|
+
return Object.fromEntries(Object.entries(groups).filter(([g]) => !(groupPresets[g] ?? []).some((p) => Object.keys(p.values).some((k) => of.get(k) === scope))));
|
|
1793
|
+
}, known = (ref, scope) => ref.kind === "variant" || ref.id !== "default" && Object.hasOwn(scopePresets.get(scope) ?? {}, ref.id);
|
|
1719
1794
|
function validBase(b) {
|
|
1720
|
-
let preset = b.preset?.kind === "preset" && !(b.preset.id !== "default" && Object.hasOwn(presets, b.preset.id)) ? null : b.preset, groups = Object.fromEntries(Object.entries(b.groups).filter(([g, i]) => groupPresets[g]?.[i] !== void 0)), next = makeBase(preset, groups);
|
|
1795
|
+
let preset = b.preset?.kind === "preset" && !(b.preset.id !== "default" && Object.hasOwn(presets, b.preset.id)) ? null : b.preset, groups = Object.fromEntries(Object.entries(b.groups).filter(([g, i]) => groupPresets[g]?.[i] !== void 0)), scopes = Object.fromEntries(Object.entries(b.scopes).filter(([s, ref]) => scopePresets.has(s) && known(ref, s))), next = makeBase(preset, groups, scopes);
|
|
1721
1796
|
return sameBase(next, b) ? b : next;
|
|
1722
1797
|
}
|
|
1798
|
+
let readRef = (raw) => raw && typeof raw === "object" && (raw.kind === "preset" || raw.kind === "variant") && typeof raw.id === "string" ? Object.freeze({ kind: raw.kind, id: raw.id }) : null;
|
|
1723
1799
|
function readBase(raw) {
|
|
1724
1800
|
if (!raw || typeof raw !== "object")
|
|
1725
1801
|
return NO_BASE;
|
|
1726
|
-
let { preset, groups } = raw, ref =
|
|
1727
|
-
|
|
1802
|
+
let { preset, groups, scopes } = raw, ref = readRef(preset), byGroup = groups && typeof groups === "object" ? Object.fromEntries(Object.entries(groups).filter((e) => Number.isInteger(e[1]))) : {}, byScope = {};
|
|
1803
|
+
if (scopes && typeof scopes === "object")
|
|
1804
|
+
for (let [s, r] of Object.entries(scopes)) {
|
|
1805
|
+
let found = readRef(r);
|
|
1806
|
+
if (found)
|
|
1807
|
+
byScope[s] = found;
|
|
1808
|
+
}
|
|
1809
|
+
if (ref?.kind === "preset" && !Object.hasOwn(presets, ref.id)) {
|
|
1810
|
+
for (let [s, list] of scopePresets)
|
|
1811
|
+
if (!byScope[s] && ref.id !== "default" && Object.hasOwn(list, ref.id))
|
|
1812
|
+
byScope[s] = ref;
|
|
1813
|
+
ref = null;
|
|
1814
|
+
} else if (ref?.kind === "variant" && seedsScopes()) {
|
|
1815
|
+
let id = ref.id;
|
|
1816
|
+
for (let s of scopePresets.keys())
|
|
1817
|
+
if (!byScope[s] && scopeVariants(s).list().some((v) => v.id === id))
|
|
1818
|
+
byScope[s] = ref;
|
|
1819
|
+
ref = null;
|
|
1820
|
+
}
|
|
1821
|
+
return validBase(makeBase(ref, byGroup, byScope));
|
|
1728
1822
|
}
|
|
1729
1823
|
function activeBase() {
|
|
1730
1824
|
load();
|
|
1731
|
-
let ref = base.preset;
|
|
1732
|
-
|
|
1733
|
-
|
|
1825
|
+
let gone = (ref, list) => ref?.kind === "variant" && !list().some((v) => v.id === ref.id), preset = gone(base.preset, () => variants.list()) ? null : base.preset, scopes = base.scopes;
|
|
1826
|
+
for (let [s, ref] of Object.entries(base.scopes))
|
|
1827
|
+
if (gone(ref, () => scopeVariants(s).list()))
|
|
1828
|
+
scopes = withScope(scopes, s, void 0);
|
|
1829
|
+
if (preset !== base.preset || scopes !== base.scopes)
|
|
1830
|
+
base = makeBase(preset, base.groups, scopes);
|
|
1734
1831
|
return base;
|
|
1735
1832
|
}
|
|
1736
1833
|
let hasBase = () => activeBase() !== NO_BASE, baseCache;
|
|
@@ -1740,17 +1837,23 @@ function defineControls(id, input, options = {}) {
|
|
|
1740
1837
|
let b = activeBase();
|
|
1741
1838
|
if (b === NO_BASE)
|
|
1742
1839
|
return locked;
|
|
1743
|
-
let
|
|
1744
|
-
|
|
1840
|
+
let lists = [
|
|
1841
|
+
b.preset?.kind === "variant" ? variants.list() : null,
|
|
1842
|
+
...Object.entries(b.scopes).map(([s, ref]) => ref.kind === "variant" ? scopeVariants(s).list() : null)
|
|
1843
|
+
], c = baseCache;
|
|
1844
|
+
if (c && c.base === b && c.schema === schema && c.presets === presets && c.scopePresets === scopePresets && c.groupPresets === groupPresets && c.variants.length === lists.length && c.variants.every((l, i) => l === lists[i]))
|
|
1745
1845
|
return c.values;
|
|
1746
|
-
let
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
else if (ref?.kind === "variant") {
|
|
1846
|
+
let valuesOf = (ref, scope, list) => {
|
|
1847
|
+
if (ref.kind === "preset")
|
|
1848
|
+
return presetsIn(scope)[ref.id];
|
|
1750
1849
|
let found = list?.find((v) => v.id === ref.id);
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1850
|
+
return found ? within(normalize(schema, found.values), scope) : void 0;
|
|
1851
|
+
}, out = locked;
|
|
1852
|
+
if (b.preset)
|
|
1853
|
+
out = valuesOf(b.preset, "", lists[0]) ?? locked;
|
|
1854
|
+
let scoped = Object.entries(b.scopes);
|
|
1855
|
+
if (scoped.length)
|
|
1856
|
+
out = { ...out }, scoped.forEach(([s, ref], i) => Object.assign(out, patchIn(valuesOf(ref, s, lists[i + 1]) ?? locked, s)));
|
|
1754
1857
|
let groups = Object.entries(b.groups);
|
|
1755
1858
|
if (groups.length) {
|
|
1756
1859
|
out = { ...out };
|
|
@@ -1758,13 +1861,16 @@ function defineControls(id, input, options = {}) {
|
|
|
1758
1861
|
Object.assign(out, groupPresets[g]?.[i]?.values);
|
|
1759
1862
|
}
|
|
1760
1863
|
let values = Object.freeze(out);
|
|
1761
|
-
return baseCache = { base: b, schema, presets, groupPresets, variants:
|
|
1864
|
+
return baseCache = { base: b, schema, presets, scopePresets, groupPresets, variants: lists, values }, values;
|
|
1762
1865
|
}
|
|
1763
1866
|
let covered = (key) => {
|
|
1764
1867
|
let b = activeBase(), group = schema[key]?.group;
|
|
1765
1868
|
if (group !== void 0 && Object.hasOwn(b.groups, group))
|
|
1766
1869
|
return !0;
|
|
1767
|
-
|
|
1870
|
+
let scope = scoping().of.get(key);
|
|
1871
|
+
if (scope === void 0)
|
|
1872
|
+
return !1;
|
|
1873
|
+
return scope === "" ? b.preset !== null : Object.hasOwn(b.scopes, scope);
|
|
1768
1874
|
};
|
|
1769
1875
|
function declaredShortcut(id) {
|
|
1770
1876
|
let slash = id.indexOf("/"), key = slash < 0 ? id : id.slice(0, slash), field = Object.hasOwn(schema, key) ? schema[key] : void 0;
|
|
@@ -1999,7 +2105,7 @@ function defineControls(id, input, options = {}) {
|
|
|
1999
2105
|
schema = Object.freeze({ ...next });
|
|
2000
2106
|
if (changed) {
|
|
2001
2107
|
let previous = load();
|
|
2002
|
-
schema = Object.freeze({ ...next }), locked = normalize(schema, {}), presets = buildPresets(), groupPresets = buildGroupPresets(), base = validBase(base);
|
|
2108
|
+
schema = Object.freeze({ ...next }), locked = normalize(schema, {}), presets = buildPresets(""), scopePresets = buildScopePresets(), groupPresets = buildGroupPresets(), base = validBase(base);
|
|
2003
2109
|
for (let k of [...locks])
|
|
2004
2110
|
if (!valueField(k))
|
|
2005
2111
|
locks.delete(k);
|
|
@@ -2034,7 +2140,33 @@ function defineControls(id, input, options = {}) {
|
|
|
2034
2140
|
listen(cb) {
|
|
2035
2141
|
return readoutListeners.add(cb), () => readoutListeners.delete(cb);
|
|
2036
2142
|
}
|
|
2037
|
-
}, variants = createVariants(() => schema, id, storageKey(id, "variants"), variantStorage, () => unpinned(get()), (v, variant, coalesce) => write(
|
|
2143
|
+
}, variants = createVariants(() => schema, id, storageKey(id, "variants"), variantStorage, () => unpinned(get()), (v, variant, coalesce) => write(patchIn(v, ""), { source: "variant", coalesce }, makeBase(Object.freeze({ kind: "variant", id: variant }), {}, activeBase().scopes)), notify, enabled), scopeVariantsMade = /* @__PURE__ */ new Map;
|
|
2144
|
+
function scopeVariants(scope) {
|
|
2145
|
+
let made = scopeVariantsMade.get(scope);
|
|
2146
|
+
if (made)
|
|
2147
|
+
return made;
|
|
2148
|
+
return made = createVariants(() => schema, id, storageKey(id, `variants:${scope}`), variantStorage, () => within(get(), scope), (v, variant, coalesce) => {
|
|
2149
|
+
let b = activeBase();
|
|
2150
|
+
write(patchIn(v, scope), { source: "variant", coalesce }, makeBase(b.preset, groupsOutside(b.groups, scope), withScope(b.scopes, scope, Object.freeze({ kind: "variant", id: variant }))));
|
|
2151
|
+
}, notify, enabled, () => !seedsScopes() ? [] : variants.list().flatMap((v) => {
|
|
2152
|
+
let values = within(normalize(schema, v.values), scope);
|
|
2153
|
+
return equal(values, locked) ? [] : [{ ...v, values }];
|
|
2154
|
+
})), scopeVariantsMade.set(scope, made), made;
|
|
2155
|
+
}
|
|
2156
|
+
let scopesOf, scopes = () => {
|
|
2157
|
+
if (scopesOf?.presets === scopePresets)
|
|
2158
|
+
return scopesOf.value;
|
|
2159
|
+
let of = scoping().of, value = Object.freeze(Object.fromEntries([...scopePresets].map(([scope, list]) => [
|
|
2160
|
+
scope,
|
|
2161
|
+
Object.freeze({
|
|
2162
|
+
id: scope,
|
|
2163
|
+
keys: Object.freeze([...of].flatMap(([k, s]) => s === scope ? [k] : [])),
|
|
2164
|
+
presets: list,
|
|
2165
|
+
variants: scopeVariants(scope)
|
|
2166
|
+
})
|
|
2167
|
+
])));
|
|
2168
|
+
return scopesOf = { presets: scopePresets, value }, value;
|
|
2169
|
+
}, resettable = (keys) => (keys ?? fieldKeys()).filter((k) => valueField(k) && !blocked(k));
|
|
2038
2170
|
function offBase(keys) {
|
|
2039
2171
|
if (!hasBase())
|
|
2040
2172
|
return !1;
|
|
@@ -2098,6 +2230,10 @@ function defineControls(id, input, options = {}) {
|
|
|
2098
2230
|
get presets() {
|
|
2099
2231
|
return presets;
|
|
2100
2232
|
},
|
|
2233
|
+
get scopes() {
|
|
2234
|
+
return scopes();
|
|
2235
|
+
},
|
|
2236
|
+
scopeOf: (key) => scoping().of.get(key),
|
|
2101
2237
|
actions,
|
|
2102
2238
|
theme,
|
|
2103
2239
|
appearance,
|
|
@@ -2118,7 +2254,10 @@ function defineControls(id, input, options = {}) {
|
|
|
2118
2254
|
sectionDescription: (section) => options.sectionDescriptions?.[section] ?? fieldLabels().sectionText.get(section),
|
|
2119
2255
|
groupFolded: options.groupFolded,
|
|
2120
2256
|
sectionFolded: options.sectionFolded,
|
|
2121
|
-
presetLabel: (presetId
|
|
2257
|
+
presetLabel: (presetId, scope = "") => {
|
|
2258
|
+
let v = scoping().variants === scope ? variantsChoice() : void 0, option = presetId === "default" ? v?.field.value : presetId;
|
|
2259
|
+
return options.presetLabels?.[presetId] ?? (presetId === "default" ? options.defaultLabel : void 0) ?? (v && option !== void 0 && v.field.options.includes(option) ? v.field.labels?.[option] ?? option : presetId);
|
|
2260
|
+
},
|
|
2122
2261
|
isPinned: (key) => pinned().has(key),
|
|
2123
2262
|
get,
|
|
2124
2263
|
set,
|
|
@@ -2247,7 +2386,7 @@ function defineControls(id, input, options = {}) {
|
|
|
2247
2386
|
options.onPreset?.({ group, index, name: preset.name });
|
|
2248
2387
|
return;
|
|
2249
2388
|
}
|
|
2250
|
-
let { [group]: _, ...others } = b.groups, forget = index === void 0 ? void 0 : makeBase(b.preset, others);
|
|
2389
|
+
let { [group]: _, ...others } = b.groups, forget = index === void 0 ? void 0 : makeBase(b.preset, others, b.scopes);
|
|
2251
2390
|
if (open.length < keys.length)
|
|
2252
2391
|
return toDefaults(open, forget);
|
|
2253
2392
|
let patch = {};
|
|
@@ -2392,13 +2531,15 @@ function defineControls(id, input, options = {}) {
|
|
|
2392
2531
|
comparing = before, options.onChange?.(changes(now, before), before, { source: "compare" }), notify();
|
|
2393
2532
|
},
|
|
2394
2533
|
preset(id, presetOptions) {
|
|
2395
|
-
|
|
2534
|
+
let scope = presetOptions?.scope ?? "", list = presetsIn(scope);
|
|
2535
|
+
if (!Object.hasOwn(list, id))
|
|
2396
2536
|
throw Error(`Unknown preset: ${id}`);
|
|
2397
|
-
|
|
2537
|
+
let b = activeBase(), ref = id === "default" ? void 0 : Object.freeze({ kind: "preset", id });
|
|
2538
|
+
write(patchIn(list[id], scope), { source: "preset", coalesce: presetOptions?.coalesce }, scope === "" ? makeBase(ref ?? null, {}, b.scopes) : makeBase(b.preset, groupsOutside(b.groups, scope), withScope(b.scopes, scope, ref)));
|
|
2398
2539
|
},
|
|
2399
|
-
matchingPreset: () => {
|
|
2400
|
-
let cur =
|
|
2401
|
-
return Object.keys(
|
|
2540
|
+
matchingPreset: (scope = "") => {
|
|
2541
|
+
let list = presetsIn(scope), cur = within(get(), scope);
|
|
2542
|
+
return Object.keys(list).find((id) => equal(cur, list[id])) ?? "custom";
|
|
2402
2543
|
},
|
|
2403
2544
|
get groupPresets() {
|
|
2404
2545
|
return groupPresets;
|
|
@@ -2410,12 +2551,13 @@ function defineControls(id, input, options = {}) {
|
|
|
2410
2551
|
if (!enabled())
|
|
2411
2552
|
return;
|
|
2412
2553
|
let b = activeBase();
|
|
2413
|
-
write(preset.values, { source: "preset", group, coalesce: presetOptions?.coalesce }, makeBase(b.preset, { ...b.groups, [group]: index })), options.onPreset?.({ group, index, name: preset.name });
|
|
2554
|
+
write(preset.values, { source: "preset", group, coalesce: presetOptions?.coalesce }, makeBase(b.preset, { ...b.groups, [group]: index }, b.scopes)), options.onPreset?.({ group, index, name: preset.name });
|
|
2414
2555
|
},
|
|
2415
|
-
activePreset() {
|
|
2556
|
+
activePreset(scope) {
|
|
2416
2557
|
if (!enabled())
|
|
2417
2558
|
return null;
|
|
2418
|
-
|
|
2559
|
+
let b = activeBase();
|
|
2560
|
+
return scope ? b.scopes[scope] ?? null : b.preset;
|
|
2419
2561
|
},
|
|
2420
2562
|
activeGroupPreset(group) {
|
|
2421
2563
|
if (!enabled())
|
|
@@ -2471,7 +2613,7 @@ function descriptorToField(d) {
|
|
|
2471
2613
|
if (readoutDescriptor(d))
|
|
2472
2614
|
return readoutField(d);
|
|
2473
2615
|
if (d.kind === "toolbar")
|
|
2474
|
-
return toolbar(d.items.map(({ key, ...item }) => ({ ...item, id: key })), meta);
|
|
2616
|
+
return toolbar(d.items.map(({ key, ...item }) => ({ ...item, id: key })), d.labels !== void 0 ? { ...meta, labels: d.labels } : meta);
|
|
2475
2617
|
if (d.bind)
|
|
2476
2618
|
return flatSpring({}, { ...meta, id: d.key }).duration;
|
|
2477
2619
|
if (d.kind === "knob" || d.kind === "number") {
|
|
@@ -2546,6 +2688,12 @@ function descriptorToField(d) {
|
|
|
2546
2688
|
});
|
|
2547
2689
|
if (d.kind === "keybind")
|
|
2548
2690
|
return keybind(typeof d.default === "string" ? d.default : "", meta);
|
|
2691
|
+
if (d.kind === "text")
|
|
2692
|
+
return text(typeof d.default === "string" ? d.default : "", {
|
|
2693
|
+
...d.multiline ? { multiline: !0 } : {},
|
|
2694
|
+
...d.placeholder ? { placeholder: d.placeholder } : {},
|
|
2695
|
+
...meta
|
|
2696
|
+
});
|
|
2549
2697
|
if (d.kind === "gradient") {
|
|
2550
2698
|
let fallback = [
|
|
2551
2699
|
{ at: 0, color: "#000000" },
|
|
@@ -2624,7 +2772,7 @@ var decimal = (n) => String(Math.round(n * 1e4) / 1e4), swiftLiteral = (d, v) =>
|
|
|
2624
2772
|
let [a, b] = v;
|
|
2625
2773
|
return `${decimal(a)}...${decimal(b)}`;
|
|
2626
2774
|
}
|
|
2627
|
-
if (d.kind === "keybind")
|
|
2775
|
+
if (d.kind === "keybind" || d.kind === "text")
|
|
2628
2776
|
return JSON.stringify(v);
|
|
2629
2777
|
if (d.kind === "gradient")
|
|
2630
2778
|
return `Gradient(stops: [${(Array.isArray(v) ? v : []).map((s) => {
|
|
@@ -2653,6 +2801,7 @@ var decimal = (n) => String(Math.round(n * 1e4) / 1e4), swiftLiteral = (d, v) =>
|
|
|
2653
2801
|
range: "ClosedRange<Double>",
|
|
2654
2802
|
seed: "Int",
|
|
2655
2803
|
keybind: "String",
|
|
2804
|
+
text: "String",
|
|
2656
2805
|
gradient: "Gradient",
|
|
2657
2806
|
curve: "[CGPoint]"
|
|
2658
2807
|
};
|
|
@@ -2726,6 +2875,7 @@ function createRemoteControls(id, descriptors, options = {}) {
|
|
|
2726
2875
|
tunable: options.tunable,
|
|
2727
2876
|
history: options.history,
|
|
2728
2877
|
presets: options.presets,
|
|
2878
|
+
scopedPresets: options.scopedPresets,
|
|
2729
2879
|
pinned: options.pinned,
|
|
2730
2880
|
groupPresets: options.groupPresets,
|
|
2731
2881
|
onPreset: options.onPreset,
|
|
@@ -2862,6 +3012,7 @@ export {
|
|
|
2862
3012
|
springCss,
|
|
2863
3013
|
springMotion,
|
|
2864
3014
|
table,
|
|
3015
|
+
text,
|
|
2865
3016
|
toggle,
|
|
2866
3017
|
toolbar,
|
|
2867
3018
|
toolbarShortcut,
|