@akcelik/strct 4.12.0 → 4.14.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/fesm2022/akcelik-strct.mjs +370 -50
- package/fesm2022/akcelik-strct.mjs.map +1 -1
- package/package.json +1 -1
- package/types/akcelik-strct.d.ts +139 -11
|
@@ -2998,6 +2998,15 @@ class StrctMenuPanel {
|
|
|
2998
2998
|
...(ngDevMode ? [{ debugName: "y" }] : /* istanbul ignore next */ []));
|
|
2999
2999
|
/** Render as a nested submenu panel. */
|
|
3000
3000
|
submenu = input(false, { ...(ngDevMode ? { debugName: "submenu" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
3001
|
+
/** The anchor's viewport rect, when the menu is placed against a control. */
|
|
3002
|
+
anchorRect = input(null, /* @ts-ignore */
|
|
3003
|
+
...(ngDevMode ? [{ debugName: "anchorRect" }] : /* istanbul ignore next */ []));
|
|
3004
|
+
/** Preferred side and alignment against `anchorRect`. */
|
|
3005
|
+
placement = input('bottom-start', /* @ts-ignore */
|
|
3006
|
+
...(ngDevMode ? [{ debugName: "placement" }] : /* istanbul ignore next */ []));
|
|
3007
|
+
/** Gap between the anchor and the menu. */
|
|
3008
|
+
offset = input(4, /* @ts-ignore */
|
|
3009
|
+
...(ngDevMode ? [{ debugName: "offset" }] : /* istanbul ignore next */ []));
|
|
3001
3010
|
/** Emitted when an item is selected. */
|
|
3002
3011
|
select = output();
|
|
3003
3012
|
/** Emitted when the menu requests closing. */
|
|
@@ -3008,6 +3017,13 @@ class StrctMenuPanel {
|
|
|
3008
3017
|
...(ngDevMode ? [{ debugName: "posX" }] : /* istanbul ignore next */ []));
|
|
3009
3018
|
posY = signal(0, /* @ts-ignore */
|
|
3010
3019
|
...(ngDevMode ? [{ debugName: "posY" }] : /* istanbul ignore next */ []));
|
|
3020
|
+
/**
|
|
3021
|
+
* An anchored menu is placed from its real size, which is known only after it
|
|
3022
|
+
* renders — so it stays hidden for that one frame rather than appearing in
|
|
3023
|
+
* the wrong place first.
|
|
3024
|
+
*/
|
|
3025
|
+
placed = signal(true, /* @ts-ignore */
|
|
3026
|
+
...(ngDevMode ? [{ debugName: "placed" }] : /* istanbul ignore next */ []));
|
|
3011
3027
|
/** Vertical offset of a submenu fly-out (matches the CSS `top: -5px` default). */
|
|
3012
3028
|
subTop = signal(-5, /* @ts-ignore */
|
|
3013
3029
|
...(ngDevMode ? [{ debugName: "subTop" }] : /* istanbul ignore next */ []));
|
|
@@ -3032,15 +3048,60 @@ class StrctMenuPanel {
|
|
|
3032
3048
|
constructor() {
|
|
3033
3049
|
this.posX.set(this.x());
|
|
3034
3050
|
this.posY.set(this.y());
|
|
3051
|
+
if (this.anchorRect())
|
|
3052
|
+
this.placed.set(false);
|
|
3035
3053
|
afterNextRender(() => {
|
|
3036
3054
|
// Open on the first entry that can act; a disabled-but-hinted one is
|
|
3037
3055
|
// reachable by arrow keys, not the landing spot.
|
|
3038
3056
|
const nav = this.navIndices();
|
|
3039
3057
|
this.activeIndex.set(nav.find((i) => !this.items()[i].disabled) ?? nav[0] ?? 0);
|
|
3040
|
-
this.
|
|
3058
|
+
if (this.anchorRect())
|
|
3059
|
+
this.placeAgainstAnchor();
|
|
3060
|
+
else
|
|
3061
|
+
this.clampToViewport();
|
|
3062
|
+
this.placed.set(true);
|
|
3041
3063
|
this.focusItem(this.activeIndex());
|
|
3042
3064
|
});
|
|
3043
3065
|
}
|
|
3066
|
+
/**
|
|
3067
|
+
* Place the panel against its anchor from the panel's measured size: the
|
|
3068
|
+
* preferred side when it fits, the opposite side when it does not and the
|
|
3069
|
+
* opposite side does, and clamped on the cross axis either way.
|
|
3070
|
+
*/
|
|
3071
|
+
placeAgainstAnchor() {
|
|
3072
|
+
const host = this.host.nativeElement;
|
|
3073
|
+
const r = this.anchorRect();
|
|
3074
|
+
const w = host.offsetWidth;
|
|
3075
|
+
const h = host.offsetHeight;
|
|
3076
|
+
const vw = window.innerWidth;
|
|
3077
|
+
const vh = window.innerHeight;
|
|
3078
|
+
const gap = this.offset();
|
|
3079
|
+
const m = 6;
|
|
3080
|
+
const [preferred, align] = this.placement().split('-');
|
|
3081
|
+
let side = preferred;
|
|
3082
|
+
if (side === 'bottom' && r.bottom + gap + h > vh - m && r.top - gap - h >= m)
|
|
3083
|
+
side = 'top';
|
|
3084
|
+
else if (side === 'top' && r.top - gap - h < m && r.bottom + gap + h <= vh - m)
|
|
3085
|
+
side = 'bottom';
|
|
3086
|
+
else if (side === 'right' && r.right + gap + w > vw - m && r.left - gap - w >= m)
|
|
3087
|
+
side = 'left';
|
|
3088
|
+
else if (side === 'left' && r.left - gap - w < m && r.right + gap + w <= vw - m)
|
|
3089
|
+
side = 'right';
|
|
3090
|
+
let x;
|
|
3091
|
+
let y;
|
|
3092
|
+
if (side === 'bottom' || side === 'top') {
|
|
3093
|
+
x = align === 'end' ? r.right - w : r.left;
|
|
3094
|
+
y = side === 'bottom' ? r.bottom + gap : r.top - gap - h;
|
|
3095
|
+
}
|
|
3096
|
+
else {
|
|
3097
|
+
x = side === 'right' ? r.right + gap : r.left - gap - w;
|
|
3098
|
+
y = align === 'end' ? r.bottom - h : r.top;
|
|
3099
|
+
}
|
|
3100
|
+
this.posX.set(Math.max(m, Math.min(x, vw - w - m)));
|
|
3101
|
+
this.posY.set(Math.max(m, Math.min(y, vh - h - m)));
|
|
3102
|
+
const rtl = getComputedStyle(host).direction === 'rtl';
|
|
3103
|
+
this.flipLeft.set(rtl ? this.posX() < 220 : this.posX() + w > vw - 220);
|
|
3104
|
+
}
|
|
3044
3105
|
clampToViewport() {
|
|
3045
3106
|
const host = this.host.nativeElement;
|
|
3046
3107
|
const vh = window.innerHeight;
|
|
@@ -3172,7 +3233,7 @@ class StrctMenuPanel {
|
|
|
3172
3233
|
}
|
|
3173
3234
|
}
|
|
3174
3235
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctMenuPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3175
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctMenuPanel, isStandalone: true, selector: "strct-menu-panel", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, x: { classPropertyName: "x", publicName: "x", isSignal: true, isRequired: false, transformFunction: null }, y: { classPropertyName: "y", publicName: "y", isSignal: true, isRequired: false, transformFunction: null }, submenu: { classPropertyName: "submenu", publicName: "submenu", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { select: "select", close: "close", back: "back" }, host: { properties: { "style.position": "submenu() ? null : 'fixed'", "style.left.px": "submenu() ? null : posX()", "style.top.px": "submenu() ? subTop() : posY()", "style.zIndex": "submenu() ? null : 1100" }, classAttribute: "strct-menu-host" }, ngImport: i0, template: `
|
|
3236
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctMenuPanel, isStandalone: true, selector: "strct-menu-panel", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, x: { classPropertyName: "x", publicName: "x", isSignal: true, isRequired: false, transformFunction: null }, y: { classPropertyName: "y", publicName: "y", isSignal: true, isRequired: false, transformFunction: null }, submenu: { classPropertyName: "submenu", publicName: "submenu", isSignal: true, isRequired: false, transformFunction: null }, anchorRect: { classPropertyName: "anchorRect", publicName: "anchorRect", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { select: "select", close: "close", back: "back" }, host: { properties: { "style.position": "submenu() ? null : 'fixed'", "style.visibility": "placed() ? null : 'hidden'", "style.left.px": "submenu() ? null : posX()", "style.top.px": "submenu() ? subTop() : posY()", "style.zIndex": "submenu() ? null : 1100" }, classAttribute: "strct-menu-host" }, ngImport: i0, template: `
|
|
3176
3237
|
<div class="strct-menu" role="menu" tabindex="-1" (keydown)="onKeydown($event)">
|
|
3177
3238
|
@for (item of items(); track $index; let i = $index) {
|
|
3178
3239
|
@if (item.divider) {
|
|
@@ -3241,7 +3302,7 @@ class StrctMenuPanel {
|
|
|
3241
3302
|
}
|
|
3242
3303
|
}
|
|
3243
3304
|
</div>
|
|
3244
|
-
`, isInline: true, styles: [".strct-menu-host{display:block}.strct-menu{min-width:180px;padding:4px;background:var(--bg-1);border:1px solid var(--b2);border-radius:var(--radius-md);box-shadow:var(--shh);animation:strct-menu-in .1s ease}.strct-menu:focus{outline:none}.strct-menu__wrap{position:relative}.strct-menu__item{display:flex;align-items:center;gap:8px;width:100%;padding:7px 8px 7px 10px;border:0;border-radius:5px;cursor:pointer;background:transparent;color:var(--t1);font-size:13px;font-family:var(--font);text-align:start}.strct-menu__item:hover:not([aria-disabled=true]),.strct-menu__item--active:not([aria-disabled=true]){background:var(--bg-3)}.strct-menu__item:focus-visible{outline:none;background:var(--bg-3)}.strct-menu__item--critical{color:var(--critical)}.strct-menu__item--critical:hover:not([aria-disabled=true]),.strct-menu__item--critical.strct-menu__item--active:not([aria-disabled=true]){background:var(--critical-bg)}.strct-menu__item[aria-disabled=true]{opacity:.45;cursor:not-allowed}.strct-menu__icon{color:var(--t2);flex-shrink:0}.strct-menu__item--critical .strct-menu__icon{color:var(--critical)}.strct-menu__icon-spacer{width:14px;flex-shrink:0}.strct-menu__label{flex:1;white-space:nowrap}.strct-menu__arrow{color:var(--t3);flex-shrink:0}.strct-menu__sep{height:1px;margin:4px 6px;background:var(--b1)}.strct-menu__subpanel{position:absolute;top:-5px;inset-inline-start:100%;margin-inline-start:2px;z-index:var(--z-base)}.strct-menu__subpanel--flip{inset-inline-start:auto;inset-inline-end:100%;margin-inline-start:0;margin-inline-end:2px}[dir=rtl] .strct-menu__arrow{transform:rotate(180deg)}@keyframes strct-menu-in{0%{opacity:0;transform:scale(.97)}}\n"], dependencies: [{ kind: "component", type: StrctMenuPanel, selector: "strct-menu-panel", inputs: ["items", "data", "x", "y", "submenu"], outputs: ["select", "close", "back"] }, { kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel", "count", "countMax", "countStatus", "countLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
3305
|
+
`, isInline: true, styles: [".strct-menu-host{display:block}.strct-menu{min-width:180px;padding:4px;background:var(--bg-1);border:1px solid var(--b2);border-radius:var(--radius-md);box-shadow:var(--shh);animation:strct-menu-in .1s ease}.strct-menu:focus{outline:none}.strct-menu__wrap{position:relative}.strct-menu__item{display:flex;align-items:center;gap:8px;width:100%;padding:7px 8px 7px 10px;border:0;border-radius:5px;cursor:pointer;background:transparent;color:var(--t1);font-size:13px;font-family:var(--font);text-align:start}.strct-menu__item:hover:not([aria-disabled=true]),.strct-menu__item--active:not([aria-disabled=true]){background:var(--bg-3)}.strct-menu__item:focus-visible{outline:none;background:var(--bg-3)}.strct-menu__item--critical{color:var(--critical)}.strct-menu__item--critical:hover:not([aria-disabled=true]),.strct-menu__item--critical.strct-menu__item--active:not([aria-disabled=true]){background:var(--critical-bg)}.strct-menu__item[aria-disabled=true]{opacity:.45;cursor:not-allowed}.strct-menu__icon{color:var(--t2);flex-shrink:0}.strct-menu__item--critical .strct-menu__icon{color:var(--critical)}.strct-menu__icon-spacer{width:14px;flex-shrink:0}.strct-menu__label{flex:1;white-space:nowrap}.strct-menu__arrow{color:var(--t3);flex-shrink:0}.strct-menu__sep{height:1px;margin:4px 6px;background:var(--b1)}.strct-menu__subpanel{position:absolute;top:-5px;inset-inline-start:100%;margin-inline-start:2px;z-index:var(--z-base)}.strct-menu__subpanel--flip{inset-inline-start:auto;inset-inline-end:100%;margin-inline-start:0;margin-inline-end:2px}[dir=rtl] .strct-menu__arrow{transform:rotate(180deg)}@keyframes strct-menu-in{0%{opacity:0;transform:scale(.97)}}\n"], dependencies: [{ kind: "component", type: StrctMenuPanel, selector: "strct-menu-panel", inputs: ["items", "data", "x", "y", "submenu", "anchorRect", "placement", "offset"], outputs: ["select", "close", "back"] }, { kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel", "count", "countMax", "countStatus", "countLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
3245
3306
|
}
|
|
3246
3307
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctMenuPanel, decorators: [{
|
|
3247
3308
|
type: Component,
|
|
@@ -3317,11 +3378,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
3317
3378
|
`, host: {
|
|
3318
3379
|
class: 'strct-menu-host',
|
|
3319
3380
|
'[style.position]': "submenu() ? null : 'fixed'",
|
|
3381
|
+
'[style.visibility]': "placed() ? null : 'hidden'",
|
|
3320
3382
|
'[style.left.px]': 'submenu() ? null : posX()',
|
|
3321
3383
|
'[style.top.px]': 'submenu() ? subTop() : posY()',
|
|
3322
3384
|
'[style.zIndex]': 'submenu() ? null : 1100',
|
|
3323
3385
|
}, styles: [".strct-menu-host{display:block}.strct-menu{min-width:180px;padding:4px;background:var(--bg-1);border:1px solid var(--b2);border-radius:var(--radius-md);box-shadow:var(--shh);animation:strct-menu-in .1s ease}.strct-menu:focus{outline:none}.strct-menu__wrap{position:relative}.strct-menu__item{display:flex;align-items:center;gap:8px;width:100%;padding:7px 8px 7px 10px;border:0;border-radius:5px;cursor:pointer;background:transparent;color:var(--t1);font-size:13px;font-family:var(--font);text-align:start}.strct-menu__item:hover:not([aria-disabled=true]),.strct-menu__item--active:not([aria-disabled=true]){background:var(--bg-3)}.strct-menu__item:focus-visible{outline:none;background:var(--bg-3)}.strct-menu__item--critical{color:var(--critical)}.strct-menu__item--critical:hover:not([aria-disabled=true]),.strct-menu__item--critical.strct-menu__item--active:not([aria-disabled=true]){background:var(--critical-bg)}.strct-menu__item[aria-disabled=true]{opacity:.45;cursor:not-allowed}.strct-menu__icon{color:var(--t2);flex-shrink:0}.strct-menu__item--critical .strct-menu__icon{color:var(--critical)}.strct-menu__icon-spacer{width:14px;flex-shrink:0}.strct-menu__label{flex:1;white-space:nowrap}.strct-menu__arrow{color:var(--t3);flex-shrink:0}.strct-menu__sep{height:1px;margin:4px 6px;background:var(--b1)}.strct-menu__subpanel{position:absolute;top:-5px;inset-inline-start:100%;margin-inline-start:2px;z-index:var(--z-base)}.strct-menu__subpanel--flip{inset-inline-start:auto;inset-inline-end:100%;margin-inline-start:0;margin-inline-end:2px}[dir=rtl] .strct-menu__arrow{transform:rotate(180deg)}@keyframes strct-menu-in{0%{opacity:0;transform:scale(.97)}}\n"] }]
|
|
3324
|
-
}], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], x: [{ type: i0.Input, args: [{ isSignal: true, alias: "x", required: false }] }], y: [{ type: i0.Input, args: [{ isSignal: true, alias: "y", required: false }] }], submenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "submenu", required: false }] }], select: [{ type: i0.Output, args: ["select"] }], close: [{ type: i0.Output, args: ["close"] }], back: [{ type: i0.Output, args: ["back"] }] } });
|
|
3386
|
+
}], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], x: [{ type: i0.Input, args: [{ isSignal: true, alias: "x", required: false }] }], y: [{ type: i0.Input, args: [{ isSignal: true, alias: "y", required: false }] }], submenu: [{ type: i0.Input, args: [{ isSignal: true, alias: "submenu", required: false }] }], anchorRect: [{ type: i0.Input, args: [{ isSignal: true, alias: "anchorRect", required: false }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "offset", required: false }] }], select: [{ type: i0.Output, args: ["select"] }], close: [{ type: i0.Output, args: ["close"] }], back: [{ type: i0.Output, args: ["back"] }] } });
|
|
3325
3387
|
/**
|
|
3326
3388
|
* Imperatively opens the data-driven menu panel, portaled into `<body>`. Shared
|
|
3327
3389
|
* by the `[strctContextMenu]` directive (right-click) and any click trigger such
|
|
@@ -3343,8 +3405,20 @@ class StrctMenuService {
|
|
|
3343
3405
|
const ref = createComponent(StrctMenuPanel, { environmentInjector: this.envInjector });
|
|
3344
3406
|
ref.setInput('items', opts.items);
|
|
3345
3407
|
ref.setInput('data', opts.data);
|
|
3346
|
-
ref.setInput('x', opts.x);
|
|
3347
|
-
ref.setInput('y', opts.y);
|
|
3408
|
+
ref.setInput('x', opts.x ?? 0);
|
|
3409
|
+
ref.setInput('y', opts.y ?? 0);
|
|
3410
|
+
if (opts.anchor) {
|
|
3411
|
+
const rect = opts.anchor instanceof Element ? opts.anchor.getBoundingClientRect() : opts.anchor;
|
|
3412
|
+
ref.setInput('anchorRect', rect);
|
|
3413
|
+
ref.setInput('placement', opts.placement ?? 'bottom-start');
|
|
3414
|
+
ref.setInput('offset', opts.offset ?? 4);
|
|
3415
|
+
// Focus goes back to the control the menu belongs to, when that control
|
|
3416
|
+
// can take it — otherwise to whatever had focus before.
|
|
3417
|
+
if (opts.anchor instanceof HTMLElement &&
|
|
3418
|
+
opts.anchor.matches('button, a[href], input, select, textarea, [tabindex]')) {
|
|
3419
|
+
this.restoreTo = opts.anchor;
|
|
3420
|
+
}
|
|
3421
|
+
}
|
|
3348
3422
|
ref.instance.select.subscribe((item) => {
|
|
3349
3423
|
item.action?.(opts.data);
|
|
3350
3424
|
opts.onSelect?.(item);
|
|
@@ -5003,7 +5077,10 @@ class StrctDropdown {
|
|
|
5003
5077
|
onInnerActivate(event) {
|
|
5004
5078
|
if (this.popover())
|
|
5005
5079
|
return;
|
|
5006
|
-
const
|
|
5080
|
+
const target = event.target;
|
|
5081
|
+
if (target?.closest('.strct-dd__itemaction'))
|
|
5082
|
+
return; // the second action is not the item
|
|
5083
|
+
const item = target?.closest('strct-dropdown-item');
|
|
5007
5084
|
if (item && item.getAttribute('aria-disabled') !== 'true')
|
|
5008
5085
|
this.close(true);
|
|
5009
5086
|
}
|
|
@@ -5035,10 +5112,39 @@ class StrctDropdown {
|
|
|
5035
5112
|
if (target.getAttribute('aria-disabled') !== 'true')
|
|
5036
5113
|
target.click();
|
|
5037
5114
|
}
|
|
5115
|
+
else if (key === 'ArrowRight' || key === 'ArrowLeft' || key === 'Delete') {
|
|
5116
|
+
this.onItemActionKey(event, key);
|
|
5117
|
+
}
|
|
5038
5118
|
else if (key === 'Tab') {
|
|
5039
5119
|
this.close();
|
|
5040
5120
|
}
|
|
5041
5121
|
}
|
|
5122
|
+
/**
|
|
5123
|
+
* An item with a trailing action has two targets: the right arrow reaches the
|
|
5124
|
+
* action from its item, the left arrow returns, and Delete on the item
|
|
5125
|
+
* triggers it (the WAI-ARIA pattern for a secondary action). Keys that do not
|
|
5126
|
+
* apply are left alone, so submenus keep their own arrow behaviour.
|
|
5127
|
+
*/
|
|
5128
|
+
onItemActionKey(event, key) {
|
|
5129
|
+
const target = event.target;
|
|
5130
|
+
if (key === 'ArrowLeft') {
|
|
5131
|
+
const item = target.closest('strct-dropdown-item');
|
|
5132
|
+
if (!target.classList.contains('strct-dd__itemaction') || !item)
|
|
5133
|
+
return;
|
|
5134
|
+
event.preventDefault();
|
|
5135
|
+
item.focus();
|
|
5136
|
+
return;
|
|
5137
|
+
}
|
|
5138
|
+
const item = target.closest('strct-dropdown-item');
|
|
5139
|
+
const action = item?.querySelector('.strct-dd__itemaction');
|
|
5140
|
+
if (!item || item !== target || !action)
|
|
5141
|
+
return;
|
|
5142
|
+
event.preventDefault();
|
|
5143
|
+
if (key === 'ArrowRight')
|
|
5144
|
+
action.focus();
|
|
5145
|
+
else
|
|
5146
|
+
action.click();
|
|
5147
|
+
}
|
|
5042
5148
|
enabledItems() {
|
|
5043
5149
|
return [
|
|
5044
5150
|
...this.host.nativeElement.querySelectorAll('strct-dropdown-item:not([aria-disabled="true"]), strct-submenu .strct-submenu__trigger'),
|
|
@@ -5174,6 +5280,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
5174
5280
|
}] });
|
|
5175
5281
|
let dropdownItemCounter = 0;
|
|
5176
5282
|
/** A selectable row inside a `<strct-dropdown>`. */
|
|
5283
|
+
/**
|
|
5284
|
+
* A second action at the end of a menu item — "delete this saved view" beside
|
|
5285
|
+
* "open it". It stops its own click from reaching the item, so the item is not
|
|
5286
|
+
* activated and the menu stays open, and it stays out of the Tab order: the
|
|
5287
|
+
* right arrow reaches it from its item, the left arrow returns, and Delete on
|
|
5288
|
+
* the item triggers it.
|
|
5289
|
+
*/
|
|
5290
|
+
class StrctDropdownItemAction {
|
|
5291
|
+
onClick(event) {
|
|
5292
|
+
event.stopPropagation();
|
|
5293
|
+
}
|
|
5294
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctDropdownItemAction, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
5295
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.4", type: StrctDropdownItemAction, isStandalone: true, selector: "[strctDropdownItemAction]", host: { attributes: { "tabindex": "-1" }, listeners: { "click": "onClick($event)" }, classAttribute: "strct-dd__itemaction" }, ngImport: i0 });
|
|
5296
|
+
}
|
|
5297
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctDropdownItemAction, decorators: [{
|
|
5298
|
+
type: Directive,
|
|
5299
|
+
args: [{
|
|
5300
|
+
selector: '[strctDropdownItemAction]',
|
|
5301
|
+
host: {
|
|
5302
|
+
class: 'strct-dd__itemaction',
|
|
5303
|
+
tabindex: '-1',
|
|
5304
|
+
'(click)': 'onClick($event)',
|
|
5305
|
+
},
|
|
5306
|
+
}]
|
|
5307
|
+
}] });
|
|
5177
5308
|
class StrctDropdownItem {
|
|
5178
5309
|
/**
|
|
5179
5310
|
* Select-like usage: bind `selected` and the item becomes a
|
|
@@ -5217,12 +5348,15 @@ class StrctDropdownItem {
|
|
|
5217
5348
|
}
|
|
5218
5349
|
</span>
|
|
5219
5350
|
}
|
|
5351
|
+
<!-- Declared before the catch-all so its selector wins; CSS order and an
|
|
5352
|
+
auto margin put it at the item's end. -->
|
|
5353
|
+
<ng-content select="[strctDropdownItemAction]" />
|
|
5220
5354
|
<ng-content />
|
|
5221
5355
|
@if (hint()) {
|
|
5222
5356
|
<!-- hidden: kept out of the item's accessible NAME, still read as its
|
|
5223
5357
|
description through aria-describedby. -->
|
|
5224
5358
|
<span [id]="hintId" hidden>{{ hint() }}</span>
|
|
5225
|
-
}`, isInline: true, styles: [".strct-dd__item{display:flex;align-items:center;gap:8px;padding:9px 10px;border-radius:5px;cursor:pointer;font-size:13px;color:var(--t1)}.strct-dd__item:hover,.strct-dd__item:focus-visible{background:var(--bg-3);outline:none}.strct-dd__check{display:inline-flex;width:14px;flex:none;color:var(--acc)}.strct-dd__item--selected{color:var(--t1);font-weight:600;background:var(--acc-s)}.strct-dd__item--critical{color:var(--critical)}.strct-dd__item--critical:hover{background:var(--critical-bg)}.strct-dd__item[aria-disabled=true]{color:var(--t4);pointer-events:none}.strct-dd__item--hinted[aria-disabled=true]{pointer-events:auto;cursor:not-allowed}.strct-dd__item--hinted[aria-disabled=true]:hover{background:transparent}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel", "count", "countMax", "countStatus", "countLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
5359
|
+
}`, isInline: true, styles: [".strct-dd__item{display:flex;align-items:center;gap:8px;padding:9px 10px;border-radius:5px;cursor:pointer;font-size:13px;color:var(--t1)}.strct-dd__item:hover,.strct-dd__item:focus-visible{background:var(--bg-3);outline:none}.strct-dd__itemaction{order:1;margin-inline-start:auto;flex:none}.strct-dd__check{display:inline-flex;width:14px;flex:none;color:var(--acc)}.strct-dd__item--selected{color:var(--t1);font-weight:600;background:var(--acc-s)}.strct-dd__item--critical{color:var(--critical)}.strct-dd__item--critical:hover{background:var(--critical-bg)}.strct-dd__item[aria-disabled=true]{color:var(--t4);pointer-events:none}.strct-dd__item--hinted[aria-disabled=true]{pointer-events:auto;cursor:not-allowed}.strct-dd__item--hinted[aria-disabled=true]:hover{background:transparent}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel", "count", "countMax", "countStatus", "countLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
5226
5360
|
}
|
|
5227
5361
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctDropdownItem, decorators: [{
|
|
5228
5362
|
type: Component,
|
|
@@ -5233,6 +5367,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
5233
5367
|
}
|
|
5234
5368
|
</span>
|
|
5235
5369
|
}
|
|
5370
|
+
<!-- Declared before the catch-all so its selector wins; CSS order and an
|
|
5371
|
+
auto margin put it at the item's end. -->
|
|
5372
|
+
<ng-content select="[strctDropdownItemAction]" />
|
|
5236
5373
|
<ng-content />
|
|
5237
5374
|
@if (hint()) {
|
|
5238
5375
|
<!-- hidden: kept out of the item's accessible NAME, still read as its
|
|
@@ -5250,7 +5387,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
5250
5387
|
'[class.strct-dd__item--critical]': 'critical()',
|
|
5251
5388
|
'[class.strct-dd__item--selected]': 'selected() === true',
|
|
5252
5389
|
'[attr.aria-disabled]': 'disabled() || null',
|
|
5253
|
-
}, styles: [".strct-dd__item{display:flex;align-items:center;gap:8px;padding:9px 10px;border-radius:5px;cursor:pointer;font-size:13px;color:var(--t1)}.strct-dd__item:hover,.strct-dd__item:focus-visible{background:var(--bg-3);outline:none}.strct-dd__check{display:inline-flex;width:14px;flex:none;color:var(--acc)}.strct-dd__item--selected{color:var(--t1);font-weight:600;background:var(--acc-s)}.strct-dd__item--critical{color:var(--critical)}.strct-dd__item--critical:hover{background:var(--critical-bg)}.strct-dd__item[aria-disabled=true]{color:var(--t4);pointer-events:none}.strct-dd__item--hinted[aria-disabled=true]{pointer-events:auto;cursor:not-allowed}.strct-dd__item--hinted[aria-disabled=true]:hover{background:transparent}\n"] }]
|
|
5390
|
+
}, styles: [".strct-dd__item{display:flex;align-items:center;gap:8px;padding:9px 10px;border-radius:5px;cursor:pointer;font-size:13px;color:var(--t1)}.strct-dd__item:hover,.strct-dd__item:focus-visible{background:var(--bg-3);outline:none}.strct-dd__itemaction{order:1;margin-inline-start:auto;flex:none}.strct-dd__check{display:inline-flex;width:14px;flex:none;color:var(--acc)}.strct-dd__item--selected{color:var(--t1);font-weight:600;background:var(--acc-s)}.strct-dd__item--critical{color:var(--critical)}.strct-dd__item--critical:hover{background:var(--critical-bg)}.strct-dd__item[aria-disabled=true]{color:var(--t4);pointer-events:none}.strct-dd__item--hinted[aria-disabled=true]{pointer-events:auto;cursor:not-allowed}.strct-dd__item--hinted[aria-disabled=true]:hover{background:transparent}\n"] }]
|
|
5254
5391
|
}], ctorParameters: () => [], propDecorators: { selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], critical: [{ type: i0.Input, args: [{ isSignal: true, alias: "critical", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }] } });
|
|
5255
5392
|
/** Thin separator between groups of menu items. */
|
|
5256
5393
|
class StrctDropdownDivider {
|
|
@@ -17884,6 +18021,22 @@ class StrctMetricTile {
|
|
|
17884
18021
|
/** Tints the value (defaults to neutral primary text). */
|
|
17885
18022
|
status = input('neutral', /* @ts-ignore */
|
|
17886
18023
|
...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
|
|
18024
|
+
/**
|
|
18025
|
+
* Tints the caption instead of the value — "2 down" is the warning, and the
|
|
18026
|
+
* 14 nodes above it are not. `null` keeps the caption muted.
|
|
18027
|
+
*/
|
|
18028
|
+
captionStatus = input(null, /* @ts-ignore */
|
|
18029
|
+
...(ngDevMode ? [{ debugName: "captionStatus" }] : /* istanbul ignore next */ []));
|
|
18030
|
+
/** Renders the tile as a link: the whole tile is the target. */
|
|
18031
|
+
href = input(null, /* @ts-ignore */
|
|
18032
|
+
...(ngDevMode ? [{ debugName: "href" }] : /* istanbul ignore next */ []));
|
|
18033
|
+
/** Makes the whole tile a control that emits `activated`. */
|
|
18034
|
+
interactive = input(false, { ...(ngDevMode ? { debugName: "interactive" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
18035
|
+
/** Emitted when an `interactive` tile is activated. */
|
|
18036
|
+
activated = output();
|
|
18037
|
+
/** The link / button's name: the KPI and its value, since the tile is the target. */
|
|
18038
|
+
hitLabel = computed(() => [this.label(), `${this.value()}${this.unit()}`].filter(Boolean).join(': '), /* @ts-ignore */
|
|
18039
|
+
...(ngDevMode ? [{ debugName: "hitLabel" }] : /* istanbul ignore next */ []));
|
|
17887
18040
|
/** Change indicator; sign drives the arrow + colour. Null hides it. */
|
|
17888
18041
|
delta = input(null, /* @ts-ignore */
|
|
17889
18042
|
...(ngDevMode ? [{ debugName: "delta" }] : /* istanbul ignore next */ []));
|
|
@@ -17935,7 +18088,7 @@ class StrctMetricTile {
|
|
|
17935
18088
|
}, /* @ts-ignore */
|
|
17936
18089
|
...(ngDevMode ? [{ debugName: "sparkStatus" }] : /* istanbul ignore next */ []));
|
|
17937
18090
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctMetricTile, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
17938
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctMetricTile, isStandalone: true, selector: "strct-metric-tile", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, unit: { classPropertyName: "unit", publicName: "unit", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, delta: { classPropertyName: "delta", publicName: "delta", isSignal: true, isRequired: false, transformFunction: null }, deltaSuffix: { classPropertyName: "deltaSuffix", publicName: "deltaSuffix", isSignal: true, isRequired: false, transformFunction: null }, deltaAriaLabel: { classPropertyName: "deltaAriaLabel", publicName: "deltaAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, invertDelta: { classPropertyName: "invertDelta", publicName: "invertDelta", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, caption: { classPropertyName: "caption", publicName: "caption", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.strct-mt--loading": "loading()", "attr.aria-busy": "loading() ? \"true\" : null" }, classAttribute: "strct-mt" }, ngImport: i0, template: `
|
|
18091
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctMetricTile, isStandalone: true, selector: "strct-metric-tile", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, unit: { classPropertyName: "unit", publicName: "unit", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, captionStatus: { classPropertyName: "captionStatus", publicName: "captionStatus", isSignal: true, isRequired: false, transformFunction: null }, href: { classPropertyName: "href", publicName: "href", isSignal: true, isRequired: false, transformFunction: null }, interactive: { classPropertyName: "interactive", publicName: "interactive", isSignal: true, isRequired: false, transformFunction: null }, delta: { classPropertyName: "delta", publicName: "delta", isSignal: true, isRequired: false, transformFunction: null }, deltaSuffix: { classPropertyName: "deltaSuffix", publicName: "deltaSuffix", isSignal: true, isRequired: false, transformFunction: null }, deltaAriaLabel: { classPropertyName: "deltaAriaLabel", publicName: "deltaAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, invertDelta: { classPropertyName: "invertDelta", publicName: "invertDelta", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, caption: { classPropertyName: "caption", publicName: "caption", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activated: "activated" }, host: { properties: { "class.strct-mt--actionable": "href() || interactive()", "class.strct-mt--loading": "loading()", "attr.aria-busy": "loading() ? \"true\" : null" }, classAttribute: "strct-mt" }, ngImport: i0, template: `
|
|
17939
18092
|
@if (loading()) {
|
|
17940
18093
|
<strct-skeleton width="45%" height="12px" />
|
|
17941
18094
|
<strct-skeleton width="65%" height="28px" />
|
|
@@ -17961,8 +18114,14 @@ class StrctMetricTile {
|
|
|
17961
18114
|
}
|
|
17962
18115
|
</div>
|
|
17963
18116
|
|
|
18117
|
+
<!-- A number over its bar: the meter sits under the value and above the
|
|
18118
|
+
caption, so "62 %" and "of 80 GB" read as one thing. -->
|
|
18119
|
+
<div class="strct-mt__meter"><ng-content select="[strctMetricMeter]" /></div>
|
|
18120
|
+
|
|
17964
18121
|
@if (caption()) {
|
|
17965
|
-
<div class="strct-mt__caption
|
|
18122
|
+
<div class="strct-mt__caption strct-mt__caption--{{ captionStatus() ?? 'none' }}">
|
|
18123
|
+
{{ caption() }}
|
|
18124
|
+
</div>
|
|
17966
18125
|
}
|
|
17967
18126
|
|
|
17968
18127
|
@if (data().length) {
|
|
@@ -17971,7 +18130,19 @@ class StrctMetricTile {
|
|
|
17971
18130
|
</div>
|
|
17972
18131
|
}
|
|
17973
18132
|
}
|
|
17974
|
-
|
|
18133
|
+
<!-- A KPI you can drill into is a link. The hit area covers the tile, so
|
|
18134
|
+
the whole tile is the target and the focus ring is the tile's own. -->
|
|
18135
|
+
@if (href()) {
|
|
18136
|
+
<a class="strct-mt__hit" [href]="href()" [attr.aria-label]="hitLabel()"></a>
|
|
18137
|
+
} @else if (interactive()) {
|
|
18138
|
+
<button
|
|
18139
|
+
type="button"
|
|
18140
|
+
class="strct-mt__hit"
|
|
18141
|
+
[attr.aria-label]="hitLabel()"
|
|
18142
|
+
(click)="activated.emit()"
|
|
18143
|
+
></button>
|
|
18144
|
+
}
|
|
18145
|
+
`, isInline: true, styles: [".strct-mt{position:relative;display:flex;flex-direction:column;gap:6px;padding:var(--space-3) var(--space-4);border:1px solid var(--b2);border-radius:var(--radius-lg);background:var(--bg-1);min-width:0}.strct-mt__top{display:flex;align-items:center;gap:7px}.strct-mt__icon{display:inline-flex;color:var(--t3);flex-shrink:0}.strct-mt__label{font-size:12px;font-weight:500;color:var(--t3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.strct-mt__delta{display:inline-flex;align-items:center;gap:2px;margin-inline-start:auto;font-size:12px;font-weight:600;font-variant-numeric:tabular-nums;flex-shrink:0}.strct-mt__delta--up{color:var(--success)}.strct-mt__delta--down{color:var(--critical)}.strct-mt__delta--flat{color:var(--t3)}.strct-mt__meter:empty{display:none}.strct-mt__hit{position:absolute;inset:-1px;padding:0;border:0;background:none;border-radius:inherit;cursor:pointer}.strct-mt__hit:focus-visible{outline:2px solid var(--acc50);outline-offset:2px}.strct-mt--actionable:hover{border-color:var(--b3);background:var(--bg-2)}.strct-mt__sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.strct-mt__value{display:flex;align-items:baseline;gap:4px;font-size:var(--text-3xl);font-weight:650;letter-spacing:-.01em;color:var(--t1);line-height:1.1}.strct-mt__value--accent{color:var(--acc)}.strct-mt__value--success{color:var(--success)}.strct-mt__value--warning{color:var(--warning)}.strct-mt__value--critical{color:var(--critical)}.strct-mt__unit{font-size:14px;font-weight:500;color:var(--t3);letter-spacing:0}.strct-mt__caption{font-size:12px;color:var(--t3)}.strct-mt__caption--accent{color:var(--acc)}.strct-mt__caption--success{color:var(--success)}.strct-mt__caption--warning{color:var(--warning)}.strct-mt__caption--critical{color:var(--critical)}.strct-mt__spark{margin-top:2px;line-height:0}.strct-mt__spark strct-sparkline,.strct-mt__spark .strct-spark__svg{width:100%}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel", "count", "countMax", "countStatus", "countLabel"] }, { kind: "component", type: StrctSkeleton, selector: "strct-skeleton", inputs: ["width", "height", "circle"] }, { kind: "component", type: StrctSparkline, selector: "strct-sparkline", inputs: ["data", "status", "area", "width", "height", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
17975
18146
|
}
|
|
17976
18147
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctMetricTile, decorators: [{
|
|
17977
18148
|
type: Component,
|
|
@@ -18001,8 +18172,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
18001
18172
|
}
|
|
18002
18173
|
</div>
|
|
18003
18174
|
|
|
18175
|
+
<!-- A number over its bar: the meter sits under the value and above the
|
|
18176
|
+
caption, so "62 %" and "of 80 GB" read as one thing. -->
|
|
18177
|
+
<div class="strct-mt__meter"><ng-content select="[strctMetricMeter]" /></div>
|
|
18178
|
+
|
|
18004
18179
|
@if (caption()) {
|
|
18005
|
-
<div class="strct-mt__caption
|
|
18180
|
+
<div class="strct-mt__caption strct-mt__caption--{{ captionStatus() ?? 'none' }}">
|
|
18181
|
+
{{ caption() }}
|
|
18182
|
+
</div>
|
|
18006
18183
|
}
|
|
18007
18184
|
|
|
18008
18185
|
@if (data().length) {
|
|
@@ -18011,12 +18188,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
18011
18188
|
</div>
|
|
18012
18189
|
}
|
|
18013
18190
|
}
|
|
18191
|
+
<!-- A KPI you can drill into is a link. The hit area covers the tile, so
|
|
18192
|
+
the whole tile is the target and the focus ring is the tile's own. -->
|
|
18193
|
+
@if (href()) {
|
|
18194
|
+
<a class="strct-mt__hit" [href]="href()" [attr.aria-label]="hitLabel()"></a>
|
|
18195
|
+
} @else if (interactive()) {
|
|
18196
|
+
<button
|
|
18197
|
+
type="button"
|
|
18198
|
+
class="strct-mt__hit"
|
|
18199
|
+
[attr.aria-label]="hitLabel()"
|
|
18200
|
+
(click)="activated.emit()"
|
|
18201
|
+
></button>
|
|
18202
|
+
}
|
|
18014
18203
|
`, host: {
|
|
18015
18204
|
class: 'strct-mt',
|
|
18205
|
+
'[class.strct-mt--actionable]': 'href() || interactive()',
|
|
18016
18206
|
'[class.strct-mt--loading]': 'loading()',
|
|
18017
18207
|
'[attr.aria-busy]': 'loading() ? "true" : null',
|
|
18018
|
-
}, styles: [".strct-mt{display:flex;flex-direction:column;gap:6px;padding:var(--space-3) var(--space-4);border:1px solid var(--b2);border-radius:var(--radius-lg);background:var(--bg-1);min-width:0}.strct-mt__top{display:flex;align-items:center;gap:7px}.strct-mt__icon{display:inline-flex;color:var(--t3);flex-shrink:0}.strct-mt__label{font-size:12px;font-weight:500;color:var(--t3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.strct-mt__delta{display:inline-flex;align-items:center;gap:2px;margin-inline-start:auto;font-size:12px;font-weight:600;font-variant-numeric:tabular-nums;flex-shrink:0}.strct-mt__delta--up{color:var(--success)}.strct-mt__delta--down{color:var(--critical)}.strct-mt__delta--flat{color:var(--t3)}.strct-mt__sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.strct-mt__value{display:flex;align-items:baseline;gap:4px;font-size:var(--text-3xl);font-weight:650;letter-spacing:-.01em;color:var(--t1);line-height:1.1}.strct-mt__value--accent{color:var(--acc)}.strct-mt__value--success{color:var(--success)}.strct-mt__value--warning{color:var(--warning)}.strct-mt__value--critical{color:var(--critical)}.strct-mt__unit{font-size:14px;font-weight:500;color:var(--t3);letter-spacing:0}.strct-mt__caption{font-size:12px;color:var(--t3)}.strct-mt__spark{margin-top:2px;line-height:0}.strct-mt__spark strct-sparkline,.strct-mt__spark .strct-spark__svg{width:100%}\n"] }]
|
|
18019
|
-
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], unit: [{ type: i0.Input, args: [{ isSignal: true, alias: "unit", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], delta: [{ type: i0.Input, args: [{ isSignal: true, alias: "delta", required: false }] }], deltaSuffix: [{ type: i0.Input, args: [{ isSignal: true, alias: "deltaSuffix", required: false }] }], deltaAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "deltaAriaLabel", required: false }] }], invertDelta: [{ type: i0.Input, args: [{ isSignal: true, alias: "invertDelta", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], caption: [{ type: i0.Input, args: [{ isSignal: true, alias: "caption", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }] } });
|
|
18208
|
+
}, styles: [".strct-mt{position:relative;display:flex;flex-direction:column;gap:6px;padding:var(--space-3) var(--space-4);border:1px solid var(--b2);border-radius:var(--radius-lg);background:var(--bg-1);min-width:0}.strct-mt__top{display:flex;align-items:center;gap:7px}.strct-mt__icon{display:inline-flex;color:var(--t3);flex-shrink:0}.strct-mt__label{font-size:12px;font-weight:500;color:var(--t3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.strct-mt__delta{display:inline-flex;align-items:center;gap:2px;margin-inline-start:auto;font-size:12px;font-weight:600;font-variant-numeric:tabular-nums;flex-shrink:0}.strct-mt__delta--up{color:var(--success)}.strct-mt__delta--down{color:var(--critical)}.strct-mt__delta--flat{color:var(--t3)}.strct-mt__meter:empty{display:none}.strct-mt__hit{position:absolute;inset:-1px;padding:0;border:0;background:none;border-radius:inherit;cursor:pointer}.strct-mt__hit:focus-visible{outline:2px solid var(--acc50);outline-offset:2px}.strct-mt--actionable:hover{border-color:var(--b3);background:var(--bg-2)}.strct-mt__sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.strct-mt__value{display:flex;align-items:baseline;gap:4px;font-size:var(--text-3xl);font-weight:650;letter-spacing:-.01em;color:var(--t1);line-height:1.1}.strct-mt__value--accent{color:var(--acc)}.strct-mt__value--success{color:var(--success)}.strct-mt__value--warning{color:var(--warning)}.strct-mt__value--critical{color:var(--critical)}.strct-mt__unit{font-size:14px;font-weight:500;color:var(--t3);letter-spacing:0}.strct-mt__caption{font-size:12px;color:var(--t3)}.strct-mt__caption--accent{color:var(--acc)}.strct-mt__caption--success{color:var(--success)}.strct-mt__caption--warning{color:var(--warning)}.strct-mt__caption--critical{color:var(--critical)}.strct-mt__spark{margin-top:2px;line-height:0}.strct-mt__spark strct-sparkline,.strct-mt__spark .strct-spark__svg{width:100%}\n"] }]
|
|
18209
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], unit: [{ type: i0.Input, args: [{ isSignal: true, alias: "unit", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], captionStatus: [{ type: i0.Input, args: [{ isSignal: true, alias: "captionStatus", required: false }] }], href: [{ type: i0.Input, args: [{ isSignal: true, alias: "href", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], activated: [{ type: i0.Output, args: ["activated"] }], delta: [{ type: i0.Input, args: [{ isSignal: true, alias: "delta", required: false }] }], deltaSuffix: [{ type: i0.Input, args: [{ isSignal: true, alias: "deltaSuffix", required: false }] }], deltaAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "deltaAriaLabel", required: false }] }], invertDelta: [{ type: i0.Input, args: [{ isSignal: true, alias: "invertDelta", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], caption: [{ type: i0.Input, args: [{ isSignal: true, alias: "caption", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }] } });
|
|
18020
18210
|
|
|
18021
18211
|
let heroCounter = 0;
|
|
18022
18212
|
/** Default leading icon per status, when `icon` is not supplied. */
|
|
@@ -18119,9 +18309,18 @@ class StrctAlert {
|
|
|
18119
18309
|
/** Accessible label of the dismiss button (localizable). */
|
|
18120
18310
|
dismissLabel = input('Dismiss', /* @ts-ignore */
|
|
18121
18311
|
...(ngDevMode ? [{ debugName: "dismissLabel" }] : /* istanbul ignore next */ []));
|
|
18312
|
+
/**
|
|
18313
|
+
* Overrides the icon derived from `type` — a lock for a locked setting, a
|
|
18314
|
+
* shield for a security note, when the tone alone does not say what kind of
|
|
18315
|
+
* note this is. `null` keeps the derived one.
|
|
18316
|
+
*/
|
|
18317
|
+
icon = input(null, /* @ts-ignore */
|
|
18318
|
+
...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
|
|
18122
18319
|
/** Emitted when the alert is dismissed. */
|
|
18123
18320
|
closed = output();
|
|
18124
|
-
|
|
18321
|
+
iconName = computed(() => this.icon() ?? this.derivedIcon(), /* @ts-ignore */
|
|
18322
|
+
...(ngDevMode ? [{ debugName: "iconName" }] : /* istanbul ignore next */ []));
|
|
18323
|
+
derivedIcon = computed(() => {
|
|
18125
18324
|
switch (this.type()) {
|
|
18126
18325
|
case 'success':
|
|
18127
18326
|
return 'success';
|
|
@@ -18133,38 +18332,46 @@ class StrctAlert {
|
|
|
18133
18332
|
return 'info';
|
|
18134
18333
|
}
|
|
18135
18334
|
}, /* @ts-ignore */
|
|
18136
|
-
...(ngDevMode ? [{ debugName: "
|
|
18335
|
+
...(ngDevMode ? [{ debugName: "derivedIcon" }] : /* istanbul ignore next */ []));
|
|
18137
18336
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctAlert, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
18138
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctAlert, isStandalone: true, selector: "strct-alert", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, dismissLabel: { classPropertyName: "dismissLabel", publicName: "dismissLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, host: { properties: { "attr.role": "type() === 'critical' ? 'alert' : 'status'", "class.strct-alert--success": "type() === 'success'", "class.strct-alert--warning": "type() === 'warning'", "class.strct-alert--critical": "type() === 'critical'" }, classAttribute: "strct-alert" }, ngImport: i0, template: `
|
|
18139
|
-
|
|
18140
|
-
|
|
18141
|
-
|
|
18142
|
-
<
|
|
18143
|
-
|
|
18144
|
-
|
|
18145
|
-
|
|
18146
|
-
|
|
18147
|
-
|
|
18148
|
-
|
|
18149
|
-
|
|
18150
|
-
|
|
18151
|
-
|
|
18337
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctAlert, isStandalone: true, selector: "strct-alert", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, closable: { classPropertyName: "closable", publicName: "closable", isSignal: true, isRequired: false, transformFunction: null }, dismissLabel: { classPropertyName: "dismissLabel", publicName: "dismissLabel", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, host: { properties: { "attr.role": "type() === 'critical' ? 'alert' : 'status'", "class.strct-alert--success": "type() === 'success'", "class.strct-alert--warning": "type() === 'warning'", "class.strct-alert--critical": "type() === 'critical'" }, classAttribute: "strct-alert" }, ngImport: i0, template: `
|
|
18338
|
+
<!-- The row carries the layout, not the host: a consumer setting
|
|
18339
|
+
display:block for spacing must not put the icon on its own line. -->
|
|
18340
|
+
<div class="strct-alert__row">
|
|
18341
|
+
<strct-icon class="strct-alert__icon" [name]="iconName()" [size]="16" />
|
|
18342
|
+
<div class="strct-alert__body"><ng-content /></div>
|
|
18343
|
+
@if (closable()) {
|
|
18344
|
+
<button
|
|
18345
|
+
type="button"
|
|
18346
|
+
class="strct-alert__close"
|
|
18347
|
+
[attr.aria-label]="dismissLabel()"
|
|
18348
|
+
(click)="closed.emit()"
|
|
18349
|
+
>
|
|
18350
|
+
<strct-icon name="close" [size]="13" />
|
|
18351
|
+
</button>
|
|
18352
|
+
}
|
|
18353
|
+
</div>
|
|
18354
|
+
`, isInline: true, styles: [".strct-alert{display:block;padding:var(--space-2) var(--space-3);border-radius:var(--radius-lg);font-size:13px;color:var(--t1);background:var(--bg-1);border:1px solid var(--b2);border-inline-start:3px solid var(--acc)}.strct-alert__row{display:flex;align-items:flex-start;gap:var(--space-2)}.strct-alert strct-icon{color:var(--acc);margin-top:1px;flex-shrink:0}.strct-alert__body{flex:1;color:var(--t1)}.strct-alert__close{flex-shrink:0;display:inline-flex;padding:2px;margin-block-start:-2px;margin-inline-end:-2px;border:0;background:transparent;color:var(--t3);cursor:pointer;border-radius:var(--radius-sm)}.strct-alert__close:hover{color:var(--t1);background:var(--bg-3)}.strct-alert--success{border-inline-start-color:var(--success)}.strct-alert--success strct-icon{color:var(--success)}.strct-alert--warning{border-inline-start-color:var(--warning)}.strct-alert--warning strct-icon{color:var(--warning)}.strct-alert--critical{border-inline-start-color:var(--critical)}.strct-alert--critical strct-icon{color:var(--critical)}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel", "count", "countMax", "countStatus", "countLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
18152
18355
|
}
|
|
18153
18356
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctAlert, decorators: [{
|
|
18154
18357
|
type: Component,
|
|
18155
18358
|
args: [{ selector: 'strct-alert', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [StrctIcon], template: `
|
|
18156
|
-
|
|
18157
|
-
|
|
18158
|
-
|
|
18159
|
-
<
|
|
18160
|
-
|
|
18161
|
-
|
|
18162
|
-
|
|
18163
|
-
|
|
18164
|
-
|
|
18165
|
-
|
|
18166
|
-
|
|
18167
|
-
|
|
18359
|
+
<!-- The row carries the layout, not the host: a consumer setting
|
|
18360
|
+
display:block for spacing must not put the icon on its own line. -->
|
|
18361
|
+
<div class="strct-alert__row">
|
|
18362
|
+
<strct-icon class="strct-alert__icon" [name]="iconName()" [size]="16" />
|
|
18363
|
+
<div class="strct-alert__body"><ng-content /></div>
|
|
18364
|
+
@if (closable()) {
|
|
18365
|
+
<button
|
|
18366
|
+
type="button"
|
|
18367
|
+
class="strct-alert__close"
|
|
18368
|
+
[attr.aria-label]="dismissLabel()"
|
|
18369
|
+
(click)="closed.emit()"
|
|
18370
|
+
>
|
|
18371
|
+
<strct-icon name="close" [size]="13" />
|
|
18372
|
+
</button>
|
|
18373
|
+
}
|
|
18374
|
+
</div>
|
|
18168
18375
|
`, host: {
|
|
18169
18376
|
class: 'strct-alert',
|
|
18170
18377
|
// role="alert" implies aria-live="assertive" for critical alerts.
|
|
@@ -18172,8 +18379,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
18172
18379
|
'[class.strct-alert--success]': "type() === 'success'",
|
|
18173
18380
|
'[class.strct-alert--warning]': "type() === 'warning'",
|
|
18174
18381
|
'[class.strct-alert--critical]': "type() === 'critical'",
|
|
18175
|
-
}, styles: [".strct-alert{display:
|
|
18176
|
-
}], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], closable: [{ type: i0.Input, args: [{ isSignal: true, alias: "closable", required: false }] }], dismissLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissLabel", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
|
|
18382
|
+
}, styles: [".strct-alert{display:block;padding:var(--space-2) var(--space-3);border-radius:var(--radius-lg);font-size:13px;color:var(--t1);background:var(--bg-1);border:1px solid var(--b2);border-inline-start:3px solid var(--acc)}.strct-alert__row{display:flex;align-items:flex-start;gap:var(--space-2)}.strct-alert strct-icon{color:var(--acc);margin-top:1px;flex-shrink:0}.strct-alert__body{flex:1;color:var(--t1)}.strct-alert__close{flex-shrink:0;display:inline-flex;padding:2px;margin-block-start:-2px;margin-inline-end:-2px;border:0;background:transparent;color:var(--t3);cursor:pointer;border-radius:var(--radius-sm)}.strct-alert__close:hover{color:var(--t1);background:var(--bg-3)}.strct-alert--success{border-inline-start-color:var(--success)}.strct-alert--success strct-icon{color:var(--success)}.strct-alert--warning{border-inline-start-color:var(--warning)}.strct-alert--warning strct-icon{color:var(--warning)}.strct-alert--critical{border-inline-start-color:var(--critical)}.strct-alert--critical strct-icon{color:var(--critical)}\n"] }]
|
|
18383
|
+
}], propDecorators: { type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], closable: [{ type: i0.Input, args: [{ isSignal: true, alias: "closable", required: false }] }], dismissLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissLabel", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
|
|
18177
18384
|
|
|
18178
18385
|
let tooltipCounter = 0;
|
|
18179
18386
|
/**
|
|
@@ -21721,13 +21928,19 @@ class StrctStatusDot {
|
|
|
21721
21928
|
/** Dot size: `sm` for dense rows, `md` standalone. */
|
|
21722
21929
|
size = input('md', /* @ts-ignore */
|
|
21723
21930
|
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
21931
|
+
/**
|
|
21932
|
+
* Something happening *now* — a task running, a live chart. The halo pulses
|
|
21933
|
+
* once a second; the dot itself never changes size, so a column of dots does
|
|
21934
|
+
* not jitter. Under `prefers-reduced-motion` the halo is a static ring.
|
|
21935
|
+
*/
|
|
21936
|
+
pulse = input(false, { ...(ngDevMode ? { debugName: "pulse" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
21724
21937
|
text = computed(() => this.label() || DEFAULT_LABEL[this.status()], /* @ts-ignore */
|
|
21725
21938
|
...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
|
|
21726
21939
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctStatusDot, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
21727
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: StrctStatusDot, isStandalone: true, selector: "strct-status-dot", inputs: { status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.strct-dot--accent": "status() === 'accent'", "class.strct-dot--success": "status() === 'success'", "class.strct-dot--warning": "status() === 'warning'", "class.strct-dot--critical": "status() === 'critical'", "class.strct-dot--sm": "size() === 'sm'" }, classAttribute: "strct-dot" }, ngImport: i0, template: `
|
|
21940
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: StrctStatusDot, isStandalone: true, selector: "strct-status-dot", inputs: { status: { classPropertyName: "status", publicName: "status", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, pulse: { classPropertyName: "pulse", publicName: "pulse", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class.strct-dot--accent": "status() === 'accent'", "class.strct-dot--success": "status() === 'success'", "class.strct-dot--warning": "status() === 'warning'", "class.strct-dot--critical": "status() === 'critical'", "class.strct-dot--sm": "size() === 'sm'", "class.strct-dot--pulse": "pulse()" }, classAttribute: "strct-dot" }, ngImport: i0, template: `
|
|
21728
21941
|
<span class="strct-dot__dot" aria-hidden="true"></span>
|
|
21729
21942
|
<span class="strct-dot__sr">{{ text() }}</span>
|
|
21730
|
-
`, isInline: true, styles: [".strct-dot{display:inline-flex;align-items:center;flex:none;line-height:0}.strct-dot__dot{width:10px;height:10px;border-radius:50%;background:var(--t3)}.strct-dot--sm .strct-dot__dot{width:8px;height:8px}.strct-dot--accent .strct-dot__dot{background:var(--acc)}.strct-dot--success .strct-dot__dot{background:var(--success)}.strct-dot--warning .strct-dot__dot{background:var(--warning)}.strct-dot--critical .strct-dot__dot{background:var(--critical)}.strct-dot__sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
21943
|
+
`, isInline: true, styles: [".strct-dot{display:inline-flex;align-items:center;flex:none;line-height:0}.strct-dot__dot{width:10px;height:10px;border-radius:50%;background:var(--t3)}.strct-dot--sm .strct-dot__dot{width:8px;height:8px}.strct-dot--accent .strct-dot__dot{background:var(--acc)}.strct-dot--success .strct-dot__dot{background:var(--success)}.strct-dot--warning .strct-dot__dot{background:var(--warning)}.strct-dot--critical .strct-dot__dot{background:var(--critical)}.strct-dot--pulse .strct-dot__dot{position:relative}.strct-dot--pulse .strct-dot__dot:after{content:\"\";position:absolute;inset:0;border-radius:50%;background:inherit;animation:strct-dot-pulse 1s ease-out infinite}@keyframes strct-dot-pulse{0%{box-shadow:0 0 0 0 currentColor;opacity:.55}to{box-shadow:0 0 0 5px transparent;opacity:0}}.strct-dot--pulse .strct-dot__dot{color:var(--t3)}.strct-dot--pulse.strct-dot--accent .strct-dot__dot{color:var(--acc)}.strct-dot--pulse.strct-dot--success .strct-dot__dot{color:var(--success)}.strct-dot--pulse.strct-dot--warning .strct-dot__dot{color:var(--warning)}.strct-dot--pulse.strct-dot--critical .strct-dot__dot{color:var(--critical)}@media(prefers-reduced-motion:reduce){.strct-dot--pulse .strct-dot__dot:after{animation:none;box-shadow:0 0 0 3px currentColor;opacity:.25}}.strct-dot__sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
21731
21944
|
}
|
|
21732
21945
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctStatusDot, decorators: [{
|
|
21733
21946
|
type: Component,
|
|
@@ -21741,8 +21954,115 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
21741
21954
|
'[class.strct-dot--warning]': "status() === 'warning'",
|
|
21742
21955
|
'[class.strct-dot--critical]': "status() === 'critical'",
|
|
21743
21956
|
'[class.strct-dot--sm]': "size() === 'sm'",
|
|
21744
|
-
|
|
21745
|
-
|
|
21957
|
+
'[class.strct-dot--pulse]': 'pulse()',
|
|
21958
|
+
}, styles: [".strct-dot{display:inline-flex;align-items:center;flex:none;line-height:0}.strct-dot__dot{width:10px;height:10px;border-radius:50%;background:var(--t3)}.strct-dot--sm .strct-dot__dot{width:8px;height:8px}.strct-dot--accent .strct-dot__dot{background:var(--acc)}.strct-dot--success .strct-dot__dot{background:var(--success)}.strct-dot--warning .strct-dot__dot{background:var(--warning)}.strct-dot--critical .strct-dot__dot{background:var(--critical)}.strct-dot--pulse .strct-dot__dot{position:relative}.strct-dot--pulse .strct-dot__dot:after{content:\"\";position:absolute;inset:0;border-radius:50%;background:inherit;animation:strct-dot-pulse 1s ease-out infinite}@keyframes strct-dot-pulse{0%{box-shadow:0 0 0 0 currentColor;opacity:.55}to{box-shadow:0 0 0 5px transparent;opacity:0}}.strct-dot--pulse .strct-dot__dot{color:var(--t3)}.strct-dot--pulse.strct-dot--accent .strct-dot__dot{color:var(--acc)}.strct-dot--pulse.strct-dot--success .strct-dot__dot{color:var(--success)}.strct-dot--pulse.strct-dot--warning .strct-dot__dot{color:var(--warning)}.strct-dot--pulse.strct-dot--critical .strct-dot__dot{color:var(--critical)}@media(prefers-reduced-motion:reduce){.strct-dot--pulse .strct-dot__dot:after{animation:none;box-shadow:0 0 0 3px currentColor;opacity:.25}}.strct-dot__sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}\n"] }]
|
|
21959
|
+
}], propDecorators: { status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], pulse: [{ type: i0.Input, args: [{ isSignal: true, alias: "pulse", required: false }] }] } });
|
|
21960
|
+
|
|
21961
|
+
const DEFAULT_LABELS = {
|
|
21962
|
+
live: 'Live',
|
|
21963
|
+
liveEvery: (s) => `Live · updates every ${s} s`,
|
|
21964
|
+
connecting: 'Connecting…',
|
|
21965
|
+
reconnecting: 'Reconnecting…',
|
|
21966
|
+
paused: 'Paused',
|
|
21967
|
+
stale: (relative) => `Last updated ${relative}`,
|
|
21968
|
+
justNow: 'just now',
|
|
21969
|
+
minutesAgo: (n) => `${n} min ago`,
|
|
21970
|
+
hoursAgo: (n) => `${n} h ago`,
|
|
21971
|
+
};
|
|
21972
|
+
const TONE = {
|
|
21973
|
+
live: 'success',
|
|
21974
|
+
connecting: 'accent',
|
|
21975
|
+
reconnecting: 'warning',
|
|
21976
|
+
paused: 'neutral',
|
|
21977
|
+
stale: 'warning',
|
|
21978
|
+
};
|
|
21979
|
+
/**
|
|
21980
|
+
* "Live · updates every 5 s" and "Reconnecting…" are states of one indicator,
|
|
21981
|
+
* not three captions written by hand next to three hand-rolled dots. A dot that
|
|
21982
|
+
* is live and a dot that is merely green are different facts.
|
|
21983
|
+
*
|
|
21984
|
+
* <strct-live-indicator state="live" [interval]="5000" />
|
|
21985
|
+
* <strct-live-indicator state="stale" [updatedAt]="lastRead" />
|
|
21986
|
+
*
|
|
21987
|
+
* It is a `role="status"`, so a change of state is announced politely — and the
|
|
21988
|
+
* relative time re-renders on its own every 30 s without announcing each tick.
|
|
21989
|
+
*/
|
|
21990
|
+
class StrctLiveIndicator {
|
|
21991
|
+
/** What the view is doing. */
|
|
21992
|
+
state = input('live', /* @ts-ignore */
|
|
21993
|
+
...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
|
|
21994
|
+
/** Refresh period in ms — turns "Live" into "Live · updates every 5 s". */
|
|
21995
|
+
interval = input(null, /* @ts-ignore */
|
|
21996
|
+
...(ngDevMode ? [{ debugName: "interval" }] : /* istanbul ignore next */ []));
|
|
21997
|
+
/** When the data last arrived; drives the relative time of `stale`. */
|
|
21998
|
+
updatedAt = input(null, /* @ts-ignore */
|
|
21999
|
+
...(ngDevMode ? [{ debugName: "updatedAt" }] : /* istanbul ignore next */ []));
|
|
22000
|
+
/** Every string, for localisation. */
|
|
22001
|
+
labels = input({}, /* @ts-ignore */
|
|
22002
|
+
...(ngDevMode ? [{ debugName: "labels" }] : /* istanbul ignore next */ []));
|
|
22003
|
+
tone = computed(() => TONE[this.state()], /* @ts-ignore */
|
|
22004
|
+
...(ngDevMode ? [{ debugName: "tone" }] : /* istanbul ignore next */ []));
|
|
22005
|
+
/** Only a view that is actually receiving data pulses. */
|
|
22006
|
+
pulsing = computed(() => this.state() === 'live', /* @ts-ignore */
|
|
22007
|
+
...(ngDevMode ? [{ debugName: "pulsing" }] : /* istanbul ignore next */ []));
|
|
22008
|
+
L = computed(() => ({ ...DEFAULT_LABELS, ...this.labels() }), /* @ts-ignore */
|
|
22009
|
+
...(ngDevMode ? [{ debugName: "L" }] : /* istanbul ignore next */ []));
|
|
22010
|
+
/** Re-read every 30 s, so "3 min ago" does not go stale on screen. */
|
|
22011
|
+
now = signal(Date.now(), /* @ts-ignore */
|
|
22012
|
+
...(ngDevMode ? [{ debugName: "now" }] : /* istanbul ignore next */ []));
|
|
22013
|
+
constructor() {
|
|
22014
|
+
const timer = setInterval(() => this.now.set(Date.now()), 30_000);
|
|
22015
|
+
inject(DestroyRef).onDestroy(() => clearInterval(timer));
|
|
22016
|
+
}
|
|
22017
|
+
relative = computed(() => {
|
|
22018
|
+
const at = this.updatedAt();
|
|
22019
|
+
if (at == null)
|
|
22020
|
+
return '';
|
|
22021
|
+
const ms = this.now() - (at instanceof Date ? at.getTime() : at);
|
|
22022
|
+
const mins = Math.floor(ms / 60_000);
|
|
22023
|
+
if (mins < 1)
|
|
22024
|
+
return this.L().justNow;
|
|
22025
|
+
if (mins < 60)
|
|
22026
|
+
return this.L().minutesAgo(mins);
|
|
22027
|
+
return this.L().hoursAgo(Math.floor(mins / 60));
|
|
22028
|
+
}, /* @ts-ignore */
|
|
22029
|
+
...(ngDevMode ? [{ debugName: "relative" }] : /* istanbul ignore next */ []));
|
|
22030
|
+
text = computed(() => {
|
|
22031
|
+
const l = this.L();
|
|
22032
|
+
switch (this.state()) {
|
|
22033
|
+
case 'live': {
|
|
22034
|
+
const ms = this.interval();
|
|
22035
|
+
return ms ? l.liveEvery(Math.round(ms / 1000)) : l.live;
|
|
22036
|
+
}
|
|
22037
|
+
case 'connecting':
|
|
22038
|
+
return l.connecting;
|
|
22039
|
+
case 'reconnecting':
|
|
22040
|
+
return l.reconnecting;
|
|
22041
|
+
case 'paused':
|
|
22042
|
+
return l.paused;
|
|
22043
|
+
case 'stale':
|
|
22044
|
+
return this.relative() ? l.stale(this.relative()) : l.stale('');
|
|
22045
|
+
}
|
|
22046
|
+
}, /* @ts-ignore */
|
|
22047
|
+
...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
|
|
22048
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctLiveIndicator, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
22049
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.4", type: StrctLiveIndicator, isStandalone: true, selector: "strct-live-indicator", inputs: { state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: false, transformFunction: null }, interval: { classPropertyName: "interval", publicName: "interval", isSignal: true, isRequired: false, transformFunction: null }, updatedAt: { classPropertyName: "updatedAt", publicName: "updatedAt", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "status", "aria-live": "polite" }, properties: { "attr.data-state": "state()" }, classAttribute: "strct-live" }, ngImport: i0, template: `
|
|
22050
|
+
<strct-status-dot size="sm" [status]="tone()" [pulse]="pulsing()" [label]="text()" />
|
|
22051
|
+
<span class="strct-live__text">{{ text() }}</span>
|
|
22052
|
+
`, isInline: true, styles: [".strct-live{display:inline-flex;align-items:center;gap:6px;font-size:var(--text-sm);color:var(--t3)}.strct-live[data-state=reconnecting] .strct-live__text,.strct-live[data-state=stale] .strct-live__text{color:var(--warning)}.strct-live .strct-dot__sr{display:none}\n"], dependencies: [{ kind: "component", type: StrctStatusDot, selector: "strct-status-dot", inputs: ["status", "label", "size", "pulse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
22053
|
+
}
|
|
22054
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctLiveIndicator, decorators: [{
|
|
22055
|
+
type: Component,
|
|
22056
|
+
args: [{ selector: 'strct-live-indicator', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [StrctStatusDot], template: `
|
|
22057
|
+
<strct-status-dot size="sm" [status]="tone()" [pulse]="pulsing()" [label]="text()" />
|
|
22058
|
+
<span class="strct-live__text">{{ text() }}</span>
|
|
22059
|
+
`, host: {
|
|
22060
|
+
class: 'strct-live',
|
|
22061
|
+
role: 'status',
|
|
22062
|
+
'aria-live': 'polite',
|
|
22063
|
+
'[attr.data-state]': 'state()',
|
|
22064
|
+
}, styles: [".strct-live{display:inline-flex;align-items:center;gap:6px;font-size:var(--text-sm);color:var(--t3)}.strct-live[data-state=reconnecting] .strct-live__text,.strct-live[data-state=stale] .strct-live__text{color:var(--warning)}.strct-live .strct-dot__sr{display:none}\n"] }]
|
|
22065
|
+
}], ctorParameters: () => [], propDecorators: { state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: false }] }], interval: [{ type: i0.Input, args: [{ isSignal: true, alias: "interval", required: false }] }], updatedAt: [{ type: i0.Input, args: [{ isSignal: true, alias: "updatedAt", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }] } });
|
|
21746
22066
|
|
|
21747
22067
|
/**
|
|
21748
22068
|
* A generic anchored overlay panel for arbitrary projected content — the
|
|
@@ -23610,5 +23930,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
23610
23930
|
* Generated bundle index. Do not edit.
|
|
23611
23931
|
*/
|
|
23612
23932
|
|
|
23613
|
-
export { FOCUSABLE_SELECTOR, STRCT_DP_DOW, STRCT_DP_DOW_FULL, STRCT_DP_MONTHS, STRCT_ICONS, STRCT_ICON_GROUPS, STRCT_ICON_NAMES, STRCT_MASKS, STRCT_NOTIFICATION_HISTORY_LIMIT, STRCT_PALETTES, STRCT_RAW_ICONS, STRCT_TIME_RANGE_PRESETS, STRCT_WIZARD_DEFAULTS, StrctAccordion, StrctAccordionPanel, StrctAlert, StrctAnnouncer, StrctAvatar, StrctBadge, StrctBreadcrumb, StrctBreadcrumbItem, StrctButton, StrctButtonGroup, StrctBytesPipe, StrctCard, StrctCardBlock, StrctCardFooter, StrctCardHeader, StrctCardHeaderActions, StrctCardHeaderMeta, StrctCardHeaderNote, StrctCascadeColumn, StrctCascadeHost, StrctCascadeSelect, StrctCellDef, StrctCellStatus, StrctChart, StrctCheckbox, StrctChips, StrctCode, StrctCodeInline, StrctColorPicker, StrctCombobox, StrctCommandPalette, StrctConfirmOutlet, StrctConfirmService, StrctContextMenu, StrctContextMenuTrigger, StrctControlDescription, StrctCopy, StrctDatagrid, StrctDatagridActionBar, StrctDatagridActionBarCaption, StrctDatepicker, StrctDatetimePicker, StrctDesc, StrctDescriptionList, StrctDiff, StrctDivider, StrctDonut, StrctDrawer, StrctDrawerFooter, StrctDropdown, StrctDropdownDivider, StrctDropdownItem, StrctDropdownTrigger, StrctDurationPipe, StrctEmptyState, StrctField, StrctFieldGroup, StrctFieldHint, StrctFieldPrefix, StrctFieldSuffix, StrctFile, StrctFilterBar, StrctFlow, StrctFooter, StrctGauge, StrctHeader, StrctHeatmap, StrctHero, StrctHotkeysHelp, StrctHotkeysService, StrctIcon, StrctInlineEdit, StrctInput, StrctInputMask, StrctInputOtp, StrctKbd, StrctKnob, StrctList, StrctListItem, StrctListItemDescription, StrctListItemLeading, StrctListItemMeta, StrctListItemTrailing, StrctLogViewer, StrctLogin, StrctMenuPanel, StrctMenuService, StrctMenubar, StrctMetricTile, StrctModal, StrctModalContent, StrctNav, StrctNavItem, StrctNotificationCenter, StrctNumber, StrctOverlay, StrctPageHeader, StrctPageHeaderActions, StrctPageHeaderCrumbs, StrctPageHeaderTitleMeta, StrctPagination, StrctPassword, StrctPopover, StrctPopoverTrigger, StrctProgress, StrctRadio, StrctRadioGroup, StrctRail, StrctRange, StrctRatePipe, StrctRating, StrctReorder, StrctReorderItem, StrctRowDetailDef, StrctSearchbox, StrctSectionHeader, StrctSectionHeaderActions, StrctSectionHeaderMeta, StrctSectionMenu, StrctSegmented, StrctSelect, StrctShell, StrctShellService, StrctSiPipe, StrctSignpost, StrctSignpostTrigger, StrctSkeleton, StrctSparkline, StrctSpeedDial, StrctSpinner, StrctSplitButton, StrctSplitter, StrctStack, StrctStackItem, StrctStatusDot, StrctStep, StrctSubmenu, StrctTab, StrctTable, StrctTabs, StrctTag, StrctTagLeading, StrctThemeService, StrctThemeSwitcher, StrctTimeRangePicker, StrctTimeline, StrctTimelineItem, StrctToastOutlet, StrctToastService, StrctToggle, StrctToolbar, StrctToolbarCaption, StrctToolbarSpacer, StrctTooltip, StrctTour, StrctTransfer, StrctTree, StrctTreeNode, StrctTreeSelect, StrctVerticalNav, StrctWatermark, StrctWizard, StrctWizardAside, focusFirstIn, keepTabInside, lockBodyScroll, parseAnsi, provideStrctWizardDefaults, registerStrctIcon, restoreFocus, saveFocusedElement, strctComputeDiff, strctDpPad, strctFormatBytes, strctFormatDuration, strctFormatRate, strctFormatSi, strctValidationIcon, strctValidationTone, unlockBodyScroll };
|
|
23933
|
+
export { FOCUSABLE_SELECTOR, STRCT_DP_DOW, STRCT_DP_DOW_FULL, STRCT_DP_MONTHS, STRCT_ICONS, STRCT_ICON_GROUPS, STRCT_ICON_NAMES, STRCT_MASKS, STRCT_NOTIFICATION_HISTORY_LIMIT, STRCT_PALETTES, STRCT_RAW_ICONS, STRCT_TIME_RANGE_PRESETS, STRCT_WIZARD_DEFAULTS, StrctAccordion, StrctAccordionPanel, StrctAlert, StrctAnnouncer, StrctAvatar, StrctBadge, StrctBreadcrumb, StrctBreadcrumbItem, StrctButton, StrctButtonGroup, StrctBytesPipe, StrctCard, StrctCardBlock, StrctCardFooter, StrctCardHeader, StrctCardHeaderActions, StrctCardHeaderMeta, StrctCardHeaderNote, StrctCascadeColumn, StrctCascadeHost, StrctCascadeSelect, StrctCellDef, StrctCellStatus, StrctChart, StrctCheckbox, StrctChips, StrctCode, StrctCodeInline, StrctColorPicker, StrctCombobox, StrctCommandPalette, StrctConfirmOutlet, StrctConfirmService, StrctContextMenu, StrctContextMenuTrigger, StrctControlDescription, StrctCopy, StrctDatagrid, StrctDatagridActionBar, StrctDatagridActionBarCaption, StrctDatepicker, StrctDatetimePicker, StrctDesc, StrctDescriptionList, StrctDiff, StrctDivider, StrctDonut, StrctDrawer, StrctDrawerFooter, StrctDropdown, StrctDropdownDivider, StrctDropdownItem, StrctDropdownItemAction, StrctDropdownTrigger, StrctDurationPipe, StrctEmptyState, StrctField, StrctFieldGroup, StrctFieldHint, StrctFieldPrefix, StrctFieldSuffix, StrctFile, StrctFilterBar, StrctFlow, StrctFooter, StrctGauge, StrctHeader, StrctHeatmap, StrctHero, StrctHotkeysHelp, StrctHotkeysService, StrctIcon, StrctInlineEdit, StrctInput, StrctInputMask, StrctInputOtp, StrctKbd, StrctKnob, StrctList, StrctListItem, StrctListItemDescription, StrctListItemLeading, StrctListItemMeta, StrctListItemTrailing, StrctLiveIndicator, StrctLogViewer, StrctLogin, StrctMenuPanel, StrctMenuService, StrctMenubar, StrctMetricTile, StrctModal, StrctModalContent, StrctNav, StrctNavItem, StrctNotificationCenter, StrctNumber, StrctOverlay, StrctPageHeader, StrctPageHeaderActions, StrctPageHeaderCrumbs, StrctPageHeaderTitleMeta, StrctPagination, StrctPassword, StrctPopover, StrctPopoverTrigger, StrctProgress, StrctRadio, StrctRadioGroup, StrctRail, StrctRange, StrctRatePipe, StrctRating, StrctReorder, StrctReorderItem, StrctRowDetailDef, StrctSearchbox, StrctSectionHeader, StrctSectionHeaderActions, StrctSectionHeaderMeta, StrctSectionMenu, StrctSegmented, StrctSelect, StrctShell, StrctShellService, StrctSiPipe, StrctSignpost, StrctSignpostTrigger, StrctSkeleton, StrctSparkline, StrctSpeedDial, StrctSpinner, StrctSplitButton, StrctSplitter, StrctStack, StrctStackItem, StrctStatusDot, StrctStep, StrctSubmenu, StrctTab, StrctTable, StrctTabs, StrctTag, StrctTagLeading, StrctThemeService, StrctThemeSwitcher, StrctTimeRangePicker, StrctTimeline, StrctTimelineItem, StrctToastOutlet, StrctToastService, StrctToggle, StrctToolbar, StrctToolbarCaption, StrctToolbarSpacer, StrctTooltip, StrctTour, StrctTransfer, StrctTree, StrctTreeNode, StrctTreeSelect, StrctVerticalNav, StrctWatermark, StrctWizard, StrctWizardAside, focusFirstIn, keepTabInside, lockBodyScroll, parseAnsi, provideStrctWizardDefaults, registerStrctIcon, restoreFocus, saveFocusedElement, strctComputeDiff, strctDpPad, strctFormatBytes, strctFormatDuration, strctFormatRate, strctFormatSi, strctValidationIcon, strctValidationTone, unlockBodyScroll };
|
|
23614
23934
|
//# sourceMappingURL=akcelik-strct.mjs.map
|