@ponchia/ui 0.9.0 → 0.11.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/CHANGELOG.md +107 -4
- package/MIGRATIONS.json +127 -18
- package/README.md +17 -9
- package/behaviors/index.d.ts +0 -2
- package/behaviors/index.d.ts.map +1 -1
- package/behaviors/index.js +0 -2
- package/behaviors/popover.js +4 -4
- package/classes/classes.json +53 -9
- package/classes/index.d.ts +20 -3
- package/classes/index.js +33 -3
- package/classes/vscode.css-custom-data.json +10 -10
- package/css/annotations.css +2 -2
- package/css/app.css +55 -31
- package/css/base.css +10 -14
- package/css/command.css +4 -4
- package/css/content.css +23 -21
- package/css/disclosure.css +17 -17
- package/css/discussion.css +150 -0
- package/css/feedback.css +15 -15
- package/css/figure.css +6 -4
- package/css/forms.css +8 -7
- package/css/generated.css +19 -12
- package/css/legend.css +13 -5
- package/css/navigation.css +3 -3
- package/css/overlay.css +13 -29
- package/css/primitives.css +48 -28
- package/css/report.css +91 -53
- package/css/sources.css +1 -1
- package/css/state.css +95 -6
- package/css/table.css +3 -3
- package/css/tokens.css +10 -10
- package/css/workbench.css +21 -9
- package/dist/bronto.css +1 -1
- package/dist/css/analytical.css +1 -1
- package/dist/css/annotations.css +1 -1
- package/dist/css/app.css +1 -1
- package/dist/css/base.css +1 -1
- package/dist/css/command.css +1 -1
- package/dist/css/content.css +1 -1
- package/dist/css/disclosure.css +1 -1
- package/dist/css/discussion.css +1 -0
- package/dist/css/feedback.css +1 -1
- package/dist/css/figure.css +1 -1
- package/dist/css/forms.css +1 -1
- package/dist/css/generated.css +1 -1
- package/dist/css/legend.css +1 -1
- package/dist/css/navigation.css +1 -1
- package/dist/css/overlay.css +1 -1
- package/dist/css/primitives.css +1 -1
- package/dist/css/report-kit.css +1 -1
- package/dist/css/report.css +1 -1
- package/dist/css/sources.css +1 -1
- package/dist/css/state.css +1 -1
- package/dist/css/table.css +1 -1
- package/dist/css/tokens.css +1 -1
- package/dist/css/workbench.css +1 -1
- package/docs/adr/0004-prune-unused-adapters.md +5 -1
- package/docs/adr/0005-productive-tools-and-editorial-reports.md +58 -0
- package/docs/adr/0006-trusted-publishing.md +92 -0
- package/docs/architecture.md +16 -23
- package/docs/command.md +1 -2
- package/docs/compositions.md +131 -0
- package/docs/discussion.md +64 -0
- package/docs/figure.md +10 -1
- package/docs/frontier-primitives.md +1 -2
- package/docs/migrations/0.10-to-0.11.md +61 -0
- package/docs/migrations/0.9-to-0.10.md +47 -0
- package/docs/package-contract.md +16 -13
- package/docs/reference.md +47 -18
- package/docs/reporting.md +15 -9
- package/docs/stability.md +20 -55
- package/docs/state.md +47 -0
- package/docs/usage.md +18 -30
- package/llms.txt +7 -18
- package/package.json +18 -54
- package/tokens/figma.variables.json +20 -20
- package/tokens/index.js +10 -10
- package/tokens/index.json +20 -20
- package/tokens/resolved.json +10 -10
- package/tokens/tokens.dtcg.json +20 -20
- package/behaviors/modal.d.ts +0 -45
- package/behaviors/modal.d.ts.map +0 -1
- package/behaviors/modal.js +0 -373
- package/qwik/index.d.ts +0 -48
- package/qwik/index.d.ts.map +0 -1
- package/qwik/index.js +0 -227
- package/react/index.d.ts +0 -45
- package/react/index.d.ts.map +0 -1
- package/react/index.js +0 -165
- package/solid/index.d.ts +0 -75
- package/solid/index.d.ts.map +0 -1
- package/solid/index.js +0 -172
- package/svelte/index.d.ts +0 -114
- package/svelte/index.d.ts.map +0 -1
- package/svelte/index.js +0 -197
- package/vue/index.d.ts +0 -116
- package/vue/index.d.ts.map +0 -1
- package/vue/index.js +0 -266
package/behaviors/modal.js
DELETED
|
@@ -1,373 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
hasDom,
|
|
3
|
-
resolveHost,
|
|
4
|
-
noop,
|
|
5
|
-
bindOnce,
|
|
6
|
-
byIdInHost,
|
|
7
|
-
collectHosts,
|
|
8
|
-
focusInto,
|
|
9
|
-
closestSafe,
|
|
10
|
-
} from './internal.js';
|
|
11
|
-
|
|
12
|
-
const states = new WeakMap();
|
|
13
|
-
|
|
14
|
-
const snapshotAttrs = (el, names) => {
|
|
15
|
-
const attrs = {};
|
|
16
|
-
for (const name of names) {
|
|
17
|
-
attrs[name] = {
|
|
18
|
-
had: el.hasAttribute(name),
|
|
19
|
-
value: el.getAttribute(name),
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
return attrs;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const restoreAttrs = (el, attrs) => {
|
|
26
|
-
for (const [name, state] of Object.entries(attrs)) {
|
|
27
|
-
if (state.had) el.setAttribute(name, state.value);
|
|
28
|
-
else el.removeAttribute(name);
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
function modalState(doc) {
|
|
33
|
-
let state = states.get(doc);
|
|
34
|
-
if (state) return state;
|
|
35
|
-
state = {
|
|
36
|
-
doc,
|
|
37
|
-
records: new Set(),
|
|
38
|
-
byModal: new Map(),
|
|
39
|
-
ownedInert: new Set(),
|
|
40
|
-
pendingOverlays: new Set(),
|
|
41
|
-
observer: null,
|
|
42
|
-
observing: false,
|
|
43
|
-
sequence: 0,
|
|
44
|
-
scheduled: false,
|
|
45
|
-
top: null,
|
|
46
|
-
};
|
|
47
|
-
states.set(doc, state);
|
|
48
|
-
return state;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function isEffectivelyActive(record, state) {
|
|
52
|
-
if (!record.active || !record.modal.isConnected) return false;
|
|
53
|
-
for (let node = record.modal.parentElement; node; node = node.parentElement) {
|
|
54
|
-
const ancestor = state.byModal.get(node);
|
|
55
|
-
if (ancestor && (!ancestor.active || !ancestor.modal.isConnected)) return false;
|
|
56
|
-
}
|
|
57
|
-
return true;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function activeTop(state) {
|
|
61
|
-
let top = null;
|
|
62
|
-
for (const record of state.records) {
|
|
63
|
-
if (!isEffectivelyActive(record, state)) continue;
|
|
64
|
-
if (!top || top.modal.contains(record.modal)) {
|
|
65
|
-
top = record;
|
|
66
|
-
continue;
|
|
67
|
-
}
|
|
68
|
-
if (!record.modal.contains(top.modal) && record.openedAt > top.openedAt) top = record;
|
|
69
|
-
}
|
|
70
|
-
return top;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function popoverIsOpen(panel, state) {
|
|
74
|
-
if (state.pendingOverlays.has(panel) || panel.classList.contains('is-open')) return true;
|
|
75
|
-
try {
|
|
76
|
-
return panel.matches(':popover-open');
|
|
77
|
-
} catch {
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function modalOwnsPopover(modal, panel) {
|
|
83
|
-
if (modal.contains(panel)) return true;
|
|
84
|
-
if (!panel.id) return false;
|
|
85
|
-
return collectHosts(modal, '[data-bronto-popover]').some(
|
|
86
|
-
(trigger) => trigger.getAttribute('data-bronto-popover') === panel.id,
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function liveRoots(state, top) {
|
|
91
|
-
const roots = new Set([top.modal]);
|
|
92
|
-
for (const trigger of collectHosts(top.modal, '[data-bronto-popover]')) {
|
|
93
|
-
const panel = byIdInHost(top.modal, trigger.getAttribute('data-bronto-popover'));
|
|
94
|
-
if (panel && popoverIsOpen(panel, state)) roots.add(panel);
|
|
95
|
-
}
|
|
96
|
-
for (const panel of state.pendingOverlays) {
|
|
97
|
-
if (modalOwnsPopover(top.modal, panel)) roots.add(panel);
|
|
98
|
-
}
|
|
99
|
-
return roots;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function desiredInert(state, top) {
|
|
103
|
-
const body = state.doc.body;
|
|
104
|
-
if (!body || !top) return new Set();
|
|
105
|
-
const roots = liveRoots(state, top);
|
|
106
|
-
const livePath = new Set([body]);
|
|
107
|
-
for (const root of roots) {
|
|
108
|
-
for (let node = root; node && node !== body; node = node.parentElement) {
|
|
109
|
-
livePath.add(node);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
const desired = new Set();
|
|
114
|
-
for (const parent of livePath) {
|
|
115
|
-
if (roots.has(parent)) continue;
|
|
116
|
-
for (const child of parent.children || []) {
|
|
117
|
-
if (!livePath.has(child)) desired.add(child);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
return desired;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
function reconcileInert(state) {
|
|
124
|
-
const previousTop = state.top;
|
|
125
|
-
const nextTop = activeTop(state);
|
|
126
|
-
const desired = desiredInert(state, nextTop);
|
|
127
|
-
|
|
128
|
-
for (const element of [...state.ownedInert]) {
|
|
129
|
-
if (desired.has(element)) {
|
|
130
|
-
if (!element.inert) element.inert = true;
|
|
131
|
-
continue;
|
|
132
|
-
}
|
|
133
|
-
element.inert = false;
|
|
134
|
-
state.ownedInert.delete(element);
|
|
135
|
-
}
|
|
136
|
-
for (const element of desired) {
|
|
137
|
-
if (state.ownedInert.has(element) || element.inert) continue;
|
|
138
|
-
element.inert = true;
|
|
139
|
-
state.ownedInert.add(element);
|
|
140
|
-
}
|
|
141
|
-
state.top = nextTop;
|
|
142
|
-
return { previousTop, nextTop };
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
function scheduleReconcile(state) {
|
|
146
|
-
if (state.scheduled) return;
|
|
147
|
-
state.scheduled = true;
|
|
148
|
-
queueMicrotask(() => {
|
|
149
|
-
state.scheduled = false;
|
|
150
|
-
reconcileInert(state);
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
function ensureDocumentObserver(state) {
|
|
155
|
-
if (state.observing) return;
|
|
156
|
-
state.observing = true;
|
|
157
|
-
const view = state.doc.defaultView;
|
|
158
|
-
const Observer = view?.MutationObserver;
|
|
159
|
-
if (Observer && state.doc.body) {
|
|
160
|
-
state.observer = new Observer((mutations) => {
|
|
161
|
-
const relevant = mutations.some(
|
|
162
|
-
(mutation) =>
|
|
163
|
-
mutation.type === 'childList' || mutation.target.matches?.('.ui-popover, [popover]'),
|
|
164
|
-
);
|
|
165
|
-
if (relevant && state.top) scheduleReconcile(state);
|
|
166
|
-
});
|
|
167
|
-
state.observer.observe(state.doc.body, {
|
|
168
|
-
attributes: true,
|
|
169
|
-
attributeFilter: ['class'],
|
|
170
|
-
childList: true,
|
|
171
|
-
subtree: true,
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
state.onBeforeToggle = (event) => {
|
|
176
|
-
const panel = event.target;
|
|
177
|
-
if (!panel?.matches?.('[popover]')) return;
|
|
178
|
-
if (event.newState === 'open') state.pendingOverlays.add(panel);
|
|
179
|
-
else state.pendingOverlays.delete(panel);
|
|
180
|
-
reconcileInert(state);
|
|
181
|
-
};
|
|
182
|
-
state.onToggle = (event) => {
|
|
183
|
-
state.pendingOverlays.delete(event.target);
|
|
184
|
-
scheduleReconcile(state);
|
|
185
|
-
};
|
|
186
|
-
state.doc.addEventListener('beforetoggle', state.onBeforeToggle, true);
|
|
187
|
-
state.doc.addEventListener('toggle', state.onToggle, true);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
function releaseDocumentState(state) {
|
|
191
|
-
if (state.records.size) return;
|
|
192
|
-
state.observer?.disconnect();
|
|
193
|
-
state.observer = null;
|
|
194
|
-
state.observing = false;
|
|
195
|
-
state.doc.removeEventListener('beforetoggle', state.onBeforeToggle, true);
|
|
196
|
-
state.doc.removeEventListener('toggle', state.onToggle, true);
|
|
197
|
-
state.pendingOverlays.clear();
|
|
198
|
-
reconcileInert(state);
|
|
199
|
-
states.delete(state.doc);
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
function restoreAfterClose(record, nextTop) {
|
|
203
|
-
const back = record.opener;
|
|
204
|
-
record.opener = null;
|
|
205
|
-
if (nextTop) {
|
|
206
|
-
if (back?.isConnected && nextTop.modal.contains(back)) back.focus?.();
|
|
207
|
-
else focusInto(nextTop.modal);
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
if (back?.isConnected && typeof back.focus === 'function') back.focus();
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
function syncRecord(record) {
|
|
214
|
-
const { modal, state } = record;
|
|
215
|
-
const nextActive = modal.classList.contains('is-open');
|
|
216
|
-
if (nextActive === record.active) {
|
|
217
|
-
if (!record.isNativeDialog) modal.hidden = !nextActive;
|
|
218
|
-
scheduleReconcile(state);
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
const oldTop = state.top ?? activeTop(state);
|
|
223
|
-
record.active = nextActive;
|
|
224
|
-
if (nextActive) {
|
|
225
|
-
record.opener = state.doc.activeElement;
|
|
226
|
-
record.openedAt = ++state.sequence;
|
|
227
|
-
if (!record.isNativeDialog) modal.hidden = false;
|
|
228
|
-
const { nextTop } = reconcileInert(state);
|
|
229
|
-
if (nextTop && (nextTop === record || modal.contains(nextTop.modal))) {
|
|
230
|
-
focusInto(nextTop.modal);
|
|
231
|
-
}
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
if (!record.isNativeDialog) modal.hidden = true;
|
|
236
|
-
const closedOwnedTop = oldTop && (oldTop === record || modal.contains(oldTop.modal));
|
|
237
|
-
const { nextTop } = reconcileInert(state);
|
|
238
|
-
if (closedOwnedTop) restoreAfterClose(record, nextTop);
|
|
239
|
-
else record.opener = null;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
function unregisterRecord(record) {
|
|
243
|
-
const { state, modal } = record;
|
|
244
|
-
const oldTop = state.top ?? activeTop(state);
|
|
245
|
-
const removedOwnedTop = oldTop && (oldTop === record || modal.contains(oldTop.modal));
|
|
246
|
-
record.active = false;
|
|
247
|
-
state.records.delete(record);
|
|
248
|
-
state.byModal.delete(modal);
|
|
249
|
-
const { nextTop } = reconcileInert(state);
|
|
250
|
-
if (removedOwnedTop) restoreAfterClose(record, nextTop);
|
|
251
|
-
else record.opener = null;
|
|
252
|
-
releaseDocumentState(state);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
function targetIsOwnedPopover(target, modal, state) {
|
|
256
|
-
const panel = closestSafe(target, '.ui-popover, [popover]');
|
|
257
|
-
return Boolean(panel && popoverIsOpen(panel, state) && modalOwnsPopover(modal, panel));
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* @typedef {object} ModalCloseDetail
|
|
262
|
-
* @property {'escape'} reason What asked the modal to close (currently only Escape).
|
|
263
|
-
*/
|
|
264
|
-
|
|
265
|
-
/**
|
|
266
|
-
* Focus management for the **controlled, non-`<dialog>` modal** — the
|
|
267
|
-
* `.ui-modal.is-open` path a portal/React overlay uses when it genuinely can't
|
|
268
|
-
* be a native `<dialog>`. The native `<dialog>` path gets a focus trap, Escape,
|
|
269
|
-
* and the top layer for free (use `initDialog`); this supplies the equivalent
|
|
270
|
-
* for the `.is-open` path, which otherwise leaves focus management to the
|
|
271
|
-
* consumer.
|
|
272
|
-
*
|
|
273
|
-
* Mark the overlay `[data-bronto-modal]` (opt-in). On bind it gives the modal a
|
|
274
|
-
* `role="dialog"` + `aria-modal="true"` (unless the author set a role) and
|
|
275
|
-
* dev-warns when it has no accessible name. While open, a document-level stack
|
|
276
|
-
* reconciler keeps only the top controlled modal interactive, marks the rest of
|
|
277
|
-
* the page `inert`, admits an open popover owned by the top modal even when the
|
|
278
|
-
* panel is portaled elsewhere, and applies the trap to background nodes added
|
|
279
|
-
* after open. Nested and sibling portal modals therefore share one ownership
|
|
280
|
-
* model instead of independently inverting each other's `inert` state.
|
|
281
|
-
*
|
|
282
|
-
* Bronto owns focus only: the **consumer still owns open/close state** (the
|
|
283
|
-
* `is-open` class). Escape dispatches a cancelable `bronto:modal:close`
|
|
284
|
-
* ({@link ModalCloseDetail}) on the modal so the consumer can drop `is-open` in
|
|
285
|
-
* response; the behavior never changes visibility itself. Closing a parent
|
|
286
|
-
* modal temporarily suspends any still-`is-open` controlled descendants; they
|
|
287
|
-
* resume at the top of the stack if the parent reopens.
|
|
288
|
-
*
|
|
289
|
-
* SSR-safe, idempotent per modal; returns a cleanup function.
|
|
290
|
-
*
|
|
291
|
-
* @deprecated Use a native `<dialog>` with `initDialog()`. This controlled
|
|
292
|
-
* non-dialog path remains compatible in 0.7 and is scheduled for removal no
|
|
293
|
-
* earlier than 0.8 because no real consumer adopted it.
|
|
294
|
-
*
|
|
295
|
-
* @param {import('./internal.js').DelegateOpts} [opts]
|
|
296
|
-
* @returns {import('./internal.js').Cleanup}
|
|
297
|
-
*/
|
|
298
|
-
export function initModal({ root } = {}) {
|
|
299
|
-
if (!hasDom()) return noop;
|
|
300
|
-
const host = resolveHost(root);
|
|
301
|
-
if (!host) return noop;
|
|
302
|
-
const modals = collectHosts(host, '[data-bronto-modal]');
|
|
303
|
-
const cleanups = [];
|
|
304
|
-
|
|
305
|
-
for (const modal of modals) {
|
|
306
|
-
const doc = modal.ownerDocument;
|
|
307
|
-
if (!doc) continue;
|
|
308
|
-
const view = doc.defaultView;
|
|
309
|
-
cleanups.push(
|
|
310
|
-
bindOnce(modal, 'modal', () => {
|
|
311
|
-
const attrs = snapshotAttrs(modal, ['role', 'aria-modal', 'tabindex', 'hidden']);
|
|
312
|
-
const state = modalState(doc);
|
|
313
|
-
const record = {
|
|
314
|
-
active: modal.classList.contains('is-open'),
|
|
315
|
-
isNativeDialog: modal.localName === 'dialog',
|
|
316
|
-
modal,
|
|
317
|
-
openedAt: 0,
|
|
318
|
-
opener: null,
|
|
319
|
-
state,
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
if (!modal.hasAttribute('role')) modal.setAttribute('role', 'dialog');
|
|
323
|
-
if (!modal.hasAttribute('aria-modal')) modal.setAttribute('aria-modal', 'true');
|
|
324
|
-
const named =
|
|
325
|
-
modal.hasAttribute('aria-label') ||
|
|
326
|
-
modal.hasAttribute('aria-labelledby') ||
|
|
327
|
-
modal.hasAttribute('title');
|
|
328
|
-
if (!named && typeof console !== 'undefined') {
|
|
329
|
-
console.warn(
|
|
330
|
-
`[bronto] initModal(): a [data-bronto-modal] has no accessible name — add aria-label or aria-labelledby so it is announced as a named dialog.`,
|
|
331
|
-
);
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
if (record.active) {
|
|
335
|
-
record.opener = doc.activeElement;
|
|
336
|
-
record.openedAt = ++state.sequence;
|
|
337
|
-
}
|
|
338
|
-
if (!record.isNativeDialog) modal.hidden = !record.active;
|
|
339
|
-
state.records.add(record);
|
|
340
|
-
state.byModal.set(modal, record);
|
|
341
|
-
ensureDocumentObserver(state);
|
|
342
|
-
reconcileInert(state);
|
|
343
|
-
if (state.top === record) focusInto(modal);
|
|
344
|
-
|
|
345
|
-
const Observer = view?.MutationObserver;
|
|
346
|
-
const observer = Observer ? new Observer(() => syncRecord(record)) : null;
|
|
347
|
-
observer?.observe(modal, { attributes: true, attributeFilter: ['class'] });
|
|
348
|
-
const onKey = (event) => {
|
|
349
|
-
if (event.key !== 'Escape' || state.top !== record) return;
|
|
350
|
-
if (targetIsOwnedPopover(event.target, modal, state)) return;
|
|
351
|
-
const ModalCloseEvent = view?.CustomEvent ?? CustomEvent;
|
|
352
|
-
modal.dispatchEvent(
|
|
353
|
-
new ModalCloseEvent('bronto:modal:close', {
|
|
354
|
-
detail: { reason: 'escape' },
|
|
355
|
-
bubbles: true,
|
|
356
|
-
cancelable: true,
|
|
357
|
-
}),
|
|
358
|
-
);
|
|
359
|
-
};
|
|
360
|
-
doc.addEventListener('keydown', onKey, true);
|
|
361
|
-
|
|
362
|
-
return () => {
|
|
363
|
-
observer?.disconnect();
|
|
364
|
-
doc.removeEventListener('keydown', onKey, true);
|
|
365
|
-
unregisterRecord(record);
|
|
366
|
-
restoreAttrs(modal, attrs);
|
|
367
|
-
};
|
|
368
|
-
}),
|
|
369
|
-
);
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
return () => cleanups.forEach((fn) => fn());
|
|
373
|
-
}
|
package/qwik/index.d.ts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/** Generic escape hatch. NOTE for Qwik: prefer the specific `use*` hooks
|
|
2
|
-
* below — they inline a statically-imported behavior so the optimizer can
|
|
3
|
-
* serialize the task. Passing a runtime function here is only safe when it
|
|
4
|
-
* is itself optimizer-visible (a module import).
|
|
5
|
-
* @template {DelegateOpts} [T=DelegateOpts]
|
|
6
|
-
* @param {(opts?: T) => Cleanup | void} init
|
|
7
|
-
* @param {BrontoBindingOptsResolver<T>} [opts]
|
|
8
|
-
* @returns {void} */
|
|
9
|
-
export function useBrontoBehavior<T extends DelegateOpts = import("../behaviors/internal.js").DelegateOpts>(init: (opts?: T) => Cleanup | void, opts?: BrontoBindingOptsResolver<T>): void;
|
|
10
|
-
export function useThemeToggle(opts?: BrontoBindingOptsResolver<ThemeStorageOpts & DelegateOpts>): void;
|
|
11
|
-
export function useDismissible(opts?: BrontoBindingOptsResolver): void;
|
|
12
|
-
export function useDisabledGuard(opts?: BrontoBindingOptsResolver): void;
|
|
13
|
-
export function useDisclosure(opts?: BrontoBindingOptsResolver): void;
|
|
14
|
-
export function useMenu(opts?: BrontoBindingOptsResolver): void;
|
|
15
|
-
export function useFormValidation(opts?: BrontoBindingOptsResolver): void;
|
|
16
|
-
export function useCombobox(opts?: BrontoBindingOptsResolver): void;
|
|
17
|
-
export function usePopover(opts?: BrontoBindingOptsResolver): void;
|
|
18
|
-
export function useTableSort(opts?: BrontoBindingOptsResolver): void;
|
|
19
|
-
export function useTabs(opts?: BrontoBindingOptsResolver): void;
|
|
20
|
-
export function useDialog(opts?: BrontoBindingOptsResolver): void;
|
|
21
|
-
export function useModal(opts?: BrontoBindingOptsResolver): void;
|
|
22
|
-
export function useCarousel(opts?: BrontoBindingOptsResolver): void;
|
|
23
|
-
export function useDotGlyph(opts?: BrontoBindingOptsResolver): void;
|
|
24
|
-
export function useLegend(opts?: BrontoBindingOptsResolver): void;
|
|
25
|
-
export function useConnectors(opts?: BrontoBindingOptsResolver): void;
|
|
26
|
-
export function useSpotlight(opts?: BrontoBindingOptsResolver): void;
|
|
27
|
-
export function useCrosshair(opts?: BrontoBindingOptsResolver): void;
|
|
28
|
-
export function useCommand(opts?: BrontoBindingOptsResolver): void;
|
|
29
|
-
export function useSources(opts?: BrontoBindingOptsResolver): void;
|
|
30
|
-
export function useSplitter(opts?: BrontoBindingOptsResolver): void;
|
|
31
|
-
export function useToast(): (message: string, opts?: ToastOpts) => Cleanup;
|
|
32
|
-
export { applyStoredTheme };
|
|
33
|
-
export type Cleanup = import("../behaviors/index.js").Cleanup;
|
|
34
|
-
export type DelegateOpts = import("../behaviors/index.js").DelegateOpts;
|
|
35
|
-
export type ThemeStorageOpts = import("../behaviors/index.js").ThemeStorageOpts;
|
|
36
|
-
export type ToastOpts = import("../behaviors/index.js").ToastOpts;
|
|
37
|
-
export type BrontoBindingRoot = Document | Element | {
|
|
38
|
-
value: Document | Element | null | undefined;
|
|
39
|
-
} | {
|
|
40
|
-
current: Document | Element | null | undefined;
|
|
41
|
-
} | (() => Document | Element | null | undefined) | null | undefined;
|
|
42
|
-
export type BrontoBindingOpts<T extends DelegateOpts = import("../behaviors/internal.js").DelegateOpts> = Omit<T, "root"> & {
|
|
43
|
-
root?: BrontoBindingRoot;
|
|
44
|
-
};
|
|
45
|
-
export type BrontoBindingOptsResolver<T extends DelegateOpts = import("../behaviors/internal.js").DelegateOpts> = BrontoBindingOpts<T> | (() => BrontoBindingOpts<T> | null | undefined) | null | undefined;
|
|
46
|
-
import { applyStoredTheme } from '../behaviors/index.js';
|
|
47
|
-
export { cls, ui, cx } from "../classes/index.js";
|
|
48
|
-
//# sourceMappingURL=index.d.ts.map
|
package/qwik/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.js"],"names":[],"mappings":"AAuHA;;;;;;;sBAOsB;AACtB,kCAJ8B,CAAC,SAAhB,YAAa,0DAChB,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,OAAO,GAAG,IAAI,SAC5B,yBAAyB,CAAC,CAAC,CAAC,GAC1B,IAAI,CAIjB;AAGM,sCADK,yBAAyB,CAAC,gBAAgB,GAAG,YAAY,CAAC,GAAmB,IAAI,CAGhC;AAEtD,sCADK,yBAAyB,GAAmB,IAAI,CAGH;AAElD,wCADK,yBAAyB,GAAmB,IAAI,CAGG;AAExD,qCADK,yBAAyB,GAAmB,IAAI,CAGA;AAErD,+BADK,yBAAyB,GAAmB,IAAI,CAGN;AAE/C,yCADK,yBAAyB,GAAmB,IAAI,CAGI;AAEzD,mCADK,yBAAyB,GAAmB,IAAI,CAGF;AAEnD,kCADK,yBAAyB,GAAmB,IAAI,CAGH;AAElD,oCADK,yBAAyB,GAAmB,IAAI,CAGD;AAEpD,+BADK,yBAAyB,GAAmB,IAAI,CAGN;AAE/C,iCADK,yBAAyB,GAAmB,IAAI,CAGJ;AAEjD,gCADK,yBAAyB,GAAmB,IAAI,CAGL;AAEhD,mCADK,yBAAyB,GAAmB,IAAI,CAGF;AAEnD,mCADK,yBAAyB,GAAmB,IAAI,CAGF;AAEnD,iCADK,yBAAyB,GAAmB,IAAI,CAGJ;AAEjD,qCADK,yBAAyB,GAAmB,IAAI,CAGA;AAErD,oCADK,yBAAyB,GAAmB,IAAI,CAGD;AAEpD,oCADK,yBAAyB,GAAmB,IAAI,CAGD;AAEpD,kCADK,yBAAyB,GAAmB,IAAI,CAGH;AAElD,kCADK,yBAAyB,GAAmB,IAAI,CAGH;AAElD,mCADK,yBAAyB,GAAmB,IAAI,CAGF;AAInD,4BADO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,SAAS,KAAK,OAAO,CACzB;;sBA5LtB,OAAO,uBAAuB,EAAE,OAAO;2BACvC,OAAO,uBAAuB,EAAE,YAAY;+BAC5C,OAAO,uBAAuB,EAAE,gBAAgB;wBAChD,OAAO,uBAAuB,EAAE,SAAS;gCAEzC,QAAQ,GACd,OAAO,GACP;IAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAA;CAAE,GAChD;IAAE,OAAO,EAAE,QAAQ,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAA;CAAE,GAClD,CAAC,MAAM,QAAQ,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC,GAC7C,IAAI,GACJ,SAAS;8BAIa,CAAC,SAAhB,YAAa,sDACd,IAAI,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG;IAAE,IAAI,CAAC,EAAE,iBAAiB,CAAA;CAAE;sCAI9B,CAAC,SAAhB,YAAa,sDACd,iBAAiB,CAAC,CAAC,CAAC,GAC1B,CAAC,MAAM,iBAAiB,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,GAC/C,IAAI,GACJ,SAAS;iCA2BT,uBAAuB"}
|
package/qwik/index.js
DELETED
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @ponchia/ui/qwik — thin Qwik bindings over @ponchia/ui/behaviors.
|
|
3
|
-
*
|
|
4
|
-
* The CSS is the framework; these are *optional* hooks that wrap the SSR-safe
|
|
5
|
-
* vanilla `init*` behaviors in Qwik's client lifecycle. Thin adapters, not a
|
|
6
|
-
* component library (architecture ADR). `@builder.io/qwik` is an optional peer
|
|
7
|
-
* dependency.
|
|
8
|
-
*
|
|
9
|
-
* Qwik is resumable: nothing runs until needed, and our behaviors are exactly
|
|
10
|
-
* the kind of "enhance on the client" glue that fits — they `useVisibleTask$`
|
|
11
|
-
* (run when the owning component first becomes visible) and register cleanup,
|
|
12
|
-
* so a server-rendered page stays zero-JS until interaction. Each hook inlines
|
|
13
|
-
* its specific behavior so the Qwik optimizer can resolve the import inside the
|
|
14
|
-
* extracted task segment.
|
|
15
|
-
*
|
|
16
|
-
* import { component$ } from '@builder.io/qwik';
|
|
17
|
-
* import { useDialog, useToast } from '@ponchia/ui/qwik';
|
|
18
|
-
* export default component$(() => {
|
|
19
|
-
* useDialog(); // wires every .ui-modal under document
|
|
20
|
-
* const toast = useToast();
|
|
21
|
-
* return <button onClick$={() => toast('Saved', { tone: 'success' })}>Save</button>;
|
|
22
|
-
* });
|
|
23
|
-
*
|
|
24
|
-
* Scope a behavior to a subtree by passing a Qwik signal:
|
|
25
|
-
* const root = useSignal();
|
|
26
|
-
* useDialog({ root }); // <section ref={root}> … </section>
|
|
27
|
-
*
|
|
28
|
-
* @deprecated Import the framework-agnostic behavior initializers directly.
|
|
29
|
-
* This adapter remains compatible in 0.7 and is scheduled for removal no
|
|
30
|
-
* earlier than 0.8 because no real consumer adopted it.
|
|
31
|
-
*
|
|
32
|
-
* @typedef {import('../behaviors/index.js').Cleanup} Cleanup
|
|
33
|
-
* @typedef {import('../behaviors/index.js').DelegateOpts} DelegateOpts
|
|
34
|
-
* @typedef {import('../behaviors/index.js').ThemeStorageOpts} ThemeStorageOpts
|
|
35
|
-
* @typedef {import('../behaviors/index.js').ToastOpts} ToastOpts
|
|
36
|
-
*
|
|
37
|
-
* @typedef {Document
|
|
38
|
-
* | Element
|
|
39
|
-
* | { value: Document | Element | null | undefined }
|
|
40
|
-
* | { current: Document | Element | null | undefined }
|
|
41
|
-
* | (() => Document | Element | null | undefined)
|
|
42
|
-
* | null
|
|
43
|
-
* | undefined} BrontoBindingRoot
|
|
44
|
-
*/
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* @template {DelegateOpts} [T=DelegateOpts]
|
|
48
|
-
* @typedef {Omit<T, 'root'> & { root?: BrontoBindingRoot }} BrontoBindingOpts
|
|
49
|
-
*/
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* @template {DelegateOpts} [T=DelegateOpts]
|
|
53
|
-
* @typedef {BrontoBindingOpts<T>
|
|
54
|
-
* | (() => BrontoBindingOpts<T> | null | undefined)
|
|
55
|
-
* | null
|
|
56
|
-
* | undefined} BrontoBindingOptsResolver
|
|
57
|
-
*/
|
|
58
|
-
import { useVisibleTask$ } from '@builder.io/qwik';
|
|
59
|
-
import {
|
|
60
|
-
applyStoredTheme,
|
|
61
|
-
initThemeToggle,
|
|
62
|
-
dismissible,
|
|
63
|
-
initDisabledGuard,
|
|
64
|
-
initDisclosure,
|
|
65
|
-
initMenu,
|
|
66
|
-
initFormValidation,
|
|
67
|
-
initCombobox,
|
|
68
|
-
initPopover,
|
|
69
|
-
initTableSort,
|
|
70
|
-
initTabs,
|
|
71
|
-
initDialog,
|
|
72
|
-
initModal,
|
|
73
|
-
initCarousel,
|
|
74
|
-
initDotGlyph,
|
|
75
|
-
initLegend,
|
|
76
|
-
initConnectors,
|
|
77
|
-
initSpotlight,
|
|
78
|
-
initCrosshair,
|
|
79
|
-
initCommand,
|
|
80
|
-
initSources,
|
|
81
|
-
initSplitter,
|
|
82
|
-
toast,
|
|
83
|
-
} from '../behaviors/index.js';
|
|
84
|
-
|
|
85
|
-
function resolveMaybe(v) {
|
|
86
|
-
return typeof v === 'function' ? v() : v;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function resolveRoot(root) {
|
|
90
|
-
const value = resolveMaybe(root);
|
|
91
|
-
if (value && typeof value === 'object') {
|
|
92
|
-
if ('value' in value) return value.value; // Qwik signal (useSignal)
|
|
93
|
-
if ('current' in value) return value.current; // generic ref shape
|
|
94
|
-
}
|
|
95
|
-
return value;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function resolveOpts(opts) {
|
|
99
|
-
const value = resolveMaybe(opts);
|
|
100
|
-
if (!value || typeof value !== 'object') return undefined;
|
|
101
|
-
// No `root` key → no scope requested; leave root out so the behavior
|
|
102
|
-
// delegates from `document`. A `root` key that resolves falsy means a scope
|
|
103
|
-
// WAS requested but the ref is not ready: emit `root: null` so the behavior
|
|
104
|
-
// no-ops instead of hijacking the whole document.
|
|
105
|
-
if (!('root' in value)) return { ...value };
|
|
106
|
-
const root = resolveRoot(value.root);
|
|
107
|
-
return { ...value, root: root || null };
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/** Run a delegated behavior on visible and register its cleanup on dispose.
|
|
111
|
-
* `init` and `opts` are resolved inside the visible task, so a Qwik-signal
|
|
112
|
-
* root is read after the element is assigned and tracked for later changes.
|
|
113
|
-
* Shared, non-QRL, so the optimizer keeps the captured behavior import inside
|
|
114
|
-
* the task segment. */
|
|
115
|
-
function start(init, opts, ctx) {
|
|
116
|
-
const cleanup = init(ctx.track(() => resolveOpts(opts)));
|
|
117
|
-
if (typeof cleanup === 'function') ctx.cleanup(cleanup);
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/** Generic escape hatch. NOTE for Qwik: prefer the specific `use*` hooks
|
|
121
|
-
* below — they inline a statically-imported behavior so the optimizer can
|
|
122
|
-
* serialize the task. Passing a runtime function here is only safe when it
|
|
123
|
-
* is itself optimizer-visible (a module import).
|
|
124
|
-
* @template {DelegateOpts} [T=DelegateOpts]
|
|
125
|
-
* @param {(opts?: T) => Cleanup | void} init
|
|
126
|
-
* @param {BrontoBindingOptsResolver<T>} [opts]
|
|
127
|
-
* @returns {void} */
|
|
128
|
-
export function useBrontoBehavior(init, opts) {
|
|
129
|
-
// eslint-disable-next-line qwik/no-use-visible-task -- intentional delegated DOM glue + cleanup
|
|
130
|
-
useVisibleTask$((ctx) => start(init, opts, ctx));
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/** @param {BrontoBindingOptsResolver<ThemeStorageOpts & DelegateOpts>} [opts] @returns {void} */
|
|
134
|
-
export const useThemeToggle = (opts) =>
|
|
135
|
-
// eslint-disable-next-line qwik/no-use-visible-task -- intentional delegated DOM glue + cleanup
|
|
136
|
-
useVisibleTask$((ctx) => start(initThemeToggle, opts, ctx));
|
|
137
|
-
/** @param {BrontoBindingOptsResolver} [opts] @returns {void} */
|
|
138
|
-
export const useDismissible = (opts) =>
|
|
139
|
-
// eslint-disable-next-line qwik/no-use-visible-task -- intentional delegated DOM glue + cleanup
|
|
140
|
-
useVisibleTask$((ctx) => start(dismissible, opts, ctx));
|
|
141
|
-
/** @param {BrontoBindingOptsResolver} [opts] @returns {void} */
|
|
142
|
-
export const useDisabledGuard = (opts) =>
|
|
143
|
-
// eslint-disable-next-line qwik/no-use-visible-task -- intentional delegated DOM glue + cleanup
|
|
144
|
-
useVisibleTask$((ctx) => start(initDisabledGuard, opts, ctx));
|
|
145
|
-
/** @param {BrontoBindingOptsResolver} [opts] @returns {void} */
|
|
146
|
-
export const useDisclosure = (opts) =>
|
|
147
|
-
// eslint-disable-next-line qwik/no-use-visible-task -- intentional delegated DOM glue + cleanup
|
|
148
|
-
useVisibleTask$((ctx) => start(initDisclosure, opts, ctx));
|
|
149
|
-
/** @param {BrontoBindingOptsResolver} [opts] @returns {void} */
|
|
150
|
-
export const useMenu = (opts) =>
|
|
151
|
-
// eslint-disable-next-line qwik/no-use-visible-task -- intentional delegated DOM glue + cleanup
|
|
152
|
-
useVisibleTask$((ctx) => start(initMenu, opts, ctx));
|
|
153
|
-
/** @param {BrontoBindingOptsResolver} [opts] @returns {void} */
|
|
154
|
-
export const useFormValidation = (opts) =>
|
|
155
|
-
// eslint-disable-next-line qwik/no-use-visible-task -- intentional delegated DOM glue + cleanup
|
|
156
|
-
useVisibleTask$((ctx) => start(initFormValidation, opts, ctx));
|
|
157
|
-
/** @param {BrontoBindingOptsResolver} [opts] @returns {void} */
|
|
158
|
-
export const useCombobox = (opts) =>
|
|
159
|
-
// eslint-disable-next-line qwik/no-use-visible-task -- intentional delegated DOM glue + cleanup
|
|
160
|
-
useVisibleTask$((ctx) => start(initCombobox, opts, ctx));
|
|
161
|
-
/** @param {BrontoBindingOptsResolver} [opts] @returns {void} */
|
|
162
|
-
export const usePopover = (opts) =>
|
|
163
|
-
// eslint-disable-next-line qwik/no-use-visible-task -- intentional delegated DOM glue + cleanup
|
|
164
|
-
useVisibleTask$((ctx) => start(initPopover, opts, ctx));
|
|
165
|
-
/** @param {BrontoBindingOptsResolver} [opts] @returns {void} */
|
|
166
|
-
export const useTableSort = (opts) =>
|
|
167
|
-
// eslint-disable-next-line qwik/no-use-visible-task -- intentional delegated DOM glue + cleanup
|
|
168
|
-
useVisibleTask$((ctx) => start(initTableSort, opts, ctx));
|
|
169
|
-
/** @param {BrontoBindingOptsResolver} [opts] @returns {void} */
|
|
170
|
-
export const useTabs = (opts) =>
|
|
171
|
-
// eslint-disable-next-line qwik/no-use-visible-task -- intentional delegated DOM glue + cleanup
|
|
172
|
-
useVisibleTask$((ctx) => start(initTabs, opts, ctx));
|
|
173
|
-
/** @param {BrontoBindingOptsResolver} [opts] @returns {void} */
|
|
174
|
-
export const useDialog = (opts) =>
|
|
175
|
-
// eslint-disable-next-line qwik/no-use-visible-task -- intentional delegated DOM glue + cleanup
|
|
176
|
-
useVisibleTask$((ctx) => start(initDialog, opts, ctx));
|
|
177
|
-
/** @param {BrontoBindingOptsResolver} [opts] @returns {void} */
|
|
178
|
-
export const useModal = (opts) =>
|
|
179
|
-
// eslint-disable-next-line qwik/no-use-visible-task -- intentional delegated DOM glue + cleanup
|
|
180
|
-
useVisibleTask$((ctx) => start(initModal, opts, ctx));
|
|
181
|
-
/** @param {BrontoBindingOptsResolver} [opts] @returns {void} */
|
|
182
|
-
export const useCarousel = (opts) =>
|
|
183
|
-
// eslint-disable-next-line qwik/no-use-visible-task -- intentional delegated DOM glue + cleanup
|
|
184
|
-
useVisibleTask$((ctx) => start(initCarousel, opts, ctx));
|
|
185
|
-
/** @param {BrontoBindingOptsResolver} [opts] @returns {void} */
|
|
186
|
-
export const useDotGlyph = (opts) =>
|
|
187
|
-
// eslint-disable-next-line qwik/no-use-visible-task -- intentional delegated DOM glue + cleanup
|
|
188
|
-
useVisibleTask$((ctx) => start(initDotGlyph, opts, ctx));
|
|
189
|
-
/** @param {BrontoBindingOptsResolver} [opts] @returns {void} */
|
|
190
|
-
export const useLegend = (opts) =>
|
|
191
|
-
// eslint-disable-next-line qwik/no-use-visible-task -- intentional delegated DOM glue + cleanup
|
|
192
|
-
useVisibleTask$((ctx) => start(initLegend, opts, ctx));
|
|
193
|
-
/** @param {BrontoBindingOptsResolver} [opts] @returns {void} */
|
|
194
|
-
export const useConnectors = (opts) =>
|
|
195
|
-
// eslint-disable-next-line qwik/no-use-visible-task -- intentional delegated DOM glue + cleanup
|
|
196
|
-
useVisibleTask$((ctx) => start(initConnectors, opts, ctx));
|
|
197
|
-
/** @param {BrontoBindingOptsResolver} [opts] @returns {void} */
|
|
198
|
-
export const useSpotlight = (opts) =>
|
|
199
|
-
// eslint-disable-next-line qwik/no-use-visible-task -- intentional delegated DOM glue + cleanup
|
|
200
|
-
useVisibleTask$((ctx) => start(initSpotlight, opts, ctx));
|
|
201
|
-
/** @param {BrontoBindingOptsResolver} [opts] @returns {void} */
|
|
202
|
-
export const useCrosshair = (opts) =>
|
|
203
|
-
// eslint-disable-next-line qwik/no-use-visible-task -- intentional delegated DOM glue + cleanup
|
|
204
|
-
useVisibleTask$((ctx) => start(initCrosshair, opts, ctx));
|
|
205
|
-
/** @param {BrontoBindingOptsResolver} [opts] @returns {void} */
|
|
206
|
-
export const useCommand = (opts) =>
|
|
207
|
-
// eslint-disable-next-line qwik/no-use-visible-task -- intentional delegated DOM glue + cleanup
|
|
208
|
-
useVisibleTask$((ctx) => start(initCommand, opts, ctx));
|
|
209
|
-
/** @param {BrontoBindingOptsResolver} [opts] @returns {void} */
|
|
210
|
-
export const useSources = (opts) =>
|
|
211
|
-
// eslint-disable-next-line qwik/no-use-visible-task -- intentional delegated DOM glue + cleanup
|
|
212
|
-
useVisibleTask$((ctx) => start(initSources, opts, ctx));
|
|
213
|
-
/** @param {BrontoBindingOptsResolver} [opts] @returns {void} */
|
|
214
|
-
export const useSplitter = (opts) =>
|
|
215
|
-
// eslint-disable-next-line qwik/no-use-visible-task -- intentional delegated DOM glue + cleanup
|
|
216
|
-
useVisibleTask$((ctx) => start(initSplitter, opts, ctx));
|
|
217
|
-
|
|
218
|
-
/** The `toast()` imperative (no lifecycle of its own).
|
|
219
|
-
* @returns {(message: string, opts?: ToastOpts) => Cleanup} */
|
|
220
|
-
export const useToast = () => toast;
|
|
221
|
-
|
|
222
|
-
// No-flash theme application must run before paint — do it in an inline head
|
|
223
|
-
// script, not on visible. Re-exported for manual/SSR-bootstrap use.
|
|
224
|
-
export { applyStoredTheme };
|
|
225
|
-
|
|
226
|
-
// Convenience: the framework-agnostic class contract, re-exported.
|
|
227
|
-
export { cls, ui, cx } from '../classes/index.js';
|