tweakit 0.5.2 → 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 (120) hide show
  1. package/AGENTS.md +32 -30
  2. package/README.md +55 -29
  3. package/THIRD-PARTY-NOTICES.md +0 -1
  4. package/dist/tweaks/auto.js +2 -0
  5. package/dist/tweaks/auto.js.map +6 -0
  6. package/dist/tweaks/bezier-S2BOXQBM.js +2 -0
  7. package/dist/tweaks/bezier-S2BOXQBM.js.map +6 -0
  8. package/dist/tweaks/chunk-3MZAAMC2.js +2 -0
  9. package/dist/tweaks/chunk-3MZAAMC2.js.map +6 -0
  10. package/dist/tweaks/chunk-ETB35KFV.js +2 -0
  11. package/dist/tweaks/chunk-ETB35KFV.js.map +6 -0
  12. package/dist/tweaks/chunk-YB5GKWZI.js +2 -0
  13. package/dist/tweaks/chunk-YB5GKWZI.js.map +6 -0
  14. package/dist/tweaks/clip-A3VI53BK.js +2 -0
  15. package/dist/tweaks/clip-A3VI53BK.js.map +6 -0
  16. package/dist/tweaks/color-UGYMAF3W.js +2 -0
  17. package/dist/tweaks/color-UGYMAF3W.js.map +6 -0
  18. package/dist/tweaks/core.js +2 -1
  19. package/dist/tweaks/core.js.map +6 -0
  20. package/dist/tweaks/fold-GY47HIQA.js +2 -0
  21. package/dist/tweaks/fold-GY47HIQA.js.map +6 -0
  22. package/dist/tweaks/gradient-BTX25WSH.js +2 -0
  23. package/dist/tweaks/gradient-BTX25WSH.js.map +6 -0
  24. package/dist/tweaks/heavy-NPFIGHRM.js +2 -0
  25. package/dist/tweaks/heavy-NPFIGHRM.js.map +6 -0
  26. package/dist/tweaks/image-HTQQ4WX6.js +4 -0
  27. package/dist/tweaks/image-HTQQ4WX6.js.map +6 -0
  28. package/dist/tweaks/image-store-QD5SMZXG.js +2 -0
  29. package/dist/tweaks/image-store-QD5SMZXG.js.map +6 -0
  30. package/dist/tweaks/interval-BHPI4LRN.js +2 -0
  31. package/dist/tweaks/interval-BHPI4LRN.js.map +6 -0
  32. package/dist/tweaks/markup-QM53TQJZ.js +2 -0
  33. package/dist/tweaks/markup-QM53TQJZ.js.map +6 -0
  34. package/dist/tweaks/monitor-722WIYGW.js +3 -0
  35. package/dist/tweaks/monitor-722WIYGW.js.map +6 -0
  36. package/dist/tweaks/motion-HMCZK6HJ.js +2 -0
  37. package/dist/tweaks/motion-HMCZK6HJ.js.map +6 -0
  38. package/dist/tweaks/plot-D3NQ6XNN.js +3 -0
  39. package/dist/tweaks/plot-D3NQ6XNN.js.map +6 -0
  40. package/dist/tweaks/point-XDXKMDXH.js +2 -0
  41. package/dist/tweaks/point-XDXKMDXH.js.map +6 -0
  42. package/dist/tweaks/presets-EUWNSCUW.js +2 -0
  43. package/dist/tweaks/presets-EUWNSCUW.js.map +6 -0
  44. package/dist/tweaks/shadow-AM7VSRNS.js +2 -0
  45. package/dist/tweaks/shadow-AM7VSRNS.js.map +6 -0
  46. package/dist/tweaks/shadow-root-RYUV3AGS.js +3 -0
  47. package/dist/tweaks/shadow-root-RYUV3AGS.js.map +6 -0
  48. package/dist/tweaks/sides-JWIURDA4.js +2 -0
  49. package/dist/tweaks/sides-JWIURDA4.js.map +6 -0
  50. package/dist/tweaks/spring-BF5GBTPM.js +2 -0
  51. package/dist/tweaks/spring-BF5GBTPM.js.map +6 -0
  52. package/dist/tweaks/tabs-PRVUUZXZ.js +2 -0
  53. package/dist/tweaks/tabs-PRVUUZXZ.js.map +6 -0
  54. package/dist/tweaks.css +1 -1
  55. package/dist/tweaks.js +7 -3
  56. package/dist/tweaks.js.map +6 -0
  57. package/dist/types/tweaks/easing.d.ts +8 -11
  58. package/dist/types/tweaks/enhance.d.ts +3 -2
  59. package/dist/types/tweaks/panel.d.ts +6 -4
  60. package/dist/types/tweaks/schema.d.ts +4 -8
  61. package/dist/types/tweaks/standalone.d.ts +3 -3
  62. package/dist/types/tweaks/types.d.ts +499 -116
  63. package/package.json +30 -5
  64. package/src/tweaks/auto.ts +16 -0
  65. package/src/tweaks/clip.ts +156 -0
  66. package/src/tweaks/controls/basic.ts +727 -0
  67. package/src/tweaks/controls/bezier.ts +204 -0
  68. package/src/tweaks/controls/color.ts +861 -0
  69. package/src/tweaks/controls/gradient.ts +419 -0
  70. package/src/tweaks/controls/image.ts +555 -0
  71. package/src/tweaks/controls/interval.ts +189 -0
  72. package/src/tweaks/controls/monitor.ts +211 -0
  73. package/src/tweaks/controls/motion.ts +316 -0
  74. package/src/tweaks/controls/plot.ts +440 -0
  75. package/src/tweaks/controls/point.ts +208 -0
  76. package/src/tweaks/controls/shadow.ts +156 -0
  77. package/src/tweaks/controls/sides.ts +196 -0
  78. package/src/tweaks/controls/spring.ts +308 -0
  79. package/src/tweaks/controls/tabs.ts +68 -0
  80. package/src/tweaks/core.ts +9 -0
  81. package/src/tweaks/easing.ts +118 -0
  82. package/src/tweaks/enhance.ts +35 -0
  83. package/src/tweaks/feedback.ts +218 -0
  84. package/src/tweaks/fold.ts +33 -0
  85. package/src/tweaks/heavy.ts +626 -0
  86. package/src/tweaks/icons.ts +26 -0
  87. package/src/tweaks/image-store.ts +189 -0
  88. package/src/tweaks/lazy.ts +63 -0
  89. package/src/tweaks/markup.ts +317 -0
  90. package/src/tweaks/panel.ts +1693 -0
  91. package/src/tweaks/presets.ts +85 -0
  92. package/src/tweaks/schema.ts +351 -0
  93. package/src/tweaks/shadow-root.ts +178 -0
  94. package/src/tweaks/shared.ts +1137 -0
  95. package/src/tweaks/single.ts +22 -0
  96. package/src/tweaks/standalone.ts +179 -0
  97. package/src/tweaks/types.ts +1027 -0
  98. package/src/tweaks/undo.ts +104 -0
  99. package/src/tweaks.css +965 -0
  100. package/src/wide-gamut.ts +658 -0
  101. package/dist/tweaks/bezier-2RABC6LD.js +0 -1
  102. package/dist/tweaks/chunk-4ATI34PB.js +0 -1
  103. package/dist/tweaks/chunk-7OSCMZ2J.js +0 -1
  104. package/dist/tweaks/chunk-W3JNIJ2F.js +0 -1
  105. package/dist/tweaks/clip-ECGCECEC.js +0 -1
  106. package/dist/tweaks/colour-2RE3FQ5E.js +0 -1
  107. package/dist/tweaks/fold-UGN7TXGX.js +0 -1
  108. package/dist/tweaks/gradient-DB6XTDHO.js +0 -1
  109. package/dist/tweaks/heavy-PKOMHB3C.js +0 -1
  110. package/dist/tweaks/image-7MCLBOZ3.js +0 -1
  111. package/dist/tweaks/interval-L2E4L3AZ.js +0 -1
  112. package/dist/tweaks/markup-ZJJ6CCWM.js +0 -1
  113. package/dist/tweaks/monitor-IEK742PG.js +0 -2
  114. package/dist/tweaks/motion-N5UNVR55.js +0 -1
  115. package/dist/tweaks/plot-VVTOY3RA.js +0 -2
  116. package/dist/tweaks/point-YMMHSLO7.js +0 -1
  117. package/dist/tweaks/shadow-IKYOV3VN.js +0 -1
  118. package/dist/tweaks/sides-FH227Z54.js +0 -1
  119. package/dist/tweaks/spring-3PKAFIH7.js +0 -1
  120. package/dist/tweaks/tabs-BKK5NIIY.js +0 -1
@@ -0,0 +1,104 @@
1
+ /* Undo / redo (opts.undo) — a debounced history of snapshots, scoped to a hovered or focused panel so it doesn't hijack
2
+ * the page's own undo. Its own module, so the history can be tested without a panel (test/undo.test.mjs). */
3
+ import { hasOwn, valueChanged, activeIn } from "./shared.js";
4
+ import type { Snapshot } from "./panel.js";
5
+
6
+ /** A panel's history: `snapshot` reads its values, `applySnapshot` writes them back, `watch` subscribes to every change
7
+ * (the silent ones too), and ⌘Z belongs to `panel` while it's hovered or focused, outside an editable field.
8
+ * Positional, as a context object's keys would survive minification in the core. */
9
+ export const createUndo = (
10
+ panel: HTMLElement,
11
+ snapshot: () => Snapshot,
12
+ applySnapshot: (snap: Snapshot) => void,
13
+ atPath: (obj: Snapshot | null, path: string[]) => unknown,
14
+ inEditable: (t: Element | null) => boolean,
15
+ watch: (fn: () => void) => void,
16
+ ) => {
17
+ // Bounded: each step is a deep clone of every value.
18
+ const HIST_MAX = 200;
19
+ let history: Snapshot[] = [],
20
+ histIdx = 0,
21
+ applyingHistory = false,
22
+ histTimer = 0;
23
+ // Walk a new step beside the one before it: a string that didn't change takes the earlier step's copy, so an image's
24
+ // data URL is held once across history, not once a step. Strings only, never objects, so no step can edit another.
25
+ // True when nothing changed, which spares serializing both steps to compare them.
26
+ // (Snapshots are JSON: own keys, no undefined. A key b lacks reads undefined or an inherited function, and never
27
+ // matches.)
28
+ const share = (a: any, b: any): boolean => {
29
+ if (a === b) return true;
30
+ if (!a || !b || typeof a != "object" || typeof b != "object" || Array.isArray(a) != Array.isArray(b)) return false;
31
+ let same = Object.keys(a).length == Object.keys(b).length;
32
+ for (const k in a)
33
+ if (a[k] === b[k]) a[k] = b[k];
34
+ else if (!share(a[k], b[k])) same = false;
35
+ return same;
36
+ };
37
+ const commit = () => {
38
+ histTimer = 0;
39
+ const snap = snapshot();
40
+ if (share(snap, history[histIdx])) return; // unchanged
41
+ history = history.slice(0, histIdx + 1);
42
+ history.push(snap); // a new edit drops the redo branch
43
+ if (history.length > HIST_MAX) history = history.slice(history.length - HIST_MAX); // oldest steps age out
44
+ histIdx = history.length - 1;
45
+ };
46
+ const record = () => {
47
+ if (applyingHistory) return;
48
+ clearTimeout(histTimer);
49
+ histTimer = setTimeout(commit, 350);
50
+ };
51
+ // so ⌘Z right after a change still undoes that change
52
+ const flush = () => {
53
+ if (histTimer) {
54
+ clearTimeout(histTimer);
55
+ commit();
56
+ }
57
+ };
58
+ watch(record);
59
+ const restore = (idx: number) => {
60
+ applyingHistory = true;
61
+ applySnapshot(history[idx]);
62
+ applyingHistory = false;
63
+ histIdx = idx;
64
+ };
65
+ const undo = () => {
66
+ flush();
67
+ if (histIdx > 0) restore(histIdx - 1);
68
+ };
69
+ const redo = () => {
70
+ flush();
71
+ if (histIdx < history.length - 1) restore(histIdx + 1);
72
+ };
73
+ const focused = () => panel.matches(":hover") || panel.contains(activeIn(panel));
74
+ const onKey = (e: KeyboardEvent) => {
75
+ // the path: a shadow host retargets e.target
76
+ if (!focused() || !(e.metaKey || e.ctrlKey) || inEditable(e.composedPath()[0] as Element)) return;
77
+ const k = e.key.toLowerCase();
78
+ if (k === "z") {
79
+ e.preventDefault();
80
+ e.shiftKey ? redo() : undo();
81
+ } else if (k === "y") {
82
+ e.preventDefault();
83
+ redo();
84
+ }
85
+ };
86
+ // patch: a late restore (an image the store just answered for) goes into every step that still held what its row
87
+ // held, so it isn't a step of its own, and ⌘Z neither takes it back out nor folds a pending edit into the base.
88
+ const patch = (path: string[], held: unknown, v: unknown) => {
89
+ const k = path[path.length - 1],
90
+ h = JSON.parse(JSON.stringify(held ?? null)),
91
+ nv = JSON.parse(JSON.stringify(v ?? null));
92
+ for (const step of history) {
93
+ const o: any = atPath(step, path.slice(0, -1));
94
+ if (o && typeof o === "object" && hasOwn(o, k) && !valueChanged(o[k], h)) o[k] = nv;
95
+ }
96
+ };
97
+ // the base step: the panel as built and restored
98
+ const arm = () => {
99
+ history = [snapshot()];
100
+ histIdx = 0;
101
+ };
102
+ return { undo, redo, onKey, flush, arm, patch };
103
+ };
104
+ export type Undo = ReturnType<typeof createUndo>;