@vielzeug/craftit 1.0.1 → 2.0.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.
- package/README.md +112 -401
- package/dist/core/component.cjs +2 -0
- package/dist/core/component.cjs.map +1 -0
- package/dist/core/component.d.ts +172 -0
- package/dist/core/component.d.ts.map +1 -0
- package/dist/core/component.js +2 -0
- package/dist/core/component.js.map +1 -0
- package/dist/core/host.cjs +2 -0
- package/dist/core/host.cjs.map +1 -0
- package/dist/core/host.d.ts +77 -0
- package/dist/core/host.d.ts.map +1 -0
- package/dist/core/host.js +2 -0
- package/dist/core/host.js.map +1 -0
- package/dist/core/internal.cjs +2 -0
- package/dist/core/internal.cjs.map +1 -0
- package/dist/core/internal.d.ts +105 -0
- package/dist/core/internal.d.ts.map +1 -0
- package/dist/core/internal.js +2 -0
- package/dist/core/internal.js.map +1 -0
- package/dist/core/runtime-bindings.cjs +2 -0
- package/dist/core/runtime-bindings.cjs.map +1 -0
- package/dist/core/runtime-bindings.d.ts +6 -0
- package/dist/core/runtime-bindings.d.ts.map +1 -0
- package/dist/core/runtime-bindings.js +2 -0
- package/dist/core/runtime-bindings.js.map +1 -0
- package/dist/core/runtime-lifecycle.cjs +2 -0
- package/dist/core/runtime-lifecycle.cjs.map +1 -0
- package/dist/core/runtime-lifecycle.d.ts +116 -0
- package/dist/core/runtime-lifecycle.d.ts.map +1 -0
- package/dist/core/runtime-lifecycle.js +2 -0
- package/dist/core/runtime-lifecycle.js.map +1 -0
- package/dist/core/runtime.cjs +1 -0
- package/dist/core/runtime.d.ts +3 -0
- package/dist/core/runtime.d.ts.map +1 -0
- package/dist/core/runtime.js +1 -0
- package/dist/core/template-bindings.cjs +2 -0
- package/dist/core/template-bindings.cjs.map +1 -0
- package/dist/core/template-bindings.d.ts +59 -0
- package/dist/core/template-bindings.d.ts.map +1 -0
- package/dist/core/template-bindings.js +2 -0
- package/dist/core/template-bindings.js.map +1 -0
- package/dist/core/template-compiler.cjs +2 -0
- package/dist/core/template-compiler.cjs.map +1 -0
- package/dist/core/template-compiler.d.ts +25 -0
- package/dist/core/template-compiler.d.ts.map +1 -0
- package/dist/core/template-compiler.js +2 -0
- package/dist/core/template-compiler.js.map +1 -0
- package/dist/core/template-dom.cjs +2 -0
- package/dist/core/template-dom.cjs.map +1 -0
- package/dist/core/template-dom.d.ts +13 -0
- package/dist/core/template-dom.d.ts.map +1 -0
- package/dist/core/template-dom.js +2 -0
- package/dist/core/template-dom.js.map +1 -0
- package/dist/core/template-html.cjs +2 -0
- package/dist/core/template-html.cjs.map +1 -0
- package/dist/core/template-html.d.ts +26 -0
- package/dist/core/template-html.d.ts.map +1 -0
- package/dist/core/template-html.js +2 -0
- package/dist/core/template-html.js.map +1 -0
- package/dist/core/template.cjs +2 -0
- package/dist/core/template.cjs.map +1 -0
- package/dist/core/template.d.ts +11 -0
- package/dist/core/template.d.ts.map +1 -0
- package/dist/core/template.js +2 -0
- package/dist/core/template.js.map +1 -0
- package/dist/core/utilities.cjs +2 -0
- package/dist/core/utilities.cjs.map +1 -0
- package/dist/core/utilities.d.ts +68 -0
- package/dist/core/utilities.d.ts.map +1 -0
- package/dist/core/utilities.js +2 -0
- package/dist/core/utilities.js.map +1 -0
- package/dist/craftit.cjs +2 -18
- package/dist/craftit.cjs.map +1 -1
- package/dist/craftit.js +2 -580
- package/dist/craftit.js.map +1 -1
- package/dist/directives/attr.cjs +2 -0
- package/dist/directives/attr.cjs.map +1 -0
- package/dist/directives/attr.d.ts +14 -0
- package/dist/directives/attr.d.ts.map +1 -0
- package/dist/directives/attr.js +2 -0
- package/dist/directives/attr.js.map +1 -0
- package/dist/directives/bind.cjs +2 -0
- package/dist/directives/bind.cjs.map +1 -0
- package/dist/directives/bind.d.ts +30 -0
- package/dist/directives/bind.d.ts.map +1 -0
- package/dist/directives/bind.js +2 -0
- package/dist/directives/bind.js.map +1 -0
- package/dist/directives/choose.cjs +2 -0
- package/dist/directives/choose.cjs.map +1 -0
- package/dist/directives/choose.d.ts +34 -0
- package/dist/directives/choose.d.ts.map +1 -0
- package/dist/directives/choose.js +2 -0
- package/dist/directives/choose.js.map +1 -0
- package/dist/directives/classes.cjs +2 -0
- package/dist/directives/classes.cjs.map +1 -0
- package/dist/directives/classes.d.ts +20 -0
- package/dist/directives/classes.d.ts.map +1 -0
- package/dist/directives/classes.js +2 -0
- package/dist/directives/classes.js.map +1 -0
- package/dist/directives/each.cjs +2 -0
- package/dist/directives/each.cjs.map +1 -0
- package/dist/directives/each.d.ts +68 -0
- package/dist/directives/each.d.ts.map +1 -0
- package/dist/directives/each.js +2 -0
- package/dist/directives/each.js.map +1 -0
- package/dist/directives/index.cjs +1 -0
- package/dist/directives/index.d.ts +14 -0
- package/dist/directives/index.d.ts.map +1 -0
- package/dist/directives/index.js +1 -0
- package/dist/directives/match.cjs +2 -0
- package/dist/directives/match.cjs.map +1 -0
- package/dist/directives/match.d.ts +31 -0
- package/dist/directives/match.d.ts.map +1 -0
- package/dist/directives/match.js +2 -0
- package/dist/directives/match.js.map +1 -0
- package/dist/directives/memo.cjs +2 -0
- package/dist/directives/memo.cjs.map +1 -0
- package/dist/directives/memo.d.ts +23 -0
- package/dist/directives/memo.d.ts.map +1 -0
- package/dist/directives/memo.js +2 -0
- package/dist/directives/memo.js.map +1 -0
- package/dist/directives/on.cjs +2 -0
- package/dist/directives/on.cjs.map +1 -0
- package/dist/directives/on.d.ts +25 -0
- package/dist/directives/on.d.ts.map +1 -0
- package/dist/directives/on.js +2 -0
- package/dist/directives/on.js.map +1 -0
- package/dist/directives/raw.cjs +2 -0
- package/dist/directives/raw.cjs.map +1 -0
- package/dist/directives/raw.d.ts +25 -0
- package/dist/directives/raw.d.ts.map +1 -0
- package/dist/directives/raw.js +2 -0
- package/dist/directives/raw.js.map +1 -0
- package/dist/directives/spread.cjs +2 -0
- package/dist/directives/spread.cjs.map +1 -0
- package/dist/directives/spread.d.ts +14 -0
- package/dist/directives/spread.d.ts.map +1 -0
- package/dist/directives/spread.js +2 -0
- package/dist/directives/spread.js.map +1 -0
- package/dist/directives/style.cjs +2 -0
- package/dist/directives/style.cjs.map +1 -0
- package/dist/directives/style.d.ts +22 -0
- package/dist/directives/style.d.ts.map +1 -0
- package/dist/directives/style.js +2 -0
- package/dist/directives/style.js.map +1 -0
- package/dist/directives/until.cjs +2 -0
- package/dist/directives/until.cjs.map +1 -0
- package/dist/directives/until.d.ts +26 -0
- package/dist/directives/until.d.ts.map +1 -0
- package/dist/directives/until.js +2 -0
- package/dist/directives/until.js.map +1 -0
- package/dist/directives/when.cjs +2 -0
- package/dist/directives/when.cjs.map +1 -0
- package/dist/directives/when.d.ts +17 -0
- package/dist/directives/when.d.ts.map +1 -0
- package/dist/directives/when.js +2 -0
- package/dist/directives/when.js.map +1 -0
- package/dist/index.cjs +1 -2
- package/dist/index.d.ts +10 -265
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -13
- package/dist/labs/a11y.cjs +2 -0
- package/dist/labs/a11y.cjs.map +1 -0
- package/dist/labs/a11y.d.ts +61 -0
- package/dist/labs/a11y.d.ts.map +1 -0
- package/dist/labs/a11y.js +2 -0
- package/dist/labs/a11y.js.map +1 -0
- package/dist/labs/index.d.ts +8 -0
- package/dist/labs/index.d.ts.map +1 -0
- package/dist/labs/list.cjs +2 -0
- package/dist/labs/list.cjs.map +1 -0
- package/dist/labs/list.d.ts +26 -0
- package/dist/labs/list.d.ts.map +1 -0
- package/dist/labs/list.js +2 -0
- package/dist/labs/list.js.map +1 -0
- package/dist/labs/observers.cjs +2 -0
- package/dist/labs/observers.cjs.map +1 -0
- package/dist/labs/observers.d.ts +42 -0
- package/dist/labs/observers.d.ts.map +1 -0
- package/dist/labs/observers.js +2 -0
- package/dist/labs/observers.js.map +1 -0
- package/dist/labs/overlay.cjs +2 -0
- package/dist/labs/overlay.cjs.map +1 -0
- package/dist/labs/overlay.d.ts +35 -0
- package/dist/labs/overlay.d.ts.map +1 -0
- package/dist/labs/overlay.js +2 -0
- package/dist/labs/overlay.js.map +1 -0
- package/dist/labs/selectable.cjs +2 -0
- package/dist/labs/selectable.cjs.map +1 -0
- package/dist/labs/selectable.d.ts +70 -0
- package/dist/labs/selectable.d.ts.map +1 -0
- package/dist/labs/selectable.js +2 -0
- package/dist/labs/selectable.js.map +1 -0
- package/dist/labs/selection.cjs +2 -0
- package/dist/labs/selection.cjs.map +1 -0
- package/dist/labs/selection.d.ts +68 -0
- package/dist/labs/selection.d.ts.map +1 -0
- package/dist/labs/selection.js +2 -0
- package/dist/labs/selection.js.map +1 -0
- package/dist/labs.cjs +1 -0
- package/dist/labs.js +1 -0
- package/dist/test/index.d.ts +2 -0
- package/dist/test/index.d.ts.map +1 -0
- package/dist/test/test.cjs +2 -0
- package/dist/test/test.cjs.map +1 -0
- package/dist/test/test.d.ts +198 -0
- package/dist/test/test.d.ts.map +1 -0
- package/dist/test/test.js +2 -0
- package/dist/test/test.js.map +1 -0
- package/dist/test.cjs +1 -0
- package/dist/test.js +1 -0
- package/package.json +37 -9
- package/dist/index.cjs.map +0 -1
- 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
|
-
|
|
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)=>{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={"'":`'`,'"':`"`,"&":`&`,"<":`<`,">":`>`},_=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 ie(e,t,n,r){e&&(e.addEventListener(t,n,r),C(()=>e.removeEventListener(t,n,r)))}var E={bubbles:!0,cancelable:!0,composed:!0},ae={basic:(e,t,n={})=>e.dispatchEvent(new Event(t,{...E,...n})),custom:(e,t,n={})=>e.dispatchEvent(new CustomEvent(t,{...E,...n})),event:(e,t)=>e.dispatchEvent(t),focus:(e,t,n={})=>e.dispatchEvent(new FocusEvent(t,{...E,...n})),keyboard:(e,t,n={})=>e.dispatchEvent(new KeyboardEvent(t,{...E,...n})),mouse:(e,t,n={})=>e.dispatchEvent(new MouseEvent(t,{...E,...n})),touch:(e,t,n={})=>typeof TouchEvent<`u`?e.dispatchEvent(new TouchEvent(t,{...E,...n})):e.dispatchEvent(new CustomEvent(t,{...E,...n}))};function oe(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 D=new WeakMap,se=(e,t)=>{let n=x().el;D.has(n)||D.set(n,new Map),D.get(n).set(e,t)};function ce(e,...t){let n=x().el;for(;n;){if(n instanceof HTMLElement){let t=D.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 le(e){return Symbol(e)}var ue=(e,t,n)=>{e&&S(()=>{T(()=>{for(let r of n){let n=e[r]?.value;n!==void 0&&(t[r].value=n)}})})},O=new Set,k=(e,t,n)=>{let r=`${n}:${e.localName}:${t||`default`}`;O.has(r)||(O.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 k(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);ie(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})}function me(){return{value:null}}function he(){return[]}function j(e,t=[]){return{__bindings:t,__html:e,toString:()=>e}}var M=Symbol(`craftit.eachSignal`),N=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},P=(e,t)=>{if(!Object.is(e.value,t))try{e.value=t}catch{}},F=new Map,I=e=>(e=>{let t=F.get(e);if(!t){if(t=document.createElement(`template`),t.innerHTML=e,F.size>=1e3){let e=F.keys().next().value;e!==void 0&&F.delete(e)}F.set(e,t)}return t})(e).content.cloneNode(!0),L=(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)},R=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(L(n,t);e.nextNode();)L(e.currentNode,t)}return t},z=e=>Array.from(I(e).childNodes),B=(e,t,n)=>{if(e.parentNode)for(let r of t)e.parentNode.insertBefore(r,n)},V=e=>Array.isArray(e)||typeof e==`object`&&!!e,H=(e,t,n)=>{n(T(()=>t(e.value)))},_e=(e,t,n)=>{let r=n=>{let r=$.get(e)?.get(t.name);if(!r&&V(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=V(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?H(t.signal,r,n):r(t.value)},ve=(e,t,n)=>{let r=n=>{e[t.name]=n};t.signal?H(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`,()=>{P(n,e.value)})):t===`checked`&&e instanceof HTMLInputElement&&r(d(e,`change`,()=>{P(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}))},U=(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),H(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)}}}},W=(e,t,n,r)=>{let i=N(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=N(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`),G=e=>typeof e==`object`&&!!e&&`__html`in e,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*["']?$/}],K=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}},q=()=>{let e=0;return()=>String(e++)},J=(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`)}},Y=e=>typeof e==`string`?_(e):e==null?``:G(e)?e.__html:_(String(e)),Te=(e,n)=>{let i=(e=>typeof e==`object`&&e&&M in e?e[M]: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=q(),o=``,s=[];for(let e of i)if(G(e)){let t=J(e,a);o+=t.html,s.push(...t.bindings)}else o+=Y(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)&&G(e.value)?{keyed:!1,signal:t(()=>{let t=e.value;if(!G(t))return{bindings:[],html:String(t)};let n=J(t,q());return{bindings:n.bindings,html:n.html}})}:null},X=e=>{l(e.cleanups);for(let t of e.nodes)t.remove()},Z=(e,t,n=R(e))=>{let r=[];return U(t,e=>r.push(e),n),r},Ee=(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]&&B(u,a.nodes,s),l(a.cleanups);let t=R(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=z(i.html),n=R(t);B(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=z(i.html),n=R(t);B(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)||X(n);a.set(r.uid,e)}else{if(r.keyed&&g&&g.size>0)for(let[,e]of g)X(e);else for(let e of h)e.remove();let e=I(c);h=Array.from(e.childNodes),u.after(e),r.keyed&&a.set(r.uid,new Map)}}),v||s(_,i,f,{onHtml:e=>Ee(_,e,f,a,s)})})})})),i(p),r.keyed&&i(()=>a.delete(r.uid))},De=(e,t,n,r)=>{U(t,n,(e=>{let t={comments:new Map,elements:new Map},n=document.createTreeWalker(e,NodeFilter.SHOW_COMMENT|NodeFilter.SHOW_ELEMENT);for(L(e,t);n.nextNode();)L(n.currentNode,t);return t})(e),r)},Oe=(e,...t)=>((e,t,n)=>{let i=(e=>{let t=K.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),K.set(e,t)),t})(e),o=``,s=[],c=null,l=q(),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(W(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(W(`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=q(),o=``,s=[];for(let e of n)if(G(e)){let t=J(e,a);o+=t.html,s.push(...t.bindings)}else o+=Y(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(G(t)){let n=J(t,l);e+=n.html,s.push(...n.bindings)}else e+=Y(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(G(f)){let e=J(f,l);o+=c.raw+e.html,s.push(...e.bindings)}else o+=c.raw+Y(f)}return o+=i.tail,j((e=>e.replace(/>\s+</g,`><`).trim())(o),s)})(e,t,T),Q=new WeakMap,ke=new WeakMap,Ae=(e,t)=>{let r=x().el;if(!r.constructor.formAssociated)throw Error(`[craftit:E8] defineField() requires defineComponent({ formAssociated: true })`);let i=ke.get(r)??r.attachInternals();ke.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)}},je=new Set([`default`,`omit`,`parse`,`reflect`,`type`]),Me=e=>typeof e==`object`&&!!e&&`default`in e&&Object.keys(e).every(e=>je.has(e)),$=new WeakMap,Ne=(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},Pe=(e,t)=>({...t,default:e}),Fe=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`?j(this._template):this._template;if(this.shadow.replaceChildren(I(e.__html)),e.__bindings.length){let t=e=>this._runtime.cleanups.push(e);De(this.shadow,e.__bindings,t,{onHtml:e=>{this._appliedHtmlBindings.has(e.uid)||(this._appliedHtmlBindings.add(e.uid),((e,t,n,r)=>{Ee(e,t,n,r,De)})(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 Ie(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 Fe{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=Me(r)?r:{default:r},i={reflect:!(typeof e.default==`object`&&e.default!==null||Array.isArray(e.default)),...e};t[n]=Ne(h(n),e.default,i)}return t}(r):{},n=(()=>{let e=x().el;return(t,...n)=>{ae.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 k(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 Le=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{oe as aria,le as createContext,p as createFormIds,f as createId,ee as css,Ie as defineComponent,Ae as defineField,T as effect,_ as escapeHtml,ae as fire,m as guard,ie as handle,Oe as html,ce as inject,Le as observeResize,C as onCleanup,ne as onError,S as onMount,de as onSlotChange,Ne as prop,se as provide,me as ref,A as reflect,he as refs,ue as syncContextProps,h as toKebab,Pe as typed,re as watch};
|
|
2
|
+
//# sourceMappingURL=craftit.js.map
|