juxscript 1.0.62 → 1.0.63

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 (141) hide show
  1. package/bin/cli.js +161 -293
  2. package/docs/v2comps/HEADLESS.md +83 -0
  3. package/docs/v2comps/ISOMORPHISM.md +10 -0
  4. package/juxconfig.example.js +63 -58
  5. package/lib/componentsv2/base/BaseEngine.js +258 -0
  6. package/lib/componentsv2/base/BaseEngine.js.map +1 -0
  7. package/lib/componentsv2/base/BaseEngine.ts +303 -0
  8. package/lib/componentsv2/base/BaseSkin.js +108 -0
  9. package/lib/componentsv2/base/BaseSkin.js.map +1 -0
  10. package/lib/componentsv2/base/BaseSkin.ts +137 -0
  11. package/lib/componentsv2/base/GlobalBus.js +56 -0
  12. package/lib/componentsv2/base/GlobalBus.js.map +1 -0
  13. package/lib/componentsv2/base/GlobalBus.ts +60 -0
  14. package/lib/componentsv2/base/State.js +68 -0
  15. package/lib/componentsv2/base/State.js.map +1 -0
  16. package/lib/componentsv2/base/State.ts +62 -0
  17. package/lib/componentsv2/grid/component.js +41 -0
  18. package/lib/componentsv2/grid/component.js.map +1 -0
  19. package/lib/componentsv2/grid/component.ts +67 -0
  20. package/lib/componentsv2/grid/engine.js +73 -0
  21. package/lib/componentsv2/grid/engine.js.map +1 -0
  22. package/lib/componentsv2/grid/engine.ts +110 -0
  23. package/lib/componentsv2/grid/skin.js +95 -0
  24. package/lib/componentsv2/grid/skin.js.map +1 -0
  25. package/lib/componentsv2/grid/skin.ts +105 -0
  26. package/lib/componentsv2/grid/structure.css +58 -0
  27. package/lib/componentsv2/index.js +218 -0
  28. package/lib/componentsv2/index.js.map +1 -0
  29. package/lib/componentsv2/index.ts +253 -0
  30. package/lib/componentsv2/input/component.js +21 -0
  31. package/lib/componentsv2/input/component.js.map +1 -0
  32. package/lib/componentsv2/input/component.ts +28 -0
  33. package/lib/componentsv2/input/engine.js +50 -0
  34. package/lib/componentsv2/input/engine.js.map +1 -0
  35. package/lib/componentsv2/input/engine.ts +76 -0
  36. package/lib/componentsv2/input/skin.js +91 -0
  37. package/lib/componentsv2/input/skin.js.map +1 -0
  38. package/lib/componentsv2/input/skin.ts +91 -0
  39. package/lib/componentsv2/input/structure.css +47 -0
  40. package/lib/componentsv2/list/component.js +83 -0
  41. package/lib/componentsv2/list/component.js.map +1 -0
  42. package/lib/componentsv2/list/component.ts +97 -0
  43. package/lib/componentsv2/list/engine.js +261 -0
  44. package/lib/componentsv2/list/engine.js.map +1 -0
  45. package/lib/componentsv2/list/engine.ts +345 -0
  46. package/lib/componentsv2/list/skin.js +343 -0
  47. package/lib/componentsv2/list/skin.js.map +1 -0
  48. package/lib/componentsv2/list/skin.ts +367 -0
  49. package/lib/componentsv2/list/structure.css +359 -0
  50. package/lib/componentsv2/plugins/ClientSQLitePlugin.js +130 -0
  51. package/lib/componentsv2/plugins/ClientSQLitePlugin.js.map +1 -0
  52. package/lib/componentsv2/plugins/ClientSQLitePlugin.ts +154 -0
  53. package/lib/componentsv2/plugins/IndexedDBPlugin.js +75 -0
  54. package/lib/componentsv2/plugins/IndexedDBPlugin.js.map +1 -0
  55. package/lib/componentsv2/plugins/IndexedDBPlugin.ts +96 -0
  56. package/lib/componentsv2/plugins/LocalStoragePlugin.js +65 -0
  57. package/lib/componentsv2/plugins/LocalStoragePlugin.js.map +1 -0
  58. package/lib/componentsv2/plugins/LocalStoragePlugin.ts +86 -0
  59. package/lib/componentsv2/plugins/ServerSQLitePlugin.js +70 -0
  60. package/lib/componentsv2/plugins/ServerSQLitePlugin.js.map +1 -0
  61. package/lib/componentsv2/plugins/ServerSQLitePlugin.ts +99 -0
  62. package/lib/componentsv2/stubs/ComponentComposition.ts.stub +32 -0
  63. package/lib/componentsv2/stubs/ComponentEngine.ts.stub +36 -0
  64. package/lib/componentsv2/stubs/ComponentSkin.ts.stub +34 -0
  65. package/lib/componentsv2/stubs/ComponentStructure.css.stub +13 -0
  66. package/lib/componentsv2/tools/CreateSkin.js +62 -0
  67. package/lib/componentsv2/tools/DocSpam.js +134 -0
  68. package/lib/componentsv2/tools/FluencyAudit.js +141 -0
  69. package/lib/componentsv2/tools/OptionsAudit.js +177 -0
  70. package/lib/componentsv2/tools/Scaffold.js +140 -0
  71. package/lib/utils/fetch.js +428 -0
  72. package/lib/utils/fetch.js.map +1 -0
  73. package/machinery/build.js +2 -1
  74. package/machinery/compiler.js +200 -37
  75. package/machinery/config.js +93 -6
  76. package/machinery/diagnose.js +72 -0
  77. package/machinery/jux-module-pattern.md +118 -0
  78. package/machinery/server.js +23 -7
  79. package/machinery/verifier.js +143 -0
  80. package/machinery/watcher.js +53 -64
  81. package/package.json +11 -2
  82. package/lib/components/alert.ts +0 -200
  83. package/lib/components/app.ts +0 -258
  84. package/lib/components/badge.ts +0 -101
  85. package/lib/components/base/BaseComponent.ts +0 -417
  86. package/lib/components/base/FormInput.ts +0 -227
  87. package/lib/components/button.ts +0 -178
  88. package/lib/components/card.ts +0 -173
  89. package/lib/components/chart.ts +0 -231
  90. package/lib/components/checkbox.ts +0 -242
  91. package/lib/components/code.ts +0 -123
  92. package/lib/components/container.ts +0 -140
  93. package/lib/components/data.ts +0 -135
  94. package/lib/components/datepicker.ts +0 -234
  95. package/lib/components/dialog.ts +0 -172
  96. package/lib/components/divider.ts +0 -100
  97. package/lib/components/dropdown.ts +0 -186
  98. package/lib/components/element.ts +0 -267
  99. package/lib/components/error-handler.ts +0 -285
  100. package/lib/components/fileupload.ts +0 -309
  101. package/lib/components/grid.ts +0 -291
  102. package/lib/components/guard.ts +0 -92
  103. package/lib/components/heading.ts +0 -96
  104. package/lib/components/helpers.ts +0 -41
  105. package/lib/components/hero.ts +0 -224
  106. package/lib/components/icon.ts +0 -160
  107. package/lib/components/icons.ts +0 -175
  108. package/lib/components/include.ts +0 -440
  109. package/lib/components/input.ts +0 -457
  110. package/lib/components/list.ts +0 -419
  111. package/lib/components/loading.ts +0 -100
  112. package/lib/components/menu.ts +0 -260
  113. package/lib/components/modal.ts +0 -239
  114. package/lib/components/nav.ts +0 -257
  115. package/lib/components/paragraph.ts +0 -97
  116. package/lib/components/progress.ts +0 -139
  117. package/lib/components/radio.ts +0 -278
  118. package/lib/components/req.ts +0 -302
  119. package/lib/components/script.ts +0 -43
  120. package/lib/components/select.ts +0 -252
  121. package/lib/components/sidebar.ts +0 -167
  122. package/lib/components/style.ts +0 -43
  123. package/lib/components/switch.ts +0 -246
  124. package/lib/components/table.ts +0 -1249
  125. package/lib/components/tabs.ts +0 -250
  126. package/lib/components/theme-toggle.ts +0 -300
  127. package/lib/components/token-calculator.ts +0 -313
  128. package/lib/components/tooltip.ts +0 -144
  129. package/lib/components/view.ts +0 -190
  130. package/lib/components/write.ts +0 -272
  131. package/lib/jux.ts +0 -365
  132. package/lib/layouts/default.css +0 -260
  133. package/lib/layouts/figma.css +0 -334
  134. package/lib/reactivity/state.ts +0 -78
  135. package/machinery/bundleAssets.js +0 -0
  136. package/machinery/bundleJux.js +0 -0
  137. package/machinery/bundleVendors.js +0 -0
  138. package/presets/default/all.jux +0 -343
  139. package/presets/default/index.jux +0 -90
  140. package/presets/default/layout.jux +0 -57
  141. package/presets/default/style.css +0 -1612
@@ -0,0 +1,68 @@
1
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
+ if (kind === "m") throw new TypeError("Private method is not writable");
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
+ };
7
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
+ };
12
+ var _State_instances, _State_value, _State_subscribers, _State_history, _State_future, _State_notify;
13
+ /**
14
+ * REGINALD'S LEDGER
15
+ * A protected reactive container for atomic state management.
16
+ */
17
+ export class State {
18
+ constructor(initialValue) {
19
+ _State_instances.add(this);
20
+ _State_value.set(this, void 0);
21
+ _State_subscribers.set(this, new Set());
22
+ _State_history.set(this, []);
23
+ _State_future.set(this, []);
24
+ __classPrivateFieldSet(this, _State_value, initialValue, "f");
25
+ }
26
+ get value() {
27
+ return JSON.parse(JSON.stringify(__classPrivateFieldGet(this, _State_value, "f")));
28
+ }
29
+ /**
30
+ * Access the timeline of past states (The Ledger).
31
+ */
32
+ get history() {
33
+ return [...__classPrivateFieldGet(this, _State_history, "f")];
34
+ }
35
+ set(newValue) {
36
+ // Snap state serially before change
37
+ __classPrivateFieldGet(this, _State_history, "f").push(JSON.stringify(__classPrivateFieldGet(this, _State_value, "f")));
38
+ __classPrivateFieldSet(this, _State_future, [], "f"); // Clear future timeline on new divergence
39
+ __classPrivateFieldSet(this, _State_value, newValue, "f");
40
+ __classPrivateFieldGet(this, _State_instances, "m", _State_notify).call(this);
41
+ }
42
+ rollback() {
43
+ const previous = __classPrivateFieldGet(this, _State_history, "f").pop();
44
+ if (previous !== undefined) {
45
+ __classPrivateFieldGet(this, _State_future, "f").push(JSON.stringify(__classPrivateFieldGet(this, _State_value, "f"))); // Save current for redo
46
+ __classPrivateFieldSet(this, _State_value, JSON.parse(previous), "f");
47
+ __classPrivateFieldGet(this, _State_instances, "m", _State_notify).call(this);
48
+ }
49
+ }
50
+ rollforward() {
51
+ const next = __classPrivateFieldGet(this, _State_future, "f").pop();
52
+ if (next !== undefined) {
53
+ __classPrivateFieldGet(this, _State_history, "f").push(JSON.stringify(__classPrivateFieldGet(this, _State_value, "f"))); // Save current for undo
54
+ __classPrivateFieldSet(this, _State_value, JSON.parse(next), "f");
55
+ __classPrivateFieldGet(this, _State_instances, "m", _State_notify).call(this);
56
+ }
57
+ }
58
+ subscribe(callback) {
59
+ __classPrivateFieldGet(this, _State_subscribers, "f").add(callback);
60
+ callback(this.value); // Immediate handshake
61
+ return () => __classPrivateFieldGet(this, _State_subscribers, "f").delete(callback);
62
+ }
63
+ }
64
+ _State_value = new WeakMap(), _State_subscribers = new WeakMap(), _State_history = new WeakMap(), _State_future = new WeakMap(), _State_instances = new WeakSet(), _State_notify = function _State_notify() {
65
+ const currentValue = this.value;
66
+ __classPrivateFieldGet(this, _State_subscribers, "f").forEach(callback => callback(currentValue));
67
+ };
68
+ //# sourceMappingURL=State.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"State.js","sourceRoot":"","sources":["State.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA;;;GAGG;AACH,MAAM,OAAO,KAAK;IAMd,YAAY,YAAe;;QAL3B,+BAAU;QACV,6BAAwC,IAAI,GAAG,EAAE,EAAC;QAClD,yBAAqB,EAAE,EAAC;QACxB,wBAAoB,EAAE,EAAC;QAGnB,uBAAA,IAAI,gBAAU,YAAY,MAAA,CAAC;IAC/B,CAAC;IAED,IAAI,KAAK;QACL,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,uBAAA,IAAI,oBAAO,CAAC,CAAC,CAAC;IACnD,CAAC;IAED;;OAEG;IACH,IAAI,OAAO;QACP,OAAO,CAAC,GAAG,uBAAA,IAAI,sBAAS,CAAC,CAAC;IAC9B,CAAC;IAED,GAAG,CAAC,QAAW;QACX,oCAAoC;QACpC,uBAAA,IAAI,sBAAS,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,uBAAA,IAAI,oBAAO,CAAC,CAAC,CAAC;QAChD,uBAAA,IAAI,iBAAW,EAAE,MAAA,CAAC,CAAC,0CAA0C;QAC7D,uBAAA,IAAI,gBAAU,QAAQ,MAAA,CAAC;QACvB,uBAAA,IAAI,uCAAQ,MAAZ,IAAI,CAAU,CAAC;IACnB,CAAC;IAED,QAAQ;QACJ,MAAM,QAAQ,GAAG,uBAAA,IAAI,sBAAS,CAAC,GAAG,EAAE,CAAC;QACrC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YACzB,uBAAA,IAAI,qBAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,uBAAA,IAAI,oBAAO,CAAC,CAAC,CAAC,CAAC,wBAAwB;YACxE,uBAAA,IAAI,gBAAU,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAA,CAAC;YACnC,uBAAA,IAAI,uCAAQ,MAAZ,IAAI,CAAU,CAAC;QACnB,CAAC;IACL,CAAC;IAED,WAAW;QACP,MAAM,IAAI,GAAG,uBAAA,IAAI,qBAAQ,CAAC,GAAG,EAAE,CAAC;QAChC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACrB,uBAAA,IAAI,sBAAS,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,uBAAA,IAAI,oBAAO,CAAC,CAAC,CAAC,CAAC,wBAAwB;YACzE,uBAAA,IAAI,gBAAU,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAA,CAAC;YAC/B,uBAAA,IAAI,uCAAQ,MAAZ,IAAI,CAAU,CAAC;QACnB,CAAC;IACL,CAAC;IAED,SAAS,CAAC,QAA4B;QAClC,uBAAA,IAAI,0BAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAChC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,sBAAsB;QAC5C,OAAO,GAAG,EAAE,CAAC,uBAAA,IAAI,0BAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACpD,CAAC;CAMJ;;IAHO,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC;IAChC,uBAAA,IAAI,0BAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;AAClE,CAAC"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * REGINALD'S LEDGER
3
+ * A protected reactive container for atomic state management.
4
+ */
5
+ export class State<T> {
6
+ #value: T;
7
+ #subscribers: Set<(value: T) => void> = new Set();
8
+ #history: string[] = [];
9
+ #future: string[] = [];
10
+
11
+ constructor(initialValue: T) {
12
+ this.#value = initialValue;
13
+ }
14
+
15
+ get value(): T {
16
+ return JSON.parse(JSON.stringify(this.#value));
17
+ }
18
+
19
+ /**
20
+ * Access the timeline of past states (The Ledger).
21
+ */
22
+ get history(): string[] {
23
+ return [...this.#history];
24
+ }
25
+
26
+ set(newValue: T): void {
27
+ // Snap state serially before change
28
+ this.#history.push(JSON.stringify(this.#value));
29
+ this.#future = []; // Clear future timeline on new divergence
30
+ this.#value = newValue;
31
+ this.#notify();
32
+ }
33
+
34
+ rollback(): void {
35
+ const previous = this.#history.pop();
36
+ if (previous !== undefined) {
37
+ this.#future.push(JSON.stringify(this.#value)); // Save current for redo
38
+ this.#value = JSON.parse(previous);
39
+ this.#notify();
40
+ }
41
+ }
42
+
43
+ rollforward(): void {
44
+ const next = this.#future.pop();
45
+ if (next !== undefined) {
46
+ this.#history.push(JSON.stringify(this.#value)); // Save current for undo
47
+ this.#value = JSON.parse(next);
48
+ this.#notify();
49
+ }
50
+ }
51
+
52
+ subscribe(callback: (value: T) => void): () => void {
53
+ this.#subscribers.add(callback);
54
+ callback(this.value); // Immediate handshake
55
+ return () => this.#subscribers.delete(callback);
56
+ }
57
+
58
+ #notify(): void {
59
+ const currentValue = this.value;
60
+ this.#subscribers.forEach(callback => callback(currentValue));
61
+ }
62
+ }
@@ -0,0 +1,41 @@
1
+ import { GridEngine } from './engine.js';
2
+ import { GridSkin } from './skin.js';
3
+ export function Grid(id, options = {}) {
4
+ const engine = new GridEngine(id, options);
5
+ if (typeof window !== 'undefined') {
6
+ // @ts-ignore
7
+ window.juxEngines = window.juxEngines || {};
8
+ // @ts-ignore
9
+ window.juxEngines[id] = engine;
10
+ }
11
+ const skin = new GridSkin(engine);
12
+ // Dynamic Augmentation
13
+ // @ts-ignore
14
+ engine.render = (targetId) => {
15
+ const target = typeof targetId === 'string' ? document.getElementById(targetId) : targetId;
16
+ if (target)
17
+ skin.renderSkin(target);
18
+ return engine;
19
+ };
20
+ // @ts-ignore
21
+ engine.injectCSS = (id, css) => skin.injectCSS(id, css);
22
+ // --- Structural API ---
23
+ // @ts-ignore
24
+ engine.rows = (config) => { engine.setRows(config); return engine; };
25
+ // @ts-ignore
26
+ engine.columns = (config) => { engine.setColumns(config); return engine; };
27
+ // @ts-ignore
28
+ engine.gap = (gap) => { engine.setGap(gap); return engine; };
29
+ // @ts-ignore
30
+ engine.width = (w) => { engine.setWidth(w); return engine; };
31
+ // @ts-ignore
32
+ engine.height = (h) => { engine.setHeight(h); return engine; };
33
+ // --- Tools ---
34
+ // @ts-ignore
35
+ engine.gridder = (active) => { engine.toggleGridder(active); return engine; };
36
+ // --- Helpers ---
37
+ // @ts-ignore
38
+ engine.getCellId = (row, col) => `${id}-${row}-${col}`;
39
+ return engine;
40
+ }
41
+ //# sourceMappingURL=component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component.js","sourceRoot":"","sources":["component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA0B,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAoBrC,MAAM,UAAU,IAAI,CAAC,EAAU,EAAE,UAAuB,EAAE;IACtD,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAE3C,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE,CAAC;QAChC,aAAa;QACb,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;QAC5C,aAAa;QACb,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC;IACnC,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;IAElC,uBAAuB;IAEvB,aAAa;IACb,MAAM,CAAC,MAAM,GAAG,CAAC,QAA8B,EAAE,EAAE;QAC/C,MAAM,MAAM,GAAG,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC3F,IAAI,MAAM;YAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QACpC,OAAO,MAAuB,CAAC;IACnC,CAAC,CAAC;IAEF,aAAa;IACb,MAAM,CAAC,SAAS,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAExD,yBAAyB;IACzB,aAAa;IACb,MAAM,CAAC,IAAI,GAAG,CAAC,MAAiB,EAAE,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IAChF,aAAa;IACb,MAAM,CAAC,OAAO,GAAG,CAAC,MAAiB,EAAE,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IACtF,aAAa;IACb,MAAM,CAAC,GAAG,GAAG,CAAC,GAAW,EAAE,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IACrE,aAAa;IACb,MAAM,CAAC,KAAK,GAAG,CAAC,CAAS,EAAE,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IACrE,aAAa;IACb,MAAM,CAAC,MAAM,GAAG,CAAC,CAAS,EAAE,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IAEvE,gBAAgB;IAChB,aAAa;IACb,MAAM,CAAC,OAAO,GAAG,CAAC,MAAgB,EAAE,EAAE,GAAG,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;IAExF,kBAAkB;IAClB,aAAa;IACb,MAAM,CAAC,SAAS,GAAG,CAAC,GAAW,EAAE,GAAW,EAAE,EAAE,CAAC,GAAG,EAAE,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;IAEvE,OAAO,MAAuB,CAAC;AACnC,CAAC"}
@@ -0,0 +1,67 @@
1
+ import { GridEngine, GridOptions, GridInput } from './engine.js';
2
+ import { GridSkin } from './skin.js';
3
+
4
+ export type GridComponent = GridEngine & {
5
+ render: (targetId: string | HTMLElement) => GridComponent;
6
+ injectCSS: (id: string, cssContent: string) => void;
7
+
8
+ // Structure
9
+ rows: (config: GridInput) => GridComponent;
10
+ columns: (config: GridInput) => GridComponent;
11
+ gap: (gap: string) => GridComponent;
12
+ width: (width: string) => GridComponent;
13
+ height: (height: string) => GridComponent;
14
+
15
+ // Tools
16
+ gridder: (active?: boolean) => GridComponent;
17
+
18
+ // Helpers
19
+ getCellId: (row: number, col: number) => string;
20
+ };
21
+
22
+ export function Grid(id: string, options: GridOptions = {}): GridComponent {
23
+ const engine = new GridEngine(id, options);
24
+
25
+ if (typeof window !== 'undefined') {
26
+ // @ts-ignore
27
+ window.juxEngines = window.juxEngines || {};
28
+ // @ts-ignore
29
+ window.juxEngines[id] = engine;
30
+ }
31
+
32
+ const skin = new GridSkin(engine);
33
+
34
+ // Dynamic Augmentation
35
+
36
+ // @ts-ignore
37
+ engine.render = (targetId: string | HTMLElement) => {
38
+ const target = typeof targetId === 'string' ? document.getElementById(targetId) : targetId;
39
+ if (target) skin.renderSkin(target);
40
+ return engine as GridComponent;
41
+ };
42
+
43
+ // @ts-ignore
44
+ engine.injectCSS = (id, css) => skin.injectCSS(id, css);
45
+
46
+ // --- Structural API ---
47
+ // @ts-ignore
48
+ engine.rows = (config: GridInput) => { engine.setRows(config); return engine; };
49
+ // @ts-ignore
50
+ engine.columns = (config: GridInput) => { engine.setColumns(config); return engine; };
51
+ // @ts-ignore
52
+ engine.gap = (gap: string) => { engine.setGap(gap); return engine; };
53
+ // @ts-ignore
54
+ engine.width = (w: string) => { engine.setWidth(w); return engine; };
55
+ // @ts-ignore
56
+ engine.height = (h: string) => { engine.setHeight(h); return engine; };
57
+
58
+ // --- Tools ---
59
+ // @ts-ignore
60
+ engine.gridder = (active?: boolean) => { engine.toggleGridder(active); return engine; };
61
+
62
+ // --- Helpers ---
63
+ // @ts-ignore
64
+ engine.getCellId = (row: number, col: number) => `${id}-${row}-${col}`;
65
+
66
+ return engine as GridComponent;
67
+ }
@@ -0,0 +1,73 @@
1
+ import { BaseEngine } from '../base/BaseEngine.js';
2
+ export class GridEngine extends BaseEngine {
3
+ constructor(id, options = {}) {
4
+ super(id, options);
5
+ }
6
+ prepareState(id, options) {
7
+ return {
8
+ id,
9
+ classes: ['jux-grid'],
10
+ visible: true,
11
+ disabled: false,
12
+ loading: false,
13
+ attributes: {},
14
+ // FIX: Use standard private method instead of JS private '#' to allow access during super() call
15
+ rows: this.normalizeTracks(options.rows || 1),
16
+ columns: this.normalizeTracks(options.columns || 1),
17
+ gap: options.gap || '0',
18
+ boundaryWidth: options.width || '100%',
19
+ boundaryHeight: options.height || '100%',
20
+ gridder: options.gridder || false
21
+ };
22
+ }
23
+ // --- Helpers ---
24
+ /**
25
+ * helper: Normalizes simple numbers into full config arrays.
26
+ * Changed from #normalizeTracks to private normalizeTracks to avoid initialization errors
27
+ * when called via BaseEngine constructor -> prepareState.
28
+ */
29
+ normalizeTracks(input) {
30
+ if (typeof input === 'number') {
31
+ // Default to '1fr' for equal distribution
32
+ return Array(input).fill({ size: '1fr' });
33
+ }
34
+ return input.map(t => ({
35
+ size: t.size || '1fr',
36
+ style: t.style,
37
+ class: t.class
38
+ }));
39
+ }
40
+ // --- Mutators ---
41
+ setRows(input) {
42
+ this.updateState({ rows: this.normalizeTracks(input) });
43
+ this.emit('layout:rows', { rows: this.state.rows });
44
+ return this;
45
+ }
46
+ setColumns(input) {
47
+ this.updateState({ columns: this.normalizeTracks(input) });
48
+ this.emit('layout:columns', { columns: this.state.columns });
49
+ return this;
50
+ }
51
+ setGap(gap) {
52
+ this.updateState({ gap });
53
+ this.emit('layout:gap', { gap });
54
+ return this;
55
+ }
56
+ setWidth(width) {
57
+ this.updateState({ boundaryWidth: width });
58
+ this.emit('layout:resize', { width });
59
+ return this;
60
+ }
61
+ setHeight(height) {
62
+ this.updateState({ boundaryHeight: height });
63
+ this.emit('layout:resize', { height });
64
+ return this;
65
+ }
66
+ toggleGridder(active) {
67
+ const next = active !== undefined ? active : !this.state.gridder;
68
+ this.updateState({ gridder: next });
69
+ this.emit('debug:gridder', { active: next });
70
+ return this;
71
+ }
72
+ }
73
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,110 @@
1
+ import { BaseEngine, BaseState } from '../base/BaseEngine.js';
2
+
3
+ export interface GridTrackConfig {
4
+ size?: string; // CSS size (e.g. "20%", "1fr", "100px")
5
+ style?: string; // Inline styles for cells in this track
6
+ class?: string; // Classes for cells in this track
7
+ }
8
+
9
+ // Input can be a simple number (count) or array of configs
10
+ export type GridInput = number | GridTrackConfig[];
11
+
12
+ export interface GridState extends BaseState {
13
+ rows: GridTrackConfig[];
14
+ columns: GridTrackConfig[];
15
+ gap: string;
16
+ boundaryWidth: string;
17
+ boundaryHeight: string;
18
+ gridder: boolean; // Debug/Blueprinting mode
19
+ }
20
+
21
+ export interface GridOptions {
22
+ rows?: GridInput;
23
+ columns?: GridInput;
24
+ gap?: string;
25
+ width?: string;
26
+ height?: string;
27
+ gridder?: boolean;
28
+ }
29
+
30
+ export class GridEngine extends BaseEngine<GridState, GridOptions> {
31
+ constructor(id: string, options: GridOptions = {}) {
32
+ super(id, options);
33
+ }
34
+
35
+ protected prepareState(id: string, options: GridOptions): GridState {
36
+ return {
37
+ id,
38
+ classes: ['jux-grid'],
39
+ visible: true,
40
+ disabled: false,
41
+ loading: false,
42
+ attributes: {},
43
+ // FIX: Use standard private method instead of JS private '#' to allow access during super() call
44
+ rows: this.normalizeTracks(options.rows || 1),
45
+ columns: this.normalizeTracks(options.columns || 1),
46
+ gap: options.gap || '0',
47
+ boundaryWidth: options.width || '100%',
48
+ boundaryHeight: options.height || '100%',
49
+ gridder: options.gridder || false
50
+ };
51
+ }
52
+
53
+ // --- Helpers ---
54
+
55
+ /**
56
+ * helper: Normalizes simple numbers into full config arrays.
57
+ * Changed from #normalizeTracks to private normalizeTracks to avoid initialization errors
58
+ * when called via BaseEngine constructor -> prepareState.
59
+ */
60
+ private normalizeTracks(input: GridInput): GridTrackConfig[] {
61
+ if (typeof input === 'number') {
62
+ // Default to '1fr' for equal distribution
63
+ return Array(input).fill({ size: '1fr' });
64
+ }
65
+ return input.map(t => ({
66
+ size: t.size || '1fr',
67
+ style: t.style,
68
+ class: t.class
69
+ }));
70
+ }
71
+
72
+ // --- Mutators ---
73
+
74
+ setRows(input: GridInput): this {
75
+ this.updateState({ rows: this.normalizeTracks(input) });
76
+ this.emit('layout:rows', { rows: this.state.rows });
77
+ return this;
78
+ }
79
+
80
+ setColumns(input: GridInput): this {
81
+ this.updateState({ columns: this.normalizeTracks(input) });
82
+ this.emit('layout:columns', { columns: this.state.columns });
83
+ return this;
84
+ }
85
+
86
+ setGap(gap: string): this {
87
+ this.updateState({ gap });
88
+ this.emit('layout:gap', { gap });
89
+ return this;
90
+ }
91
+
92
+ setWidth(width: string): this {
93
+ this.updateState({ boundaryWidth: width });
94
+ this.emit('layout:resize', { width });
95
+ return this;
96
+ }
97
+
98
+ setHeight(height: string): this {
99
+ this.updateState({ boundaryHeight: height });
100
+ this.emit('layout:resize', { height });
101
+ return this;
102
+ }
103
+
104
+ toggleGridder(active?: boolean): this {
105
+ const next = active !== undefined ? active : !this.state.gridder;
106
+ this.updateState({ gridder: next });
107
+ this.emit('debug:gridder', { active: next });
108
+ return this;
109
+ }
110
+ }
@@ -0,0 +1,95 @@
1
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
3
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
4
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
5
+ };
6
+ var _GridSkin_cells;
7
+ import { BaseSkin } from '../base/BaseSkin.js';
8
+ export class GridSkin extends BaseSkin {
9
+ constructor(engine) {
10
+ super(engine);
11
+ _GridSkin_cells.set(this, new Map());
12
+ }
13
+ // ✅ Implements Contract: Points to ./structure.css at runtime
14
+ get structureCss() {
15
+ return new URL('./structure.css', import.meta.url).href;
16
+ }
17
+ bindEvents(root) {
18
+ root.addEventListener('click', (e) => {
19
+ if (this.engine.state.gridder) {
20
+ const cell = e.target.closest('.jux-grid-cell');
21
+ if (cell && cell.id) {
22
+ console.log(`[Ordinal Grid] Targeted Cell: #${cell.id}`);
23
+ }
24
+ }
25
+ });
26
+ }
27
+ updateSkin(state) {
28
+ if (!this.root)
29
+ return;
30
+ this.applySkinAttributes(this.root, state);
31
+ this.root.className = state.classes.join(' ');
32
+ // 1. Container Styles
33
+ this.root.style.width = state.boundaryWidth;
34
+ this.root.style.height = state.boundaryHeight;
35
+ this.root.style.gap = state.gap;
36
+ // CSS Grid Definitions
37
+ const rowSizes = state.rows.map(r => r.size).join(' ');
38
+ const colSizes = state.columns.map(c => c.size).join(' ');
39
+ this.root.style.gridTemplateRows = rowSizes;
40
+ this.root.style.gridTemplateColumns = colSizes;
41
+ // Toggle Debug Class
42
+ if (state.gridder) {
43
+ this.root.classList.add('jux-gridder-active');
44
+ }
45
+ else {
46
+ this.root.classList.remove('jux-gridder-active');
47
+ }
48
+ // 2. Structural Reconciliation
49
+ const validIds = new Set();
50
+ state.rows.forEach((rowConfig, rIndex) => {
51
+ state.columns.forEach((colConfig, cIndex) => {
52
+ const cellId = `${state.id}-${rIndex}-${cIndex}`;
53
+ validIds.add(cellId);
54
+ let cell = __classPrivateFieldGet(this, _GridSkin_cells, "f").get(cellId);
55
+ if (!cell) {
56
+ cell = document.createElement('div');
57
+ cell.id = cellId;
58
+ cell.className = 'jux-grid-cell';
59
+ cell.dataset.row = String(rIndex);
60
+ cell.dataset.col = String(cIndex);
61
+ const label = document.createElement('span');
62
+ label.className = 'jux-grid-ordinal-label';
63
+ label.textContent = `#${rIndex}-${cIndex}`;
64
+ cell.appendChild(label);
65
+ __classPrivateFieldGet(this, _GridSkin_cells, "f").set(cellId, cell);
66
+ if (!this.root.contains(cell)) {
67
+ this.root.appendChild(cell);
68
+ }
69
+ }
70
+ cell.style.cssText = '';
71
+ cell.className = 'jux-grid-cell';
72
+ if (rowConfig.style)
73
+ cell.style.cssText += rowConfig.style;
74
+ if (colConfig.style)
75
+ cell.style.cssText += colConfig.style;
76
+ if (rowConfig.class)
77
+ cell.classList.add(rowConfig.class);
78
+ if (colConfig.class)
79
+ cell.classList.add(colConfig.class);
80
+ });
81
+ });
82
+ // 3. Cleanup Orphans
83
+ __classPrivateFieldGet(this, _GridSkin_cells, "f").forEach((cell, id) => {
84
+ if (!validIds.has(id)) {
85
+ cell.remove();
86
+ __classPrivateFieldGet(this, _GridSkin_cells, "f").delete(id);
87
+ }
88
+ });
89
+ }
90
+ createRoot() {
91
+ return document.createElement('div');
92
+ }
93
+ }
94
+ _GridSkin_cells = new WeakMap();
95
+ //# sourceMappingURL=skin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skin.js","sourceRoot":"","sources":["skin.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAG/C,MAAM,OAAO,QAAS,SAAQ,QAA+B;IAIzD,YAAY,MAAkB;QAC1B,KAAK,CAAC,MAAM,CAAC,CAAC;QAHlB,0BAAS,IAAI,GAAG,EAAuB,EAAC;IAIxC,CAAC;IAED,8DAA8D;IAC9D,IAAc,YAAY;QACtB,OAAO,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;IAC5D,CAAC;IAES,UAAU,CAAC,IAAiB;QAClC,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;YACjC,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;gBAC5B,MAAM,IAAI,GAAI,CAAC,CAAC,MAAsB,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;gBACjE,IAAI,IAAI,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,kCAAkC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC7D,CAAC;YACL,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAES,UAAU,CAAC,KAAgB;QACjC,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,OAAO;QACvB,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAE3C,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAE9C,sBAAsB;QACtB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,aAAa,CAAC;QAC5C,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,cAAc,CAAC;QAC9C,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;QAEhC,uBAAuB;QACvB,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvD,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAE1D,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,GAAG,QAAQ,CAAC;QAC5C,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,mBAAmB,GAAG,QAAQ,CAAC;QAE/C,qBAAqB;QACrB,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAChB,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QAClD,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACrD,CAAC;QAED,+BAA+B;QAC/B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;QAEnC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE;YACrC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE;gBACxC,MAAM,MAAM,GAAG,GAAG,KAAK,CAAC,EAAE,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;gBACjD,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBAErB,IAAI,IAAI,GAAG,uBAAA,IAAI,uBAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBAEnC,IAAI,CAAC,IAAI,EAAE,CAAC;oBACR,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;oBACrC,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC;oBACjB,IAAI,CAAC,SAAS,GAAG,eAAe,CAAC;oBACjC,IAAI,CAAC,OAAO,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;oBAClC,IAAI,CAAC,OAAO,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;oBAElC,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;oBAC7C,KAAK,CAAC,SAAS,GAAG,wBAAwB,CAAC;oBAC3C,KAAK,CAAC,WAAW,GAAG,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;oBAC3C,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;oBAExB,uBAAA,IAAI,uBAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;oBAE9B,IAAI,CAAC,IAAI,CAAC,IAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;wBAC7B,IAAI,CAAC,IAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;oBACjC,CAAC;gBACL,CAAC;gBAED,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC;gBACxB,IAAI,CAAC,SAAS,GAAG,eAAe,CAAC;gBAEjC,IAAI,SAAS,CAAC,KAAK;oBAAE,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,SAAS,CAAC,KAAK,CAAC;gBAC3D,IAAI,SAAS,CAAC,KAAK;oBAAE,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,SAAS,CAAC,KAAK,CAAC;gBAE3D,IAAI,SAAS,CAAC,KAAK;oBAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;gBACzD,IAAI,SAAS,CAAC,KAAK;oBAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAC7D,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,qBAAqB;QACrB,uBAAA,IAAI,uBAAO,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE;YAC7B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBACpB,IAAI,CAAC,MAAM,EAAE,CAAC;gBACd,uBAAA,IAAI,uBAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC3B,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAES,UAAU;QAChB,OAAO,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;CACJ"}
@@ -0,0 +1,105 @@
1
+ import { BaseSkin } from '../base/BaseSkin.js';
2
+ import { GridEngine, GridState } from './engine.js';
3
+
4
+ export class GridSkin extends BaseSkin<GridState, GridEngine> {
5
+
6
+ #cells = new Map<string, HTMLElement>();
7
+
8
+ constructor(engine: GridEngine) {
9
+ super(engine);
10
+ }
11
+
12
+ // ✅ Implements Contract: Points to ./structure.css at runtime
13
+ protected get structureCss(): string {
14
+ return new URL('./structure.css', import.meta.url).href;
15
+ }
16
+
17
+ protected bindEvents(root: HTMLElement): void {
18
+ root.addEventListener('click', (e) => {
19
+ if (this.engine.state.gridder) {
20
+ const cell = (e.target as HTMLElement).closest('.jux-grid-cell');
21
+ if (cell && cell.id) {
22
+ console.log(`[Ordinal Grid] Targeted Cell: #${cell.id}`);
23
+ }
24
+ }
25
+ });
26
+ }
27
+
28
+ protected updateSkin(state: GridState): void {
29
+ if (!this.root) return;
30
+ this.applySkinAttributes(this.root, state);
31
+
32
+ this.root.className = state.classes.join(' ');
33
+
34
+ // 1. Container Styles
35
+ this.root.style.width = state.boundaryWidth;
36
+ this.root.style.height = state.boundaryHeight;
37
+ this.root.style.gap = state.gap;
38
+
39
+ // CSS Grid Definitions
40
+ const rowSizes = state.rows.map(r => r.size).join(' ');
41
+ const colSizes = state.columns.map(c => c.size).join(' ');
42
+
43
+ this.root.style.gridTemplateRows = rowSizes;
44
+ this.root.style.gridTemplateColumns = colSizes;
45
+
46
+ // Toggle Debug Class
47
+ if (state.gridder) {
48
+ this.root.classList.add('jux-gridder-active');
49
+ } else {
50
+ this.root.classList.remove('jux-gridder-active');
51
+ }
52
+
53
+ // 2. Structural Reconciliation
54
+ const validIds = new Set<string>();
55
+
56
+ state.rows.forEach((rowConfig, rIndex) => {
57
+ state.columns.forEach((colConfig, cIndex) => {
58
+ const cellId = `${state.id}-${rIndex}-${cIndex}`;
59
+ validIds.add(cellId);
60
+
61
+ let cell = this.#cells.get(cellId);
62
+
63
+ if (!cell) {
64
+ cell = document.createElement('div');
65
+ cell.id = cellId;
66
+ cell.className = 'jux-grid-cell';
67
+ cell.dataset.row = String(rIndex);
68
+ cell.dataset.col = String(cIndex);
69
+
70
+ const label = document.createElement('span');
71
+ label.className = 'jux-grid-ordinal-label';
72
+ label.textContent = `#${rIndex}-${cIndex}`;
73
+ cell.appendChild(label);
74
+
75
+ this.#cells.set(cellId, cell);
76
+
77
+ if (!this.root!.contains(cell)) {
78
+ this.root!.appendChild(cell);
79
+ }
80
+ }
81
+
82
+ cell.style.cssText = '';
83
+ cell.className = 'jux-grid-cell';
84
+
85
+ if (rowConfig.style) cell.style.cssText += rowConfig.style;
86
+ if (colConfig.style) cell.style.cssText += colConfig.style;
87
+
88
+ if (rowConfig.class) cell.classList.add(rowConfig.class);
89
+ if (colConfig.class) cell.classList.add(colConfig.class);
90
+ });
91
+ });
92
+
93
+ // 3. Cleanup Orphans
94
+ this.#cells.forEach((cell, id) => {
95
+ if (!validIds.has(id)) {
96
+ cell.remove();
97
+ this.#cells.delete(id);
98
+ }
99
+ });
100
+ }
101
+
102
+ protected createRoot(): HTMLElement {
103
+ return document.createElement('div');
104
+ }
105
+ }