@vielzeug/craftit 1.0.1 → 2.0.1

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 (214) hide show
  1. package/README.md +112 -401
  2. package/dist/core/component.cjs +2 -0
  3. package/dist/core/component.cjs.map +1 -0
  4. package/dist/core/component.d.ts +172 -0
  5. package/dist/core/component.d.ts.map +1 -0
  6. package/dist/core/component.js +2 -0
  7. package/dist/core/component.js.map +1 -0
  8. package/dist/core/host.cjs +2 -0
  9. package/dist/core/host.cjs.map +1 -0
  10. package/dist/core/host.d.ts +77 -0
  11. package/dist/core/host.d.ts.map +1 -0
  12. package/dist/core/host.js +2 -0
  13. package/dist/core/host.js.map +1 -0
  14. package/dist/core/internal.cjs +2 -0
  15. package/dist/core/internal.cjs.map +1 -0
  16. package/dist/core/internal.d.ts +107 -0
  17. package/dist/core/internal.d.ts.map +1 -0
  18. package/dist/core/internal.js +2 -0
  19. package/dist/core/internal.js.map +1 -0
  20. package/dist/core/runtime-bindings.cjs +2 -0
  21. package/dist/core/runtime-bindings.cjs.map +1 -0
  22. package/dist/core/runtime-bindings.d.ts +6 -0
  23. package/dist/core/runtime-bindings.d.ts.map +1 -0
  24. package/dist/core/runtime-bindings.js +2 -0
  25. package/dist/core/runtime-bindings.js.map +1 -0
  26. package/dist/core/runtime-lifecycle.cjs +2 -0
  27. package/dist/core/runtime-lifecycle.cjs.map +1 -0
  28. package/dist/core/runtime-lifecycle.d.ts +116 -0
  29. package/dist/core/runtime-lifecycle.d.ts.map +1 -0
  30. package/dist/core/runtime-lifecycle.js +2 -0
  31. package/dist/core/runtime-lifecycle.js.map +1 -0
  32. package/dist/core/runtime.cjs +1 -0
  33. package/dist/core/runtime.d.ts +3 -0
  34. package/dist/core/runtime.d.ts.map +1 -0
  35. package/dist/core/runtime.js +1 -0
  36. package/dist/core/template-bindings.cjs +2 -0
  37. package/dist/core/template-bindings.cjs.map +1 -0
  38. package/dist/core/template-bindings.d.ts +59 -0
  39. package/dist/core/template-bindings.d.ts.map +1 -0
  40. package/dist/core/template-bindings.js +2 -0
  41. package/dist/core/template-bindings.js.map +1 -0
  42. package/dist/core/template-compiler.cjs +2 -0
  43. package/dist/core/template-compiler.cjs.map +1 -0
  44. package/dist/core/template-compiler.d.ts +25 -0
  45. package/dist/core/template-compiler.d.ts.map +1 -0
  46. package/dist/core/template-compiler.js +2 -0
  47. package/dist/core/template-compiler.js.map +1 -0
  48. package/dist/core/template-dom.cjs +2 -0
  49. package/dist/core/template-dom.cjs.map +1 -0
  50. package/dist/core/template-dom.d.ts +13 -0
  51. package/dist/core/template-dom.d.ts.map +1 -0
  52. package/dist/core/template-dom.js +2 -0
  53. package/dist/core/template-dom.js.map +1 -0
  54. package/dist/core/template-html.cjs +2 -0
  55. package/dist/core/template-html.cjs.map +1 -0
  56. package/dist/core/template-html.d.ts +26 -0
  57. package/dist/core/template-html.d.ts.map +1 -0
  58. package/dist/core/template-html.js +2 -0
  59. package/dist/core/template-html.js.map +1 -0
  60. package/dist/core/template.cjs +2 -0
  61. package/dist/core/template.cjs.map +1 -0
  62. package/dist/core/template.d.ts +11 -0
  63. package/dist/core/template.d.ts.map +1 -0
  64. package/dist/core/template.js +2 -0
  65. package/dist/core/template.js.map +1 -0
  66. package/dist/core/utilities.cjs +2 -0
  67. package/dist/core/utilities.cjs.map +1 -0
  68. package/dist/core/utilities.d.ts +68 -0
  69. package/dist/core/utilities.d.ts.map +1 -0
  70. package/dist/core/utilities.js +2 -0
  71. package/dist/core/utilities.js.map +1 -0
  72. package/dist/craftit.cjs +2 -18
  73. package/dist/craftit.cjs.map +1 -1
  74. package/dist/craftit.js +2 -580
  75. package/dist/craftit.js.map +1 -1
  76. package/dist/directives/attr.cjs +2 -0
  77. package/dist/directives/attr.cjs.map +1 -0
  78. package/dist/directives/attr.d.ts +14 -0
  79. package/dist/directives/attr.d.ts.map +1 -0
  80. package/dist/directives/attr.js +2 -0
  81. package/dist/directives/attr.js.map +1 -0
  82. package/dist/directives/bind.cjs +2 -0
  83. package/dist/directives/bind.cjs.map +1 -0
  84. package/dist/directives/bind.d.ts +30 -0
  85. package/dist/directives/bind.d.ts.map +1 -0
  86. package/dist/directives/bind.js +2 -0
  87. package/dist/directives/bind.js.map +1 -0
  88. package/dist/directives/choose.cjs +2 -0
  89. package/dist/directives/choose.cjs.map +1 -0
  90. package/dist/directives/choose.d.ts +34 -0
  91. package/dist/directives/choose.d.ts.map +1 -0
  92. package/dist/directives/choose.js +2 -0
  93. package/dist/directives/choose.js.map +1 -0
  94. package/dist/directives/classes.cjs +2 -0
  95. package/dist/directives/classes.cjs.map +1 -0
  96. package/dist/directives/classes.d.ts +20 -0
  97. package/dist/directives/classes.d.ts.map +1 -0
  98. package/dist/directives/classes.js +2 -0
  99. package/dist/directives/classes.js.map +1 -0
  100. package/dist/directives/each.cjs +2 -0
  101. package/dist/directives/each.cjs.map +1 -0
  102. package/dist/directives/each.d.ts +68 -0
  103. package/dist/directives/each.d.ts.map +1 -0
  104. package/dist/directives/each.js +2 -0
  105. package/dist/directives/each.js.map +1 -0
  106. package/dist/directives/index.cjs +1 -0
  107. package/dist/directives/index.d.ts +14 -0
  108. package/dist/directives/index.d.ts.map +1 -0
  109. package/dist/directives/index.js +1 -0
  110. package/dist/directives/match.cjs +2 -0
  111. package/dist/directives/match.cjs.map +1 -0
  112. package/dist/directives/match.d.ts +31 -0
  113. package/dist/directives/match.d.ts.map +1 -0
  114. package/dist/directives/match.js +2 -0
  115. package/dist/directives/match.js.map +1 -0
  116. package/dist/directives/memo.cjs +2 -0
  117. package/dist/directives/memo.cjs.map +1 -0
  118. package/dist/directives/memo.d.ts +23 -0
  119. package/dist/directives/memo.d.ts.map +1 -0
  120. package/dist/directives/memo.js +2 -0
  121. package/dist/directives/memo.js.map +1 -0
  122. package/dist/directives/on.cjs +2 -0
  123. package/dist/directives/on.cjs.map +1 -0
  124. package/dist/directives/on.d.ts +25 -0
  125. package/dist/directives/on.d.ts.map +1 -0
  126. package/dist/directives/on.js +2 -0
  127. package/dist/directives/on.js.map +1 -0
  128. package/dist/directives/raw.cjs +2 -0
  129. package/dist/directives/raw.cjs.map +1 -0
  130. package/dist/directives/raw.d.ts +25 -0
  131. package/dist/directives/raw.d.ts.map +1 -0
  132. package/dist/directives/raw.js +2 -0
  133. package/dist/directives/raw.js.map +1 -0
  134. package/dist/directives/spread.cjs +2 -0
  135. package/dist/directives/spread.cjs.map +1 -0
  136. package/dist/directives/spread.d.ts +14 -0
  137. package/dist/directives/spread.d.ts.map +1 -0
  138. package/dist/directives/spread.js +2 -0
  139. package/dist/directives/spread.js.map +1 -0
  140. package/dist/directives/style.cjs +2 -0
  141. package/dist/directives/style.cjs.map +1 -0
  142. package/dist/directives/style.d.ts +22 -0
  143. package/dist/directives/style.d.ts.map +1 -0
  144. package/dist/directives/style.js +2 -0
  145. package/dist/directives/style.js.map +1 -0
  146. package/dist/directives/until.cjs +2 -0
  147. package/dist/directives/until.cjs.map +1 -0
  148. package/dist/directives/until.d.ts +26 -0
  149. package/dist/directives/until.d.ts.map +1 -0
  150. package/dist/directives/until.js +2 -0
  151. package/dist/directives/until.js.map +1 -0
  152. package/dist/directives/when.cjs +2 -0
  153. package/dist/directives/when.cjs.map +1 -0
  154. package/dist/directives/when.d.ts +17 -0
  155. package/dist/directives/when.d.ts.map +1 -0
  156. package/dist/directives/when.js +2 -0
  157. package/dist/directives/when.js.map +1 -0
  158. package/dist/index.cjs +1 -2
  159. package/dist/index.d.ts +10 -265
  160. package/dist/index.d.ts.map +1 -0
  161. package/dist/index.js +1 -13
  162. package/dist/labs/a11y.cjs +2 -0
  163. package/dist/labs/a11y.cjs.map +1 -0
  164. package/dist/labs/a11y.d.ts +61 -0
  165. package/dist/labs/a11y.d.ts.map +1 -0
  166. package/dist/labs/a11y.js +2 -0
  167. package/dist/labs/a11y.js.map +1 -0
  168. package/dist/labs/index.d.ts +8 -0
  169. package/dist/labs/index.d.ts.map +1 -0
  170. package/dist/labs/list.cjs +2 -0
  171. package/dist/labs/list.cjs.map +1 -0
  172. package/dist/labs/list.d.ts +26 -0
  173. package/dist/labs/list.d.ts.map +1 -0
  174. package/dist/labs/list.js +2 -0
  175. package/dist/labs/list.js.map +1 -0
  176. package/dist/labs/observers.cjs +2 -0
  177. package/dist/labs/observers.cjs.map +1 -0
  178. package/dist/labs/observers.d.ts +42 -0
  179. package/dist/labs/observers.d.ts.map +1 -0
  180. package/dist/labs/observers.js +2 -0
  181. package/dist/labs/observers.js.map +1 -0
  182. package/dist/labs/overlay.cjs +2 -0
  183. package/dist/labs/overlay.cjs.map +1 -0
  184. package/dist/labs/overlay.d.ts +35 -0
  185. package/dist/labs/overlay.d.ts.map +1 -0
  186. package/dist/labs/overlay.js +2 -0
  187. package/dist/labs/overlay.js.map +1 -0
  188. package/dist/labs/selectable.cjs +2 -0
  189. package/dist/labs/selectable.cjs.map +1 -0
  190. package/dist/labs/selectable.d.ts +70 -0
  191. package/dist/labs/selectable.d.ts.map +1 -0
  192. package/dist/labs/selectable.js +2 -0
  193. package/dist/labs/selectable.js.map +1 -0
  194. package/dist/labs/selection.cjs +2 -0
  195. package/dist/labs/selection.cjs.map +1 -0
  196. package/dist/labs/selection.d.ts +68 -0
  197. package/dist/labs/selection.d.ts.map +1 -0
  198. package/dist/labs/selection.js +2 -0
  199. package/dist/labs/selection.js.map +1 -0
  200. package/dist/labs.cjs +1 -0
  201. package/dist/labs.js +1 -0
  202. package/dist/test/index.d.ts +2 -0
  203. package/dist/test/index.d.ts.map +1 -0
  204. package/dist/test/test.cjs +2 -0
  205. package/dist/test/test.cjs.map +1 -0
  206. package/dist/test/test.d.ts +198 -0
  207. package/dist/test/test.d.ts.map +1 -0
  208. package/dist/test/test.js +2 -0
  209. package/dist/test/test.js.map +1 -0
  210. package/dist/test.cjs +1 -0
  211. package/dist/test.js +1 -0
  212. package/package.json +37 -9
  213. package/dist/index.cjs.map +0 -1
  214. package/dist/index.js.map +0 -1
package/dist/craftit.js CHANGED
@@ -1,580 +1,2 @@
1
- const d = /* @__PURE__ */ new Map(), b = (r) => {
2
- if (d.has(r)) return d.get(r);
3
- const t = r.replace(/-([a-z])/g, (e, s) => s.toUpperCase());
4
- return d.set(r, t), t;
5
- }, f = /* @__PURE__ */ new Map(), l = (r) => {
6
- if (f.has(r)) return f.get(r);
7
- const t = r.replace(/[A-Z]/g, (e) => `-${e.toLowerCase()}`);
8
- return f.set(r, t), t;
9
- }, y = (r) => {
10
- const t = document.createElement("template");
11
- return t.innerHTML = r.trim(), t.content;
12
- }, g = async (r) => {
13
- if (r instanceof CSSStyleSheet) return r;
14
- const t = new CSSStyleSheet();
15
- return await t.replace(r), t;
16
- }, p = (r, t) => {
17
- const e = { ...r }, s = /* @__PURE__ */ new WeakMap(), i = (n) => {
18
- if (n == null || typeof n != "object" || n instanceof Node)
19
- return n;
20
- const o = s.get(n);
21
- if (o)
22
- return o;
23
- const a = new Proxy(n, {
24
- get(c, h) {
25
- const u = Reflect.get(c, h);
26
- return i(u);
27
- },
28
- set(c, h, u) {
29
- if (Reflect.get(c, h) === u) return !0;
30
- const m = Reflect.set(c, h, u);
31
- return typeof h == "string" && !h.startsWith("_") && t(), m;
32
- }
33
- });
34
- return s.set(n, a), a;
35
- };
36
- return new Proxy(e, {
37
- get(n, o) {
38
- const a = Reflect.get(n, o);
39
- return i(a);
40
- },
41
- set(n, o, a) {
42
- if (Reflect.get(n, o) === a) return !0;
43
- const h = Reflect.set(n, o, a);
44
- return typeof o == "string" && !o.startsWith("_") && t(), h;
45
- }
46
- });
47
- };
48
- class A extends HTMLElement {
49
- shadow;
50
- state;
51
- value;
52
- #r = new AbortController();
53
- #i = /* @__PURE__ */ new Set();
54
- #a = !1;
55
- #e = !1;
56
- #t;
57
- #s;
58
- #o;
59
- #n;
60
- #c = /* @__PURE__ */ new Map();
61
- #h = 0;
62
- constructor(t) {
63
- super(), this.#t = t, this.shadow = this.attachShadow({ mode: "open" }), this.state = p(t.state || {}, () => {
64
- this.render(), this.notifyWatchers();
65
- }), t.formAssociated && "attachInternals" in this && (this.#s = this.attachInternals()), this.initStyles(), this.initAttributes();
66
- }
67
- get root() {
68
- return this.shadow.firstElementChild;
69
- }
70
- get internals() {
71
- return this.#s;
72
- }
73
- get form() {
74
- if (this.#s)
75
- return {
76
- /**
77
- * Set validity state
78
- * @example component.form.valid({ valueMissing: true }, 'Required')
79
- */
80
- valid: (t, e, s) => {
81
- !t || Object.keys(t).length === 0 ? this.#s.setValidity({}) : this.#s.setValidity(t, e, s);
82
- },
83
- /**
84
- * Set form value and sync with ElementInternals
85
- * @example component.form.value('new value')
86
- */
87
- value: (t, e) => {
88
- typeof t == "string" && (this.value = t), this.#s.setFormValue(t, e);
89
- }
90
- };
91
- }
92
- async initStyles() {
93
- if (!this.#t.styles?.length) return;
94
- const t = await Promise.all(this.#t.styles.map(g));
95
- this.shadow.adoptedStyleSheets = t;
96
- }
97
- initAttributes() {
98
- const t = this.#t.observedAttributes;
99
- if (t?.length)
100
- for (const e of t) {
101
- const s = b(e);
102
- s in this || Object.defineProperty(this, s, {
103
- configurable: !0,
104
- enumerable: !0,
105
- get: () => {
106
- const i = this.getAttribute(e);
107
- return i === "" ? !0 : i;
108
- },
109
- set: (i) => {
110
- i == null || i === !1 ? this.removeAttribute(e) : this.setAttribute(e, i === !0 ? "" : String(i));
111
- }
112
- });
113
- }
114
- }
115
- notifyWatchers() {
116
- for (const [, t] of this.#c)
117
- try {
118
- const e = t.selector(this.state);
119
- e !== t.lastValue && (t.callback(e, t.lastValue), t.lastValue = e);
120
- } catch {
121
- }
122
- }
123
- /* ==================== Lifecycle Callbacks ==================== */
124
- connectedCallback() {
125
- this.#r.signal.aborted && (this.#r = new AbortController()), this.shadow.hasChildNodes() || this.performRender(), this.#t.onConnected?.(this);
126
- }
127
- disconnectedCallback() {
128
- this.#t.onDisconnected?.(this), this.#r.abort();
129
- for (const t of this.#i)
130
- clearTimeout(t);
131
- this.#i.clear();
132
- }
133
- attributeChangedCallback(t, e, s) {
134
- e !== s && (this.#t.onAttributeChanged?.(t, e, s, this), this.render());
135
- }
136
- /* ==================== Form Callbacks ==================== */
137
- formDisabledCallback(t) {
138
- this.#t.onFormDisabled?.(t, this);
139
- }
140
- formResetCallback() {
141
- this.#t.onFormReset?.(this);
142
- }
143
- formStateRestoreCallback(t, e) {
144
- this.#t.onFormStateRestore?.(t, e, this);
145
- }
146
- /* ==================== Public API ==================== */
147
- /**
148
- * Schedule a render in the next animation frame
149
- */
150
- render() {
151
- this.#a || this.#e || (this.#a = !0, this.#n || (this.#n = new Promise((t) => {
152
- this.#o = t;
153
- })), requestAnimationFrame(() => {
154
- this.#a = !1, this.performRender(), this.#o?.(), this.#n = void 0, this.#o = void 0;
155
- }));
156
- }
157
- /**
158
- * Wait for pending render to complete
159
- * @returns Promise that resolves after render finishes
160
- * @example
161
- * component.set({ count: 10 });
162
- * await component.flush();
163
- * expect(component.find('.count')?.textContent).toBe('10');
164
- */
165
- async flush() {
166
- this.#n && await this.#n;
167
- }
168
- /**
169
- * Update component state
170
- * @param patchOrUpdater - State patch object or updater function
171
- * @param options - Update options
172
- * @param options.replace - Replace entire state instead of merging
173
- * @param options.silent - Update without triggering render
174
- * @returns Promise that resolves after update completes
175
- * @example
176
- * // Merge state
177
- * component.set({ count: 1 });
178
- *
179
- * // Replace state
180
- * component.set({ count: 1 }, { replace: true });
181
- *
182
- * // Updater function (sync)
183
- * component.set(state => ({ ...state, count: state.count + 1 }));
184
- *
185
- * // Updater function (async)
186
- * await component.set(async state => {
187
- * const data = await fetch('/api').then(r => r.json());
188
- * return { ...state, data };
189
- * });
190
- */
191
- async set(t, e) {
192
- if (typeof t == "function") {
193
- const i = await Promise.resolve(t(this.state));
194
- this.#e = !0;
195
- for (const n of Object.keys(this.state))
196
- delete this.state[n];
197
- Object.assign(this.state, i), this.#e = !1, e?.silent || (this.render(), await this.flush());
198
- return;
199
- }
200
- const s = t;
201
- if (e?.replace) {
202
- this.#e = !0;
203
- for (const i of Object.keys(this.state))
204
- delete this.state[i];
205
- Object.assign(this.state, s), this.#e = !1, e.silent || this.render();
206
- } else
207
- e?.silent ? (this.#e = !0, Object.assign(this.state, s), this.#e = !1) : Object.assign(this.state, s);
208
- }
209
- /**
210
- * Watch a state slice and react to changes
211
- * @param selector - Function to select a slice of state
212
- * @param callback - Function called when selected value changes
213
- * @returns Unsubscribe function
214
- * @example
215
- * const unwatch = component.watch(
216
- * state => state.count,
217
- * (count, prevCount) => console.log('Count changed:', count, prevCount)
218
- * );
219
- * unwatch(); // Stop watching
220
- */
221
- watch(t, e) {
222
- const s = ++this.#h, i = t(this.state);
223
- this.#c.set(s, {
224
- callback: e,
225
- lastValue: i,
226
- selector: t
227
- });
228
- try {
229
- e(i, i);
230
- } catch {
231
- }
232
- return () => this.#c.delete(s);
233
- }
234
- /**
235
- * Find single element in shadow DOM
236
- * @param selector - CSS selector
237
- * @returns First matching element or null
238
- * @example component.find<HTMLInputElement>('input[name="email"]')
239
- */
240
- find(t) {
241
- return this.shadow.querySelector(t);
242
- }
243
- /**
244
- * Find all matching elements in shadow DOM
245
- * @param selector - CSS selector
246
- * @returns Array of matching elements
247
- * @example component.findAll<HTMLButtonElement>('button')
248
- */
249
- findAll(t) {
250
- return Array.from(this.shadow.querySelectorAll(t));
251
- }
252
- /**
253
- * Add event listener with automatic cleanup
254
- *
255
- * Supports event delegation for dynamic elements:
256
- * - If target is a string selector, uses delegation on shadow root
257
- * - Events bubble up and handler is called when target matches selector
258
- * - Works for elements added after registration
259
- *
260
- * @param target - CSS selector or EventTarget
261
- * @param event - Event name
262
- * @param handler - Event handler function
263
- * @param options - Event listener options
264
- *
265
- * @example
266
- * // Direct element binding
267
- * const button = component.find('button')!;
268
- * component.on(button, 'click', () => console.log('clicked'));
269
- *
270
- * // Delegated binding (works for dynamic elements)
271
- * component.on('button', 'click', (e) => {
272
- * console.log('Button clicked:', e.target);
273
- * });
274
- *
275
- * // Delegated with event filtering
276
- * component.on('.todo-item', 'click', (e) => {
277
- * const item = e.target as HTMLElement;
278
- * console.log('Todo clicked:', item.dataset.id);
279
- * });
280
- */
281
- on(t, e, s, i) {
282
- if (typeof t == "string") {
283
- const n = t, o = (a) => {
284
- const c = a.target;
285
- if (!c?.matches) return;
286
- const h = c.matches(n) ? c : c.closest(n);
287
- h && this.shadow.contains(h) && (Object.defineProperty(a, "currentTarget", {
288
- configurable: !0,
289
- value: h
290
- }), s.call(h, a));
291
- };
292
- this.shadow.addEventListener(e, o, {
293
- ...i,
294
- signal: this.#r.signal
295
- });
296
- } else
297
- t.addEventListener(e, s, {
298
- ...i,
299
- signal: this.#r.signal
300
- });
301
- }
302
- /**
303
- * Dispatch custom event
304
- * @param name - Event name
305
- * @param detail - Event detail data
306
- * @param options - CustomEvent options
307
- */
308
- emit(t, e, s) {
309
- this.dispatchEvent(
310
- new CustomEvent(t, {
311
- bubbles: !0,
312
- composed: !0,
313
- detail: e,
314
- ...s
315
- })
316
- );
317
- }
318
- /**
319
- * Set timeout with automatic cleanup
320
- * @param callback - Function to call after delay
321
- * @param ms - Delay in milliseconds
322
- * @returns Timeout ID
323
- */
324
- delay(t, e) {
325
- const s = setTimeout(() => {
326
- this.#i.delete(s), t();
327
- }, e);
328
- return this.#i.add(s), s;
329
- }
330
- /**
331
- * Clear a scheduled timeout
332
- * @param id - Timeout ID returned from delay()
333
- */
334
- clear(t) {
335
- clearTimeout(t), this.#i.delete(t);
336
- }
337
- /* ==================== Rendering ==================== */
338
- /**
339
- * Perform rendering with error handling and node cloning
340
- */
341
- performRender() {
342
- const { template: t } = this.#t;
343
- try {
344
- let e;
345
- typeof t == "function" ? e = t(this) : e = t;
346
- let s;
347
- if (typeof e == "string")
348
- s = Array.from(y(e).childNodes);
349
- else if (e instanceof DocumentFragment) {
350
- const i = e.cloneNode(!0);
351
- s = Array.from(i.childNodes);
352
- } else
353
- s = [e.cloneNode(!0)];
354
- this.reconcile(this.shadow, s), this.#t.onUpdated?.(this);
355
- } catch (e) {
356
- const s = e instanceof Error ? e.message : String(e), i = e instanceof Error ? e.stack : "";
357
- console.error("[craftit] Render error:", e), this.shadow.innerHTML = `
358
- <div style="color: red; padding: 1rem; border: 1px solid red; border-radius: 4px; font-family: monospace;" data-debug="render-error">
359
- <strong>Render Error</strong>
360
- <p style="margin: 0.5rem 0;">${s}</p>
361
- ${i ? `<details style="margin: 0.5rem 0;"><summary>Stack Trace</summary><pre style="overflow: auto; font-size: 0.8em;">${i}</pre></details>` : ""}
362
- <button onclick="this.getRootNode().host.render()" style="margin-top: 0.5rem; padding: 0.25rem 0.5rem; cursor: pointer;">
363
- Retry Render
364
- </button>
365
- </div>
366
- `;
367
- }
368
- }
369
- /**
370
- * Reconcile DOM nodes using index-based diffing
371
- * @remarks Works well for static/append-only lists. For frequently reordered lists,
372
- * consider keyed diffing libraries (lit-html, uhtml).
373
- */
374
- // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: DOM reconciliation requires conditional logic
375
- reconcile(t, e) {
376
- const s = Array.from(t.childNodes), i = Math.max(s.length, e.length);
377
- for (let n = 0; n < i; n++) {
378
- const o = s[n], a = e[n];
379
- if (!o && a) {
380
- t.appendChild(a);
381
- continue;
382
- }
383
- if (o && !a) {
384
- t.removeChild(o);
385
- continue;
386
- }
387
- if (o && a) {
388
- if (o.nodeType !== a.nodeType) {
389
- t.replaceChild(a, o);
390
- continue;
391
- }
392
- if (o.nodeType === Node.TEXT_NODE) {
393
- o.textContent !== a.textContent && (o.textContent = a.textContent);
394
- continue;
395
- }
396
- if (o instanceof Element && a instanceof Element) {
397
- if (o.tagName !== a.tagName) {
398
- t.replaceChild(a, o);
399
- continue;
400
- }
401
- this.updateElement(o, a);
402
- }
403
- }
404
- }
405
- }
406
- /**
407
- * Update element attributes and children
408
- */
409
- updateElement(t, e) {
410
- const s = Array.from(t.attributes), i = Array.from(e.attributes);
411
- for (const { name: n } of s)
412
- e.hasAttribute(n) || t.removeAttribute(n);
413
- for (const { name: n, value: o } of i)
414
- t.getAttribute(n) !== o && t.setAttribute(n, o);
415
- t instanceof HTMLInputElement ? this.updateInputElement(t, e) : t instanceof HTMLTextAreaElement ? this.updateTextAreaElement(t, e) : t instanceof HTMLSelectElement && this.updateSelectElement(t, e), this.reconcile(t, Array.from(e.childNodes));
416
- }
417
- // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Form element syncing requires handling multiple input types
418
- updateInputElement(t, e) {
419
- if (t.type === "checkbox" || t.type === "radio") {
420
- const n = e.hasAttribute("checked");
421
- t.checked !== n && (t.checked = n);
422
- } else {
423
- if (t.type === "file")
424
- return;
425
- if (e.hasAttribute("value")) {
426
- const n = e.getAttribute("value") || "";
427
- t.value !== n && (t.value = n);
428
- } else t.value !== "" && (t.value = "");
429
- }
430
- const s = e.hasAttribute("disabled");
431
- t.disabled !== s && (t.disabled = s);
432
- const i = e.hasAttribute("readonly");
433
- t.readOnly !== i && (t.readOnly = i);
434
- }
435
- updateTextAreaElement(t, e) {
436
- const s = e.textContent || "";
437
- t.value !== s && (t.value = s);
438
- const i = e.hasAttribute("disabled");
439
- t.disabled !== i && (t.disabled = i);
440
- const n = e.hasAttribute("readonly");
441
- t.readOnly !== n && (t.readOnly = n);
442
- }
443
- updateSelectElement(t, e) {
444
- const s = e.hasAttribute("disabled");
445
- if (t.disabled !== s && (t.disabled = s), e.hasAttribute("value")) {
446
- const i = e.getAttribute("value") || "";
447
- t.value !== i && (t.value = i);
448
- }
449
- }
450
- }
451
- const v = (r) => {
452
- class t extends A {
453
- static formAssociated = r.formAssociated;
454
- static get observedAttributes() {
455
- return r.observedAttributes || [];
456
- }
457
- constructor() {
458
- super(r);
459
- }
460
- }
461
- return t;
462
- }, C = (r, t) => {
463
- if (customElements.get(r)) {
464
- console.warn(`[craftit] Element "${r}" already defined`);
465
- return;
466
- }
467
- customElements.define(r, v(t));
468
- }, w = (r, t) => (C(r, t), customElements.get(r)), $ = (r, ...t) => r.reduce((e, s, i) => {
469
- const n = t[i] ?? "";
470
- return e + s + n;
471
- }, ""), x = Object.assign(
472
- (r, ...t) => r.reduce((e, s, i) => {
473
- const n = t[i] ?? "";
474
- return e + s + n;
475
- }, ""),
476
- {
477
- /**
478
- * Create a typed theme with CSS variables and autocomplete
479
- *
480
- * Single theme mode:
481
- * Returns a typed proxy with autocomplete for all theme properties
482
- *
483
- * Light/dark mode:
484
- * Returns the same typed proxy - CSS handles which theme applies via media queries
485
- * You reference variables the same way regardless of theme mode
486
- *
487
- * @param light - Theme variables (or light theme for dual-mode)
488
- * @param dark - Optional dark theme variables
489
- * @param options - Configuration options
490
- * @param options.selector - CSS selector (default: ':host')
491
- * @param options.attribute - Attribute for manual override (default: 'data-theme')
492
- * @returns Typed proxy with autocomplete
493
- *
494
- * @example
495
- * // Single theme
496
- * const theme = css.theme({
497
- * primaryColor: '#3b82f6',
498
- * spacing: '1rem',
499
- * });
500
- *
501
- * css`
502
- * ${theme}
503
- * .button {
504
- * color: ${theme.primaryColor}; // Autocomplete!
505
- * padding: ${theme.spacing};
506
- * }
507
- * `
508
- *
509
- * @example
510
- * // Light/dark theme - same variable references!
511
- * const theme = css.theme(
512
- * { bg: '#fff', text: '#000' }, // Light
513
- * { bg: '#000', text: '#fff' } // Dark
514
- * );
515
- *
516
- * css`
517
- * ${theme}
518
- * .card {
519
- * background: ${theme.bg}; // Autocomplete! CSS handles light/dark
520
- * color: ${theme.text}; // Same variable for both themes
521
- * }
522
- * `
523
- */
524
- theme: ((r, t, e) => {
525
- const s = e?.selector ?? ":host", i = (o) => Object.entries(o).map(([a, c]) => `${a.startsWith("--") ? a : `--${l(a)}`}: ${c};`).join(" ");
526
- let n;
527
- if (!t)
528
- n = `${s} { ${i(r)} }`;
529
- else {
530
- const o = e?.attribute ?? "data-theme", a = i(r), c = i(t);
531
- n = `
532
- ${s} { ${a} }
533
- @media (prefers-color-scheme: dark) {
534
- ${s}:not([${o}="light"]) { ${c} }
535
- }
536
- ${s}[${o}="dark"] { ${c} }
537
- ${s}[${o}="light"] { ${a} }
538
- `.trim();
539
- }
540
- return new Proxy({}, {
541
- get(o, a) {
542
- if (a === "toString" || a === Symbol.toPrimitive)
543
- return () => n;
544
- if (typeof a == "string" && a in r)
545
- return `var(${a.startsWith("--") ? a : `--${l(a)}`})`;
546
- }
547
- });
548
- }),
549
- /**
550
- * Reference a CSS custom property with var()
551
- * Automatically converts camelCase to --kebab-case
552
- * @param name - Variable name (with or without --)
553
- * @param fallback - Optional fallback value
554
- * @returns var() function string
555
- * @example css.var('primaryColor') // "var(--primary-color)"
556
- */
557
- var: (r, t) => {
558
- const e = r.startsWith("--") ? r : `--${l(r)}`;
559
- return t !== void 0 ? `var(${e}, ${t})` : `var(${e})`;
560
- }
561
- }
562
- ), k = (r) => Object.entries(r).filter(([, t]) => t).map(([t]) => t).join(" "), R = (r) => Object.entries(r).filter(([, t]) => t != null).map(([t, e]) => `${l(t)}: ${e}`).join("; ");
563
- async function V(r, t = document.body) {
564
- return t.appendChild(r), "flush" in r && typeof r.flush == "function" ? await r.flush() : await new Promise((e) => requestAnimationFrame(e)), r;
565
- }
566
- function T(r) {
567
- r.remove();
568
- }
569
- export {
570
- V as attach,
571
- k as classMap,
572
- v as createComponent,
573
- x as css,
574
- C as defineElement,
575
- T as destroy,
576
- w as element,
577
- $ as html,
578
- R as styleMap
579
- };
580
- //# sourceMappingURL=craftit.js.map
1
+ import{batch as e,computed as t,effect as n,isSignal as r,onCleanup as i,signal as a,untrack as o,watch as s}from"@vielzeug/stateit";export*from"@vielzeug/stateit";var c=0,l=e=>{for(let t of e)t()},u=(e,t,n)=>{/^on/i.test(t)||n==null||!1===n?e.removeAttribute(t):!0===n?e.setAttribute(t,``):e.setAttribute(t,String(n))},d=(e,t,n,r)=>{let i=n;return e.addEventListener(t,i,r),()=>e.removeEventListener(t,i,r)},f=e=>`${e?`${e}-`:`cft-`}${++c}`,p=(e,t)=>{let n=`${e}-${t&&t.trim()?t:f(e)}`;return{errorId:`error-${n}`,fieldId:n,helperId:`helper-${n}`,labelId:`label-${n}`}},m=(e,t)=>n=>{e()&&t(n)},h=e=>e.replace(/[A-Z]/g,e=>`-${e.toLowerCase()}`),g={"'":`&#39;`,'"':`&quot;`,"&":`&amp;`,"<":`&lt;`,">":`&gt;`},_=e=>String(e).replace(/[&<>"']/g,e=>g[e]),v=function(){return this.content},ee=(e,...t)=>{let n=``;for(let r=0;r<e.length;r++)if(n+=e[r],r<t.length){let e=t[r];n+=e&&typeof e==`object`&&`content`in e?e.content:e??``}return{content:n.trim(),toString:v}},y=new Map,te=e=>{if(e instanceof CSSStyleSheet)return e;let t=typeof e==`string`?e:e.content,n=y.get(t);if(n)return n;let r=new CSSStyleSheet;try{r.replaceSync(t),y.set(t,r)}catch(e){console.error(`[craftit:E2] style replace failed`,e)}return r},b=[],x=()=>{let e=b[b.length-1];if(!e)throw Error(`[craftit:E1] lifecycle outside setup`);return e},S=e=>{x().onMount.push(e)},C=e=>{b.length>0?x().cleanups.push(e):i(e)},ne=e=>{x().errorHandlers.push(e)},w=e=>{b.length>0&&C(e)},T=(e,t)=>{let r=n(e,t);return w(r),r};function re(e,t,r){if(Array.isArray(e)){let i=r,a=!1,s=!1,c=n(()=>{for(let t of e)t.value;if(a)o(t),i?.once&&c();else if(a=!0,i?.immediate&&(o(t),i.once))return void(s=!0)});return w(c),s&&c(),c}let i=s(e,t,r);return w(i),i}function E(e,t,n,r){e&&(e.addEventListener(t,n,r),C(()=>e.removeEventListener(t,n,r)))}var D={bubbles:!0,cancelable:!0,composed:!0},O={basic:(e,t,n={})=>e.dispatchEvent(new Event(t,{...D,...n})),custom:(e,t,n={})=>e.dispatchEvent(new CustomEvent(t,{...D,...n})),event:(e,t)=>e.dispatchEvent(t),focus:(e,t,n={})=>e.dispatchEvent(new FocusEvent(t,{...D,...n})),keyboard:(e,t,n={})=>e.dispatchEvent(new KeyboardEvent(t,{...D,...n})),mouse:(e,t,n={})=>e.dispatchEvent(new MouseEvent(t,{...D,...n})),touch:(e,t,n={})=>typeof TouchEvent<`u`?e.dispatchEvent(new TouchEvent(t,{...D,...n})):e.dispatchEvent(new CustomEvent(t,{...D,...n}))};function ie(e,t){let n=t===void 0?x().el:e,r=Object.entries(t===void 0?e:t).map(([e,t])=>T(()=>((e,t)=>{let r=`aria-${e}`,i=typeof t==`function`?t():t;i==null||!1===i?n.removeAttribute(r):n.setAttribute(r,String(i))})(e,t)));if(t!==void 0)return()=>{for(let e of r)e()}}var k=new WeakMap,ae=(e,t)=>{let n=x().el;k.has(n)||k.set(n,new Map),k.get(n).set(e,t)};function oe(e,...t){let n=x().el;for(;n;){if(n instanceof HTMLElement){let t=k.get(n)?.get(e);if(t!==void 0)return t}let t=n.getRootNode();n=n.parentElement??(t instanceof ShadowRoot?t.host:null)}return t.length>0?t[0]:void 0}function se(e){return Symbol(e)}var ce=(e,t,n)=>{e&&S(()=>{T(()=>{for(let r of n){let n=e[r]?.value;n!==void 0&&(t[r].value=n)}})})},le=new Set,ue=(e,t,n)=>{let r=`${n}:${e.localName}:${t||`default`}`;le.has(r)||(le.add(r),console.warn(`[craftit:E10] ${n} could not find a matching <slot${t?` name="${t}"`:``}> in <${e.localName}>. Render the slot before using ${n}.`))},de=(e,t)=>{let n=x().el,r=e===`default`?``:e,i=r?`slot[name="${r}"]`:`slot:not([name])`,a=n.shadowRoot?.querySelector(i);if(!a)return void ue(n,r,`onSlotChange()`);let o=()=>t(a.assignedElements({flatten:!0}));o(),a.addEventListener(`slotchange`,o),C(()=>a.removeEventListener(`slotchange`,o))};function A(e,t){for(let[n,r]of Object.entries(t))if(n===`classMap`)pe(e,r);else if(n.startsWith(`on`)&&n.length>2&&typeof r==`function`){let t=n.slice(2);E(e,t[0].toLowerCase()+t.slice(1),r)}else fe(e,n,r)}function fe(e,t,n){typeof n==`function`?T(()=>u(e,t,n())):u(e,t,n)}function pe(e,t){let n=new Set;T(()=>{let r=new Set(Object.entries(t()).filter(([,e])=>e).map(([e])=>e));for(let t of n)r.has(t)||e.classList.remove(t);for(let t of r)n.has(t)||e.classList.add(t);n=r})}var j=Symbol(`craftit.htmlResultBrand`);function me(){return{value:null}}function he(){return[]}function M(e,t=[]){let n={__bindings:t,__html:e,toString:()=>e};return Object.defineProperty(n,j,{configurable:!1,enumerable:!1,value:!0,writable:!1}),n}var N=e=>typeof e==`object`&&!!e&&!0===e[j],P=Symbol(`craftit.eachSignal`),F=e=>r(e)?e:typeof e==`function`?t(e):void 0,ge=e=>{if(!r(e))return!1;let t=Object.getPrototypeOf(e);for(;t;){let e=Object.getOwnPropertyDescriptor(t,`value`);if(e)return typeof e.set==`function`;t=Object.getPrototypeOf(t)}return!1},I=(e,t)=>{if(!Object.is(e.value,t))try{e.value=t}catch{}},L=new Map,R=e=>(e=>{let t=L.get(e);if(!t){if(t=document.createElement(`template`),t.innerHTML=e,L.size>=1e3){let e=L.keys().next().value;e!==void 0&&L.delete(e)}L.set(e,t)}return t})(e).content.cloneNode(!0),z=(e,t)=>{if(e.nodeType===Node.COMMENT_NODE){let n=e.nodeValue;n&&t.comments.set(n,e);return}if(e.nodeType!==Node.ELEMENT_NODE)return;let n=e.getAttribute(`u`);n&&t.elements.set(n,e)},B=e=>{let t={comments:new Map,elements:new Map};for(let n of e){let e=document.createTreeWalker(n,NodeFilter.SHOW_COMMENT|NodeFilter.SHOW_ELEMENT);for(z(n,t);e.nextNode();)z(e.currentNode,t)}return t},V=e=>Array.from(R(e).childNodes),H=(e,t,n)=>{if(e.parentNode)for(let r of t)e.parentNode.insertBefore(r,n)},U=e=>Array.isArray(e)||typeof e==`object`&&!!e,W=(e,t,n)=>{n(T(()=>t(e.value)))},_e=(e,t,n)=>{let r=n=>{let r=$.get(e)?.get(t.name);if(!r&&U(n))return void(e[t.name]=n);if(r&&!r.reflect||(t.mode===`bool`?e.toggleAttribute(t.name,!!n):u(e,t.name,n)),!r)return;let i=U(n)?n:r.parse(t.mode===`bool`?n?``:null:n==null||!1===n?null:String(n));Object.is(r.signal.peek(),i)||(r.signal.value=i)};t.signal?W(t.signal,r,n):r(t.value)},ve=(e,t,n)=>{let r=n=>{e[t.name]=n};t.signal?W(t.signal,r,n):r(t.value),((e,t,n,r)=>{n&&(t===`value`?(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement)&&r(d(e,e instanceof HTMLSelectElement?`change`:`input`,()=>{I(n,e.value)})):t===`checked`&&e instanceof HTMLInputElement&&r(d(e,`change`,()=>{I(n,e.checked)})))})(e,t.name,t.model,n)},ye=(e,t,n)=>{let{modifiers:r}=t,i=r?{capture:!!r.capture,once:!!r.once,passive:!!r.passive}:void 0;n(d(e,t.name,e=>{r?.self&&e.target!==e.currentTarget||(r?.stop&&e.stopPropagation(),r?.prevent&&!r?.passive&&e.preventDefault(),t.handler(e))},i))},be=(e,t,n)=>{let{ref:r}=t;typeof r==`function`?(r(e),n(()=>r(null))):Array.isArray(r)?(r.push(e),n(()=>{let t=r.indexOf(e);t!==-1&&r.splice(t,1)})):(r.value=e,n(()=>{r.value=null}))},G=(e,t,n,r)=>{let i=new Map;for(let a of e){let e=a.uid;if(a.type===`text`){let r=n.comments.get(e);if(r){let i=document.createTextNode(``);r.replaceWith(i),n.comments.delete(e),W(a.signal,e=>{i.textContent=String(e)},t)}}else a.type===`html`?r?.onHtml?.(a):(i.has(e)||i.set(e,[]),i.get(e).push(a))}for(let[e,r]of i){let i=n.elements.get(e);if(i){i.removeAttribute(`u`),n.elements.delete(e);for(let e of r)switch(e.type){case`attr`:_e(i,e,t);break;case`callback`:e.apply(i,t);break;case`event`:ye(i,e,t);break;case`prop`:ve(i,e,t);break;case`ref`:be(i,e,t)}}}},K=(e,t,n,r)=>{let i=F(r);return i?{mode:e,name:t,signal:i,type:`attr`,uid:n}:{mode:e,name:t,type:`attr`,uid:n,value:r}},xe=(e,t,n)=>{let r=F(n);return r?{model:ge(n)?n:void 0,name:e,signal:r,type:`prop`,uid:t}:{name:e,type:`prop`,uid:t,value:n}},Se=RegExp(`u="([^"]+)"`,`g`),Ce=[{kind:`event`,regex:/\s+@([a-zA-Z_][-a-zA-Z0-9_.]*)\s*=\s*["']?$/},{kind:`ref`,regex:/\s+ref\s*=\s*["']?$/},{kind:`specialAttr`,regex:/\s+([:?])([a-zA-Z_][-a-zA-Z0-9_]*)\s*=\s*["']?$/},{kind:`prop`,regex:/\.([a-zA-Z_][-a-zA-Z0-9_]*)\s*=\s*["']?$/},{kind:`plainAttr`,regex:/\s+([a-zA-Z_][-a-zA-Z0-9_]*)\s*=\s*["']?$/}],q=new WeakMap,we=e=>{let[t,...n]=e.split(`.`),r={};for(let e of n)e===`capture`?r.capture=!0:e===`once`?r.once=!0:e===`passive`?r.passive=!0:e===`prevent`?r.prevent=!0:e===`self`?r.self=!0:e===`stop`&&(r.stop=!0);return{modifiers:Object.keys(r).length?r:void 0,name:t}},J=()=>{let e=0;return()=>String(e++)},Y=(e,t)=>{let n=new Map,r=e=>{let r=n.get(e);if(r)return r;let i=t();return n.set(e,i),i};return{bindings:e.__bindings.map(e=>({...e,uid:r(e.uid)})),html:e.__html.replace(Se,(e,t)=>`u="${r(t)}"`).replace(/<!--(\d+)-->/g,(e,t)=>`\x3c!--${r(t)}--\x3e`)}},X=e=>typeof e==`string`?_(e):e==null?``:N(e)?e.__html:_(String(e)),Te=(e,n)=>{let i=(e=>typeof e==`object`&&e&&P in e?e[P]:null)(e);if(i)return{keyed:!0,signal:i};if(typeof e==`function`&&!r(e)){let{signal:t}=((e,t)=>{let n={bindings:[],html:``},r=a(n);return t(()=>{let t=e(),i=Array.isArray(t)?t:[t],a=J(),o=``,s=[];for(let e of i)if(N(e)){let t=Y(e,a);o+=t.html,s.push(...t.bindings)}else o+=X(e);let c=s.length!==n.bindings.length||s.some((e,t)=>e!==n.bindings[t]);(o!==n.html||c)&&(n={bindings:s,html:o},r.value=n)}),{bindings:[],signal:r}})(e,n);return{keyed:!1,signal:t}}return r(e)&&N(e.value)?{keyed:!1,signal:t(()=>{let t=e.value;if(!N(t))return{bindings:[],html:X(t)};let n=Y(t,J());return{bindings:n.bindings,html:n.html}})}:null},Ee=e=>{l(e.cleanups);for(let t of e.nodes)t.remove()},Z=(e,t,n=B(e))=>{let r=[];return G(t,e=>r.push(e),n),r},De=(t,r,i,a,s)=>{let c=((e,t)=>{let n=document.createTreeWalker(e,NodeFilter.SHOW_COMMENT);for(;n.nextNode();){let e=n.currentNode;if(e.nodeValue===t)return e}return null})(t,r.uid);if(!c)return;let u=document.createComment(`html-binding`);c.replaceWith(u);let d=[],f=e=>d.push(e),p=()=>{l(d),d=[]},m=null,h=[];i(n(()=>{e(()=>{let n=r.signal.value;if(!r.keyed&&n.html===m)return;m=n.html,p();let{bindings:i,html:c,keys:d}=n;r.keyed&&!a.has(r.uid)&&a.set(r.uid,new Map);let g=r.keyed?a.get(r.uid):null,_=u.parentElement||t,v=!1;o(()=>{e(()=>{if(g&&d?.length&&n.items?.length===d.length){if(v=!0,g.size===0&&h.length>0){for(let e of h)e.remove();h=[]}let e=new Map;for(let t=0;t<d.length;t++){let r=d[t],i=n.items[t],a=g.get(r),o=t>0?e.get(d[t-1])?.nodes:null,s=o?.length?o[o.length-1].nextSibling:u.nextSibling;if(a?.html===i.html){a.nodes[0]&&H(u,a.nodes,s),l(a.cleanups);let t=B(a.nodes),n=Z(a.nodes,i.bindings,t);e.set(r,{...a,bindings:i.bindings,cleanups:n,targets:t})}else if(a){l(a.cleanups);let t=V(i.html),n=B(t);H(u,t,s);let o=Z(t,i.bindings,n);e.set(r,{bindings:i.bindings,cleanups:o,html:i.html,nodes:t,targets:n});for(let e of a.nodes)e.remove()}else{let t=V(i.html),n=B(t);H(u,t,s);let a=Z(t,i.bindings,n);e.set(r,{bindings:i.bindings,cleanups:a,html:i.html,nodes:t,targets:n})}}for(let[t,n]of g)e.has(t)||Ee(n);a.set(r.uid,e)}else{if(r.keyed&&g&&g.size>0)for(let[,e]of g)Ee(e);else for(let e of h)e.remove();let e=R(c);h=Array.from(e.childNodes),u.after(e),r.keyed&&a.set(r.uid,new Map)}}),v||s(_,i,f,{onHtml:e=>De(_,e,f,a,s)})})})})),i(p),r.keyed&&i(()=>a.delete(r.uid))},Oe=(e,t,n,r)=>{G(t,n,(e=>{let t={comments:new Map,elements:new Map},n=document.createTreeWalker(e,NodeFilter.SHOW_COMMENT|NodeFilter.SHOW_ELEMENT);for(z(e,t);n.nextNode();)z(n.currentNode,t);return t})(e),r)},ke=(e,...t)=>((e,t,n)=>{let i=(e=>{let t=q.get(e);return t||(t=(e=>{let t=[];for(let n=0;n<e.length-1;n++){let r=e[n],i=!1;for(let e of Ce){let n=e.regex.exec(r);if(!n)continue;let a=r.slice(0,-n[0].length);if(i=!0,e.kind===`event`){let e=we(n[1]);t.push({kind:`event`,modifiers:e.modifiers,name:e.name,prefix:a,raw:r})}else e.kind===`ref`?t.push({kind:`ref`,prefix:a,raw:r}):e.kind===`specialAttr`?t.push({kind:`specialAttr`,mode:n[1]===`?`?`bool`:`attr`,name:n[2],prefix:a,raw:r}):e.kind===`prop`?t.push({kind:`prop`,name:n[1],prefix:a,raw:r}):e.kind===`plainAttr`&&t.push({kind:`plainAttr`,name:n[1],prefix:a,raw:r});break}i||t.push({kind:`node`,prefix:r,raw:r})}return{slots:t,tail:e[e.length-1]??``}})(e),q.set(e,t)),t})(e),o=``,s=[],c=null,l=J(),u=e=>(c&&!(e=>e.lastIndexOf(`<`)>e.lastIndexOf(`>`))(e)||(c=l()),c),d=()=>{c=null};for(let e=0;e<i.slots.length;e++){let c=i.slots[e],f=t[e];if(c.kind===`event`){if(typeof f==`function`){let e=u(c.prefix);o+=`${c.prefix} u="${e}"`,s.push({handler:f,modifiers:c.modifiers,name:c.name,type:`event`,uid:e})}else o+=c.raw;continue}if(c.kind===`ref`){if(f){let e=u(c.prefix);o+=`${c.prefix} u="${e}"`,s.push({ref:f,type:`ref`,uid:e})}else o+=c.raw;continue}if(c.kind===`specialAttr`){let e=u(c.prefix);o+=`${c.prefix} u="${e}"`,s.push(K(c.mode,c.name,e,f));continue}if(c.kind===`prop`){let e=u(c.prefix);o+=`${c.prefix} u="${e}"`,s.push(xe(c.name,e,f));continue}if(c.kind===`plainAttr`){let e=u(c.prefix);o+=`${c.prefix} u="${e}"`,s.push(K(`attr`,c.name,e,f));continue}if(typeof f==`object`&&f&&(`mount`in f||`render`in f)){let e=`render`in f,t=e?l():u(c.raw);o+=e?`${c.raw}\x3c!--${t}--\x3e`:`${c.raw} u="${t}"`;let r=f.mount?.bind(f);if(r&&s.push({apply:(e,t)=>{r(e,{registerCleanup:t})},type:`callback`,uid:t}),e){let e=f.render.bind(f),r={bindings:[],html:``},i=a(r);n(()=>{let t=e(),n=Array.isArray(t)?t:[t],a=J(),o=``,s=[];for(let e of n)if(N(e)){let t=Y(e,a);o+=t.html,s.push(...t.bindings)}else o+=X(e);let c=s.length!==r.bindings.length||s.some((e,t)=>e!==r.bindings[t]);(o!==r.html||c)&&(r={bindings:s,html:o},i.value=r)}),s.push({keyed:!1,signal:i,type:`html`,uid:t})}continue}d();let p=Te(f,n);if(p){let e=l();o+=`${c.raw}\x3c!--${e}--\x3e`,s.push({keyed:p.keyed,signal:p.signal,type:`html`,uid:e});continue}if(Array.isArray(f)){let e=``;for(let t of f)if(N(t)){let n=Y(t,l);e+=n.html,s.push(...n.bindings)}else e+=X(t);o+=c.raw+e;continue}if(r(f)){let e=l();o+=`${c.raw}\x3c!--${e}--\x3e`,s.push({signal:f,type:`text`,uid:e})}else if(N(f)){let e=Y(f,l);o+=c.raw+e.html,s.push(...e.bindings)}else o+=c.raw+X(f)}return o+=i.tail,M((e=>e.replace(/>\s+</g,`><`).trim())(o),s)})(e,t,T),Q=new WeakMap,Ae=new WeakMap,je=(e,t)=>{let r=x().el;if(!r.constructor.formAssociated)throw Error(`[craftit:E8] defineField() requires defineComponent({ formAssociated: true })`);let i=Ae.get(r)??r.attachInternals();Ae.set(r,i);let a=e.toFormValue??(e=>e==null?``:String(e));return n(()=>{i.setFormValue(a(e.value.value))}),e.disabled&&n(()=>{e.disabled.value?i.states.add(`disabled`):i.states.delete(`disabled`)}),t&&Q.set(r,{...Q.get(r),...t}),{checkValidity:()=>i.checkValidity(),internals:i,reportValidity:()=>i.reportValidity(),setCustomValidity:e=>e?i.setValidity({customError:!0},e):i.setValidity({}),setValidity:i.setValidity.bind(i)}},Me=new Set([`default`,`omit`,`parse`,`reflect`,`type`]),Ne=e=>typeof e==`object`&&!!e&&`default`in e&&Object.keys(e).every(e=>Me.has(e)),$=new WeakMap,Pe=(e,t,r)=>{let i=x(),o=i.el;$.has(o)||$.set(o,new Map);let s=r?.parse??(e=>r?.type===Boolean?e===``||e===`true`:typeof t==`boolean`?e!==null&&e!==`false`:e==null?t:r?.type===Number||typeof t==`number`?Number(e):e),c=a(t),l=Object.prototype.hasOwnProperty.call(o,e),d=l?o[e]:void 0,f={parse:s,reflect:r?.reflect??!0,signal:c};if(l?(delete o[e],c.value=d):o.hasAttribute(e)&&(c.value=s(o.getAttribute(e))),$.get(o).set(e,f),Object.defineProperty(o,e,{configurable:!0,enumerable:!0,get:()=>c.value,set:e=>{c.value=e}}),r?.reflect??1){let t=r?.omit??!1;i.onMount.push(()=>{i.cleanups.push(n(()=>{let n=c.value;n==null||!1===n||t&&n===``?o.removeAttribute(e):u(o,e,n)}))})}return c},Fe=(e,t)=>({...t,default:e}),Ie=class extends HTMLElement{static _setup;static _options;static formAssociated=!1;static observedAttributes=[];shadow;_keyedStates=new Map;_mountFns=[];_template=null;_appliedHtmlBindings=new Set;_setupDone=!1;_runtime;constructor(){super();let e=this.constructor._options;this.shadow=this.attachShadow({mode:`open`,...e?.shadow}),this._runtime={cleanups:[],el:this,errorHandlers:[],onMount:[],styles:e?.styles}}connectedCallback(){this._setupDone||this._runSetup(),this._init()}attributeChangedCallback(e,t,n){if(t===n)return;let r=$.get(this)?.get(e);if(!r)return;let i=r.parse(n);Object.is(r.signal.peek(),i)||(r.signal.value=i)}disconnectedCallback(){l(this._runtime.cleanups),this._runtime.cleanups=[],this._runtime.onMount=this._mountFns.slice(),this._appliedHtmlBindings.clear(),this._keyedStates.clear()}formAssociatedCallback(e){Q.get(this)?.onAssociated?.(e)}formDisabledCallback(e){Q.get(this)?.onDisabled?.(e)}formResetCallback(){Q.get(this)?.onReset?.()}formStateRestoreCallback(e,t){Q.get(this)?.onStateRestore?.(e,t)}_handleError(e){if(this._runtime.errorHandlers.length>0)for(let t of this._runtime.errorHandlers)t(e);else console.error(`[craftit:E3] <${this.localName}>`,e)}_runSetup(){this._setupDone=!0,b.push(this._runtime);try{let{host:e}=this.constructor._options??{};if(e)for(let[t,n]of Object.entries(e))typeof n==`boolean`?n?this.setAttribute(t,``):this.removeAttribute(t):this.setAttribute(t,String(n));let t=this.constructor._setup({host:this,shadow:this.shadow});(typeof t==`string`||typeof t==`object`&&t&&`__html`in t)&&(this._template=t)}catch(e){this._handleError(e)}finally{b.pop()}}_init(){let{styles:e}=this._runtime;if(e?.length&&(this.shadow.adoptedStyleSheets=e.map(te)),this._template){let e=typeof this._template==`string`?M(this._template):this._template;if(this.shadow.replaceChildren(R(e.__html)),e.__bindings.length){let t=e=>this._runtime.cleanups.push(e);Oe(this.shadow,e.__bindings,t,{onHtml:e=>{this._appliedHtmlBindings.has(e.uid)||(this._appliedHtmlBindings.add(e.uid),((e,t,n,r)=>{De(e,t,n,r,Oe)})(this.shadow,e,t,this._keyedStates))}})}}queueMicrotask(()=>{b.push(this._runtime);try{let e=this._runtime.onMount;this._mountFns=e.slice();for(let t of e){let e=t();typeof e==`function`&&this._runtime.cleanups.push(e)}}catch(e){this._handleError(e)}finally{b.pop(),this._runtime.onMount=[]}})}};function Le(e){let{formAssociated:t,host:n,props:r,setup:i,shadow:o,styles:s,tag:c}=e;return function(e,t,n={}){if(!e)throw Error(`[craftit:E4] registerComponent(tag, ...) requires a tag name`);if(customElements.get(e))throw Error(`[craftit:E9] custom element already defined: ${e}`);class r extends Ie{static _setup=t;static _options=n;static formAssociated=n.formAssociated??!1;static observedAttributes=n.observedAttrs??[]}return customElements.define(e,r),e}(c,e=>{let t=r?function(e){let t={};for(let[n,r]of Object.entries(e)){let e=Ne(r)?r:{default:r},i={reflect:!(typeof e.default==`object`&&e.default!==null||Array.isArray(e.default)),...e};t[n]=Pe(h(n),e.default,i)}return t}(r):{},n=(()=>{let e=x().el;return(t,...n)=>{O.custom(e,String(t),n.length>0?{detail:n[0]}:void 0)}})(),o=(()=>{let e=x().el,t=new Map;return{has:n=>(n=>{if(t.has(n))return t.get(n);let r=a(!1);return t.set(n,r),S(()=>{let t=n?`slot[name="${n}"]`:`slot:not([name])`,i=e.shadowRoot?.querySelector(t);if(!i)return void ue(e,n,`slots.has()`);let a=()=>{r.value=i.assignedNodes().length>0};return a(),i.addEventListener(`slotchange`,a),()=>i.removeEventListener(`slotchange`,a)}),r})(n===`default`?``:String(n))}})();return i({emit:n,host:e.host,props:t,reflect:t=>A(e.host,t),shadow:e.shadow,slots:o})},{formAssociated:t,host:n,observedAttrs:r?Object.keys(r).map(h):[],shadow:o,styles:s})}var Re=e=>{let t=a({height:0,width:0}),n=new ResizeObserver(([e])=>{if(!e)return;let n=e.contentBoxSize[0];n&&(t.value={height:n.blockSize,width:n.inlineSize})});return n.observe(e),C(()=>n.disconnect()),t};export{ie as aria,se as createContext,p as createFormIds,f as createId,ee as css,Le as defineComponent,je as defineField,T as effect,_ as escapeHtml,O as fire,m as guard,E as handle,ke as html,oe as inject,Re as observeResize,C as onCleanup,ne as onError,S as onMount,de as onSlotChange,Pe as prop,ae as provide,me as ref,A as reflect,he as refs,ce as syncContextProps,h as toKebab,Fe as typed,re as watch};
2
+ //# sourceMappingURL=craftit.js.map