tweakit 0.6.0 → 0.7.0

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.
Files changed (132) hide show
  1. package/AGENTS.md +5 -5
  2. package/README.md +3 -3
  3. package/dist/tweaks/auto.js +1 -1
  4. package/dist/tweaks/auto.js.map +1 -1
  5. package/dist/tweaks/bezier-S2BOXQBM.js +2 -0
  6. package/dist/tweaks/bezier-S2BOXQBM.js.map +6 -0
  7. package/dist/tweaks/chunk-3MZAAMC2.js +2 -0
  8. package/dist/tweaks/chunk-3MZAAMC2.js.map +6 -0
  9. package/dist/tweaks/chunk-ETB35KFV.js +2 -0
  10. package/dist/tweaks/chunk-ETB35KFV.js.map +6 -0
  11. package/dist/tweaks/chunk-YB5GKWZI.js +2 -0
  12. package/dist/tweaks/chunk-YB5GKWZI.js.map +6 -0
  13. package/dist/tweaks/clip-A3VI53BK.js +2 -0
  14. package/dist/tweaks/clip-A3VI53BK.js.map +6 -0
  15. package/dist/tweaks/color-UGYMAF3W.js +2 -0
  16. package/dist/tweaks/core.js +1 -1
  17. package/dist/tweaks/core.js.map +3 -3
  18. package/dist/tweaks/fold-GY47HIQA.js +2 -0
  19. package/dist/tweaks/fold-GY47HIQA.js.map +6 -0
  20. package/dist/tweaks/gradient-BTX25WSH.js +2 -0
  21. package/dist/tweaks/gradient-BTX25WSH.js.map +6 -0
  22. package/dist/tweaks/{heavy-CLD7UAVI.js → heavy-NPFIGHRM.js} +2 -2
  23. package/dist/tweaks/image-HTQQ4WX6.js +4 -0
  24. package/dist/tweaks/image-HTQQ4WX6.js.map +6 -0
  25. package/dist/tweaks/{image-store-WRKY2NPU.js → image-store-QD5SMZXG.js} +1 -1
  26. package/dist/tweaks/image-store-QD5SMZXG.js.map +6 -0
  27. package/dist/tweaks/interval-BHPI4LRN.js +2 -0
  28. package/dist/tweaks/interval-BHPI4LRN.js.map +6 -0
  29. package/dist/tweaks/markup-QM53TQJZ.js +2 -0
  30. package/dist/tweaks/markup-QM53TQJZ.js.map +6 -0
  31. package/dist/tweaks/monitor-722WIYGW.js +3 -0
  32. package/dist/tweaks/monitor-722WIYGW.js.map +6 -0
  33. package/dist/tweaks/motion-HMCZK6HJ.js +2 -0
  34. package/dist/tweaks/motion-HMCZK6HJ.js.map +6 -0
  35. package/dist/tweaks/plot-D3NQ6XNN.js +3 -0
  36. package/dist/tweaks/plot-D3NQ6XNN.js.map +6 -0
  37. package/dist/tweaks/point-XDXKMDXH.js +2 -0
  38. package/dist/tweaks/point-XDXKMDXH.js.map +6 -0
  39. package/dist/tweaks/presets-EUWNSCUW.js +2 -0
  40. package/dist/tweaks/presets-EUWNSCUW.js.map +6 -0
  41. package/dist/tweaks/shadow-AM7VSRNS.js +2 -0
  42. package/dist/tweaks/shadow-AM7VSRNS.js.map +6 -0
  43. package/dist/tweaks/shadow-root-RYUV3AGS.js +3 -0
  44. package/dist/tweaks/shadow-root-RYUV3AGS.js.map +6 -0
  45. package/dist/tweaks/sides-JWIURDA4.js +2 -0
  46. package/dist/tweaks/sides-JWIURDA4.js.map +6 -0
  47. package/dist/tweaks/spring-BF5GBTPM.js +2 -0
  48. package/dist/tweaks/spring-BF5GBTPM.js.map +6 -0
  49. package/dist/tweaks/tabs-PRVUUZXZ.js +2 -0
  50. package/dist/tweaks/tabs-PRVUUZXZ.js.map +6 -0
  51. package/dist/tweaks.css +1 -1
  52. package/dist/tweaks.js +5 -4
  53. package/dist/tweaks.js.map +3 -3
  54. package/dist/types/tweaks/enhance.d.ts +3 -2
  55. package/dist/types/tweaks/types.d.ts +278 -72
  56. package/package.json +5 -2
  57. package/src/tweaks/auto.ts +9 -5
  58. package/src/tweaks/clip.ts +84 -22
  59. package/src/tweaks/controls/basic.ts +463 -139
  60. package/src/tweaks/controls/bezier.ts +152 -47
  61. package/src/tweaks/controls/color.ts +610 -161
  62. package/src/tweaks/controls/gradient.ts +256 -77
  63. package/src/tweaks/controls/image.ts +388 -132
  64. package/src/tweaks/controls/interval.ts +126 -41
  65. package/src/tweaks/controls/monitor.ts +142 -36
  66. package/src/tweaks/controls/motion.ts +231 -56
  67. package/src/tweaks/controls/plot.ts +321 -101
  68. package/src/tweaks/controls/point.ts +134 -45
  69. package/src/tweaks/controls/shadow.ts +103 -30
  70. package/src/tweaks/controls/sides.ts +150 -40
  71. package/src/tweaks/controls/spring.ts +220 -60
  72. package/src/tweaks/controls/tabs.ts +39 -18
  73. package/src/tweaks/core.ts +1 -1
  74. package/src/tweaks/easing.ts +45 -20
  75. package/src/tweaks/enhance.ts +21 -6
  76. package/src/tweaks/feedback.ts +133 -34
  77. package/src/tweaks/fold.ts +22 -10
  78. package/src/tweaks/heavy.ts +461 -137
  79. package/src/tweaks/icons.ts +12 -5
  80. package/src/tweaks/image-store.ts +131 -43
  81. package/src/tweaks/lazy.ts +36 -19
  82. package/src/tweaks/markup.ts +255 -92
  83. package/src/tweaks/panel.ts +1262 -438
  84. package/src/tweaks/presets.ts +85 -0
  85. package/src/tweaks/schema.ts +213 -51
  86. package/src/tweaks/shadow-root.ts +178 -0
  87. package/src/tweaks/shared.ts +802 -190
  88. package/src/tweaks/standalone.ts +120 -30
  89. package/src/tweaks/types.ts +644 -143
  90. package/src/tweaks/undo.ts +104 -0
  91. package/src/tweaks.css +556 -550
  92. package/src/wide-gamut.ts +473 -125
  93. package/dist/tweaks/bezier-JFEZMCLP.js +0 -2
  94. package/dist/tweaks/bezier-JFEZMCLP.js.map +0 -6
  95. package/dist/tweaks/chunk-6UO4DHBN.js +0 -2
  96. package/dist/tweaks/chunk-6UO4DHBN.js.map +0 -6
  97. package/dist/tweaks/chunk-DIQMLBAS.js +0 -2
  98. package/dist/tweaks/chunk-DIQMLBAS.js.map +0 -6
  99. package/dist/tweaks/chunk-XE6OUJBG.js +0 -2
  100. package/dist/tweaks/chunk-XE6OUJBG.js.map +0 -6
  101. package/dist/tweaks/clip-WW7JYO4X.js +0 -2
  102. package/dist/tweaks/clip-WW7JYO4X.js.map +0 -6
  103. package/dist/tweaks/color-YMMFURP6.js +0 -2
  104. package/dist/tweaks/fold-U6YRZLCJ.js +0 -2
  105. package/dist/tweaks/fold-U6YRZLCJ.js.map +0 -6
  106. package/dist/tweaks/gradient-JER7PW4D.js +0 -2
  107. package/dist/tweaks/gradient-JER7PW4D.js.map +0 -6
  108. package/dist/tweaks/image-H6QSLGO3.js +0 -4
  109. package/dist/tweaks/image-H6QSLGO3.js.map +0 -6
  110. package/dist/tweaks/image-store-WRKY2NPU.js.map +0 -6
  111. package/dist/tweaks/interval-TEUHQGZN.js +0 -2
  112. package/dist/tweaks/interval-TEUHQGZN.js.map +0 -6
  113. package/dist/tweaks/markup-NIBJD6E2.js +0 -2
  114. package/dist/tweaks/markup-NIBJD6E2.js.map +0 -6
  115. package/dist/tweaks/monitor-3BY7YCGX.js +0 -3
  116. package/dist/tweaks/monitor-3BY7YCGX.js.map +0 -6
  117. package/dist/tweaks/motion-FQPUBKKM.js +0 -2
  118. package/dist/tweaks/motion-FQPUBKKM.js.map +0 -6
  119. package/dist/tweaks/plot-2HBNBZSG.js +0 -3
  120. package/dist/tweaks/plot-2HBNBZSG.js.map +0 -6
  121. package/dist/tweaks/point-VV6XV3I6.js +0 -2
  122. package/dist/tweaks/point-VV6XV3I6.js.map +0 -6
  123. package/dist/tweaks/shadow-5E4E55I2.js +0 -2
  124. package/dist/tweaks/shadow-5E4E55I2.js.map +0 -6
  125. package/dist/tweaks/sides-P3STEVYY.js +0 -2
  126. package/dist/tweaks/sides-P3STEVYY.js.map +0 -6
  127. package/dist/tweaks/spring-HUVSXNVN.js +0 -2
  128. package/dist/tweaks/spring-HUVSXNVN.js.map +0 -6
  129. package/dist/tweaks/tabs-76FW7LQ7.js +0 -2
  130. package/dist/tweaks/tabs-76FW7LQ7.js.map +0 -6
  131. /package/dist/tweaks/{color-YMMFURP6.js.map → color-UGYMAF3W.js.map} +0 -0
  132. /package/dist/tweaks/{heavy-CLD7UAVI.js.map → heavy-NPFIGHRM.js.map} +0 -0
@@ -1,89 +1,179 @@
1
1
  /* Standalone controls — the kit's controls without the panel: mountControl() builds one control
2
2
  * into a host of your own, createColorPicker() hands out the color editor surface alone. */
3
- import { el, getControl, onReady, setDisabled, valueChanged } from "./shared.js";
3
+ import { el, getControl, onReady, setDisabled, valueChanged, isolate, using } from "./shared.js";
4
4
  import { metaFor, VALUELESS } from "./schema.js";
5
5
  import { ensureForMetas } from "./lazy.js";
6
6
  import { createControl } from "./controls/basic.js";
7
7
  import { addHintMarker } from "./feedback.js";
8
- import type { SchemaValue, HeldValue, KnownType, MountOptions, MountedControl, ColorPickerOptions, ColorPicker, ColorMode, Control , Get } from "./types.js";
8
+ import type {
9
+ SchemaValue,
10
+ HeldValue,
11
+ KnownType,
12
+ MountOptions,
13
+ MountedControl,
14
+ ColorPickerOptions,
15
+ ColorPicker,
16
+ ColorMode,
17
+ Control,
18
+ Get,
19
+ } from "./types.js";
9
20
  import type { Meta } from "./schema.js";
10
21
  import type { PickerBody, PickerOptions } from "./controls/color.js";
11
22
 
12
- // Outside a .tw-panel the cascade delivers none of the kit's tokens, so the wrapper carries .tw-portal.
13
- const scope = (cls: string) => el("div", `${cls} tw-standalone tw-portal`);
14
- // Run `build` once the lazy module has landed (synchronously when none is missing); the handled fork keeps a failed chunk out of the unhandled-rejection channel.
23
+ // Outside a .twk-panel the cascade delivers none of the kit's tokens, so the wrapper carries .twk-portal.
24
+ const scope = (cls: string) => el("div", `${cls} twk-standalone twk-portal`);
25
+ // Run `build` once the lazy module has landed (synchronously when none is missing); the handled fork keeps a failed
26
+ // chunk out of the unhandled-rejection channel.
15
27
  const whenLoaded = <H>(metas: Array<Pick<Meta, "type">>, build: () => void, handle: H): Promise<H> => {
16
28
  const pend = ensureForMetas(metas);
17
- if (!pend) { build(); return Promise.resolve(handle); }
29
+ if (!pend) {
30
+ build();
31
+ return Promise.resolve(handle);
32
+ }
18
33
  const ready = pend.then(build).then(() => handle);
19
34
  ready.catch(() => {});
20
35
  return ready;
21
36
  };
22
37
 
23
38
  /** One control from a schema value, into `host`; a folder or tabs set is tweaks()'s to build. */
24
- export function mountControl<const V extends HeldValue>(host: Element, value: V & KnownType<V>, opts?: MountOptions): MountedControl;
39
+ export function mountControl<const V extends HeldValue>(
40
+ host: Element,
41
+ value: V & KnownType<V>,
42
+ opts?: MountOptions,
43
+ ): MountedControl;
25
44
  export function mountControl(host: Element, value: SchemaValue, opts: MountOptions = {}): MountedControl {
26
45
  const key = opts.key ?? "value";
27
46
  const meta = metaFor(key, value);
28
- if (!meta || meta.type === "folder" || meta.type === "tabs") throw new TypeError(`[tweaks] mountControl: "${key}" is not a single-control schema value`);
47
+ if (!meta || meta.type === "folder" || meta.type === "tabs")
48
+ throw new TypeError(`[tweaks] mountControl: "${key}" is not a single-control schema value`);
29
49
  if (opts.label != null) meta.label = String(opts.label); // the option wins over the derived label; "" = no label
30
50
  const valued = !VALUELESS.has(meta.type); // display/action controls carry no value: set/get are inert
31
- const root = scope("tw-control"); // the control fills it in on ready
32
- host.append(root);
33
- let ctrl: Control | null = null, destroyed = false, last: unknown = meta.value, parked: unknown, queued = false;
51
+ const root = scope("twk-control"); // the control fills it in on ready
52
+ const iso = isolate(root, opts.shadow);
53
+ host.append(iso.box);
54
+ let ctrl: Control | null = null,
55
+ destroyed = false,
56
+ last: unknown = meta.value,
57
+ parked: unknown,
58
+ queued = false;
34
59
  // Gated the way the panel gates notify(): a same-value set() stays silent instead of echoing.
35
- const emit = (v: unknown) => { if (!valueChanged(last, v)) return; last = v; opts.onChange && opts.onChange(v, key); };
60
+ const emit = (v: unknown) => {
61
+ if (!valueChanged(last, v)) return;
62
+ last = v;
63
+ opts.onChange && opts.onChange(v, key);
64
+ };
36
65
  const build = () => {
37
66
  if (destroyed) return; // destroy() before the chunk landed — nothing to mount
38
- ctrl = createControl(meta, valued ? emit : () => {});
67
+ ctrl = using(opts.strings, () => createControl(meta, valued ? emit : () => {}));
39
68
  if (!ctrl) return; // a failed chunk degrades to an empty wrapper
40
69
  if (meta.hint) addHintMarker(ctrl.el, meta.hint);
41
70
  // Resolved once at mount: with no siblings for a predicate to read, `get` answers undefined.
42
71
  const none: Get = () => undefined;
43
- try { if (meta.render && !meta.render(none)) ctrl.el.classList.add("tw-cond-hidden"); } catch {}
44
- try { const d = typeof meta.disabled === "function" ? meta.disabled(none) : meta.disabled; if (d) setDisabled(ctrl.el, true); } catch {} // each predicate fails on its own
72
+ try {
73
+ if (meta.render && !meta.render(none)) ctrl.el.classList.add("twk-cond-hidden");
74
+ } catch {}
75
+ // each predicate fails on its own
76
+ try {
77
+ const d = typeof meta.disabled === "function" ? meta.disabled(none) : meta.disabled;
78
+ if (d) setDisabled(ctrl.el, true);
79
+ } catch {}
45
80
  root.append(ctrl.el);
46
81
  if (!valued) return;
47
82
  last = ctrl.get(); // the form the control opened on
48
- if (queued) { ctrl.set(parked); emit(ctrl.get()); } // a set() from the lazy window applies and announces now
83
+ // a set() from the lazy window applies and announces now
84
+ if (queued) {
85
+ ctrl.set(parked);
86
+ emit(ctrl.get());
87
+ }
49
88
  };
50
89
  const handle: MountedControl = {
51
- el: root,
52
- set: (v) => { if (destroyed || !valued) return; if (ctrl) { ctrl.set(v); emit(ctrl.get()); } else { parked = v; queued = true; } },
90
+ el: iso.box,
91
+ set: (v) => {
92
+ if (destroyed || !valued) return;
93
+ if (ctrl) {
94
+ ctrl.set(v);
95
+ emit(ctrl.get());
96
+ } else {
97
+ parked = v;
98
+ queued = true;
99
+ }
100
+ },
53
101
  get: () => (!valued ? undefined : ctrl ? ctrl.get() : queued ? parked : meta.value),
54
- destroy: () => { destroyed = true; if (ctrl && typeof ctrl.destroy === "function") ctrl.destroy(); root.dataset.twDestroyed = ""; root.remove(); }, // onLive listeners release on their next event by this mark
102
+ // onLive listeners release on their next event by this mark
103
+ destroy: () => {
104
+ destroyed = true;
105
+ if (ctrl && typeof ctrl.destroy === "function") ctrl.destroy();
106
+ root.dataset.twkDestroyed = "";
107
+ root.remove();
108
+ iso.end();
109
+ },
55
110
  ready: null,
56
111
  };
57
112
  handle.ready = whenLoaded([meta], build, handle);
113
+ // the handled fork whenLoaded keeps
114
+ if (iso.dressed) (handle.ready = Promise.all([handle.ready, iso.dressed]).then(() => handle)).catch(() => {});
58
115
  return handle;
59
116
  }
60
117
 
61
118
  /** The color editor surface alone, for a host page that brings its own swatch. */
62
119
  export function createColorPicker(opts: ColorPickerOptions = {}): ColorPicker {
63
- const root = scope("tw-color-picker");
64
- let body: PickerBody | null = null, destroyed = false, last = opts.value, parked: string, queued = false, parkedMode: ColorMode = null;
65
- const emit = (v: string) => { if (!valueChanged(last, v)) return; last = v; opts.onChange && opts.onChange(v); };
120
+ const root = scope("twk-color-picker"),
121
+ iso = isolate(root, opts.shadow);
122
+ let body: PickerBody | null = null,
123
+ destroyed = false,
124
+ last = opts.value,
125
+ parked: string,
126
+ queued = false,
127
+ parkedMode: ColorMode = null;
128
+ const emit = (v: string) => {
129
+ if (!valueChanged(last, v)) return;
130
+ last = v;
131
+ opts.onChange && opts.onChange(v);
132
+ };
66
133
  const build = () => {
67
134
  if (destroyed) return;
68
- const make = getControl<PickerBody, PickerOptions>("colorpicker"); // registered by the color module beside its control
135
+ // registered by the color module beside its control
136
+ const make = getControl<PickerBody, PickerOptions>("colorpicker");
69
137
  if (!make) return;
70
- body = make({ value: opts.value, mode: opts.mode }, emit);
138
+ body = using(opts.strings, () => make({ value: opts.value, mode: opts.mode }, emit));
71
139
  last = body.get();
72
140
  root.append(body.el);
73
141
  if (parkedMode) body.setMode(parkedMode);
74
- if (queued) { body.set(parked); emit(body.get()); }
142
+ if (queued) {
143
+ body.set(parked);
144
+ emit(body.get());
145
+ }
75
146
  onReady(body.reflow); // next frame: the thumbs need a real box
76
147
  };
77
148
  const picker: ColorPicker = {
78
- el: root,
79
- set: (v) => { if (destroyed) return; if (body) { body.set(v); emit(body.get()); } else { parked = v; queued = true; } },
149
+ el: iso.box,
150
+ set: (v) => {
151
+ if (destroyed) return;
152
+ if (body) {
153
+ body.set(v);
154
+ emit(body.get());
155
+ } else {
156
+ parked = v;
157
+ queued = true;
158
+ }
159
+ },
80
160
  get: () => (body ? body.get() : queued ? parked : opts.value),
81
161
  mode: () => (body ? body.mode() : parkedMode || opts.mode || "oklch"),
82
- setMode: (m) => { if (body) body.setMode(m); else parkedMode = m; },
83
- reflow: () => { if (body) body.reflow(); },
84
- destroy: () => { destroyed = true; root.remove(); },
162
+ setMode: (m) => {
163
+ if (body) body.setMode(m);
164
+ else parkedMode = m;
165
+ },
166
+ reflow: () => {
167
+ if (body) body.reflow();
168
+ },
169
+ destroy: () => {
170
+ destroyed = true;
171
+ root.remove();
172
+ iso.end();
173
+ },
85
174
  ready: null,
86
175
  };
87
176
  picker.ready = whenLoaded([{ type: "color" }], build, picker);
177
+ if (iso.dressed) (picker.ready = Promise.all([picker.ready, iso.dressed]).then(() => picker)).catch(() => {});
88
178
  return picker;
89
179
  }