@akcelik/strct 4.21.0 → 4.22.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.
@@ -23261,6 +23261,479 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
23261
23261
  }, styles: [".strct-mf{position:relative;display:flex;align-items:center;justify-content:center;overflow:hidden;border:1px solid var(--b2);border-radius:var(--radius-md);background:var(--bg-3);min-width:0}.strct-mf>img,.strct-mf>video,.strct-mf>canvas{width:100%;height:100%;object-fit:cover;display:block}.strct-mf[data-state=off]{background:#000}.strct-mf__placeholder{display:flex;flex-direction:column;align-items:center;gap:6px;padding:var(--space-2);color:var(--t3);text-align:center}.strct-mf[data-state=off] .strct-mf__placeholder{color:#fff9}.strct-mf[data-state=error] .strct-mf__placeholder{color:var(--critical)}.strct-mf__msg{font-size:var(--text-sm);line-height:1.35}.strct-mf__hit{position:absolute;inset:-1px;padding:0;border:0;background:none;cursor:pointer}.strct-mf__hit:focus-visible{outline:2px solid var(--acc50);outline-offset:2px}.strct-mf--interactive:hover{border-color:var(--b3)}\n"] }]
23262
23262
  }], propDecorators: { ratio: [{ type: i0.Input, args: [{ isSignal: true, alias: "ratio", required: false }] }], state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: false }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], activateLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "activateLabel", required: false }] }], activated: [{ type: i0.Output, args: ["activated"] }] } });
23263
23263
 
23264
+ const WINDOW_LABELS = {
23265
+ minimize: 'Minimize',
23266
+ maximize: 'Maximize',
23267
+ restore: 'Restore',
23268
+ close: 'Close',
23269
+ dock: 'Minimized windows',
23270
+ };
23271
+ let windowCounter = 0;
23272
+ /**
23273
+ * Knows which windows exist, which is on top, and which are minimised — so the
23274
+ * dock can list them and a click can raise one.
23275
+ */
23276
+ class StrctWindowService {
23277
+ topZ = 0;
23278
+ windows = signal([], /* @ts-ignore */
23279
+ ...(ngDevMode ? [{ debugName: "windows" }] : /* istanbul ignore next */ []));
23280
+ /** The minimised ones, in the order they were opened. */
23281
+ minimized = computed(() => this.windows().filter((w) => w.minimized()), /* @ts-ignore */
23282
+ ...(ngDevMode ? [{ debugName: "minimized" }] : /* istanbul ignore next */ []));
23283
+ register(w) {
23284
+ this.windows.update((ws) => [...ws, w]);
23285
+ }
23286
+ unregister(w) {
23287
+ this.windows.update((ws) => ws.filter((x) => x !== w));
23288
+ }
23289
+ /** Raise a window above the others; returns its new stacking offset. */
23290
+ raise() {
23291
+ return ++this.topZ;
23292
+ }
23293
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctWindowService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
23294
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctWindowService, providedIn: 'root' });
23295
+ }
23296
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctWindowService, decorators: [{
23297
+ type: Injectable,
23298
+ args: [{ providedIn: 'root' }]
23299
+ }] });
23300
+ /**
23301
+ * Some work lives in a window beside the page: a VM console stays open while
23302
+ * the operator browses. It can be moved, resized and minimised, and it comes
23303
+ * back from the dock. A modal blocks the page and a drawer is pinned to an
23304
+ * edge — neither is a window.
23305
+ *
23306
+ * <strct-window [(open)]="open" [(minimized)]="min" heading="APP01" palette="dark">
23307
+ * <ng-container strctWindowTitleMeta><strct-badge status="success">Running</strct-badge></ng-container>
23308
+ * <ng-container strctWindowActions>…</ng-container>
23309
+ * …content…
23310
+ * <ng-container strctWindowStatus>…</ng-container>
23311
+ * </strct-window>
23312
+ * <strct-window-dock />
23313
+ */
23314
+ class StrctWindow {
23315
+ /** Whether the window exists on screen (two-way). */
23316
+ open = model(false, /* @ts-ignore */
23317
+ ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
23318
+ /** Minimised to the dock (two-way). */
23319
+ minimized = model(false, /* @ts-ignore */
23320
+ ...(ngDevMode ? [{ debugName: "minimized" }] : /* istanbul ignore next */ []));
23321
+ /** Filling the viewport — not browser fullscreen (two-way). */
23322
+ maximized = model(false, /* @ts-ignore */
23323
+ ...(ngDevMode ? [{ debugName: "maximized" }] : /* istanbul ignore next */ []));
23324
+ /** Position and size in px (two-way); null lets the window place itself. */
23325
+ bounds = model(null, /* @ts-ignore */
23326
+ ...(ngDevMode ? [{ debugName: "bounds" }] : /* istanbul ignore next */ []));
23327
+ /** The title-bar heading, and the window's accessible name. */
23328
+ heading = input('', /* @ts-ignore */
23329
+ ...(ngDevMode ? [{ debugName: "heading" }] : /* istanbul ignore next */ []));
23330
+ /** Corner resize grips. */
23331
+ resizable = input(true, { ...(ngDevMode ? { debugName: "resizable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
23332
+ minWidth = input(480, /* @ts-ignore */
23333
+ ...(ngDevMode ? [{ debugName: "minWidth" }] : /* istanbul ignore next */ []));
23334
+ minHeight = input(320, /* @ts-ignore */
23335
+ ...(ngDevMode ? [{ debugName: "minHeight" }] : /* istanbul ignore next */ []));
23336
+ /** `dark` / `light` force that scheme inside the window (a console is dark). */
23337
+ palette = input('inherit', /* @ts-ignore */
23338
+ ...(ngDevMode ? [{ debugName: "palette" }] : /* istanbul ignore next */ []));
23339
+ /** What a click outside does. A window is not dismissed like a modal. */
23340
+ closeOnOutside = input('none', /* @ts-ignore */
23341
+ ...(ngDevMode ? [{ debugName: "closeOnOutside" }] : /* istanbul ignore next */ []));
23342
+ /** The window's own strings. */
23343
+ labels = input({}, /* @ts-ignore */
23344
+ ...(ngDevMode ? [{ debugName: "labels" }] : /* istanbul ignore next */ []));
23345
+ /** The accessible name of each resize grip. */
23346
+ resizeLabel = input((corner) => `Resize (${corner})`, /* @ts-ignore */
23347
+ ...(ngDevMode ? [{ debugName: "resizeLabel" }] : /* istanbul ignore next */ []));
23348
+ /** The window was closed. */
23349
+ closed = output();
23350
+ CORNERS = ['nw', 'ne', 'sw', 'se'];
23351
+ titleId = `strct-window-${++windowCounter}`;
23352
+ L = computed(() => ({
23353
+ ...WINDOW_LABELS,
23354
+ ...this.labels(),
23355
+ }), /* @ts-ignore */
23356
+ ...(ngDevMode ? [{ debugName: "L" }] : /* istanbul ignore next */ []));
23357
+ service = inject(StrctWindowService);
23358
+ doc = inject(DOCUMENT$1);
23359
+ host = inject(ElementRef);
23360
+ zOffset = signal(0, /* @ts-ignore */
23361
+ ...(ngDevMode ? [{ debugName: "zOffset" }] : /* istanbul ignore next */ []));
23362
+ zIndex = computed(() => `calc(var(--z-window) + ${this.zOffset()})`, /* @ts-ignore */
23363
+ ...(ngDevMode ? [{ debugName: "zIndex" }] : /* istanbul ignore next */ []));
23364
+ /** The palette in force outside, so `palette` only swaps the scheme. */
23365
+ hostPalette = computed(() => this.doc.documentElement.getAttribute('data-palette') ?? 'arctic', /* @ts-ignore */
23366
+ ...(ngDevMode ? [{ debugName: "hostPalette" }] : /* istanbul ignore next */ []));
23367
+ /** Where the window is. Defaults to a slightly offset, comfortable box. */
23368
+ fallback = signal({ x: 80, y: 80, width: 720, height: 460 }, /* @ts-ignore */
23369
+ ...(ngDevMode ? [{ debugName: "fallback" }] : /* istanbul ignore next */ []));
23370
+ rect = computed(() => this.bounds() ?? this.fallback(), /* @ts-ignore */
23371
+ ...(ngDevMode ? [{ debugName: "rect" }] : /* istanbul ignore next */ []));
23372
+ restoreTo = null;
23373
+ constructor() {
23374
+ this.service.register(this);
23375
+ effect(() => {
23376
+ if (this.open() && !this.minimized()) {
23377
+ this.restoreTo ??= saveFocusedElement();
23378
+ this.zOffset.set(this.service.raise());
23379
+ queueMicrotask(() => this.focusTitle());
23380
+ }
23381
+ });
23382
+ }
23383
+ /** Raise this window above the others when it is clicked. */
23384
+ focusWindow() {
23385
+ this.zOffset.set(this.service.raise());
23386
+ }
23387
+ focusTitle() {
23388
+ this.host.nativeElement.querySelector('.strct-window__title')?.focus();
23389
+ }
23390
+ minimize() {
23391
+ if (!this.open())
23392
+ return;
23393
+ this.minimized.set(true);
23394
+ restoreFocus(this.restoreTo);
23395
+ }
23396
+ /** Bring a minimised window back and raise it. */
23397
+ restore() {
23398
+ this.minimized.set(false);
23399
+ this.open.set(true);
23400
+ }
23401
+ close() {
23402
+ this.open.set(false);
23403
+ this.minimized.set(false);
23404
+ this.closed.emit();
23405
+ restoreFocus(this.restoreTo);
23406
+ this.restoreTo = null;
23407
+ }
23408
+ // ── Moving ───────────────────────────────────────────────────────────────
23409
+ dragFrom = null;
23410
+ onMove = (e) => this.dragMove(e);
23411
+ onUp = () => this.dragEnd();
23412
+ onDragStart(event) {
23413
+ if (event.target.closest('button'))
23414
+ return;
23415
+ if (this.maximized())
23416
+ return;
23417
+ event.preventDefault();
23418
+ this.dragFrom = { x: event.clientX, y: event.clientY, rect: this.rect() };
23419
+ this.doc.addEventListener('pointermove', this.onMove);
23420
+ this.doc.addEventListener('pointerup', this.onUp);
23421
+ this.doc.addEventListener('pointercancel', this.onUp);
23422
+ }
23423
+ dragMove(event) {
23424
+ const from = this.dragFrom;
23425
+ if (!from)
23426
+ return;
23427
+ this.setRect({
23428
+ ...from.rect,
23429
+ x: from.rect.x + (event.clientX - from.x),
23430
+ y: from.rect.y + (event.clientY - from.y),
23431
+ });
23432
+ }
23433
+ dragEnd() {
23434
+ this.dragFrom = null;
23435
+ this.doc.removeEventListener('pointermove', this.onMove);
23436
+ this.doc.removeEventListener('pointerup', this.onUp);
23437
+ this.doc.removeEventListener('pointercancel', this.onUp);
23438
+ }
23439
+ /** Alt+arrows move the window; Escape minimises it. */
23440
+ onTitleKeydown(event) {
23441
+ if (!event.altKey)
23442
+ return;
23443
+ const step = event.shiftKey ? 64 : 16;
23444
+ const r = this.rect();
23445
+ const moves = {
23446
+ ArrowLeft: { x: r.x - step },
23447
+ ArrowRight: { x: r.x + step },
23448
+ ArrowUp: { y: r.y - step },
23449
+ ArrowDown: { y: r.y + step },
23450
+ };
23451
+ const move = moves[event.key];
23452
+ if (!move)
23453
+ return;
23454
+ event.preventDefault();
23455
+ this.setRect({ ...r, ...move });
23456
+ }
23457
+ // ── Resizing ─────────────────────────────────────────────────────────────
23458
+ resizeFrom = null;
23459
+ onResizeMove = (e) => this.resizeMove(e);
23460
+ onResizeUp = () => this.resizeEnd();
23461
+ onResizeStart(event, corner) {
23462
+ event.preventDefault();
23463
+ event.stopPropagation();
23464
+ this.resizeFrom = { x: event.clientX, y: event.clientY, rect: this.rect(), corner };
23465
+ this.doc.addEventListener('pointermove', this.onResizeMove);
23466
+ this.doc.addEventListener('pointerup', this.onResizeUp);
23467
+ this.doc.addEventListener('pointercancel', this.onResizeUp);
23468
+ }
23469
+ resizeMove(event) {
23470
+ const from = this.resizeFrom;
23471
+ if (!from)
23472
+ return;
23473
+ this.setRect(this.resized(from.rect, from.corner, event.clientX - from.x, event.clientY - from.y));
23474
+ }
23475
+ resizeEnd() {
23476
+ this.resizeFrom = null;
23477
+ this.doc.removeEventListener('pointermove', this.onResizeMove);
23478
+ this.doc.removeEventListener('pointerup', this.onResizeUp);
23479
+ this.doc.removeEventListener('pointercancel', this.onResizeUp);
23480
+ }
23481
+ /** Arrows resize by 16px, Shift+arrows by 64px. */
23482
+ onResizeKeydown(event, corner) {
23483
+ const step = event.shiftKey ? 64 : 16;
23484
+ const deltas = {
23485
+ ArrowLeft: [-step, 0],
23486
+ ArrowRight: [step, 0],
23487
+ ArrowUp: [0, -step],
23488
+ ArrowDown: [0, step],
23489
+ };
23490
+ const delta = deltas[event.key];
23491
+ if (!delta)
23492
+ return;
23493
+ event.preventDefault();
23494
+ this.setRect(this.resized(this.rect(), corner, delta[0], delta[1]));
23495
+ }
23496
+ /**
23497
+ * A corner drag moves the two edges it touches: the west and north edges move
23498
+ * the window's origin as well as its size, so the opposite corner stays put.
23499
+ */
23500
+ resized(rect, corner, dx, dy) {
23501
+ const west = corner.includes('w');
23502
+ const north = corner.includes('n');
23503
+ const width = Math.max(this.minWidth(), rect.width + (west ? -dx : dx));
23504
+ const height = Math.max(this.minHeight(), rect.height + (north ? -dy : dy));
23505
+ return {
23506
+ x: west ? rect.x + (rect.width - width) : rect.x,
23507
+ y: north ? rect.y + (rect.height - height) : rect.y,
23508
+ width,
23509
+ height,
23510
+ };
23511
+ }
23512
+ setRect(next) {
23513
+ if (this.bounds())
23514
+ this.bounds.set(next);
23515
+ else
23516
+ this.fallback.set(next);
23517
+ }
23518
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctWindow, deps: [], target: i0.ɵɵFactoryTarget.Component });
23519
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctWindow, isStandalone: true, selector: "strct-window", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, minimized: { classPropertyName: "minimized", publicName: "minimized", isSignal: true, isRequired: false, transformFunction: null }, maximized: { classPropertyName: "maximized", publicName: "maximized", isSignal: true, isRequired: false, transformFunction: null }, bounds: { classPropertyName: "bounds", publicName: "bounds", isSignal: true, isRequired: false, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, minWidth: { classPropertyName: "minWidth", publicName: "minWidth", isSignal: true, isRequired: false, transformFunction: null }, minHeight: { classPropertyName: "minHeight", publicName: "minHeight", isSignal: true, isRequired: false, transformFunction: null }, palette: { classPropertyName: "palette", publicName: "palette", isSignal: true, isRequired: false, transformFunction: null }, closeOnOutside: { classPropertyName: "closeOnOutside", publicName: "closeOnOutside", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, resizeLabel: { classPropertyName: "resizeLabel", publicName: "resizeLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange", minimized: "minimizedChange", maximized: "maximizedChange", bounds: "boundsChange", closed: "closed" }, host: { classAttribute: "strct-window" }, ngImport: i0, template: `
23520
+ @if (open() && !minimized()) {
23521
+ <div
23522
+ class="strct-window__frame"
23523
+ role="dialog"
23524
+ aria-modal="false"
23525
+ [attr.aria-labelledby]="titleId"
23526
+ [attr.data-palette]="palette() === 'inherit' ? null : hostPalette()"
23527
+ [attr.data-theme]="palette() === 'inherit' ? null : palette()"
23528
+ [style.z-index]="zIndex()"
23529
+ [style.left.px]="maximized() ? null : rect().x"
23530
+ [style.top.px]="maximized() ? null : rect().y"
23531
+ [style.width.px]="maximized() ? null : rect().width"
23532
+ [style.height.px]="maximized() ? null : rect().height"
23533
+ [class.strct-window__frame--max]="maximized()"
23534
+ (pointerdown)="focusWindow()"
23535
+ (keydown.escape)="minimize()"
23536
+ >
23537
+ <!-- The title bar moves the window: by pointer, or with Alt+arrows. -->
23538
+ <div
23539
+ class="strct-window__title"
23540
+ tabindex="0"
23541
+ [attr.aria-label]="heading()"
23542
+ (pointerdown)="onDragStart($event)"
23543
+ (keydown)="onTitleKeydown($event)"
23544
+ (dblclick)="maximized.set(!maximized())"
23545
+ >
23546
+ <span class="strct-window__heading" [id]="titleId">{{ heading() }}</span>
23547
+ <span class="strct-window__meta"><ng-content select="[strctWindowTitleMeta]" /></span>
23548
+ <span class="strct-window__actions"><ng-content select="[strctWindowActions]" /></span>
23549
+ <span class="strct-window__controls">
23550
+ <button
23551
+ type="button"
23552
+ class="strct-window__btn"
23553
+ [attr.aria-label]="L().minimize"
23554
+ (click)="minimize()"
23555
+ >
23556
+ <strct-icon strictName="minus" [size]="14" />
23557
+ </button>
23558
+ <button
23559
+ type="button"
23560
+ class="strct-window__btn"
23561
+ [attr.aria-label]="maximized() ? L().restore : L().maximize"
23562
+ (click)="maximized.set(!maximized())"
23563
+ >
23564
+ <strct-icon
23565
+ [strictName]="maximized() ? 'exitFullscreen' : 'fullscreen'"
23566
+ [size]="13"
23567
+ />
23568
+ </button>
23569
+ <button
23570
+ type="button"
23571
+ class="strct-window__btn strct-window__btn--close"
23572
+ [attr.aria-label]="L().close"
23573
+ (click)="close()"
23574
+ >
23575
+ <strct-icon strictName="close" [size]="14" />
23576
+ </button>
23577
+ </span>
23578
+ </div>
23579
+
23580
+ <div class="strct-window__body"><ng-content /></div>
23581
+ <div class="strct-window__status"><ng-content select="[strctWindowStatus]" /></div>
23582
+
23583
+ @if (resizable() && !maximized()) {
23584
+ <!-- Focusable, so a window can be resized without a pointer. -->
23585
+ @for (corner of CORNERS; track corner) {
23586
+ <button
23587
+ type="button"
23588
+ class="strct-window__rz strct-window__rz--{{ corner }}"
23589
+ [attr.aria-label]="resizeLabel()(corner)"
23590
+ (pointerdown)="onResizeStart($event, corner)"
23591
+ (keydown)="onResizeKeydown($event, corner)"
23592
+ ></button>
23593
+ }
23594
+ }
23595
+ </div>
23596
+ }
23597
+ `, isInline: true, styles: [".strct-window{display:contents}.strct-window__frame{position:fixed;display:flex;flex-direction:column;min-width:0;border:1px solid var(--b2);border-radius:var(--radius-lg);background:var(--bg-1);color:var(--t1);box-shadow:var(--shadow-overlay, 0 12px 40px rgba(0, 0, 0, .32));overflow:hidden}.strct-window__frame--max{inset:var(--space-3);width:auto;height:auto}.strct-window__title{display:flex;align-items:center;gap:var(--space-2);padding:6px 6px 6px var(--space-3);border-block-end:1px solid var(--b1);background:var(--bg-2);cursor:move;-webkit-user-select:none;user-select:none;touch-action:none}.strct-window__title:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-window__heading{font-size:var(--text-sm);font-weight:600;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.strct-window__meta,.strct-window__actions{display:inline-flex;align-items:center;gap:6px}.strct-window__actions{margin-inline-start:auto}.strct-window__controls{display:inline-flex;align-items:center;gap:2px;flex:none}.strct-window__btn{display:inline-flex;padding:4px;border:0;border-radius:var(--radius-sm);background:transparent;color:var(--t2);cursor:pointer}.strct-window__btn:hover{background:var(--bg-3);color:var(--t1)}.strct-window__btn--close:hover{background:var(--critical-bg);color:var(--critical)}.strct-window__body{flex:1;min-height:0;overflow:auto}.strct-window__status:empty{display:none}.strct-window__status{border-block-start:1px solid var(--b1);padding:4px var(--space-3);font-size:var(--text-sm);color:var(--t3);background:var(--bg-2)}.strct-window__rz{position:absolute;width:14px;height:14px;padding:0;border:0;background:transparent}.strct-window__rz:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-window__rz--nw{inset-block-start:0;inset-inline-start:0;cursor:nwse-resize}.strct-window__rz--ne{inset-block-start:0;inset-inline-end:0;cursor:nesw-resize}.strct-window__rz--sw{inset-block-end:0;inset-inline-start:0;cursor:nesw-resize}.strct-window__rz--se{inset-block-end:0;inset-inline-end:0;cursor:nwse-resize}\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 });
23598
+ }
23599
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctWindow, decorators: [{
23600
+ type: Component,
23601
+ args: [{ selector: 'strct-window', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [StrctIcon], template: `
23602
+ @if (open() && !minimized()) {
23603
+ <div
23604
+ class="strct-window__frame"
23605
+ role="dialog"
23606
+ aria-modal="false"
23607
+ [attr.aria-labelledby]="titleId"
23608
+ [attr.data-palette]="palette() === 'inherit' ? null : hostPalette()"
23609
+ [attr.data-theme]="palette() === 'inherit' ? null : palette()"
23610
+ [style.z-index]="zIndex()"
23611
+ [style.left.px]="maximized() ? null : rect().x"
23612
+ [style.top.px]="maximized() ? null : rect().y"
23613
+ [style.width.px]="maximized() ? null : rect().width"
23614
+ [style.height.px]="maximized() ? null : rect().height"
23615
+ [class.strct-window__frame--max]="maximized()"
23616
+ (pointerdown)="focusWindow()"
23617
+ (keydown.escape)="minimize()"
23618
+ >
23619
+ <!-- The title bar moves the window: by pointer, or with Alt+arrows. -->
23620
+ <div
23621
+ class="strct-window__title"
23622
+ tabindex="0"
23623
+ [attr.aria-label]="heading()"
23624
+ (pointerdown)="onDragStart($event)"
23625
+ (keydown)="onTitleKeydown($event)"
23626
+ (dblclick)="maximized.set(!maximized())"
23627
+ >
23628
+ <span class="strct-window__heading" [id]="titleId">{{ heading() }}</span>
23629
+ <span class="strct-window__meta"><ng-content select="[strctWindowTitleMeta]" /></span>
23630
+ <span class="strct-window__actions"><ng-content select="[strctWindowActions]" /></span>
23631
+ <span class="strct-window__controls">
23632
+ <button
23633
+ type="button"
23634
+ class="strct-window__btn"
23635
+ [attr.aria-label]="L().minimize"
23636
+ (click)="minimize()"
23637
+ >
23638
+ <strct-icon strictName="minus" [size]="14" />
23639
+ </button>
23640
+ <button
23641
+ type="button"
23642
+ class="strct-window__btn"
23643
+ [attr.aria-label]="maximized() ? L().restore : L().maximize"
23644
+ (click)="maximized.set(!maximized())"
23645
+ >
23646
+ <strct-icon
23647
+ [strictName]="maximized() ? 'exitFullscreen' : 'fullscreen'"
23648
+ [size]="13"
23649
+ />
23650
+ </button>
23651
+ <button
23652
+ type="button"
23653
+ class="strct-window__btn strct-window__btn--close"
23654
+ [attr.aria-label]="L().close"
23655
+ (click)="close()"
23656
+ >
23657
+ <strct-icon strictName="close" [size]="14" />
23658
+ </button>
23659
+ </span>
23660
+ </div>
23661
+
23662
+ <div class="strct-window__body"><ng-content /></div>
23663
+ <div class="strct-window__status"><ng-content select="[strctWindowStatus]" /></div>
23664
+
23665
+ @if (resizable() && !maximized()) {
23666
+ <!-- Focusable, so a window can be resized without a pointer. -->
23667
+ @for (corner of CORNERS; track corner) {
23668
+ <button
23669
+ type="button"
23670
+ class="strct-window__rz strct-window__rz--{{ corner }}"
23671
+ [attr.aria-label]="resizeLabel()(corner)"
23672
+ (pointerdown)="onResizeStart($event, corner)"
23673
+ (keydown)="onResizeKeydown($event, corner)"
23674
+ ></button>
23675
+ }
23676
+ }
23677
+ </div>
23678
+ }
23679
+ `, host: { class: 'strct-window' }, styles: [".strct-window{display:contents}.strct-window__frame{position:fixed;display:flex;flex-direction:column;min-width:0;border:1px solid var(--b2);border-radius:var(--radius-lg);background:var(--bg-1);color:var(--t1);box-shadow:var(--shadow-overlay, 0 12px 40px rgba(0, 0, 0, .32));overflow:hidden}.strct-window__frame--max{inset:var(--space-3);width:auto;height:auto}.strct-window__title{display:flex;align-items:center;gap:var(--space-2);padding:6px 6px 6px var(--space-3);border-block-end:1px solid var(--b1);background:var(--bg-2);cursor:move;-webkit-user-select:none;user-select:none;touch-action:none}.strct-window__title:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-window__heading{font-size:var(--text-sm);font-weight:600;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.strct-window__meta,.strct-window__actions{display:inline-flex;align-items:center;gap:6px}.strct-window__actions{margin-inline-start:auto}.strct-window__controls{display:inline-flex;align-items:center;gap:2px;flex:none}.strct-window__btn{display:inline-flex;padding:4px;border:0;border-radius:var(--radius-sm);background:transparent;color:var(--t2);cursor:pointer}.strct-window__btn:hover{background:var(--bg-3);color:var(--t1)}.strct-window__btn--close:hover{background:var(--critical-bg);color:var(--critical)}.strct-window__body{flex:1;min-height:0;overflow:auto}.strct-window__status:empty{display:none}.strct-window__status{border-block-start:1px solid var(--b1);padding:4px var(--space-3);font-size:var(--text-sm);color:var(--t3);background:var(--bg-2)}.strct-window__rz{position:absolute;width:14px;height:14px;padding:0;border:0;background:transparent}.strct-window__rz:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-window__rz--nw{inset-block-start:0;inset-inline-start:0;cursor:nwse-resize}.strct-window__rz--ne{inset-block-start:0;inset-inline-end:0;cursor:nesw-resize}.strct-window__rz--sw{inset-block-end:0;inset-inline-start:0;cursor:nesw-resize}.strct-window__rz--se{inset-block-end:0;inset-inline-end:0;cursor:nwse-resize}\n"] }]
23680
+ }], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], minimized: [{ type: i0.Input, args: [{ isSignal: true, alias: "minimized", required: false }] }, { type: i0.Output, args: ["minimizedChange"] }], maximized: [{ type: i0.Input, args: [{ isSignal: true, alias: "maximized", required: false }] }, { type: i0.Output, args: ["maximizedChange"] }], bounds: [{ type: i0.Input, args: [{ isSignal: true, alias: "bounds", required: false }] }, { type: i0.Output, args: ["boundsChange"] }], heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: false }] }], resizable: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizable", required: false }] }], minWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "minWidth", required: false }] }], minHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "minHeight", required: false }] }], palette: [{ type: i0.Input, args: [{ isSignal: true, alias: "palette", required: false }] }], closeOnOutside: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnOutside", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }], resizeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizeLabel", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
23681
+ /**
23682
+ * Where minimised windows wait. Put it in a toolbar or a status bar; each entry
23683
+ * restores its window, and its × closes it.
23684
+ */
23685
+ class StrctWindowDock {
23686
+ service = inject(StrctWindowService);
23687
+ /** The dock's accessible name. */
23688
+ label = input('Minimized windows', /* @ts-ignore */
23689
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
23690
+ /** The name of each chip's close button. */
23691
+ closeLabel = input((heading) => `Close ${heading}`, /* @ts-ignore */
23692
+ ...(ngDevMode ? [{ debugName: "closeLabel" }] : /* istanbul ignore next */ []));
23693
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctWindowDock, deps: [], target: i0.ɵɵFactoryTarget.Component });
23694
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctWindowDock, isStandalone: true, selector: "strct-window-dock", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "group" }, properties: { "attr.aria-label": "label()" }, classAttribute: "strct-windock" }, ngImport: i0, template: `
23695
+ @for (w of service.minimized(); track w) {
23696
+ <span class="strct-windock__chip">
23697
+ <button type="button" class="strct-windock__open" (click)="w.restore()">
23698
+ {{ w.heading() }}
23699
+ </button>
23700
+ <button
23701
+ type="button"
23702
+ class="strct-windock__close"
23703
+ [attr.aria-label]="closeLabel()(w.heading())"
23704
+ (click)="w.close()"
23705
+ >
23706
+ <strct-icon strictName="close" [size]="11" />
23707
+ </button>
23708
+ </span>
23709
+ }
23710
+ `, isInline: true, styles: [".strct-windock{display:inline-flex;align-items:center;gap:6px}.strct-windock__chip{display:inline-flex;align-items:center;gap:2px;padding-inline:8px 4px;border:1px solid var(--b2);border-radius:var(--radius-full, 999px);background:var(--bg-1);font-size:12px}.strct-windock__open,.strct-windock__close{border:0;background:none;color:inherit;font:inherit;cursor:pointer;padding:3px 2px;border-radius:var(--radius-sm)}.strct-windock__open:hover{color:var(--acc)}.strct-windock__close{display:inline-flex;color:var(--t3)}.strct-windock__close:hover{color:var(--critical)}.strct-windock__open:focus-visible,.strct-windock__close:focus-visible{outline:2px solid var(--acc50);outline-offset:1px}\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 });
23711
+ }
23712
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctWindowDock, decorators: [{
23713
+ type: Component,
23714
+ args: [{ selector: 'strct-window-dock', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [StrctIcon], template: `
23715
+ @for (w of service.minimized(); track w) {
23716
+ <span class="strct-windock__chip">
23717
+ <button type="button" class="strct-windock__open" (click)="w.restore()">
23718
+ {{ w.heading() }}
23719
+ </button>
23720
+ <button
23721
+ type="button"
23722
+ class="strct-windock__close"
23723
+ [attr.aria-label]="closeLabel()(w.heading())"
23724
+ (click)="w.close()"
23725
+ >
23726
+ <strct-icon strictName="close" [size]="11" />
23727
+ </button>
23728
+ </span>
23729
+ }
23730
+ `, host: {
23731
+ class: 'strct-windock',
23732
+ role: 'group',
23733
+ '[attr.aria-label]': 'label()',
23734
+ }, styles: [".strct-windock{display:inline-flex;align-items:center;gap:6px}.strct-windock__chip{display:inline-flex;align-items:center;gap:2px;padding-inline:8px 4px;border:1px solid var(--b2);border-radius:var(--radius-full, 999px);background:var(--bg-1);font-size:12px}.strct-windock__open,.strct-windock__close{border:0;background:none;color:inherit;font:inherit;cursor:pointer;padding:3px 2px;border-radius:var(--radius-sm)}.strct-windock__open:hover{color:var(--acc)}.strct-windock__close{display:inline-flex;color:var(--t3)}.strct-windock__close:hover{color:var(--critical)}.strct-windock__open:focus-visible,.strct-windock__close:focus-visible{outline:2px solid var(--acc50);outline-offset:1px}\n"] }]
23735
+ }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], closeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeLabel", required: false }] }] } });
23736
+
23264
23737
  /**
23265
23738
  * A value change, as one phrase: "v10.27 → v10.28". The old value is muted, the
23266
23739
  * arrow is the library's, the new one is emphasised — and assistive tech hears
@@ -25177,5 +25650,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
25177
25650
  * Generated bundle index. Do not edit.
25178
25651
  */
25179
25652
 
25180
- 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, StrctChange, 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, StrctFlowNodeTemplate, StrctFooter, StrctGauge, StrctHeader, StrctHeatmap, StrctHero, StrctHotkeysHelp, StrctHotkeysService, StrctIcon, StrctInlineEdit, StrctInput, StrctInputMask, StrctInputOtp, StrctKbd, StrctKnob, StrctLegend, StrctList, StrctListItem, StrctListItemDescription, StrctListItemLeading, StrctListItemMeta, StrctListItemTrailing, StrctLiveIndicator, StrctLogViewer, StrctLogin, StrctMediaFrame, 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, StrctReorderGroup, StrctReorderHandle, StrctReorderItem, StrctResizeHandle, StrctRowDetailDef, StrctSearchbox, StrctSectionHeader, StrctSectionHeaderActions, StrctSectionHeaderMeta, StrctSectionMenu, StrctSegmented, StrctSelect, StrctShell, StrctShellService, StrctSiPipe, StrctSignpost, StrctSignpostTrigger, StrctSkeleton, StrctSparkline, StrctSpeedDial, StrctSpinner, StrctSplitButton, StrctSplitter, StrctStack, StrctStackItem, StrctStatusDot, StrctStep, StrctStepAction, StrctSteps, 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 };
25653
+ 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, StrctChange, 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, StrctFlowNodeTemplate, StrctFooter, StrctGauge, StrctHeader, StrctHeatmap, StrctHero, StrctHotkeysHelp, StrctHotkeysService, StrctIcon, StrctInlineEdit, StrctInput, StrctInputMask, StrctInputOtp, StrctKbd, StrctKnob, StrctLegend, StrctList, StrctListItem, StrctListItemDescription, StrctListItemLeading, StrctListItemMeta, StrctListItemTrailing, StrctLiveIndicator, StrctLogViewer, StrctLogin, StrctMediaFrame, 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, StrctReorderGroup, StrctReorderHandle, StrctReorderItem, StrctResizeHandle, StrctRowDetailDef, StrctSearchbox, StrctSectionHeader, StrctSectionHeaderActions, StrctSectionHeaderMeta, StrctSectionMenu, StrctSegmented, StrctSelect, StrctShell, StrctShellService, StrctSiPipe, StrctSignpost, StrctSignpostTrigger, StrctSkeleton, StrctSparkline, StrctSpeedDial, StrctSpinner, StrctSplitButton, StrctSplitter, StrctStack, StrctStackItem, StrctStatusDot, StrctStep, StrctStepAction, StrctSteps, 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, StrctWindow, StrctWindowDock, StrctWindowService, StrctWizard, StrctWizardAside, focusFirstIn, keepTabInside, lockBodyScroll, parseAnsi, provideStrctWizardDefaults, registerStrctIcon, restoreFocus, saveFocusedElement, strctComputeDiff, strctDpPad, strctFormatBytes, strctFormatDuration, strctFormatRate, strctFormatSi, strctValidationIcon, strctValidationTone, unlockBodyScroll };
25181
25654
  //# sourceMappingURL=akcelik-strct.mjs.map