@incursa/ui-kit 1.6.1 → 1.7.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/dist/inc-design-language.css +111 -51
- package/dist/inc-design-language.css.map +1 -1
- package/dist/inc-design-language.js +326 -1
- package/dist/inc-design-language.min.css +1 -1
- package/dist/inc-design-language.min.css.map +1 -1
- package/dist/mcp/components/buttons.json +3 -3
- package/dist/mcp/components/status.json +3 -3
- package/dist/mcp/examples/reference.json +2 -2
- package/dist/mcp/examples/states.json +2 -2
- package/dist/mcp/examples/web-components.json +2 -2
- package/dist/mcp/guides/latest.json +2 -2
- package/dist/mcp/guides/package-metadata.json +2 -2
- package/dist/mcp/guides/update.json +2 -2
- package/dist/mcp/install.json +1 -1
- package/dist/mcp/patterns/reference.json +2 -2
- package/dist/mcp/patterns/states.json +2 -2
- package/dist/mcp/patterns/web-components.json +2 -2
- package/dist/mcp/resources.json +49 -49
- package/dist/mcp/search-index.json +13 -13
- package/dist/mcp/update.json +2 -2
- package/dist/mcp/worker.mjs +282 -162
- package/dist/mcp/worker.mjs.map +2 -2
- package/dist/web-components/components/actions.js +89 -13
- package/dist/web-components/components/feedback.js +17 -4
- package/dist/web-components/index.js +92 -17
- package/package.json +1 -1
- package/src/inc-design-language.js +326 -1
- package/src/inc-design-language.scss +141 -55
- package/src/web-components/components/actions.js +89 -13
- package/src/web-components/components/feedback.js +17 -4
|
@@ -24,6 +24,10 @@ const BUTTON_VARIANTS = new Set([
|
|
|
24
24
|
"outline-info",
|
|
25
25
|
]);
|
|
26
26
|
const BUTTON_SIZES = new Set(["sm", "lg", "micro"]);
|
|
27
|
+
const ALERT_DEFAULT_ROLE_BY_TONE = new Map([
|
|
28
|
+
["info", "status"],
|
|
29
|
+
["secondary", "status"],
|
|
30
|
+
]);
|
|
27
31
|
|
|
28
32
|
const HostElement = typeof HTMLElement === "undefined" ? class {} : HTMLElement;
|
|
29
33
|
|
|
@@ -35,6 +39,11 @@ function toBoolean(value, fallback = false) {
|
|
|
35
39
|
return !FALSE_TOKENS.has(String(value).toLowerCase());
|
|
36
40
|
}
|
|
37
41
|
|
|
42
|
+
function toPositiveInt(value) {
|
|
43
|
+
const parsed = Number.parseInt(String(value ?? "").trim(), 10);
|
|
44
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
|
|
45
|
+
}
|
|
46
|
+
|
|
38
47
|
function emit(host, type, detail = {}, options = {}) {
|
|
39
48
|
return host.dispatchEvent(new CustomEvent(type, {
|
|
40
49
|
detail,
|
|
@@ -292,7 +301,6 @@ export class IncCloseButtonElement extends IncElement {
|
|
|
292
301
|
}
|
|
293
302
|
|
|
294
303
|
connectedCallback() {
|
|
295
|
-
addClass(this, "inc-close-button");
|
|
296
304
|
this.sync();
|
|
297
305
|
}
|
|
298
306
|
|
|
@@ -303,7 +311,7 @@ export class IncCloseButtonElement extends IncElement {
|
|
|
303
311
|
}
|
|
304
312
|
|
|
305
313
|
sync() {
|
|
306
|
-
|
|
314
|
+
this.classList.remove("inc-close-button", "inc-close-button--white");
|
|
307
315
|
this.setAttribute("part", "close-button");
|
|
308
316
|
const control = this.ensureControl();
|
|
309
317
|
const variant = normalizeToken(this.getAttribute("variant"));
|
|
@@ -316,9 +324,7 @@ export class IncCloseButtonElement extends IncElement {
|
|
|
316
324
|
|
|
317
325
|
control.type = "button";
|
|
318
326
|
control.setAttribute("aria-label", this.getAttribute("label") || "Close");
|
|
319
|
-
|
|
320
|
-
control.textContent = "×";
|
|
321
|
-
}
|
|
327
|
+
control.textContent = "";
|
|
322
328
|
}
|
|
323
329
|
|
|
324
330
|
ensureControl() {
|
|
@@ -344,7 +350,7 @@ export class IncCloseButtonElement extends IncElement {
|
|
|
344
350
|
|
|
345
351
|
export class IncAlertElement extends IncElement {
|
|
346
352
|
static get observedAttributes() {
|
|
347
|
-
return ["tone", "variant", "dismissible", "dismiss-label"];
|
|
353
|
+
return ["tone", "variant", "dismissible", "dismiss-label", "timeout"];
|
|
348
354
|
}
|
|
349
355
|
|
|
350
356
|
connectedCallback() {
|
|
@@ -354,6 +360,7 @@ export class IncAlertElement extends IncElement {
|
|
|
354
360
|
}
|
|
355
361
|
|
|
356
362
|
disconnectedCallback() {
|
|
363
|
+
this.stopDismissTimer();
|
|
357
364
|
if (this._boundClick) {
|
|
358
365
|
this.removeEventListener("click", this._boundClick);
|
|
359
366
|
}
|
|
@@ -377,7 +384,7 @@ export class IncAlertElement extends IncElement {
|
|
|
377
384
|
}
|
|
378
385
|
|
|
379
386
|
event.preventDefault();
|
|
380
|
-
this.
|
|
387
|
+
this.dismiss("manual");
|
|
381
388
|
};
|
|
382
389
|
|
|
383
390
|
this.addEventListener("click", this._boundClick);
|
|
@@ -400,12 +407,25 @@ export class IncAlertElement extends IncElement {
|
|
|
400
407
|
}
|
|
401
408
|
|
|
402
409
|
if (!this.hasAttribute("role")) {
|
|
403
|
-
this.setAttribute("role", resolvedTone
|
|
410
|
+
this.setAttribute("role", ALERT_DEFAULT_ROLE_BY_TONE.get(resolvedTone) || "alert");
|
|
404
411
|
}
|
|
405
412
|
if (!this.hasAttribute("aria-live")) {
|
|
406
413
|
this.setAttribute("aria-live", this.getAttribute("role") === "alert" ? "assertive" : "polite");
|
|
407
414
|
}
|
|
408
415
|
this.setAttribute("aria-atomic", "true");
|
|
416
|
+
|
|
417
|
+
const timeoutMs = toPositiveInt(this.getAttribute("timeout"));
|
|
418
|
+
if (timeoutMs) {
|
|
419
|
+
this.ensureProgressBar();
|
|
420
|
+
if (!this.hidden && this.getAttribute("aria-hidden") !== "true") {
|
|
421
|
+
this.startDismissTimer(timeoutMs);
|
|
422
|
+
} else {
|
|
423
|
+
this.stopDismissTimer();
|
|
424
|
+
}
|
|
425
|
+
} else {
|
|
426
|
+
this.stopDismissTimer();
|
|
427
|
+
this.removeProgressBar();
|
|
428
|
+
}
|
|
409
429
|
}
|
|
410
430
|
|
|
411
431
|
ensureDismissButton() {
|
|
@@ -420,9 +440,7 @@ export class IncAlertElement extends IncElement {
|
|
|
420
440
|
button.className = "inc-close-button";
|
|
421
441
|
button.setAttribute("part", "dismiss");
|
|
422
442
|
button.setAttribute("aria-label", this.getAttribute("dismiss-label") || "Dismiss alert");
|
|
423
|
-
|
|
424
|
-
button.textContent = "×";
|
|
425
|
-
}
|
|
443
|
+
button.textContent = "";
|
|
426
444
|
return button;
|
|
427
445
|
}
|
|
428
446
|
|
|
@@ -430,10 +448,68 @@ export class IncAlertElement extends IncElement {
|
|
|
430
448
|
this.querySelectorAll(":scope > [data-inc-alert-dismiss]").forEach((node) => node.remove());
|
|
431
449
|
}
|
|
432
450
|
|
|
433
|
-
|
|
451
|
+
ensureProgressBar() {
|
|
452
|
+
let progress = this.querySelector(":scope > .inc-alert__progress");
|
|
453
|
+
if (!progress) {
|
|
454
|
+
progress = document.createElement("div");
|
|
455
|
+
progress.className = "inc-alert__progress";
|
|
456
|
+
progress.setAttribute("part", "progress");
|
|
457
|
+
progress.setAttribute("aria-hidden", "true");
|
|
458
|
+
this.append(progress);
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
return progress;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
removeProgressBar() {
|
|
465
|
+
this.querySelectorAll(":scope > .inc-alert__progress").forEach((node) => node.remove());
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
startDismissTimer(timeoutMs) {
|
|
469
|
+
const progress = this.ensureProgressBar();
|
|
470
|
+
this.stopDismissTimer();
|
|
471
|
+
this._dismissTimeoutMs = timeoutMs;
|
|
472
|
+
this._dismissStartedAt = performance.now();
|
|
473
|
+
|
|
474
|
+
const tick = (now) => {
|
|
475
|
+
if (this.hidden || this.getAttribute("aria-hidden") === "true") {
|
|
476
|
+
this.stopDismissTimer();
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
const elapsed = Math.max(0, now - this._dismissStartedAt);
|
|
481
|
+
const remaining = Math.max(0, timeoutMs - elapsed);
|
|
482
|
+
const ratio = timeoutMs > 0 ? remaining / timeoutMs : 0;
|
|
483
|
+
progress.style.transform = `scaleX(${ratio})`;
|
|
484
|
+
|
|
485
|
+
if (remaining <= 0) {
|
|
486
|
+
this.dismiss("timeout");
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
this._dismissFrame = window.requestAnimationFrame(tick);
|
|
491
|
+
};
|
|
492
|
+
|
|
493
|
+
progress.style.transform = "scaleX(1)";
|
|
494
|
+
this._dismissFrame = window.requestAnimationFrame(tick);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
stopDismissTimer() {
|
|
498
|
+
if (this._dismissFrame) {
|
|
499
|
+
window.cancelAnimationFrame(this._dismissFrame);
|
|
500
|
+
this._dismissFrame = 0;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
dismiss(reason = "manual") {
|
|
505
|
+
this.hide(reason);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
hide(reason = "manual") {
|
|
509
|
+
this.stopDismissTimer();
|
|
434
510
|
this.hidden = true;
|
|
435
511
|
this.setAttribute("aria-hidden", "true");
|
|
436
|
-
this.emit("dismiss", { hidden: true });
|
|
512
|
+
this.emit("dismiss", { hidden: true, reason });
|
|
437
513
|
}
|
|
438
514
|
}
|
|
439
515
|
|
|
@@ -2,6 +2,14 @@ const THEME_MODES = ["light", "dark", "system"];
|
|
|
2
2
|
const DEFAULT_THEME_STORAGE_KEY = "inc-theme-mode";
|
|
3
3
|
const BADGE_TONES = new Set(["primary", "secondary", "success", "danger", "warning", "info"]);
|
|
4
4
|
const SPINNER_VARIANTS = new Set(["border", "grow"]);
|
|
5
|
+
const AUTO_REFRESH_PAUSE_ICON = `
|
|
6
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
|
|
7
|
+
<path d="M4 3h3v10H4zM9 3h3v10H9z"></path>
|
|
8
|
+
</svg>`.trim();
|
|
9
|
+
const AUTO_REFRESH_PLAY_ICON = `
|
|
10
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
|
|
11
|
+
<path d="M4 3.5v9l8-4.5-8-4.5z"></path>
|
|
12
|
+
</svg>`.trim();
|
|
5
13
|
const HostElement = typeof HTMLElement === "undefined" ? class {} : HTMLElement;
|
|
6
14
|
const themeSubscribers = new Set();
|
|
7
15
|
|
|
@@ -677,6 +685,10 @@ export class IncAutoRefresh extends HostElement {
|
|
|
677
685
|
}
|
|
678
686
|
|
|
679
687
|
this.innerHTML = `
|
|
688
|
+
<button type="button" class="inc-auto-refresh__toggle inc-btn inc-btn--outline-secondary inc-btn--micro" part="toggle">
|
|
689
|
+
<span class="inc-auto-refresh__toggle-icon" aria-hidden="true"></span>
|
|
690
|
+
<span class="inc-auto-refresh__toggle-text"></span>
|
|
691
|
+
</button>
|
|
680
692
|
<span class="inc-auto-refresh__countdown" part="countdown">
|
|
681
693
|
<span class="inc-auto-refresh__label" part="label"></span>
|
|
682
694
|
<span class="inc-auto-refresh__value" part="value"></span>
|
|
@@ -684,10 +696,6 @@ export class IncAutoRefresh extends HostElement {
|
|
|
684
696
|
<span class="inc-auto-refresh__status" part="status" hidden>
|
|
685
697
|
<span class="inc-auto-refresh__status-text"></span>
|
|
686
698
|
</span>
|
|
687
|
-
<button type="button" class="inc-auto-refresh__toggle inc-btn inc-btn--outline-secondary inc-btn--micro" part="toggle">
|
|
688
|
-
<span class="inc-auto-refresh__toggle-icon" aria-hidden="true"></span>
|
|
689
|
-
<span class="inc-auto-refresh__toggle-text"></span>
|
|
690
|
-
</button>
|
|
691
699
|
`.trim();
|
|
692
700
|
|
|
693
701
|
this.#parts = this.#getParts();
|
|
@@ -701,6 +709,7 @@ export class IncAutoRefresh extends HostElement {
|
|
|
701
709
|
status: this.querySelector(".inc-auto-refresh__status"),
|
|
702
710
|
statusText: this.querySelector(".inc-auto-refresh__status-text"),
|
|
703
711
|
toggle: this.querySelector(".inc-auto-refresh__toggle"),
|
|
712
|
+
toggleIcon: this.querySelector(".inc-auto-refresh__toggle-icon"),
|
|
704
713
|
toggleText: this.querySelector(".inc-auto-refresh__toggle-text"),
|
|
705
714
|
};
|
|
706
715
|
}
|
|
@@ -861,6 +870,10 @@ export class IncAutoRefresh extends HostElement {
|
|
|
861
870
|
if (this.#parts.toggleText) {
|
|
862
871
|
this.#parts.toggleText.textContent = actionLabel;
|
|
863
872
|
}
|
|
873
|
+
|
|
874
|
+
if (this.#parts.toggleIcon instanceof HTMLElement) {
|
|
875
|
+
this.#parts.toggleIcon.innerHTML = this.#isPaused ? AUTO_REFRESH_PLAY_ICON : AUTO_REFRESH_PAUSE_ICON;
|
|
876
|
+
}
|
|
864
877
|
}
|
|
865
878
|
|
|
866
879
|
#stop() {
|
|
@@ -1989,6 +1989,14 @@ var THEME_MODES = ["light", "dark", "system"];
|
|
|
1989
1989
|
var DEFAULT_THEME_STORAGE_KEY = "inc-theme-mode";
|
|
1990
1990
|
var BADGE_TONES = /* @__PURE__ */ new Set(["primary", "secondary", "success", "danger", "warning", "info"]);
|
|
1991
1991
|
var SPINNER_VARIANTS = /* @__PURE__ */ new Set(["border", "grow"]);
|
|
1992
|
+
var AUTO_REFRESH_PAUSE_ICON = `
|
|
1993
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
|
|
1994
|
+
<path d="M4 3h3v10H4zM9 3h3v10H9z"></path>
|
|
1995
|
+
</svg>`.trim();
|
|
1996
|
+
var AUTO_REFRESH_PLAY_ICON = `
|
|
1997
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="currentColor" aria-hidden="true">
|
|
1998
|
+
<path d="M4 3.5v9l8-4.5-8-4.5z"></path>
|
|
1999
|
+
</svg>`.trim();
|
|
1992
2000
|
var HostElement3 = typeof HTMLElement === "undefined" ? class {
|
|
1993
2001
|
} : HTMLElement;
|
|
1994
2002
|
var themeSubscribers = /* @__PURE__ */ new Set();
|
|
@@ -2525,6 +2533,10 @@ var IncAutoRefresh = class extends HostElement3 {
|
|
|
2525
2533
|
return;
|
|
2526
2534
|
}
|
|
2527
2535
|
this.innerHTML = `
|
|
2536
|
+
<button type="button" class="inc-auto-refresh__toggle inc-btn inc-btn--outline-secondary inc-btn--micro" part="toggle">
|
|
2537
|
+
<span class="inc-auto-refresh__toggle-icon" aria-hidden="true"></span>
|
|
2538
|
+
<span class="inc-auto-refresh__toggle-text"></span>
|
|
2539
|
+
</button>
|
|
2528
2540
|
<span class="inc-auto-refresh__countdown" part="countdown">
|
|
2529
2541
|
<span class="inc-auto-refresh__label" part="label"></span>
|
|
2530
2542
|
<span class="inc-auto-refresh__value" part="value"></span>
|
|
@@ -2532,10 +2544,6 @@ var IncAutoRefresh = class extends HostElement3 {
|
|
|
2532
2544
|
<span class="inc-auto-refresh__status" part="status" hidden>
|
|
2533
2545
|
<span class="inc-auto-refresh__status-text"></span>
|
|
2534
2546
|
</span>
|
|
2535
|
-
<button type="button" class="inc-auto-refresh__toggle inc-btn inc-btn--outline-secondary inc-btn--micro" part="toggle">
|
|
2536
|
-
<span class="inc-auto-refresh__toggle-icon" aria-hidden="true"></span>
|
|
2537
|
-
<span class="inc-auto-refresh__toggle-text"></span>
|
|
2538
|
-
</button>
|
|
2539
2547
|
`.trim();
|
|
2540
2548
|
this.#parts = this.#getParts();
|
|
2541
2549
|
}
|
|
@@ -2547,6 +2555,7 @@ var IncAutoRefresh = class extends HostElement3 {
|
|
|
2547
2555
|
status: this.querySelector(".inc-auto-refresh__status"),
|
|
2548
2556
|
statusText: this.querySelector(".inc-auto-refresh__status-text"),
|
|
2549
2557
|
toggle: this.querySelector(".inc-auto-refresh__toggle"),
|
|
2558
|
+
toggleIcon: this.querySelector(".inc-auto-refresh__toggle-icon"),
|
|
2550
2559
|
toggleText: this.querySelector(".inc-auto-refresh__toggle-text")
|
|
2551
2560
|
};
|
|
2552
2561
|
}
|
|
@@ -2669,6 +2678,9 @@ var IncAutoRefresh = class extends HostElement3 {
|
|
|
2669
2678
|
if (this.#parts.toggleText) {
|
|
2670
2679
|
this.#parts.toggleText.textContent = actionLabel;
|
|
2671
2680
|
}
|
|
2681
|
+
if (this.#parts.toggleIcon instanceof HTMLElement) {
|
|
2682
|
+
this.#parts.toggleIcon.innerHTML = this.#isPaused ? AUTO_REFRESH_PLAY_ICON : AUTO_REFRESH_PAUSE_ICON;
|
|
2683
|
+
}
|
|
2672
2684
|
}
|
|
2673
2685
|
#stop() {
|
|
2674
2686
|
if (this.#timeoutId) {
|
|
@@ -3028,6 +3040,10 @@ var BUTTON_VARIANTS = /* @__PURE__ */ new Set([
|
|
|
3028
3040
|
"outline-info"
|
|
3029
3041
|
]);
|
|
3030
3042
|
var BUTTON_SIZES = /* @__PURE__ */ new Set(["sm", "lg", "micro"]);
|
|
3043
|
+
var ALERT_DEFAULT_ROLE_BY_TONE = /* @__PURE__ */ new Map([
|
|
3044
|
+
["info", "status"],
|
|
3045
|
+
["secondary", "status"]
|
|
3046
|
+
]);
|
|
3031
3047
|
var HostElement4 = typeof HTMLElement === "undefined" ? class {
|
|
3032
3048
|
} : HTMLElement;
|
|
3033
3049
|
function toBoolean(value, fallback = false) {
|
|
@@ -3036,6 +3052,10 @@ function toBoolean(value, fallback = false) {
|
|
|
3036
3052
|
}
|
|
3037
3053
|
return !FALSE_TOKENS.has(String(value).toLowerCase());
|
|
3038
3054
|
}
|
|
3055
|
+
function toPositiveInt2(value) {
|
|
3056
|
+
const parsed = Number.parseInt(String(value ?? "").trim(), 10);
|
|
3057
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
|
|
3058
|
+
}
|
|
3039
3059
|
function emit2(host, type, detail = {}, options = {}) {
|
|
3040
3060
|
return host.dispatchEvent(new CustomEvent(type, {
|
|
3041
3061
|
detail,
|
|
@@ -3251,7 +3271,6 @@ var IncCloseButtonElement = class extends IncElement {
|
|
|
3251
3271
|
return ["label", "variant"];
|
|
3252
3272
|
}
|
|
3253
3273
|
connectedCallback() {
|
|
3254
|
-
addClass(this, "inc-close-button");
|
|
3255
3274
|
this.sync();
|
|
3256
3275
|
}
|
|
3257
3276
|
attributeChangedCallback() {
|
|
@@ -3260,7 +3279,7 @@ var IncCloseButtonElement = class extends IncElement {
|
|
|
3260
3279
|
}
|
|
3261
3280
|
}
|
|
3262
3281
|
sync() {
|
|
3263
|
-
|
|
3282
|
+
this.classList.remove("inc-close-button", "inc-close-button--white");
|
|
3264
3283
|
this.setAttribute("part", "close-button");
|
|
3265
3284
|
const control = this.ensureControl();
|
|
3266
3285
|
const variant = normalizeToken2(this.getAttribute("variant"));
|
|
@@ -3271,9 +3290,7 @@ var IncCloseButtonElement = class extends IncElement {
|
|
|
3271
3290
|
}
|
|
3272
3291
|
control.type = "button";
|
|
3273
3292
|
control.setAttribute("aria-label", this.getAttribute("label") || "Close");
|
|
3274
|
-
|
|
3275
|
-
control.textContent = "\xD7";
|
|
3276
|
-
}
|
|
3293
|
+
control.textContent = "";
|
|
3277
3294
|
}
|
|
3278
3295
|
ensureControl() {
|
|
3279
3296
|
const existing = this._control || this.querySelector(":scope > button.inc-close-button");
|
|
@@ -3296,7 +3313,7 @@ var IncCloseButtonElement = class extends IncElement {
|
|
|
3296
3313
|
};
|
|
3297
3314
|
var IncAlertElement = class extends IncElement {
|
|
3298
3315
|
static get observedAttributes() {
|
|
3299
|
-
return ["tone", "variant", "dismissible", "dismiss-label"];
|
|
3316
|
+
return ["tone", "variant", "dismissible", "dismiss-label", "timeout"];
|
|
3300
3317
|
}
|
|
3301
3318
|
connectedCallback() {
|
|
3302
3319
|
addClass(this, "inc-alert");
|
|
@@ -3304,6 +3321,7 @@ var IncAlertElement = class extends IncElement {
|
|
|
3304
3321
|
this.sync();
|
|
3305
3322
|
}
|
|
3306
3323
|
disconnectedCallback() {
|
|
3324
|
+
this.stopDismissTimer();
|
|
3307
3325
|
if (this._boundClick) {
|
|
3308
3326
|
this.removeEventListener("click", this._boundClick);
|
|
3309
3327
|
}
|
|
@@ -3323,7 +3341,7 @@ var IncAlertElement = class extends IncElement {
|
|
|
3323
3341
|
return;
|
|
3324
3342
|
}
|
|
3325
3343
|
event.preventDefault();
|
|
3326
|
-
this.
|
|
3344
|
+
this.dismiss("manual");
|
|
3327
3345
|
};
|
|
3328
3346
|
this.addEventListener("click", this._boundClick);
|
|
3329
3347
|
}
|
|
@@ -3341,12 +3359,24 @@ var IncAlertElement = class extends IncElement {
|
|
|
3341
3359
|
this.removeDismissButton();
|
|
3342
3360
|
}
|
|
3343
3361
|
if (!this.hasAttribute("role")) {
|
|
3344
|
-
this.setAttribute("role", resolvedTone
|
|
3362
|
+
this.setAttribute("role", ALERT_DEFAULT_ROLE_BY_TONE.get(resolvedTone) || "alert");
|
|
3345
3363
|
}
|
|
3346
3364
|
if (!this.hasAttribute("aria-live")) {
|
|
3347
3365
|
this.setAttribute("aria-live", this.getAttribute("role") === "alert" ? "assertive" : "polite");
|
|
3348
3366
|
}
|
|
3349
3367
|
this.setAttribute("aria-atomic", "true");
|
|
3368
|
+
const timeoutMs = toPositiveInt2(this.getAttribute("timeout"));
|
|
3369
|
+
if (timeoutMs) {
|
|
3370
|
+
this.ensureProgressBar();
|
|
3371
|
+
if (!this.hidden && this.getAttribute("aria-hidden") !== "true") {
|
|
3372
|
+
this.startDismissTimer(timeoutMs);
|
|
3373
|
+
} else {
|
|
3374
|
+
this.stopDismissTimer();
|
|
3375
|
+
}
|
|
3376
|
+
} else {
|
|
3377
|
+
this.stopDismissTimer();
|
|
3378
|
+
this.removeProgressBar();
|
|
3379
|
+
}
|
|
3350
3380
|
}
|
|
3351
3381
|
ensureDismissButton() {
|
|
3352
3382
|
let button = this.querySelector(":scope > [data-inc-alert-dismiss]");
|
|
@@ -3359,18 +3389,63 @@ var IncAlertElement = class extends IncElement {
|
|
|
3359
3389
|
button.className = "inc-close-button";
|
|
3360
3390
|
button.setAttribute("part", "dismiss");
|
|
3361
3391
|
button.setAttribute("aria-label", this.getAttribute("dismiss-label") || "Dismiss alert");
|
|
3362
|
-
|
|
3363
|
-
button.textContent = "\xD7";
|
|
3364
|
-
}
|
|
3392
|
+
button.textContent = "";
|
|
3365
3393
|
return button;
|
|
3366
3394
|
}
|
|
3367
3395
|
removeDismissButton() {
|
|
3368
3396
|
this.querySelectorAll(":scope > [data-inc-alert-dismiss]").forEach((node) => node.remove());
|
|
3369
3397
|
}
|
|
3370
|
-
|
|
3398
|
+
ensureProgressBar() {
|
|
3399
|
+
let progress = this.querySelector(":scope > .inc-alert__progress");
|
|
3400
|
+
if (!progress) {
|
|
3401
|
+
progress = document.createElement("div");
|
|
3402
|
+
progress.className = "inc-alert__progress";
|
|
3403
|
+
progress.setAttribute("part", "progress");
|
|
3404
|
+
progress.setAttribute("aria-hidden", "true");
|
|
3405
|
+
this.append(progress);
|
|
3406
|
+
}
|
|
3407
|
+
return progress;
|
|
3408
|
+
}
|
|
3409
|
+
removeProgressBar() {
|
|
3410
|
+
this.querySelectorAll(":scope > .inc-alert__progress").forEach((node) => node.remove());
|
|
3411
|
+
}
|
|
3412
|
+
startDismissTimer(timeoutMs) {
|
|
3413
|
+
const progress = this.ensureProgressBar();
|
|
3414
|
+
this.stopDismissTimer();
|
|
3415
|
+
this._dismissTimeoutMs = timeoutMs;
|
|
3416
|
+
this._dismissStartedAt = performance.now();
|
|
3417
|
+
const tick = (now) => {
|
|
3418
|
+
if (this.hidden || this.getAttribute("aria-hidden") === "true") {
|
|
3419
|
+
this.stopDismissTimer();
|
|
3420
|
+
return;
|
|
3421
|
+
}
|
|
3422
|
+
const elapsed = Math.max(0, now - this._dismissStartedAt);
|
|
3423
|
+
const remaining = Math.max(0, timeoutMs - elapsed);
|
|
3424
|
+
const ratio = timeoutMs > 0 ? remaining / timeoutMs : 0;
|
|
3425
|
+
progress.style.transform = `scaleX(${ratio})`;
|
|
3426
|
+
if (remaining <= 0) {
|
|
3427
|
+
this.dismiss("timeout");
|
|
3428
|
+
return;
|
|
3429
|
+
}
|
|
3430
|
+
this._dismissFrame = window.requestAnimationFrame(tick);
|
|
3431
|
+
};
|
|
3432
|
+
progress.style.transform = "scaleX(1)";
|
|
3433
|
+
this._dismissFrame = window.requestAnimationFrame(tick);
|
|
3434
|
+
}
|
|
3435
|
+
stopDismissTimer() {
|
|
3436
|
+
if (this._dismissFrame) {
|
|
3437
|
+
window.cancelAnimationFrame(this._dismissFrame);
|
|
3438
|
+
this._dismissFrame = 0;
|
|
3439
|
+
}
|
|
3440
|
+
}
|
|
3441
|
+
dismiss(reason = "manual") {
|
|
3442
|
+
this.hide(reason);
|
|
3443
|
+
}
|
|
3444
|
+
hide(reason = "manual") {
|
|
3445
|
+
this.stopDismissTimer();
|
|
3371
3446
|
this.hidden = true;
|
|
3372
3447
|
this.setAttribute("aria-hidden", "true");
|
|
3373
|
-
this.emit("dismiss", { hidden: true });
|
|
3448
|
+
this.emit("dismiss", { hidden: true, reason });
|
|
3374
3449
|
}
|
|
3375
3450
|
};
|
|
3376
3451
|
var IncEmptyStateElement = class extends IncElement {
|