@kitlangton/knobs 0.4.0-next.12 → 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/dist/dev/index.js CHANGED
@@ -481,7 +481,7 @@ function unlock(options) {
481
481
  }
482
482
 
483
483
  // src/core/variants.ts
484
- function createVariants(schema, id, key, storage, get, set, notify, enabled) {
484
+ function createVariants(schema, id, key, storage, get, set, notify, enabled, seed) {
485
485
  let ready = !1, list = Object.freeze([]);
486
486
  function parse(json) {
487
487
  let data = JSON.parse(json);
@@ -510,7 +510,7 @@ function createVariants(schema, id, key, storage, get, set, notify, enabled) {
510
510
  if (ready || !enabled())
511
511
  return;
512
512
  let json = storage()?.getItem(key);
513
- list = json ? parse(json) : Object.freeze([]), ready = !0;
513
+ list = json ? parse(json) : Object.freeze([...seed?.() ?? []]), ready = !0;
514
514
  }
515
515
  function persist(next) {
516
516
  if (!enabled())
@@ -597,26 +597,46 @@ function defineControls(id, input, options = {}) {
597
597
  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 = () => 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 = () => {
598
598
  for (let cb of [...listeners])
599
599
  cb();
600
- }, 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({ preset: null, groups: Object.freeze({}) }), base = NO_BASE, past = [], future = [], HISTORY = 100, stateKey = storageKey(id, "state"), pinnedOf, pinned = () => {
600
+ }, 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({
601
+ preset: null,
602
+ groups: Object.freeze({}),
603
+ scopes: Object.freeze({})
604
+ }), base = NO_BASE, past = [], future = [], HISTORY = 100, stateKey = storageKey(id, "state"), pinnedOf, pinned = () => {
601
605
  if (pinnedOf?.schema !== schema)
602
606
  pinnedOf = { schema, keys: pinnedKeys(schema, options.pinned) };
603
607
  return pinnedOf.keys;
604
- }, variantsChoice = () => variantsOf(schema, (key) => pinned().has(key)), unpinned = (values) => {
605
- let keys = pinned();
606
- if (keys.size === 0)
607
- return values;
608
- let out = { ...values };
609
- for (let k of keys)
610
- if (Object.hasOwn(locked, k))
611
- out[k] = locked[k];
612
- return Object.freeze(out);
613
- }, presetPatch = (values) => {
614
- let keys = pinned();
615
- if (keys.size === 0)
616
- return values;
617
- return Object.fromEntries(Object.entries(values).filter(([k]) => !keys.has(k)));
618
- }, buildPresets = () => {
619
- let own = options.presets ?? {}, v = variantsChoice();
608
+ }, variantsChoice = () => variantsOf(schema, (key) => pinned().has(key)), scopingOf, scoping = () => {
609
+ if (scopingOf?.schema === schema)
610
+ return scopingOf;
611
+ let fields = schema, groupTab = /* @__PURE__ */ new Map;
612
+ for (let f of Object.values(fields))
613
+ if (f.group !== void 0 && f.tab !== void 0 && !groupTab.has(f.group))
614
+ groupTab.set(f.group, f.tab);
615
+ let tabOf = (f) => f.tab ?? (f.group !== void 0 ? groupTab.get(f.group) : void 0), named = new Set(Object.keys(options.scopedPresets ?? {}));
616
+ if (named.has(""))
617
+ throw Error("A scope needs a nonempty tab or group id.");
618
+ let v = variantsChoice(), group = v?.field.group, variants = v ? tabOf(v.field) ?? (group !== void 0 && named.has(group) ? group : "") : void 0;
619
+ if (variants)
620
+ named.add(variants);
621
+ let of = /* @__PURE__ */ new Map;
622
+ for (let k of valueKeys(schema)) {
623
+ if (pinned().has(k))
624
+ continue;
625
+ let f = fields[k], tab = tabOf(f);
626
+ of.set(k, tab !== void 0 && named.has(tab) ? tab : f.group !== void 0 && named.has(f.group) ? f.group : "");
627
+ }
628
+ return scopingOf = { schema, of, named: [...named], variants }, scopingOf;
629
+ }, within = (values, scope) => {
630
+ let of = scoping().of, out;
631
+ for (let k of Object.keys(locked))
632
+ if (of.get(k) !== scope && !same(values[k], locked[k]))
633
+ out ??= { ...values }, out[k] = locked[k];
634
+ return out ? Object.freeze(out) : values;
635
+ }, unpinned = (values) => within(values, ""), patchIn = (values, scope) => {
636
+ let of = scoping().of;
637
+ return Object.fromEntries(Object.entries(values).filter(([k]) => of.get(k) === scope));
638
+ }, buildPresets = (scope) => {
639
+ let own = (scope === "" ? options.presets : options.scopedPresets?.[scope]) ?? {}, v = scoping().variants === scope ? variantsChoice() : void 0;
620
640
  if (v && Object.hasOwn(own, v.field.value))
621
641
  throw Error(`The default variant (${v.field.value}) is the schema's defaults; set its values there.`);
622
642
  let ids = [
@@ -629,10 +649,17 @@ function defineControls(id, input, options = {}) {
629
649
  if (id === "default" || id === "custom")
630
650
  throw Error(`Reserved preset id: ${id}`);
631
651
  let variant = v?.field.options.includes(id) ? { [v.key]: id } : {};
632
- return [id, unpinned(normalize(schema, { ...locked, ...variant, ...own[id] }))];
652
+ return [id, within(normalize(schema, { ...locked, ...variant, ...own[id] }), scope)];
633
653
  })
634
654
  ]));
635
- }, presets = buildPresets(), buildGroupPresets = () => Object.freeze(Object.fromEntries(Object.entries(options.groupPresets ?? {}).map(([group, list]) => {
655
+ }, buildScopePresets = () => new Map(scoping().named.map((scope) => [scope, buildPresets(scope)])), presets = buildPresets(""), scopePresets = buildScopePresets(), presetsIn = (scope) => {
656
+ if (scope === "")
657
+ return presets;
658
+ let found = scopePresets.get(scope);
659
+ if (!found)
660
+ throw Error(`Unknown preset scope: ${scope}`);
661
+ return found;
662
+ }, buildGroupPresets = () => Object.freeze(Object.fromEntries(Object.entries(options.groupPresets ?? {}).map(([group, list]) => {
636
663
  let named = list.flatMap((p) => Object.keys(p.values).filter((k) => Object.hasOwn(schema, k))), covered = new Set((named.length ? named : Object.keys(schema).filter((k) => schema[k].group === group)).filter((k) => hasValue2(schema[k])));
637
664
  return [
638
665
  group,
@@ -697,22 +724,54 @@ function defineControls(id, input, options = {}) {
697
724
  function commit(next) {
698
725
  current = next, persist(), notify();
699
726
  }
700
- let makeBase = (preset, groups) => preset === null && Object.keys(groups).length === 0 ? NO_BASE : Object.freeze({ preset, groups: Object.freeze({ ...groups }) }), sameBase = (a, b) => a === b || a.preset?.kind === b.preset?.kind && a.preset?.id === b.preset?.id && Object.keys(a.groups).length === Object.keys(b.groups).length && Object.entries(a.groups).every(([g, i]) => b.groups[g] === i);
727
+ let makeBase = (preset, groups, scopes = {}) => preset === null && Object.keys(groups).length === 0 && Object.keys(scopes).length === 0 ? NO_BASE : Object.freeze({
728
+ preset,
729
+ groups: Object.freeze({ ...groups }),
730
+ scopes: Object.freeze({ ...scopes })
731
+ }), withScope = (scopes, scope, ref) => {
732
+ let { [scope]: _, ...others } = scopes;
733
+ return ref ? { ...others, [scope]: ref } : others;
734
+ }, 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) => {
735
+ let of = scoping().of;
736
+ return Object.fromEntries(Object.entries(groups).filter(([g]) => !(groupPresets[g] ?? []).some((p) => Object.keys(p.values).some((k) => of.get(k) === scope))));
737
+ }, known = (ref, scope) => ref.kind === "variant" || ref.id !== "default" && Object.hasOwn(scopePresets.get(scope) ?? {}, ref.id);
701
738
  function validBase(b) {
702
- 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);
739
+ 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);
703
740
  return sameBase(next, b) ? b : next;
704
741
  }
742
+ 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;
705
743
  function readBase(raw) {
706
744
  if (!raw || typeof raw !== "object")
707
745
  return NO_BASE;
708
- let { preset, groups } = raw, ref = preset && typeof preset === "object" && (preset.kind === "preset" || preset.kind === "variant") && typeof preset.id === "string" ? Object.freeze({ kind: preset.kind, id: preset.id }) : null, byGroup = groups && typeof groups === "object" ? Object.fromEntries(Object.entries(groups).filter((e) => Number.isInteger(e[1]))) : {};
709
- return validBase(makeBase(ref, byGroup));
746
+ 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 = {};
747
+ if (scopes && typeof scopes === "object")
748
+ for (let [s, r] of Object.entries(scopes)) {
749
+ let found = readRef(r);
750
+ if (found)
751
+ byScope[s] = found;
752
+ }
753
+ if (ref?.kind === "preset" && !Object.hasOwn(presets, ref.id)) {
754
+ for (let [s, list] of scopePresets)
755
+ if (!byScope[s] && ref.id !== "default" && Object.hasOwn(list, ref.id))
756
+ byScope[s] = ref;
757
+ ref = null;
758
+ } else if (ref?.kind === "variant" && seedsScopes()) {
759
+ let id = ref.id;
760
+ for (let s of scopePresets.keys())
761
+ if (!byScope[s] && scopeVariants(s).list().some((v) => v.id === id))
762
+ byScope[s] = ref;
763
+ ref = null;
764
+ }
765
+ return validBase(makeBase(ref, byGroup, byScope));
710
766
  }
711
767
  function activeBase() {
712
768
  load();
713
- let ref = base.preset;
714
- if (ref?.kind === "variant" && !variants.list().some((v) => v.id === ref.id))
715
- base = makeBase(null, base.groups);
769
+ 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;
770
+ for (let [s, ref] of Object.entries(base.scopes))
771
+ if (gone(ref, () => scopeVariants(s).list()))
772
+ scopes = withScope(scopes, s, void 0);
773
+ if (preset !== base.preset || scopes !== base.scopes)
774
+ base = makeBase(preset, base.groups, scopes);
716
775
  return base;
717
776
  }
718
777
  let hasBase = () => activeBase() !== NO_BASE, baseCache;
@@ -722,17 +781,23 @@ function defineControls(id, input, options = {}) {
722
781
  let b = activeBase();
723
782
  if (b === NO_BASE)
724
783
  return locked;
725
- let list = b.preset?.kind === "variant" ? variants.list() : null, c = baseCache;
726
- if (c && c.base === b && c.schema === schema && c.presets === presets && c.groupPresets === groupPresets && c.variants === list)
784
+ let lists = [
785
+ b.preset?.kind === "variant" ? variants.list() : null,
786
+ ...Object.entries(b.scopes).map(([s, ref]) => ref.kind === "variant" ? scopeVariants(s).list() : null)
787
+ ], c = baseCache;
788
+ 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]))
727
789
  return c.values;
728
- let out = locked, ref = b.preset;
729
- if (ref?.kind === "preset" && Object.hasOwn(presets, ref.id))
730
- out = presets[ref.id];
731
- else if (ref?.kind === "variant") {
790
+ let valuesOf = (ref, scope, list) => {
791
+ if (ref.kind === "preset")
792
+ return presetsIn(scope)[ref.id];
732
793
  let found = list?.find((v) => v.id === ref.id);
733
- if (found)
734
- out = unpinned(normalize(schema, found.values));
735
- }
794
+ return found ? within(normalize(schema, found.values), scope) : void 0;
795
+ }, out = locked;
796
+ if (b.preset)
797
+ out = valuesOf(b.preset, "", lists[0]) ?? locked;
798
+ let scoped = Object.entries(b.scopes);
799
+ if (scoped.length)
800
+ out = { ...out }, scoped.forEach(([s, ref], i) => Object.assign(out, patchIn(valuesOf(ref, s, lists[i + 1]) ?? locked, s)));
736
801
  let groups = Object.entries(b.groups);
737
802
  if (groups.length) {
738
803
  out = { ...out };
@@ -740,13 +805,16 @@ function defineControls(id, input, options = {}) {
740
805
  Object.assign(out, groupPresets[g]?.[i]?.values);
741
806
  }
742
807
  let values = Object.freeze(out);
743
- return baseCache = { base: b, schema, presets, groupPresets, variants: list, values }, values;
808
+ return baseCache = { base: b, schema, presets, scopePresets, groupPresets, variants: lists, values }, values;
744
809
  }
745
810
  let covered = (key) => {
746
811
  let b = activeBase(), group = schema[key]?.group;
747
812
  if (group !== void 0 && Object.hasOwn(b.groups, group))
748
813
  return !0;
749
- return b.preset !== null && !pinned().has(key);
814
+ let scope = scoping().of.get(key);
815
+ if (scope === void 0)
816
+ return !1;
817
+ return scope === "" ? b.preset !== null : Object.hasOwn(b.scopes, scope);
750
818
  };
751
819
  function declaredShortcut(id) {
752
820
  let slash = id.indexOf("/"), key = slash < 0 ? id : id.slice(0, slash), field = Object.hasOwn(schema, key) ? schema[key] : void 0;
@@ -981,7 +1049,7 @@ function defineControls(id, input, options = {}) {
981
1049
  schema = Object.freeze({ ...next });
982
1050
  if (changed) {
983
1051
  let previous = load();
984
- schema = Object.freeze({ ...next }), locked = normalize(schema, {}), presets = buildPresets(), groupPresets = buildGroupPresets(), base = validBase(base);
1052
+ schema = Object.freeze({ ...next }), locked = normalize(schema, {}), presets = buildPresets(""), scopePresets = buildScopePresets(), groupPresets = buildGroupPresets(), base = validBase(base);
985
1053
  for (let k of [...locks])
986
1054
  if (!valueField(k))
987
1055
  locks.delete(k);
@@ -1016,7 +1084,33 @@ function defineControls(id, input, options = {}) {
1016
1084
  listen(cb) {
1017
1085
  return readoutListeners.add(cb), () => readoutListeners.delete(cb);
1018
1086
  }
1019
- }, variants = createVariants(() => schema, id, storageKey(id, "variants"), variantStorage, () => unpinned(get()), (v, variant, coalesce) => write(presetPatch(v), { source: "variant", coalesce }, makeBase(Object.freeze({ kind: "variant", id: variant }), {})), notify, enabled), resettable = (keys) => (keys ?? fieldKeys()).filter((k) => valueField(k) && !blocked(k));
1087
+ }, 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;
1088
+ function scopeVariants(scope) {
1089
+ let made = scopeVariantsMade.get(scope);
1090
+ if (made)
1091
+ return made;
1092
+ return made = createVariants(() => schema, id, storageKey(id, `variants:${scope}`), variantStorage, () => within(get(), scope), (v, variant, coalesce) => {
1093
+ let b = activeBase();
1094
+ write(patchIn(v, scope), { source: "variant", coalesce }, makeBase(b.preset, groupsOutside(b.groups, scope), withScope(b.scopes, scope, Object.freeze({ kind: "variant", id: variant }))));
1095
+ }, notify, enabled, () => !seedsScopes() ? [] : variants.list().flatMap((v) => {
1096
+ let values = within(normalize(schema, v.values), scope);
1097
+ return equal(values, locked) ? [] : [{ ...v, values }];
1098
+ })), scopeVariantsMade.set(scope, made), made;
1099
+ }
1100
+ let scopesOf, scopes = () => {
1101
+ if (scopesOf?.presets === scopePresets)
1102
+ return scopesOf.value;
1103
+ let of = scoping().of, value = Object.freeze(Object.fromEntries([...scopePresets].map(([scope, list]) => [
1104
+ scope,
1105
+ Object.freeze({
1106
+ id: scope,
1107
+ keys: Object.freeze([...of].flatMap(([k, s]) => s === scope ? [k] : [])),
1108
+ presets: list,
1109
+ variants: scopeVariants(scope)
1110
+ })
1111
+ ])));
1112
+ return scopesOf = { presets: scopePresets, value }, value;
1113
+ }, resettable = (keys) => (keys ?? fieldKeys()).filter((k) => valueField(k) && !blocked(k));
1020
1114
  function offBase(keys) {
1021
1115
  if (!hasBase())
1022
1116
  return !1;
@@ -1080,6 +1174,10 @@ function defineControls(id, input, options = {}) {
1080
1174
  get presets() {
1081
1175
  return presets;
1082
1176
  },
1177
+ get scopes() {
1178
+ return scopes();
1179
+ },
1180
+ scopeOf: (key) => scoping().of.get(key),
1083
1181
  actions,
1084
1182
  theme,
1085
1183
  appearance,
@@ -1100,8 +1198,8 @@ function defineControls(id, input, options = {}) {
1100
1198
  sectionDescription: (section) => options.sectionDescriptions?.[section] ?? fieldLabels().sectionText.get(section),
1101
1199
  groupFolded: options.groupFolded,
1102
1200
  sectionFolded: options.sectionFolded,
1103
- presetLabel: (presetId) => {
1104
- let v = variantsChoice(), option = presetId === "default" ? v?.field.value : presetId;
1201
+ presetLabel: (presetId, scope = "") => {
1202
+ let v = scoping().variants === scope ? variantsChoice() : void 0, option = presetId === "default" ? v?.field.value : presetId;
1105
1203
  return options.presetLabels?.[presetId] ?? (presetId === "default" ? options.defaultLabel : void 0) ?? (v && option !== void 0 && v.field.options.includes(option) ? v.field.labels?.[option] ?? option : presetId);
1106
1204
  },
1107
1205
  isPinned: (key) => pinned().has(key),
@@ -1232,7 +1330,7 @@ function defineControls(id, input, options = {}) {
1232
1330
  options.onPreset?.({ group, index, name: preset.name });
1233
1331
  return;
1234
1332
  }
1235
- let { [group]: _, ...others } = b.groups, forget = index === void 0 ? void 0 : makeBase(b.preset, others);
1333
+ let { [group]: _, ...others } = b.groups, forget = index === void 0 ? void 0 : makeBase(b.preset, others, b.scopes);
1236
1334
  if (open.length < keys.length)
1237
1335
  return toDefaults(open, forget);
1238
1336
  let patch = {};
@@ -1377,13 +1475,15 @@ function defineControls(id, input, options = {}) {
1377
1475
  comparing = before, options.onChange?.(changes(now, before), before, { source: "compare" }), notify();
1378
1476
  },
1379
1477
  preset(id, presetOptions) {
1380
- if (!Object.hasOwn(presets, id))
1478
+ let scope = presetOptions?.scope ?? "", list = presetsIn(scope);
1479
+ if (!Object.hasOwn(list, id))
1381
1480
  throw Error(`Unknown preset: ${id}`);
1382
- write(presetPatch(presets[id]), { source: "preset", coalesce: presetOptions?.coalesce }, id === "default" ? NO_BASE : makeBase(Object.freeze({ kind: "preset", id }), {}));
1481
+ let b = activeBase(), ref = id === "default" ? void 0 : Object.freeze({ kind: "preset", id });
1482
+ 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)));
1383
1483
  },
1384
- matchingPreset: () => {
1385
- let cur = unpinned(get());
1386
- return Object.keys(presets).find((id) => equal(cur, presets[id])) ?? "custom";
1484
+ matchingPreset: (scope = "") => {
1485
+ let list = presetsIn(scope), cur = within(get(), scope);
1486
+ return Object.keys(list).find((id) => equal(cur, list[id])) ?? "custom";
1387
1487
  },
1388
1488
  get groupPresets() {
1389
1489
  return groupPresets;
@@ -1395,12 +1495,13 @@ function defineControls(id, input, options = {}) {
1395
1495
  if (!enabled())
1396
1496
  return;
1397
1497
  let b = activeBase();
1398
- write(preset.values, { source: "preset", group, coalesce: presetOptions?.coalesce }, makeBase(b.preset, { ...b.groups, [group]: index })), options.onPreset?.({ group, index, name: preset.name });
1498
+ 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 });
1399
1499
  },
1400
- activePreset() {
1500
+ activePreset(scope) {
1401
1501
  if (!enabled())
1402
1502
  return null;
1403
- return activeBase().preset;
1503
+ let b = activeBase();
1504
+ return scope ? b.scopes[scope] ?? null : b.preset;
1404
1505
  },
1405
1506
  activeGroupPreset(group) {
1406
1507
  if (!enabled())
@@ -1415,11 +1516,11 @@ function defineControls(id, input, options = {}) {
1415
1516
  code: (format, values) => formatCode(values ?? get(), format),
1416
1517
  variants,
1417
1518
  attach(element, chip) {
1418
- let load = options.ship ? () => options.ship().then((m) => m.attach) : () => import("./chunk-ab7vfghg.js").then((m) => m.attach);
1519
+ let load = options.ship ? () => options.ship().then((m) => m.attach) : () => import("./chunk-44r02asc.js").then((m) => m.attach);
1419
1520
  return live(load, (attach) => attach(controls, element, chip), (detach) => detach());
1420
1521
  },
1421
1522
  mount(container, mountOptions) {
1422
- let load = options.ship ? () => options.ship().then((m) => m.mountPanel) : () => import("./chunk-9qtvxa6k.js").then((m) => m.mountPanel);
1523
+ let load = options.ship ? () => options.ship().then((m) => m.mountPanel) : () => import("./chunk-mbhy4jg5.js").then((m) => m.mountPanel);
1423
1524
  return live(load, (mountPanel) => {
1424
1525
  let panel = mountPanel(controls, container, mountOptions);
1425
1526
  return mountOptions?.onReady?.(panel), panel;
@@ -1718,6 +1819,7 @@ function createRemoteControls(id, descriptors, options = {}) {
1718
1819
  tunable: options.tunable,
1719
1820
  history: options.history,
1720
1821
  presets: options.presets,
1822
+ scopedPresets: options.scopedPresets,
1721
1823
  pinned: options.pinned,
1722
1824
  groupPresets: options.groupPresets,
1723
1825
  onPreset: options.onPreset,