@digdir/designsystemet-web 1.13.0 → 1.13.2
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 +12 -1
- package/dist/cjs/_vendors/invokers-polyfill/invoker.cjs +2 -0
- package/dist/cjs/_vendors/invokers-polyfill/invoker.cjs.map +1 -0
- package/dist/cjs/breadcrumbs/breadcrumbs.cjs +1 -1
- package/dist/cjs/breadcrumbs/breadcrumbs.cjs.map +1 -1
- package/dist/cjs/clickdelegatefor/clickdelegatefor.cjs +1 -1
- package/dist/cjs/clickdelegatefor/clickdelegatefor.cjs.map +1 -1
- package/dist/cjs/dialog/dialog.cjs +1 -1
- package/dist/cjs/dialog/dialog.cjs.map +1 -1
- package/dist/cjs/error-summary/error-summary.cjs +1 -1
- package/dist/cjs/error-summary/error-summary.cjs.map +1 -1
- package/dist/cjs/field/field.cjs +1 -1
- package/dist/cjs/field/field.cjs.map +1 -1
- package/dist/cjs/fieldset/fieldset.cjs +2 -0
- package/dist/cjs/fieldset/fieldset.cjs.map +1 -0
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/pagination/pagination.cjs +1 -1
- package/dist/cjs/pagination/pagination.cjs.map +1 -1
- package/dist/cjs/popover/popover.cjs +1 -1
- package/dist/cjs/popover/popover.cjs.map +1 -1
- package/dist/cjs/readonly/readonly.cjs +1 -1
- package/dist/cjs/readonly/readonly.cjs.map +1 -1
- package/dist/cjs/suggestion/suggestion.cjs +1 -1
- package/dist/cjs/suggestion/suggestion.cjs.map +1 -1
- package/dist/cjs/toggle-group/toggle-group.cjs +1 -1
- package/dist/cjs/toggle-group/toggle-group.cjs.map +1 -1
- package/dist/cjs/tooltip/tooltip.cjs +1 -1
- package/dist/cjs/tooltip/tooltip.cjs.map +1 -1
- package/dist/cjs/utils/utils.cjs +1 -1
- package/dist/cjs/utils/utils.cjs.map +1 -1
- package/dist/custom-elements.json +18 -12
- package/dist/esm/_vendors/invokers-polyfill/invoker.js +2 -0
- package/dist/esm/_vendors/invokers-polyfill/invoker.js.map +1 -0
- package/dist/esm/breadcrumbs/breadcrumbs.js +1 -1
- package/dist/esm/breadcrumbs/breadcrumbs.js.map +1 -1
- package/dist/esm/clickdelegatefor/clickdelegatefor.js +1 -1
- package/dist/esm/clickdelegatefor/clickdelegatefor.js.map +1 -1
- package/dist/esm/dialog/dialog.js +1 -1
- package/dist/esm/dialog/dialog.js.map +1 -1
- package/dist/esm/error-summary/error-summary.js +1 -1
- package/dist/esm/error-summary/error-summary.js.map +1 -1
- package/dist/esm/field/field.js +1 -1
- package/dist/esm/field/field.js.map +1 -1
- package/dist/esm/fieldset/fieldset.js +2 -0
- package/dist/esm/fieldset/fieldset.js.map +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/pagination/pagination.js +1 -1
- package/dist/esm/pagination/pagination.js.map +1 -1
- package/dist/esm/popover/popover.js +1 -1
- package/dist/esm/popover/popover.js.map +1 -1
- package/dist/esm/readonly/readonly.js +1 -1
- package/dist/esm/readonly/readonly.js.map +1 -1
- package/dist/esm/suggestion/suggestion.js +1 -1
- package/dist/esm/suggestion/suggestion.js.map +1 -1
- package/dist/esm/toggle-group/toggle-group.js +1 -1
- package/dist/esm/toggle-group/toggle-group.js.map +1 -1
- package/dist/esm/tooltip/tooltip.js +1 -1
- package/dist/esm/tooltip/tooltip.js.map +1 -1
- package/dist/esm/utils/utils.js +1 -1
- package/dist/esm/utils/utils.js.map +1 -1
- package/dist/index.d.ts +18 -5
- package/dist/index.js +473 -151
- package/dist/umd/index.js +4 -4
- package/dist/umd/index.js.map +1 -1
- package/dist/web.manifest.json +64 -42
- package/package.json +19 -14
package/dist/index.js
CHANGED
|
@@ -1,5 +1,294 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
1
|
+
// ../../node_modules/.pnpm/invokers-polyfill@1.0.2_patch_hash=d5677be15320f04cdc552d82cb4a79242bd1cf8b26bcbb0a13e1153e7bed3b5a/node_modules/invokers-polyfill/invoker.js
|
|
2
|
+
function isSupported() {
|
|
3
|
+
return typeof HTMLButtonElement !== "undefined" && "command" in HTMLButtonElement.prototype && "source" in ((globalThis.CommandEvent || {}).prototype || {});
|
|
4
|
+
}
|
|
5
|
+
function apply() {
|
|
6
|
+
document.addEventListener(
|
|
7
|
+
"invoke",
|
|
8
|
+
(e) => {
|
|
9
|
+
if (e.type == "invoke" && e.isTrusted) {
|
|
10
|
+
e.stopImmediatePropagation();
|
|
11
|
+
e.preventDefault();
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
true
|
|
15
|
+
);
|
|
16
|
+
document.addEventListener(
|
|
17
|
+
"command",
|
|
18
|
+
(e) => {
|
|
19
|
+
if (e.type == "command" && e.isTrusted) {
|
|
20
|
+
e.stopImmediatePropagation();
|
|
21
|
+
e.preventDefault();
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
true
|
|
25
|
+
);
|
|
26
|
+
function enumerate(obj, key, enumerable = true) {
|
|
27
|
+
Object.defineProperty(obj, key, {
|
|
28
|
+
...Object.getOwnPropertyDescriptor(obj, key),
|
|
29
|
+
enumerable
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
function getRootNode(node) {
|
|
33
|
+
if (node && typeof node.getRootNode === "function") {
|
|
34
|
+
return node.getRootNode();
|
|
35
|
+
}
|
|
36
|
+
if (node && node.parentNode) return getRootNode(node.parentNode);
|
|
37
|
+
return node;
|
|
38
|
+
}
|
|
39
|
+
const commandEventSourceElements = /* @__PURE__ */ new WeakMap();
|
|
40
|
+
const commandEventActions = /* @__PURE__ */ new WeakMap();
|
|
41
|
+
class CommandEvent extends Event {
|
|
42
|
+
constructor(type, invokeEventInit = {}) {
|
|
43
|
+
super(type, invokeEventInit);
|
|
44
|
+
const { source, command } = invokeEventInit;
|
|
45
|
+
if (source != null && !(source instanceof Element)) {
|
|
46
|
+
throw new TypeError(`source must be an element`);
|
|
47
|
+
}
|
|
48
|
+
commandEventSourceElements.set(this, source || null);
|
|
49
|
+
commandEventActions.set(
|
|
50
|
+
this,
|
|
51
|
+
command !== void 0 ? String(command) : ""
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
get [Symbol.toStringTag]() {
|
|
55
|
+
return "CommandEvent";
|
|
56
|
+
}
|
|
57
|
+
get source() {
|
|
58
|
+
if (!commandEventSourceElements.has(this)) {
|
|
59
|
+
throw new TypeError("illegal invocation");
|
|
60
|
+
}
|
|
61
|
+
const source = commandEventSourceElements.get(this);
|
|
62
|
+
if (!(source instanceof Element)) return null;
|
|
63
|
+
const invokerRoot = getRootNode(source);
|
|
64
|
+
if (invokerRoot !== getRootNode(this.target || document)) {
|
|
65
|
+
return invokerRoot.host;
|
|
66
|
+
}
|
|
67
|
+
return source;
|
|
68
|
+
}
|
|
69
|
+
get command() {
|
|
70
|
+
if (!commandEventActions.has(this)) {
|
|
71
|
+
throw new TypeError("illegal invocation");
|
|
72
|
+
}
|
|
73
|
+
return commandEventActions.get(this);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
enumerate(CommandEvent.prototype, "source");
|
|
77
|
+
enumerate(CommandEvent.prototype, "command");
|
|
78
|
+
const invokerAssociatedElements = /* @__PURE__ */ new WeakMap();
|
|
79
|
+
function applyInvokerMixin(ElementClass) {
|
|
80
|
+
Object.defineProperties(ElementClass.prototype, {
|
|
81
|
+
commandForElement: {
|
|
82
|
+
enumerable: true,
|
|
83
|
+
configurable: true,
|
|
84
|
+
set(targetElement) {
|
|
85
|
+
if (targetElement === null) {
|
|
86
|
+
this.removeAttribute("commandfor");
|
|
87
|
+
invokerAssociatedElements.delete(this);
|
|
88
|
+
} else if (!(targetElement instanceof Element)) {
|
|
89
|
+
throw new TypeError(`commandForElement must be an element or null`);
|
|
90
|
+
} else {
|
|
91
|
+
this.setAttribute("commandfor", "");
|
|
92
|
+
const targetRootNode = getRootNode(targetElement);
|
|
93
|
+
const thisRootNode = getRootNode(this);
|
|
94
|
+
if (thisRootNode === targetRootNode || targetRootNode === this.ownerDocument) {
|
|
95
|
+
invokerAssociatedElements.set(this, targetElement);
|
|
96
|
+
} else {
|
|
97
|
+
invokerAssociatedElements.delete(this);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
get() {
|
|
102
|
+
if (this.localName !== "button") {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
if (this.disabled) {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
if (this.form && this.getAttribute("type") !== "button") {
|
|
109
|
+
console.warn(
|
|
110
|
+
"Element with `commandFor` is a form participant. It should explicitly set `type=button` in order for `commandFor` to work"
|
|
111
|
+
);
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
const targetElement = invokerAssociatedElements.get(this);
|
|
115
|
+
if (targetElement) {
|
|
116
|
+
if (targetElement.isConnected) {
|
|
117
|
+
return targetElement;
|
|
118
|
+
} else {
|
|
119
|
+
invokerAssociatedElements.delete(this);
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const root = getRootNode(this);
|
|
124
|
+
const idref = this.getAttribute("commandfor");
|
|
125
|
+
if ((root instanceof Document || root instanceof ShadowRoot) && idref) {
|
|
126
|
+
return root.getElementById(idref) || null;
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
command: {
|
|
132
|
+
enumerable: true,
|
|
133
|
+
configurable: true,
|
|
134
|
+
get() {
|
|
135
|
+
const value = this.getAttribute("command") || "";
|
|
136
|
+
if (value.startsWith("--")) return value;
|
|
137
|
+
const valueLower = value.toLowerCase();
|
|
138
|
+
switch (valueLower) {
|
|
139
|
+
case "show-modal":
|
|
140
|
+
case "request-close":
|
|
141
|
+
case "close":
|
|
142
|
+
case "toggle-popover":
|
|
143
|
+
case "hide-popover":
|
|
144
|
+
case "show-popover":
|
|
145
|
+
return valueLower;
|
|
146
|
+
}
|
|
147
|
+
return "";
|
|
148
|
+
},
|
|
149
|
+
set(value) {
|
|
150
|
+
this.setAttribute("command", value);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
const onHandlers = /* @__PURE__ */ new WeakMap();
|
|
156
|
+
Object.defineProperties(HTMLElement.prototype, {
|
|
157
|
+
oncommand: {
|
|
158
|
+
enumerable: true,
|
|
159
|
+
configurable: true,
|
|
160
|
+
get() {
|
|
161
|
+
oncommandObserver.takeRecords();
|
|
162
|
+
return onHandlers.get(this) || null;
|
|
163
|
+
},
|
|
164
|
+
set(handler) {
|
|
165
|
+
const existing = onHandlers.get(this) || null;
|
|
166
|
+
if (existing) {
|
|
167
|
+
this.removeEventListener("command", existing);
|
|
168
|
+
}
|
|
169
|
+
onHandlers.set(
|
|
170
|
+
this,
|
|
171
|
+
typeof handler === "object" || typeof handler === "function" ? handler : null
|
|
172
|
+
);
|
|
173
|
+
if (typeof handler == "function") {
|
|
174
|
+
this.addEventListener("command", handler);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
function applyOnCommandHandler(els) {
|
|
180
|
+
for (const el of els) {
|
|
181
|
+
el.oncommand = new Function("event", el.getAttribute("oncommand"));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
const oncommandObserver = new MutationObserver((records) => {
|
|
185
|
+
for (const record of records) {
|
|
186
|
+
const { target } = record;
|
|
187
|
+
if (record.type === "childList") {
|
|
188
|
+
applyOnCommandHandler(target.querySelectorAll("[oncommand]"));
|
|
189
|
+
} else {
|
|
190
|
+
applyOnCommandHandler([target]);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
oncommandObserver.observe(document, {
|
|
195
|
+
subtree: true,
|
|
196
|
+
childList: true,
|
|
197
|
+
attributeFilter: ["oncommand"]
|
|
198
|
+
});
|
|
199
|
+
applyOnCommandHandler(document.querySelectorAll("[oncommand]"));
|
|
200
|
+
const processedEvents = /* @__PURE__ */ new WeakSet();
|
|
201
|
+
function handleInvokerActivation(event) {
|
|
202
|
+
if (processedEvents.has(event)) return;
|
|
203
|
+
processedEvents.add(event);
|
|
204
|
+
if (event.defaultPrevented) return;
|
|
205
|
+
if (event.type !== "click") return;
|
|
206
|
+
const source = event.composedPath().find((el) => el.matches?.("button[commandfor], button[command]"));
|
|
207
|
+
if (!source) return;
|
|
208
|
+
if (source.form && source.getAttribute("type") !== "button") {
|
|
209
|
+
event.preventDefault();
|
|
210
|
+
throw new Error(
|
|
211
|
+
"Element with `commandFor` is a form participant. It should explicitly set `type=button` in order for `commandFor` to work. In order for it to act as a Submit button, it must not have command or commandfor attributes"
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
if (source.hasAttribute("command") !== source.hasAttribute("commandfor")) {
|
|
215
|
+
const attr2 = source.hasAttribute("command") ? "command" : "commandfor";
|
|
216
|
+
const missing = source.hasAttribute("command") ? "commandfor" : "command";
|
|
217
|
+
throw new Error(
|
|
218
|
+
`Element with ${attr2} attribute must also have a ${missing} attribute to function.`
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
if (source.command !== "show-popover" && source.command !== "hide-popover" && source.command !== "toggle-popover" && source.command !== "show-modal" && source.command !== "request-close" && source.command !== "close" && !source.command.startsWith("--")) {
|
|
222
|
+
console.warn(
|
|
223
|
+
`"${source.command}" is not a valid command value. Custom commands must begin with --`
|
|
224
|
+
);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
const invokee = source.commandForElement;
|
|
228
|
+
if (!invokee) return;
|
|
229
|
+
const invokeEvent = new CommandEvent("command", {
|
|
230
|
+
command: source.command,
|
|
231
|
+
source,
|
|
232
|
+
cancelable: true
|
|
233
|
+
});
|
|
234
|
+
invokee.dispatchEvent(invokeEvent);
|
|
235
|
+
if (invokeEvent.defaultPrevented) return;
|
|
236
|
+
const command = invokeEvent.command.toLowerCase();
|
|
237
|
+
if (invokee.popover) {
|
|
238
|
+
const canShow = !invokee.matches(":popover-open");
|
|
239
|
+
const shouldShow = canShow && (command === "toggle-popover" || command === "show-popover");
|
|
240
|
+
const shouldHide = !canShow && command === "hide-popover";
|
|
241
|
+
if (shouldShow) {
|
|
242
|
+
invokee.showPopover({ source });
|
|
243
|
+
} else if (shouldHide) {
|
|
244
|
+
invokee.hidePopover();
|
|
245
|
+
}
|
|
246
|
+
} else if (invokee.localName === "dialog") {
|
|
247
|
+
const canShow = !invokee.hasAttribute("open");
|
|
248
|
+
if (canShow && command == "show-modal") {
|
|
249
|
+
invokee.showModal();
|
|
250
|
+
} else if (!canShow && command == "close") {
|
|
251
|
+
invokee.close(source.value ? source.value : void 0);
|
|
252
|
+
} else if (!canShow && command == "request-close") {
|
|
253
|
+
if (!HTMLDialogElement.prototype.requestClose) {
|
|
254
|
+
HTMLDialogElement.prototype.requestClose = function() {
|
|
255
|
+
const cancelEvent = new Event("cancel", { cancelable: true });
|
|
256
|
+
this.dispatchEvent(cancelEvent);
|
|
257
|
+
if (!cancelEvent.defaultPrevented) {
|
|
258
|
+
this.close();
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
invokee.requestClose(source.value ? source.value : void 0);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
function setupInvokeListeners(target) {
|
|
267
|
+
target.addEventListener("click", handleInvokerActivation, true);
|
|
268
|
+
}
|
|
269
|
+
function observeShadowRoots(ElementClass, callback) {
|
|
270
|
+
const attachShadow = ElementClass.prototype.attachShadow;
|
|
271
|
+
ElementClass.prototype.attachShadow = function(init) {
|
|
272
|
+
const shadow = attachShadow.call(this, init);
|
|
273
|
+
callback(shadow);
|
|
274
|
+
return shadow;
|
|
275
|
+
};
|
|
276
|
+
const attachInternals = ElementClass.prototype.attachInternals;
|
|
277
|
+
ElementClass.prototype.attachInternals = function() {
|
|
278
|
+
const internals = attachInternals.call(this);
|
|
279
|
+
if (internals.shadowRoot) callback(internals.shadowRoot);
|
|
280
|
+
return internals;
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
applyInvokerMixin(HTMLButtonElement);
|
|
284
|
+
observeShadowRoots(HTMLElement, (shadow) => {
|
|
285
|
+
setupInvokeListeners(shadow);
|
|
286
|
+
oncommandObserver.observe(shadow, { attributeFilter: ["oncommand"] });
|
|
287
|
+
applyOnCommandHandler(shadow.querySelectorAll("[oncommand]"));
|
|
288
|
+
});
|
|
289
|
+
setupInvokeListeners(document);
|
|
290
|
+
Object.assign(globalThis, { CommandEvent });
|
|
291
|
+
}
|
|
3
292
|
|
|
4
293
|
// src/utils/utils.ts
|
|
5
294
|
var QUICK_EVENT = { passive: true, capture: true };
|
|
@@ -15,22 +304,21 @@ function debounce(callback, delay) {
|
|
|
15
304
|
timer = setTimeout(() => callback.apply(this, args), delay);
|
|
16
305
|
};
|
|
17
306
|
}
|
|
18
|
-
var warn = (message, ...args) =>
|
|
307
|
+
var warn = (message, ...args) => !isBrowser() || window.dsWarnings === false || console.log(`\x1B[1mDesignsystemet:\x1B[m ${message}`, ...args);
|
|
19
308
|
var attr = (el, name, value) => {
|
|
20
309
|
if (value === void 0) return el.getAttribute(name) ?? null;
|
|
21
310
|
if (value === null) el.removeAttribute(name);
|
|
22
311
|
else if (el.getAttribute(name) !== value) el.setAttribute(name, value);
|
|
23
312
|
return null;
|
|
24
313
|
};
|
|
25
|
-
var
|
|
314
|
+
var getCSSProp = (el, prop) => getComputedStyle(el).getPropertyValue(prop).trim();
|
|
315
|
+
var STRIP_QUOTES = /^["']|["']$/g;
|
|
26
316
|
var attrOrCSS = (el, name) => {
|
|
27
317
|
let value = attr(el, name);
|
|
28
|
-
if (!value)
|
|
29
|
-
|
|
30
|
-
value = prop.replace(STRIP_SURROUNDING_QUOTES, "").trim() || null;
|
|
31
|
-
}
|
|
318
|
+
if (!value)
|
|
319
|
+
value = getCSSProp(el, `--_ds-${name}`).replace(STRIP_QUOTES, "").trim();
|
|
32
320
|
if (!value) warn(`Missing ${name} on:`, el);
|
|
33
|
-
return value;
|
|
321
|
+
return value || null;
|
|
34
322
|
};
|
|
35
323
|
var on = (el, ...rest) => {
|
|
36
324
|
const [types, ...options] = rest;
|
|
@@ -47,31 +335,16 @@ var onHotReload = (key, setup) => {
|
|
|
47
335
|
window._dsHotReloadCleanup?.get(key)?.map((cleanup) => cleanup());
|
|
48
336
|
window._dsHotReloadCleanup?.set(key, setup());
|
|
49
337
|
};
|
|
50
|
-
var SKIP_MUTATIONS = false;
|
|
51
338
|
var onMutation = (el, callback, options) => {
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
if (!el.isConnected) return cleanup();
|
|
55
|
-
callback(
|
|
56
|
-
observer.takeRecords();
|
|
57
|
-
queue = 0;
|
|
58
|
-
};
|
|
59
|
-
const cleanup = () => observer?.disconnect?.();
|
|
60
|
-
const observer = new MutationObserver(() => {
|
|
61
|
-
if (!SKIP_MUTATIONS && !queue) queue = requestAnimationFrame(onFrame);
|
|
339
|
+
const cleanup = () => observer.disconnect();
|
|
340
|
+
const observer = new MutationObserver((records) => {
|
|
341
|
+
if (!isBrowser() || !el.isConnected) return cleanup();
|
|
342
|
+
callback(el, records);
|
|
62
343
|
});
|
|
344
|
+
callback(el);
|
|
63
345
|
observer.observe(el, options);
|
|
64
|
-
requestAnimationFrame(onFrame);
|
|
65
346
|
return cleanup;
|
|
66
347
|
};
|
|
67
|
-
var setTextWithoutMutation = (el, text) => {
|
|
68
|
-
SKIP_MUTATIONS = true;
|
|
69
|
-
el.textContent = text;
|
|
70
|
-
requestAnimationFrame(enableMutations);
|
|
71
|
-
};
|
|
72
|
-
var enableMutations = () => {
|
|
73
|
-
SKIP_MUTATIONS = false;
|
|
74
|
-
};
|
|
75
348
|
var tag = (tagName, attrs) => {
|
|
76
349
|
const el = document.createElement(tagName);
|
|
77
350
|
if (attrs) for (const [key, val] of Object.entries(attrs)) attr(el, key, val);
|
|
@@ -81,9 +354,10 @@ var customElements = {
|
|
|
81
354
|
define: (name, instance) => !isBrowser() || window.customElements.get(name) || window.customElements.define(name, instance)
|
|
82
355
|
};
|
|
83
356
|
var id = 0;
|
|
84
|
-
var hash = `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 5)}`;
|
|
85
357
|
function useId(el) {
|
|
86
|
-
if (
|
|
358
|
+
if (!isBrowser()) return `:ds:${++id}`;
|
|
359
|
+
if (!window.dsUseId) window.dsUseId = 0;
|
|
360
|
+
if (el && !el.id) el.id = `:ds:${++window.dsUseId}`;
|
|
87
361
|
return el?.id || "";
|
|
88
362
|
}
|
|
89
363
|
var LIVE_EL;
|
|
@@ -91,8 +365,7 @@ var LIVE_FIX = 0;
|
|
|
91
365
|
var LIVE_CLEAR = 0;
|
|
92
366
|
var announce = (text) => {
|
|
93
367
|
clearTimeout(LIVE_CLEAR);
|
|
94
|
-
if (LIVE_EL)
|
|
95
|
-
setTextWithoutMutation(LIVE_EL, `${text}${LIVE_FIX++ % 2 ? "\xA0" : ""}`);
|
|
368
|
+
if (LIVE_EL) LIVE_EL.textContent = `${text}${LIVE_FIX++ % 2 ? "\xA0" : ""}`;
|
|
96
369
|
if (text) LIVE_CLEAR = setTimeout(announce, 2e3, "");
|
|
97
370
|
};
|
|
98
371
|
var announceMount = () => {
|
|
@@ -120,8 +393,7 @@ var SELECTOR_CLICKDELEGATEFOR = `[${ATTR_CLICKDELEGATEFOR}]`;
|
|
|
120
393
|
var SELECTOR_SKIP = 'a,button,label,input,select,textarea,details,dialog,[role="button"],[popover],[contenteditable]';
|
|
121
394
|
var handleClickDelegateFor = (event) => {
|
|
122
395
|
const isNewTab = event.button === 1 || event.metaKey || event.ctrlKey;
|
|
123
|
-
const
|
|
124
|
-
const delegateTarget = isUserLeftOrMiddleClick && getDelegateTarget(event);
|
|
396
|
+
const delegateTarget = event.button < 2 && getDelegateTarget(event);
|
|
125
397
|
if (!delegateTarget || delegateTarget.contains(event.target)) return;
|
|
126
398
|
if (isNewTab && delegateTarget instanceof HTMLAnchorElement)
|
|
127
399
|
return window.open(delegateTarget.href, void 0, delegateTarget.rel);
|
|
@@ -169,9 +441,11 @@ var handleClosedbyAny = ({
|
|
|
169
441
|
if (isClose) requestAnimationFrame(() => el.open && el.close());
|
|
170
442
|
}
|
|
171
443
|
};
|
|
444
|
+
var BUTTONS = isBrowser() ? document.getElementsByTagName("button") : [];
|
|
172
445
|
var handleAriaAttributes = () => {
|
|
173
|
-
for (const btn of
|
|
174
|
-
|
|
446
|
+
for (const btn of BUTTONS)
|
|
447
|
+
if (btn.getAttribute("command")?.endsWith("-modal"))
|
|
448
|
+
btn.setAttribute("aria-haspopup", "dialog");
|
|
175
449
|
};
|
|
176
450
|
var handleCommand = ({ command, target }) => command === "--show-non-modal" && target instanceof HTMLDialogElement && target.show();
|
|
177
451
|
onHotReload("dialog", () => [
|
|
@@ -185,6 +459,22 @@ onHotReload("dialog", () => [
|
|
|
185
459
|
})
|
|
186
460
|
]);
|
|
187
461
|
|
|
462
|
+
// src/fieldset/fieldset.ts
|
|
463
|
+
var FIELDSETS = isBrowser() ? document.getElementsByTagName("fieldset") : [];
|
|
464
|
+
var handleFieldsetMutations = () => {
|
|
465
|
+
for (const el of FIELDSETS) {
|
|
466
|
+
if (el.hasAttribute("aria-labelledby")) continue;
|
|
467
|
+
const labelledby = `${useId(el.querySelector("legend"))} ${useId(el.querySelector(':scope > :is([data-field="description"],legend + p)'))}`;
|
|
468
|
+
attr(el, "aria-labelledby", labelledby.trim() || null);
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
onHotReload("fieldset", () => [
|
|
472
|
+
onMutation(document, handleFieldsetMutations, {
|
|
473
|
+
childList: true,
|
|
474
|
+
subtree: true
|
|
475
|
+
})
|
|
476
|
+
]);
|
|
477
|
+
|
|
188
478
|
// src/popover/popover.ts
|
|
189
479
|
import {
|
|
190
480
|
autoUpdate,
|
|
@@ -200,7 +490,8 @@ var ATTR_AUTO = "data-autoplacement";
|
|
|
200
490
|
var POPOVERS = /* @__PURE__ */ new Map();
|
|
201
491
|
function handleToggle(event) {
|
|
202
492
|
let { newState, oldState, target: el, source = event.detail } = event;
|
|
203
|
-
const
|
|
493
|
+
const isPopover = el instanceof HTMLElement && attr(el, "popover") !== null;
|
|
494
|
+
const float = isPopover && getCSSProp(el, "--_ds-floating");
|
|
204
495
|
if (!float) return;
|
|
205
496
|
if (newState === "closed") return POPOVERS.get(el)?.();
|
|
206
497
|
if (!source) {
|
|
@@ -260,7 +551,6 @@ onHotReload("popover", () => [
|
|
|
260
551
|
on(document, "toggle ds-toggle-source", handleToggle, QUICK_EVENT)
|
|
261
552
|
// Use capture since the toggle event does not bubble
|
|
262
553
|
]);
|
|
263
|
-
var getCSSProp = (el, prop) => getComputedStyle(el).getPropertyValue(prop).trim();
|
|
264
554
|
var arrowPseudo = () => ({
|
|
265
555
|
name: "arrowPseudo",
|
|
266
556
|
fn(data) {
|
|
@@ -279,8 +569,10 @@ var arrowPseudo = () => ({
|
|
|
279
569
|
var isReadOnly = (el) => (el instanceof HTMLSelectElement || el instanceof HTMLInputElement) && (el.hasAttribute("readonly") || attr(el, "aria-readonly") === "true");
|
|
280
570
|
var handleKeyDown = (e) => {
|
|
281
571
|
if (e.key !== "Tab" && isReadOnly(e.target)) {
|
|
282
|
-
e.
|
|
283
|
-
|
|
572
|
+
const isArrow = e.key?.startsWith("Arrow");
|
|
573
|
+
const isModifier = e.altKey || e.ctrlKey || e.metaKey;
|
|
574
|
+
if (isArrow || !isModifier) e.preventDefault();
|
|
575
|
+
if (isArrow && attr(e.target, "type") === "radio") {
|
|
284
576
|
const all = document.querySelectorAll(`input[name="${e.target.name}"]`);
|
|
285
577
|
const move = e.key?.match(/Arrow(Right|Down)/) ? 1 : -1;
|
|
286
578
|
const next = all.length + [...all].indexOf(e.target) + move;
|
|
@@ -308,21 +600,26 @@ onHotReload("readonly", () => [
|
|
|
308
600
|
]);
|
|
309
601
|
|
|
310
602
|
// src/toggle-group/toggle-group.ts
|
|
603
|
+
var ARIA_LABELLEDBY = "aria-labelledby";
|
|
604
|
+
var ARIA_LABEL = "aria-label";
|
|
311
605
|
var ATTR_TOGGLEGROUP = "data-toggle-group";
|
|
312
606
|
var SELECTOR_TOGGLEGROUP = `[${ATTR_TOGGLEGROUP}]`;
|
|
313
|
-
var handleAriaAttributes2 =
|
|
607
|
+
var handleAriaAttributes2 = () => {
|
|
314
608
|
for (const group of document.querySelectorAll(SELECTOR_TOGGLEGROUP))
|
|
315
609
|
attr(group, "aria-label", attrOrCSS(group, ATTR_TOGGLEGROUP));
|
|
316
|
-
}
|
|
610
|
+
};
|
|
317
611
|
var handleKeydown = (event) => {
|
|
318
|
-
const
|
|
612
|
+
const { key, target: el } = event;
|
|
613
|
+
const group = el instanceof HTMLInputElement && el.closest(SELECTOR_TOGGLEGROUP);
|
|
319
614
|
if (!group) return;
|
|
320
|
-
if (
|
|
321
|
-
|
|
615
|
+
if (!attr(group, ARIA_LABEL) && !attr(group, ARIA_LABELLEDBY))
|
|
616
|
+
attr(group, ARIA_LABEL, attrOrCSS(group, ATTR_TOGGLEGROUP));
|
|
617
|
+
if (key === "Enter") el.click();
|
|
618
|
+
if (key?.startsWith("Arrow")) {
|
|
322
619
|
event.preventDefault?.();
|
|
323
620
|
const inputs = [...group.getElementsByTagName("input")];
|
|
324
|
-
const index = inputs.indexOf(
|
|
325
|
-
const move =
|
|
621
|
+
const index = inputs.indexOf(el);
|
|
622
|
+
const move = key.match(/Arrow(Right|Down)/) ? 1 : -1;
|
|
326
623
|
let nextIndex = index;
|
|
327
624
|
for (let i = 0; i < inputs.length; i++) {
|
|
328
625
|
nextIndex = (inputs.length + nextIndex + move) % inputs.length;
|
|
@@ -346,11 +643,13 @@ onHotReload("toggle-group", () => [
|
|
|
346
643
|
// src/tooltip/tooltip.ts
|
|
347
644
|
var TIP;
|
|
348
645
|
var SOURCE;
|
|
646
|
+
var IS_HOVERING = false;
|
|
349
647
|
var HOVER_TIMER = 0;
|
|
350
648
|
var SKIP_TIMER = 0;
|
|
649
|
+
var IS_IOS = isBrowser() && /iPad|iPhone|iPod/.test(navigator.userAgent);
|
|
351
650
|
var ATTR_TOOLTIP = "data-tooltip";
|
|
352
651
|
var ATTR_COLOR = "data-color";
|
|
353
|
-
var
|
|
652
|
+
var ARIA_LABEL2 = "aria-label";
|
|
354
653
|
var ARIA_DESC = "aria-description";
|
|
355
654
|
var SELECTOR_COLOR = `[${ATTR_COLOR}]`;
|
|
356
655
|
var SELECTOR_TOOLTIP = `[${ATTR_TOOLTIP}]`;
|
|
@@ -362,32 +661,36 @@ var DELAY_SKIP = 300;
|
|
|
362
661
|
var setTooltipElement = (el) => {
|
|
363
662
|
if (el && !(el instanceof HTMLElement))
|
|
364
663
|
warn("setTooltipElement expects an HTMLElement, got: ", el);
|
|
664
|
+
clearTimeout(SKIP_TIMER);
|
|
665
|
+
clearTimeout(HOVER_TIMER);
|
|
666
|
+
SOURCE = void 0;
|
|
667
|
+
IS_HOVERING = false;
|
|
365
668
|
TIP = el || void 0;
|
|
366
669
|
};
|
|
367
|
-
var handleAriaAttributes3 =
|
|
670
|
+
var handleAriaAttributes3 = () => {
|
|
368
671
|
for (const el of document.querySelectorAll(SELECTOR_TOOLTIP)) {
|
|
369
|
-
const
|
|
370
|
-
|
|
371
|
-
if (
|
|
672
|
+
const text = attrOrCSS(el, ATTR_TOOLTIP);
|
|
673
|
+
if (!text) return;
|
|
674
|
+
if (text !== (el.getAttribute(ARIA_LABEL2) || el.getAttribute(ARIA_DESC))) {
|
|
372
675
|
const hasText = attr(el, "role") !== "img" && el.textContent?.trim();
|
|
373
676
|
attr(el, ATTR_TOOLTIP, text);
|
|
374
|
-
attr(el,
|
|
677
|
+
attr(el, ARIA_LABEL2, hasText ? null : text);
|
|
375
678
|
attr(el, ARIA_DESC, hasText ? text : null);
|
|
376
679
|
if (!el.matches(SELECTOR_INTERACTIVE))
|
|
377
680
|
warn('Missing tabindex="0" attribute on: ', el);
|
|
378
681
|
}
|
|
379
|
-
const isCurrent = el === SOURCE && TIP?.
|
|
682
|
+
const isCurrent = el === SOURCE && TIP?.offsetHeight && TIP?.offsetWidth;
|
|
380
683
|
const isChanged = isCurrent && text && TIP?.textContent !== text;
|
|
381
684
|
if (isCurrent && isChanged) {
|
|
382
|
-
if (TIP)
|
|
685
|
+
if (TIP) TIP.textContent = text;
|
|
383
686
|
if (document.activeElement === el) announce(text);
|
|
384
687
|
}
|
|
385
688
|
}
|
|
386
|
-
}
|
|
689
|
+
};
|
|
387
690
|
var handleInterest = ({ type, target }) => {
|
|
388
691
|
clearTimeout(HOVER_TIMER);
|
|
389
692
|
if (target === TIP) return;
|
|
390
|
-
if (type === "mouseover" && !
|
|
693
|
+
if (type === "mouseover" && !IS_HOVERING && !IS_IOS) {
|
|
391
694
|
HOVER_TIMER = setTimeout(handleInterest, DELAY_HOVER, { target });
|
|
392
695
|
return;
|
|
393
696
|
}
|
|
@@ -403,18 +706,21 @@ var handleInterest = ({ type, target }) => {
|
|
|
403
706
|
attr(TIP, "popover", "manual");
|
|
404
707
|
attr(TIP, ATTR_SCHEME, scheme?.getAttribute(ATTR_SCHEME) || null);
|
|
405
708
|
attr(TIP, ATTR_COLOR, isReset && color?.getAttribute(ATTR_COLOR) || null);
|
|
406
|
-
|
|
709
|
+
TIP.textContent = attr(source, ATTR_TOOLTIP);
|
|
407
710
|
TIP.showPopover();
|
|
408
711
|
TIP.dispatchEvent(new CustomEvent("ds-toggle-source", { detail: source }));
|
|
712
|
+
IS_HOVERING = true;
|
|
409
713
|
SOURCE = source;
|
|
410
714
|
};
|
|
411
715
|
var hideTooltip = () => TIP?.isConnected && TIP.popover && TIP.hidePopover();
|
|
412
716
|
var handleClose = (event) => {
|
|
413
717
|
if (event?.type === "keydown")
|
|
414
718
|
return event?.key === "Escape" && hideTooltip();
|
|
415
|
-
if (!event)
|
|
416
|
-
else if (event.target === TIP && event.newState === "closed")
|
|
719
|
+
if (!event) IS_HOVERING = false;
|
|
720
|
+
else if (event.target === TIP && event.newState === "closed") {
|
|
721
|
+
SOURCE = void 0;
|
|
417
722
|
SKIP_TIMER = setTimeout(handleClose, DELAY_SKIP);
|
|
723
|
+
}
|
|
418
724
|
};
|
|
419
725
|
onHotReload("tooltip", () => [
|
|
420
726
|
on(document, "blur focus mouseover", handleInterest, QUICK_EVENT),
|
|
@@ -436,30 +742,30 @@ var DSBreadcrumbsElement = class extends DSElement {
|
|
|
436
742
|
_items;
|
|
437
743
|
// Using underscore instead of private fields for backwards compatibility
|
|
438
744
|
_label = null;
|
|
439
|
-
_render;
|
|
440
745
|
_unresize;
|
|
441
746
|
_unmutate;
|
|
442
747
|
static get observedAttributes() {
|
|
443
748
|
return [ATTR_LABEL];
|
|
444
749
|
}
|
|
445
750
|
connectedCallback() {
|
|
751
|
+
const resize = debounce(() => render(this), 100);
|
|
446
752
|
this._label = attrOrCSS(this, ATTR_LABEL);
|
|
447
753
|
this._items = this.getElementsByTagName("a");
|
|
448
|
-
this.
|
|
449
|
-
this.
|
|
450
|
-
this._unmutate = onMutation(this, this._render, {
|
|
754
|
+
this._unresize = on(window, "resize", resize);
|
|
755
|
+
this._unmutate = onMutation(this, render, {
|
|
451
756
|
childList: true,
|
|
452
757
|
subtree: true
|
|
453
758
|
});
|
|
454
759
|
}
|
|
455
760
|
attributeChangedCallback(_name, _prev, next) {
|
|
456
|
-
if (
|
|
457
|
-
this.
|
|
761
|
+
if (!this._unmutate || !next) return;
|
|
762
|
+
this._label = next;
|
|
763
|
+
render(this);
|
|
458
764
|
}
|
|
459
765
|
disconnectedCallback() {
|
|
460
766
|
this._unresize?.();
|
|
461
767
|
this._unmutate?.();
|
|
462
|
-
this._unresize = this._unmutate = this.
|
|
768
|
+
this._unresize = this._unmutate = this._items = void 0;
|
|
463
769
|
}
|
|
464
770
|
};
|
|
465
771
|
var render = (self) => {
|
|
@@ -475,104 +781,118 @@ customElements.define("ds-breadcrumbs", DSBreadcrumbsElement);
|
|
|
475
781
|
|
|
476
782
|
// src/error-summary/error-summary.ts
|
|
477
783
|
var DSErrorSummaryElement = class extends DSElement {
|
|
784
|
+
_unmutate;
|
|
785
|
+
// Using underscore instead of private fields for backwards compatibility
|
|
478
786
|
connectedCallback() {
|
|
479
787
|
on(this, "animationend", this, QUICK_EVENT);
|
|
480
|
-
requestAnimationFrame(() => this.handleEvent({ target: this }));
|
|
481
|
-
}
|
|
482
|
-
handleEvent({ target }) {
|
|
483
|
-
if (target !== this) return;
|
|
484
|
-
const heading = this.querySelector("h2,h3,h4,h5,h6");
|
|
485
|
-
if (heading) attr(this, "aria-labelledby", useId(heading));
|
|
486
788
|
attr(this, "tabindex", "-1");
|
|
789
|
+
this._unmutate = onMutation(this, render2, {
|
|
790
|
+
childList: true,
|
|
791
|
+
subtree: true
|
|
792
|
+
});
|
|
487
793
|
this.focus();
|
|
488
794
|
}
|
|
795
|
+
handleEvent({ target }) {
|
|
796
|
+
if (target === this) this.focus();
|
|
797
|
+
}
|
|
489
798
|
disconnectedCallback() {
|
|
490
799
|
off(this, "animationend", this, QUICK_EVENT);
|
|
800
|
+
this._unmutate?.();
|
|
801
|
+
this._unmutate = void 0;
|
|
491
802
|
}
|
|
492
803
|
};
|
|
804
|
+
var render2 = (self) => {
|
|
805
|
+
const heading = self.querySelector("h2,h3,h4,h5,h6");
|
|
806
|
+
if (heading) attr(self, "aria-labelledby", useId(heading));
|
|
807
|
+
};
|
|
493
808
|
customElements.define("ds-error-summary", DSErrorSummaryElement);
|
|
494
809
|
|
|
495
810
|
// src/field/field.ts
|
|
496
|
-
var
|
|
497
|
-
var
|
|
498
|
-
var COUNTS = /* @__PURE__ */ new WeakMap();
|
|
499
|
-
var FIELDSETS = isBrowser() ? document.getElementsByTagName("fieldset") : [];
|
|
500
|
-
var HAS_FIELD_SIZING = isBrowser() && CSS.supports("field-sizing", "content");
|
|
811
|
+
var ATTR_DESCRIBEDBY = "aria-describedby";
|
|
812
|
+
var ATTR_INDETERMINATE = "data-indeterminate";
|
|
501
813
|
var COUNTER_DEBOUNCE = isWindows() ? 800 : 200;
|
|
502
|
-
var
|
|
503
|
-
var
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
814
|
+
var COUNTS = /* @__PURE__ */ new WeakMap();
|
|
815
|
+
var FIELDS = /* @__PURE__ */ new Map();
|
|
816
|
+
var VALIDATIONS = /* @__PURE__ */ new WeakMap();
|
|
817
|
+
var WARNING_MULTIPLE_INPUTS = `Fields should only have one input element. Use <fieldset> to group multiple fields:`;
|
|
818
|
+
var handleFieldMutations = (_doc, records = []) => {
|
|
819
|
+
for (const { target } of records) {
|
|
820
|
+
const isFieldset = target instanceof HTMLFieldSetElement;
|
|
821
|
+
for (const [field] of FIELDS)
|
|
822
|
+
if (isFieldset ? target.contains(field) : field.contains(target))
|
|
823
|
+
handleFieldMutation(field);
|
|
507
824
|
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
if (type === "validation") {
|
|
529
|
-
descs.unshift(el);
|
|
530
|
-
hasValidation = true;
|
|
531
|
-
invalid = invalid || isInvalid(el);
|
|
532
|
-
} else if (type) descs.push(el);
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
if (!input) warn(`Field is missing input element:`, field);
|
|
536
|
-
else {
|
|
537
|
-
if (counter) COUNTS.set(input, counter);
|
|
538
|
-
for (const label of labels) attr(label, "for", useId(input));
|
|
539
|
-
const isBoolish = input.type === "radio" || input.type === "checkbox";
|
|
540
|
-
const fieldsetValidation = field.closest("fieldset")?.querySelector(':scope > [data-field="validation"]');
|
|
541
|
-
if (fieldsetValidation && !fieldsetValidation?.hidden) {
|
|
825
|
+
};
|
|
826
|
+
var handleFieldMutation = (field) => {
|
|
827
|
+
const labels = [];
|
|
828
|
+
const nextDescs = [];
|
|
829
|
+
const prevDescs = FIELDS.get(field) || [];
|
|
830
|
+
let input;
|
|
831
|
+
let counter;
|
|
832
|
+
let hasValidation = false;
|
|
833
|
+
let invalid = false;
|
|
834
|
+
for (const el of field.getElementsByTagName("*")) {
|
|
835
|
+
if (el instanceof HTMLLabelElement) labels.push(el);
|
|
836
|
+
if (el.hidden) continue;
|
|
837
|
+
if (isInputLike(el)) {
|
|
838
|
+
if (input) warn(WARNING_MULTIPLE_INPUTS, field);
|
|
839
|
+
else input = el;
|
|
840
|
+
} else {
|
|
841
|
+
const type = el.getAttribute("data-field");
|
|
842
|
+
if (type === "counter") counter = el;
|
|
843
|
+
if (type === "validation") {
|
|
844
|
+
nextDescs.unshift(useId(el));
|
|
542
845
|
hasValidation = true;
|
|
543
|
-
invalid = invalid || isInvalid(
|
|
544
|
-
|
|
545
|
-
}
|
|
546
|
-
const indeterminate = attr(input, INDETERMINATE);
|
|
547
|
-
if (indeterminate) input.indeterminate = indeterminate === "true";
|
|
548
|
-
attr(field, "data-clickdelegatefor", isBoolish ? useId(input) : null);
|
|
549
|
-
attr(input, "aria-describedby", descs.map(useId).join(" ") || null);
|
|
550
|
-
if (hasValidation || HAS_VALIDATION.has(input)) {
|
|
551
|
-
HAS_VALIDATION[hasValidation ? "add" : "delete"](input);
|
|
552
|
-
attr(input, "aria-invalid", `${invalid}`);
|
|
553
|
-
}
|
|
554
|
-
updateField(input);
|
|
846
|
+
invalid = invalid || isInvalid(el);
|
|
847
|
+
} else if (type) nextDescs.push(useId(el));
|
|
555
848
|
}
|
|
556
849
|
}
|
|
557
|
-
|
|
558
|
-
|
|
850
|
+
if (!input) return;
|
|
851
|
+
if (counter) COUNTS.set(input, counter);
|
|
852
|
+
for (const label of labels) attr(label, "for", useId(input));
|
|
853
|
+
const fieldsetValidation = field.closest("fieldset")?.querySelector(':scope > [data-field="validation"]');
|
|
854
|
+
if (fieldsetValidation && !fieldsetValidation?.hidden) {
|
|
855
|
+
hasValidation = true;
|
|
856
|
+
invalid = invalid || isInvalid(fieldsetValidation);
|
|
857
|
+
nextDescs.unshift(useId(fieldsetValidation));
|
|
858
|
+
}
|
|
859
|
+
const indeterminate = attr(input, ATTR_INDETERMINATE);
|
|
860
|
+
if (indeterminate) input.indeterminate = indeterminate === "true";
|
|
861
|
+
const isBoolish = input.type === "radio" || input.type === "checkbox";
|
|
862
|
+
if (isBoolish) attr(field, "data-clickdelegatefor", useId(input));
|
|
863
|
+
const describedby = attr(input, ATTR_DESCRIBEDBY)?.trim().split(/\s+/);
|
|
864
|
+
const keep = describedby?.filter((id2) => !prevDescs.includes(id2)) || [];
|
|
865
|
+
attr(input, ATTR_DESCRIBEDBY, [...nextDescs, ...keep].join(" ") || null);
|
|
866
|
+
FIELDS.set(field, nextDescs);
|
|
867
|
+
const hadValidation = VALIDATIONS.has(input);
|
|
868
|
+
if (hasValidation && !hadValidation) {
|
|
869
|
+
VALIDATIONS.set(input, attr(input, "aria-invalid"));
|
|
870
|
+
attr(input, "aria-invalid", "true");
|
|
871
|
+
} else if (!hasValidation && hadValidation) {
|
|
872
|
+
attr(input, "aria-invalid", VALIDATIONS.get(input));
|
|
873
|
+
VALIDATIONS.delete(input);
|
|
874
|
+
}
|
|
875
|
+
handleFieldInput(input);
|
|
876
|
+
};
|
|
877
|
+
var TEXTS = {
|
|
878
|
+
over: "%d tegn for mye",
|
|
879
|
+
under: "%d tegn igjen"
|
|
880
|
+
};
|
|
881
|
+
var handleFieldInput = (e) => {
|
|
559
882
|
const input = e.target || e;
|
|
560
883
|
const counter = COUNTS.get(input);
|
|
561
884
|
if (counter?.isConnected) {
|
|
562
885
|
const limit = Number(attr(counter, "data-limit")) || 0;
|
|
563
886
|
const count = limit - input.value.length;
|
|
564
887
|
const state = count < 0 ? "over" : "under";
|
|
565
|
-
const label = attrOrCSS(counter, `data-${state}`)?.replace(
|
|
566
|
-
"%d",
|
|
567
|
-
`${Math.abs(count)}`
|
|
568
|
-
);
|
|
888
|
+
const label = (attrOrCSS(counter, `data-${state}`) || TEXTS[state])?.replace("%d", `${Math.abs(count)}`);
|
|
569
889
|
attr(counter, "data-label", label);
|
|
570
890
|
attr(counter, "data-state", state);
|
|
571
891
|
attr(counter, "data-color", count < 0 ? "danger" : null);
|
|
572
892
|
if (e.type === "input" && label)
|
|
573
893
|
debouncedCounterLiveRegion(input, label);
|
|
574
894
|
}
|
|
575
|
-
if (
|
|
895
|
+
if (input instanceof HTMLTextAreaElement) {
|
|
576
896
|
input.style.setProperty("--_ds-field-sizing", "auto");
|
|
577
897
|
input.style.setProperty("--_ds-field-sizing", `${input.scrollHeight}px`);
|
|
578
898
|
}
|
|
@@ -586,8 +906,8 @@ var isInputLike = (el) => el instanceof HTMLElement && "validity" in el && // Ad
|
|
|
586
906
|
el.type !== "hidden";
|
|
587
907
|
var DSFieldElement = class extends DSElement {
|
|
588
908
|
connectedCallback() {
|
|
589
|
-
FIELDS.
|
|
590
|
-
|
|
909
|
+
FIELDS.set(this, []);
|
|
910
|
+
handleFieldMutation(this);
|
|
591
911
|
}
|
|
592
912
|
disconnectedCallback() {
|
|
593
913
|
FIELDS.delete(this);
|
|
@@ -595,14 +915,18 @@ var DSFieldElement = class extends DSElement {
|
|
|
595
915
|
};
|
|
596
916
|
customElements.define("ds-field", DSFieldElement);
|
|
597
917
|
onHotReload("field", () => [
|
|
598
|
-
on(document, "input",
|
|
599
|
-
onMutation(document,
|
|
918
|
+
on(document, "input", handleFieldInput, QUICK_EVENT),
|
|
919
|
+
onMutation(document, handleFieldMutations, {
|
|
600
920
|
attributeFilter: [
|
|
601
921
|
"data-field",
|
|
602
922
|
"data-limit",
|
|
603
923
|
"hidden",
|
|
924
|
+
// Needed to check validation visibility
|
|
925
|
+
"id",
|
|
926
|
+
// Needed to sync label "for" when ID of input/selec/textarea changes
|
|
604
927
|
"value",
|
|
605
|
-
|
|
928
|
+
// Needed to detect changes in controlled React inputs as they do not trigger input events
|
|
929
|
+
ATTR_INDETERMINATE
|
|
606
930
|
],
|
|
607
931
|
attributes: true,
|
|
608
932
|
childList: true,
|
|
@@ -638,21 +962,20 @@ var DSPaginationElement = class extends DSElement {
|
|
|
638
962
|
if (total && !current) warn(`Missing ${ATTR_CURRENT} attribute on:`, this);
|
|
639
963
|
attr(this, ATTR_LABEL2, attrOrCSS(this, ATTR_LABEL2));
|
|
640
964
|
attr(this, "role", "navigation");
|
|
641
|
-
this.
|
|
642
|
-
this._unmutate = onMutation(this, this._render, {
|
|
965
|
+
this._unmutate = onMutation(this, render3, {
|
|
643
966
|
childList: true,
|
|
644
967
|
subtree: true
|
|
645
968
|
});
|
|
646
969
|
}
|
|
647
970
|
attributeChangedCallback() {
|
|
648
|
-
this.
|
|
971
|
+
if (this._unmutate) render3(this);
|
|
649
972
|
}
|
|
650
973
|
disconnectedCallback() {
|
|
651
974
|
this._unmutate?.();
|
|
652
975
|
this._unmutate = this._render = void 0;
|
|
653
976
|
}
|
|
654
977
|
};
|
|
655
|
-
var
|
|
978
|
+
var render3 = (self) => {
|
|
656
979
|
const current = Number(attr(self, ATTR_CURRENT));
|
|
657
980
|
const total = Number(attr(self, ATTR_TOTAL));
|
|
658
981
|
if (current && total) {
|
|
@@ -686,13 +1009,12 @@ customElements.define("ds-pagination", DSPaginationElement);
|
|
|
686
1009
|
// src/suggestion/suggestion.ts
|
|
687
1010
|
import { UHTMLComboboxElement } from "@u-elements/u-combobox";
|
|
688
1011
|
var DSSuggestionElement = class extends UHTMLComboboxElement {
|
|
1012
|
+
_render;
|
|
689
1013
|
_unmutate;
|
|
690
1014
|
// Using underscore instead of private fields for backwards compatibility
|
|
691
|
-
_render;
|
|
692
1015
|
connectedCallback() {
|
|
693
1016
|
super.connectedCallback();
|
|
694
|
-
this.
|
|
695
|
-
this._unmutate = onMutation(this, this._render, { childList: true });
|
|
1017
|
+
this._unmutate = onMutation(this, render4, { childList: true });
|
|
696
1018
|
on(this, "toggle", polyfillToggleSource, QUICK_EVENT);
|
|
697
1019
|
}
|
|
698
1020
|
disconnectedCallback() {
|
|
@@ -702,7 +1024,7 @@ var DSSuggestionElement = class extends UHTMLComboboxElement {
|
|
|
702
1024
|
off(this, "toggle", polyfillToggleSource, QUICK_EVENT);
|
|
703
1025
|
}
|
|
704
1026
|
};
|
|
705
|
-
var
|
|
1027
|
+
var render4 = ({ control, list }) => {
|
|
706
1028
|
if (control && !control.placeholder) attr(control, "placeholder", " ");
|
|
707
1029
|
if (control) attr(control, "popovertarget", useId(list) || null);
|
|
708
1030
|
if (list) attr(list, "popover", "manual");
|
|
@@ -731,7 +1053,7 @@ customElements.define("ds-tab", DSTabElement);
|
|
|
731
1053
|
customElements.define("ds-tabpanel", DSTabPanelElement);
|
|
732
1054
|
|
|
733
1055
|
// src/index.ts
|
|
734
|
-
if (isBrowser() && !isSupported())
|
|
1056
|
+
if (isBrowser() && !isSupported()) apply();
|
|
735
1057
|
export {
|
|
736
1058
|
DSBreadcrumbsElement,
|
|
737
1059
|
DSErrorSummaryElement,
|