@ponchia/ui 0.6.8 → 0.6.10
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 +79 -4
- package/README.md +2 -2
- package/annotations/index.d.ts.map +1 -1
- package/annotations/index.js +5 -6
- package/behaviors/carousel.d.ts.map +1 -1
- package/behaviors/carousel.js +100 -60
- package/behaviors/combobox.d.ts.map +1 -1
- package/behaviors/combobox.js +167 -113
- package/behaviors/connectors.d.ts.map +1 -1
- package/behaviors/connectors.js +39 -23
- package/behaviors/forms.d.ts.map +1 -1
- package/behaviors/forms.js +211 -207
- package/behaviors/glyph.d.ts.map +1 -1
- package/behaviors/glyph.js +157 -132
- package/behaviors/inert.d.ts +1 -1
- package/behaviors/inert.d.ts.map +1 -1
- package/behaviors/inert.js +1 -1
- package/behaviors/internal.js +2 -2
- package/behaviors/modal.js +1 -1
- package/behaviors/popover.js +5 -5
- package/behaviors/table.d.ts +1 -1
- package/behaviors/table.d.ts.map +1 -1
- package/behaviors/table.js +7 -8
- package/behaviors/tabs.js +2 -2
- package/behaviors/toast.js +5 -5
- package/classes/classes.json +33 -2
- package/classes/index.d.ts +10 -0
- package/classes/index.js +59 -35
- package/connectors/index.d.ts +2 -2
- package/connectors/index.d.ts.map +1 -1
- package/connectors/index.js +7 -10
- package/css/app.css +3 -4
- package/css/base.css +1 -1
- package/css/content.css +3 -3
- package/css/disclosure.css +3 -3
- package/css/dots.css +4 -4
- package/css/feedback.css +6 -7
- package/css/forms.css +9 -12
- package/css/legend.css +1 -1
- package/css/marks.css +1 -1
- package/css/motion.css +6 -6
- package/css/overlay.css +5 -7
- package/css/primitives.css +14 -16
- package/css/sidenote.css +2 -2
- package/css/table.css +2 -2
- package/css/workbench.css +128 -0
- package/dist/css/workbench.css +1 -1
- package/docs/annotations.md +36 -0
- package/docs/architecture.md +28 -0
- package/docs/interop/react-flow.md +89 -0
- package/docs/package-contract.md +2 -0
- package/docs/reference.md +21 -1
- package/docs/reporting.md +8 -8
- package/docs/stability.md +67 -7
- package/docs/workbench.md +56 -9
- package/glyphs/glyphs.js +43 -33
- package/llms.txt +10 -4
- package/package.json +5 -2
- package/schemas/report-claims.v1.schema.json +1 -1
- package/tokens/index.js +2 -2
package/behaviors/combobox.js
CHANGED
|
@@ -10,6 +10,125 @@ import {
|
|
|
10
10
|
closestSafe,
|
|
11
11
|
} from './internal.js';
|
|
12
12
|
|
|
13
|
+
const COMBOBOX_OPTION_SELECTOR = '[role="option"], .ui-combobox__option';
|
|
14
|
+
|
|
15
|
+
const snapshotAttrs = (el, names) => {
|
|
16
|
+
const out = {};
|
|
17
|
+
for (const name of names) {
|
|
18
|
+
out[name] = {
|
|
19
|
+
had: el.hasAttribute(name),
|
|
20
|
+
value: el.getAttribute(name),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return out;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const restoreAttrs = (el, attrs) => {
|
|
27
|
+
for (const [name, attr] of Object.entries(attrs)) {
|
|
28
|
+
if (attr.had) el.setAttribute(name, attr.value);
|
|
29
|
+
else el.removeAttribute(name);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const inputLabel = (input) =>
|
|
34
|
+
input.getAttribute('aria-label') || input.labels?.[0]?.textContent?.trim();
|
|
35
|
+
|
|
36
|
+
const inputHasAccessibleName = (input) =>
|
|
37
|
+
input.hasAttribute('aria-label') ||
|
|
38
|
+
input.hasAttribute('aria-labelledby') ||
|
|
39
|
+
!!input.labels?.length ||
|
|
40
|
+
input.hasAttribute('title');
|
|
41
|
+
|
|
42
|
+
function mirrorListboxLabel(input, list) {
|
|
43
|
+
if (list.hasAttribute('aria-label') || list.hasAttribute('aria-labelledby')) return;
|
|
44
|
+
const name = inputLabel(input);
|
|
45
|
+
if (name) list.setAttribute('aria-label', name);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function warnNamelessCombobox(input) {
|
|
49
|
+
if (inputHasAccessibleName(input) || typeof console === 'undefined') return;
|
|
50
|
+
console.warn(
|
|
51
|
+
'[bronto] initCombobox(): the combobox input has no accessible name — add a <label>, aria-label, or aria-labelledby (a placeholder is not enough).',
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function prepareEmptyState(empty) {
|
|
56
|
+
if (!empty) return;
|
|
57
|
+
empty.hidden = true;
|
|
58
|
+
if (!empty.hasAttribute('role')) empty.setAttribute('role', 'status');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function liveOptionObserver(box, list, relist) {
|
|
62
|
+
if (!box.hasAttribute('data-bronto-combobox-live')) return null;
|
|
63
|
+
if (typeof MutationObserver !== 'function') return null;
|
|
64
|
+
const observer = new MutationObserver(relist);
|
|
65
|
+
observer.observe(list, { childList: true, subtree: true });
|
|
66
|
+
return observer;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function bindComboboxLifecycle({
|
|
70
|
+
box,
|
|
71
|
+
input,
|
|
72
|
+
list,
|
|
73
|
+
empty,
|
|
74
|
+
rememberState,
|
|
75
|
+
restoreState,
|
|
76
|
+
assignListId,
|
|
77
|
+
syncOptions,
|
|
78
|
+
close,
|
|
79
|
+
relist,
|
|
80
|
+
onInput,
|
|
81
|
+
onKey,
|
|
82
|
+
onOptionClick,
|
|
83
|
+
onDocClick,
|
|
84
|
+
resetActive,
|
|
85
|
+
}) {
|
|
86
|
+
const state = rememberState();
|
|
87
|
+
const listId = assignListId();
|
|
88
|
+
syncOptions();
|
|
89
|
+
list.setAttribute('role', 'listbox');
|
|
90
|
+
// Give the listbox its own accessible name (a bare role=listbox is unnamed
|
|
91
|
+
// to a screen reader) by mirroring the input's real name.
|
|
92
|
+
// The placeholder is deliberately NOT in this chain: the input warning below
|
|
93
|
+
// already rejects a placeholder as an inadequate name, so papering the
|
|
94
|
+
// listbox over with it would contradict that. If there is no real name, the
|
|
95
|
+
// listbox stays unnamed and the warning is the signal.
|
|
96
|
+
mirrorListboxLabel(input, list);
|
|
97
|
+
// A `role="combobox"` with no accessible name is a silent AT failure. A
|
|
98
|
+
// placeholder is not a robust name (it can vanish and is ignored by some
|
|
99
|
+
// AT), so warn unless there is a real label/aria-label/aria-labelledby/title
|
|
100
|
+
// We cannot invent a good name, hence a dev-time warning, not a guess.
|
|
101
|
+
warnNamelessCombobox(input);
|
|
102
|
+
input.setAttribute('role', 'combobox');
|
|
103
|
+
input.setAttribute('aria-controls', listId);
|
|
104
|
+
input.setAttribute('aria-autocomplete', 'list');
|
|
105
|
+
input.setAttribute('aria-expanded', 'false');
|
|
106
|
+
input.setAttribute('autocomplete', 'off');
|
|
107
|
+
// Hide the empty-state at rest: it must only appear once a filter yields no
|
|
108
|
+
// matches, never on an idle combobox. Without this an author who omits
|
|
109
|
+
// `hidden` on `.ui-combobox__empty` ships a box that reads "No matches"
|
|
110
|
+
// before the user has typed anything. Make it a status live region so its
|
|
111
|
+
// appearance is announced.
|
|
112
|
+
prepareEmptyState(empty);
|
|
113
|
+
close();
|
|
114
|
+
input.addEventListener('input', onInput);
|
|
115
|
+
input.addEventListener('keydown', onKey);
|
|
116
|
+
list.addEventListener('click', onOptionClick);
|
|
117
|
+
document.addEventListener('click', onDocClick);
|
|
118
|
+
// Opt-in: keep options in sync with a list mutated after init (async /
|
|
119
|
+
// remote results). Off by default so the common static case stays free.
|
|
120
|
+
const observer = liveOptionObserver(box, list, relist);
|
|
121
|
+
return () => {
|
|
122
|
+
observer?.disconnect();
|
|
123
|
+
input.removeEventListener('input', onInput);
|
|
124
|
+
input.removeEventListener('keydown', onKey);
|
|
125
|
+
list.removeEventListener('click', onOptionClick);
|
|
126
|
+
document.removeEventListener('click', onDocClick);
|
|
127
|
+
restoreState(state);
|
|
128
|
+
resetActive();
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
13
132
|
/**
|
|
14
133
|
* Editable combobox with a filtered listbox popup, implementing the
|
|
15
134
|
* WAI-ARIA APG combobox pattern (the widget the framework most lacked
|
|
@@ -55,24 +174,6 @@ export function initCombobox({ root } = {}) {
|
|
|
55
174
|
const boxes = collectHosts(host, '[data-bronto-combobox]');
|
|
56
175
|
const cleanups = [];
|
|
57
176
|
|
|
58
|
-
const snapshotAttrs = (el, names) => {
|
|
59
|
-
const out = {};
|
|
60
|
-
for (const name of names) {
|
|
61
|
-
out[name] = {
|
|
62
|
-
had: el.hasAttribute(name),
|
|
63
|
-
value: el.getAttribute(name),
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
return out;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
const restoreAttrs = (el, attrs) => {
|
|
70
|
-
for (const [name, attr] of Object.entries(attrs)) {
|
|
71
|
-
if (attr.had) el.setAttribute(name, attr.value);
|
|
72
|
-
else el.removeAttribute(name);
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
|
|
76
177
|
for (const box of boxes) {
|
|
77
178
|
const input = box.querySelector('[role="combobox"], .ui-combobox__input');
|
|
78
179
|
const list = box.querySelector('[role="listbox"], .ui-combobox__list');
|
|
@@ -134,7 +235,7 @@ export function initCombobox({ root } = {}) {
|
|
|
134
235
|
// `filter`, `move`, etc. close over this binding, so reassigning it is enough.
|
|
135
236
|
let options = [];
|
|
136
237
|
const syncOptions = () => {
|
|
137
|
-
options = [...list.querySelectorAll(
|
|
238
|
+
options = [...list.querySelectorAll(COMBOBOX_OPTION_SELECTOR)];
|
|
138
239
|
options.forEach((o, i) => {
|
|
139
240
|
rememberOptionState(o);
|
|
140
241
|
if (!o.id) o.id = `${listId}-opt-${i}`;
|
|
@@ -190,7 +291,6 @@ export function initCombobox({ root } = {}) {
|
|
|
190
291
|
// Show the human LABEL in the input; emit the `data-value` CODE in the
|
|
191
292
|
// event. The natural pattern is code in `data-value`, label in the text —
|
|
192
293
|
// putting the code in the visible input silently shows the user a raw code.
|
|
193
|
-
// (component audit C10.)
|
|
194
294
|
const label = opt.textContent.trim();
|
|
195
295
|
const value = opt.dataset.value ?? label;
|
|
196
296
|
input.value = label;
|
|
@@ -243,107 +343,61 @@ export function initCombobox({ root } = {}) {
|
|
|
243
343
|
|
|
244
344
|
const onInput = () => filter();
|
|
245
345
|
const onKey = (e) => {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
case 'Tab':
|
|
268
|
-
close();
|
|
269
|
-
break;
|
|
270
|
-
default:
|
|
271
|
-
break;
|
|
272
|
-
}
|
|
346
|
+
const handled = keyHandlers[e.key]?.();
|
|
347
|
+
if (handled) e.preventDefault();
|
|
348
|
+
};
|
|
349
|
+
const keyHandlers = {
|
|
350
|
+
ArrowDown: () => {
|
|
351
|
+
if (list.hidden) filter();
|
|
352
|
+
else move(1);
|
|
353
|
+
return true;
|
|
354
|
+
},
|
|
355
|
+
ArrowUp: () => {
|
|
356
|
+
move(-1);
|
|
357
|
+
return true;
|
|
358
|
+
},
|
|
359
|
+
Home: () => activateEdge('first'),
|
|
360
|
+
End: () => activateEdge('last'),
|
|
361
|
+
Enter: () => selectActive(),
|
|
362
|
+
Escape: () => closeIfOpen(),
|
|
363
|
+
Tab: () => {
|
|
364
|
+
close();
|
|
365
|
+
return false;
|
|
366
|
+
},
|
|
273
367
|
};
|
|
274
368
|
const onOptionClick = (e) => {
|
|
275
|
-
const opt = closestSafe(e.target,
|
|
369
|
+
const opt = closestSafe(e.target, COMBOBOX_OPTION_SELECTOR);
|
|
276
370
|
if (opt) select(opt);
|
|
277
371
|
};
|
|
278
372
|
const onDocClick = (e) => {
|
|
279
373
|
if (!box.contains(e.target)) close();
|
|
280
374
|
};
|
|
281
|
-
|
|
282
|
-
const bound = bindOnce(box, 'combobox', () => {
|
|
283
|
-
const state = rememberState();
|
|
375
|
+
const assignListId = () => {
|
|
284
376
|
listId = list.id || (list.id = `bronto-cb-list-${nextFieldUid()}`);
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
);
|
|
310
|
-
}
|
|
311
|
-
input.setAttribute('role', 'combobox');
|
|
312
|
-
input.setAttribute('aria-controls', listId);
|
|
313
|
-
input.setAttribute('aria-autocomplete', 'list');
|
|
314
|
-
input.setAttribute('aria-expanded', 'false');
|
|
315
|
-
input.setAttribute('autocomplete', 'off');
|
|
316
|
-
// Hide the empty-state at rest: it must only appear once a filter yields no
|
|
317
|
-
// matches, never on an idle combobox. Without this an author who omits
|
|
318
|
-
// `hidden` on `.ui-combobox__empty` ships a box that reads "No matches"
|
|
319
|
-
// before the user has typed anything. (component audit C10.) Make it a
|
|
320
|
-
// status live region so its appearance is announced. (component audit C38.)
|
|
321
|
-
if (empty) {
|
|
322
|
-
empty.hidden = true;
|
|
323
|
-
if (!empty.hasAttribute('role')) empty.setAttribute('role', 'status');
|
|
324
|
-
}
|
|
325
|
-
close();
|
|
326
|
-
input.addEventListener('input', onInput);
|
|
327
|
-
input.addEventListener('keydown', onKey);
|
|
328
|
-
list.addEventListener('click', onOptionClick);
|
|
329
|
-
document.addEventListener('click', onDocClick);
|
|
330
|
-
// Opt-in: keep options in sync with a list mutated after init (async /
|
|
331
|
-
// remote results). Off by default so the common static case stays free.
|
|
332
|
-
const observer =
|
|
333
|
-
box.hasAttribute('data-bronto-combobox-live') && typeof MutationObserver === 'function'
|
|
334
|
-
? new MutationObserver(relist)
|
|
335
|
-
: null;
|
|
336
|
-
observer?.observe(list, { childList: true, subtree: true });
|
|
337
|
-
return () => {
|
|
338
|
-
observer?.disconnect();
|
|
339
|
-
input.removeEventListener('input', onInput);
|
|
340
|
-
input.removeEventListener('keydown', onKey);
|
|
341
|
-
list.removeEventListener('click', onOptionClick);
|
|
342
|
-
document.removeEventListener('click', onDocClick);
|
|
343
|
-
restoreState(state);
|
|
344
|
-
active = -1;
|
|
345
|
-
};
|
|
346
|
-
});
|
|
377
|
+
return listId;
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
const bound = bindOnce(box, 'combobox', () =>
|
|
381
|
+
bindComboboxLifecycle({
|
|
382
|
+
box,
|
|
383
|
+
input,
|
|
384
|
+
list,
|
|
385
|
+
empty,
|
|
386
|
+
rememberState,
|
|
387
|
+
restoreState,
|
|
388
|
+
assignListId,
|
|
389
|
+
syncOptions,
|
|
390
|
+
close,
|
|
391
|
+
relist,
|
|
392
|
+
onInput,
|
|
393
|
+
onKey,
|
|
394
|
+
onOptionClick,
|
|
395
|
+
onDocClick,
|
|
396
|
+
resetActive: () => {
|
|
397
|
+
active = -1;
|
|
398
|
+
},
|
|
399
|
+
}),
|
|
400
|
+
);
|
|
347
401
|
cleanups.push(bound);
|
|
348
402
|
}
|
|
349
403
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connectors.d.ts","sourceRoot":"","sources":["connectors.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"connectors.d.ts","sourceRoot":"","sources":["connectors.js"],"names":[],"mappings":"AA+EA;;;;;;;;;;;;;;GAcG;AACH,0CAHW,OAAO,eAAe,EAAE,YAAY,GAClC,OAAO,eAAe,EAAE,OAAO,CAwG3C"}
|
package/behaviors/connectors.js
CHANGED
|
@@ -2,6 +2,9 @@ import { hasDom, resolveHost, noop, bindOnce, byIdInHost, collectHosts } from '.
|
|
|
2
2
|
import { connectRects, arrowHead, dotMark } from '../connectors/index.js';
|
|
3
3
|
|
|
4
4
|
const SVGNS = 'http://www.w3.org/2000/svg';
|
|
5
|
+
const NORMALIZED_PATH_LENGTH = '1';
|
|
6
|
+
const END_DOT_RADIUS = 3;
|
|
7
|
+
const END_ARROW_SIZE = 8;
|
|
5
8
|
|
|
6
9
|
const snapshotAttrs = (el) =>
|
|
7
10
|
Array.from(el.attributes, ({ name, value }) => ({
|
|
@@ -41,6 +44,39 @@ const restorePart = (svg, selector, state) => {
|
|
|
41
44
|
state.node.textContent = state.textContent;
|
|
42
45
|
};
|
|
43
46
|
|
|
47
|
+
const upsertConnectorPart = (svg, selector, className) => {
|
|
48
|
+
let part = svg.querySelector(selector);
|
|
49
|
+
if (part) return part;
|
|
50
|
+
part = document.createElementNS(SVGNS, 'path');
|
|
51
|
+
part.setAttribute('class', className);
|
|
52
|
+
svg.appendChild(part);
|
|
53
|
+
return part;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const syncDrawPathLength = (svg, path) => {
|
|
57
|
+
// pathLength normalises the draw animation, but it would also reframe a
|
|
58
|
+
// dashed line's user-unit dasharray — so only set it for draw connectors.
|
|
59
|
+
if (svg.classList.contains('ui-connector--draw')) {
|
|
60
|
+
path.setAttribute('pathLength', NORMALIZED_PATH_LENGTH);
|
|
61
|
+
} else {
|
|
62
|
+
path.removeAttribute('pathLength');
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const syncConnectorEnd = (svg, end, angle) => {
|
|
67
|
+
const kind = svg.dataset.end || 'arrow';
|
|
68
|
+
const cap = svg.querySelector('.ui-connector__end');
|
|
69
|
+
if (kind === 'none') {
|
|
70
|
+
cap?.remove();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const next = cap || upsertConnectorPart(svg, '.ui-connector__end', 'ui-connector__end');
|
|
74
|
+
next.setAttribute(
|
|
75
|
+
'd',
|
|
76
|
+
kind === 'dot' ? dotMark(end, END_DOT_RADIUS) : arrowHead(end, angle, END_ARROW_SIZE),
|
|
77
|
+
);
|
|
78
|
+
};
|
|
79
|
+
|
|
44
80
|
/**
|
|
45
81
|
* Draw + keep leader lines in sync. Each `[data-bronto-connector]` is an
|
|
46
82
|
* `.ui-connector` SVG overlaying a positioned container; `data-from`/`data-to`
|
|
@@ -118,30 +154,10 @@ export function initConnectors({ root } = {}) {
|
|
|
118
154
|
fromSide: svg.dataset.fromSide || undefined,
|
|
119
155
|
toSide: svg.dataset.toSide || undefined,
|
|
120
156
|
});
|
|
121
|
-
|
|
122
|
-
if (!path) {
|
|
123
|
-
path = document.createElementNS(SVGNS, 'path');
|
|
124
|
-
path.setAttribute('class', 'ui-connector__path');
|
|
125
|
-
svg.appendChild(path);
|
|
126
|
-
}
|
|
157
|
+
const path = upsertConnectorPart(svg, '.ui-connector__path', 'ui-connector__path');
|
|
127
158
|
path.setAttribute('d', d);
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (svg.classList.contains('ui-connector--draw')) path.setAttribute('pathLength', '1');
|
|
131
|
-
else path.removeAttribute('pathLength');
|
|
132
|
-
|
|
133
|
-
const kind = svg.dataset.end || 'arrow';
|
|
134
|
-
let cap = svg.querySelector('.ui-connector__end');
|
|
135
|
-
if (kind === 'none') {
|
|
136
|
-
cap?.remove();
|
|
137
|
-
continue;
|
|
138
|
-
}
|
|
139
|
-
if (!cap) {
|
|
140
|
-
cap = document.createElementNS(SVGNS, 'path');
|
|
141
|
-
cap.setAttribute('class', 'ui-connector__end');
|
|
142
|
-
svg.appendChild(cap);
|
|
143
|
-
}
|
|
144
|
-
cap.setAttribute('d', kind === 'dot' ? dotMark(end, 3) : arrowHead(end, angle, 8));
|
|
159
|
+
syncDrawPathLength(svg, path);
|
|
160
|
+
syncConnectorEnd(svg, end, angle);
|
|
145
161
|
}
|
|
146
162
|
};
|
|
147
163
|
|
package/behaviors/forms.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forms.d.ts","sourceRoot":"","sources":["forms.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"forms.d.ts","sourceRoot":"","sources":["forms.js"],"names":[],"mappings":"AAiMA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,8CAHW,OAAO,eAAe,EAAE,YAAY,GAClC,OAAO,eAAe,EAAE,OAAO,CA2D3C"}
|