@akcelik/strct 0.5.31 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, DOCUMENT, signal, computed, Injectable, input, ViewEncapsulation, ChangeDetectionStrategy, Component, ElementRef, NgZone, afterNextRender, Directive, booleanAttribute, output, HostListener, model, contentChildren, effect, ApplicationRef, EnvironmentInjector, createComponent, DestroyRef, forwardRef, TemplateRef, contentChild, Renderer2 } from '@angular/core';
2
+ import { inject, DOCUMENT, signal, computed, Injectable, input, ViewEncapsulation, ChangeDetectionStrategy, Component, ElementRef, NgZone, afterNextRender, Directive, model, output, booleanAttribute, HostListener, contentChildren, effect, ApplicationRef, EnvironmentInjector, createComponent, DestroyRef, contentChild, forwardRef, TemplateRef, Renderer2 } from '@angular/core';
3
3
  import { DomSanitizer } from '@angular/platform-browser';
4
4
  import { DOCUMENT as DOCUMENT$1, NgTemplateOutlet } from '@angular/common';
5
5
  import { NG_VALUE_ACCESSOR } from '@angular/forms';
@@ -793,6 +793,142 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
793
793
  }, styles: [".strct-nav-item{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:7px;cursor:pointer;color:var(--t2);transition:background .14s ease,color .14s ease}.strct-nav-item:hover{background:var(--bg-3);color:var(--t1)}.strct-nav-item--active{background:var(--acc-m);color:var(--acc)}.strct-nav-item:focus-visible{outline:2px solid var(--acc50);outline-offset:1px}\n"] }]
794
794
  }], propDecorators: { active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }] } });
795
795
 
796
+ /**
797
+ * Collapsible, data-driven primary navigation rail for an application shell.
798
+ * Each item is an icon + label + optional status badge; collapsing shrinks it to
799
+ * an icon-only rail (badges become dots, labels become tooltips).
800
+ *
801
+ * <strct-rail [items]="navItems" [(activeId)]="section" [(collapsed)]="railOff"
802
+ * (select)="go($event)" />
803
+ */
804
+ class StrctRail {
805
+ /** Navigation entries. */
806
+ items = input.required(...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
807
+ /** Currently-active item id (two-way). */
808
+ activeId = model(null, ...(ngDevMode ? [{ debugName: "activeId" }] : /* istanbul ignore next */ []));
809
+ /** Collapsed (icon-only) state (two-way). */
810
+ collapsed = model(false, ...(ngDevMode ? [{ debugName: "collapsed" }] : /* istanbul ignore next */ []));
811
+ /** Show the collapse toggle at the foot of the rail. */
812
+ collapsible = input(true, ...(ngDevMode ? [{ debugName: "collapsible" }] : /* istanbul ignore next */ []));
813
+ /** Accessible label for the nav landmark. */
814
+ ariaLabel = input('Primary', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
815
+ /** Emitted when an item is chosen. */
816
+ select = output();
817
+ pick(item) {
818
+ if (item.disabled)
819
+ return;
820
+ this.activeId.set(item.id);
821
+ this.select.emit(item);
822
+ }
823
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctRail, deps: [], target: i0.ɵɵFactoryTarget.Component });
824
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: StrctRail, isStandalone: true, selector: "strct-rail", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, activeId: { classPropertyName: "activeId", publicName: "activeId", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, collapsible: { classPropertyName: "collapsible", publicName: "collapsible", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeId: "activeIdChange", collapsed: "collapsedChange", select: "select" }, host: { properties: { "class.strct-rail--collapsed": "collapsed()" }, classAttribute: "strct-rail" }, ngImport: i0, template: `
825
+ <nav class="strct-rail__nav" [attr.aria-label]="ariaLabel()">
826
+ @for (item of items(); track item.id) {
827
+ <button
828
+ type="button"
829
+ class="strct-rail__item"
830
+ [class.strct-rail__item--active]="item.id === activeId()"
831
+ [disabled]="item.disabled"
832
+ [attr.aria-current]="item.id === activeId() ? 'page' : null"
833
+ [attr.title]="collapsed() ? item.label : null"
834
+ (click)="pick(item)"
835
+ >
836
+ <strct-icon
837
+ class="strct-rail__icon"
838
+ [name]="item.icon"
839
+ [size]="18"
840
+ [strokeWidth]="1.6"
841
+ />
842
+ @if (!collapsed()) {
843
+ <span class="strct-rail__label">{{ item.label }}</span>
844
+ }
845
+ @if (item.badge !== undefined && item.badge !== null && item.badge !== '') {
846
+ <span
847
+ class="strct-rail__badge strct-rail__badge--{{ item.badgeStatus ?? 'accent' }}"
848
+ [class.strct-rail__badge--dot]="collapsed()"
849
+ >
850
+ @if (!collapsed()) {
851
+ {{ item.badge }}
852
+ }
853
+ </span>
854
+ }
855
+ </button>
856
+ }
857
+ </nav>
858
+
859
+ @if (collapsible()) {
860
+ <button
861
+ type="button"
862
+ class="strct-rail__toggle"
863
+ [attr.aria-label]="collapsed() ? 'Expand navigation' : 'Collapse navigation'"
864
+ [attr.aria-expanded]="!collapsed()"
865
+ (click)="collapsed.set(!collapsed())"
866
+ >
867
+ <strct-icon class="strct-rail__toggle-icon" name="chevronRight" [size]="16" />
868
+ @if (!collapsed()) {
869
+ <span class="strct-rail__toggle-label">Collapse</span>
870
+ }
871
+ </button>
872
+ }
873
+ `, isInline: true, styles: [".strct-rail{display:flex;flex-direction:column;width:232px;flex-shrink:0;background:var(--bg-1);border-right:1px solid var(--b2);overflow:hidden;transition:width .16s ease}.strct-rail--collapsed{width:60px}.strct-rail__nav{flex:1;display:flex;flex-direction:column;gap:2px;padding:8px;overflow-y:auto}.strct-rail__item{position:relative;display:flex;align-items:center;gap:11px;width:100%;padding:8px 10px;border:0;border-radius:8px;background:transparent;color:var(--t2);cursor:pointer;font-size:13.5px;font-family:var(--font);text-align:left;white-space:nowrap;transition:background .14s ease,color .14s ease}.strct-rail--collapsed .strct-rail__item{justify-content:center;padding:8px}.strct-rail__item:hover:not(:disabled){background:var(--bg-3);color:var(--t1)}.strct-rail__item--active{background:var(--acc-m);color:var(--acc)}.strct-rail__item--active .strct-rail__icon{color:var(--acc)}.strct-rail__item:disabled{opacity:.5;cursor:not-allowed}.strct-rail__item:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-rail__icon{flex-shrink:0}.strct-rail__label{flex:1;overflow:hidden;text-overflow:ellipsis}.strct-rail__badge{flex-shrink:0;min-width:18px;height:18px;padding:0 5px;display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:600;line-height:1;border-radius:9px;font-variant-numeric:tabular-nums}.strct-rail__badge--dot{position:absolute;top:5px;right:7px;min-width:8px;width:8px;height:8px;padding:0;border-radius:50%}.strct-rail__badge--accent{background:var(--acc-m);color:var(--acc)}.strct-rail__badge--success{background:var(--success-bg);color:var(--success)}.strct-rail__badge--warning{background:var(--warning-bg);color:var(--warning)}.strct-rail__badge--critical{background:var(--critical-bg);color:var(--critical)}.strct-rail__badge--dot.strct-rail__badge--accent{background:var(--acc)}.strct-rail__badge--dot.strct-rail__badge--success{background:var(--success)}.strct-rail__badge--dot.strct-rail__badge--warning{background:var(--warning)}.strct-rail__badge--dot.strct-rail__badge--critical{background:var(--critical)}.strct-rail__toggle{display:flex;align-items:center;gap:10px;padding:9px 14px;border:0;border-top:1px solid var(--b1);background:transparent;color:var(--t3);cursor:pointer;font-size:12.5px;font-family:var(--font)}.strct-rail--collapsed .strct-rail__toggle{justify-content:center;padding:9px}.strct-rail__toggle:hover{color:var(--t1);background:var(--bg-3)}.strct-rail__toggle-icon{transition:transform .16s ease}.strct-rail:not(.strct-rail--collapsed) .strct-rail__toggle-icon{transform:rotate(180deg)}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "size", "strokeWidth", "badge", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
874
+ }
875
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctRail, decorators: [{
876
+ type: Component,
877
+ args: [{ selector: 'strct-rail', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [StrctIcon], template: `
878
+ <nav class="strct-rail__nav" [attr.aria-label]="ariaLabel()">
879
+ @for (item of items(); track item.id) {
880
+ <button
881
+ type="button"
882
+ class="strct-rail__item"
883
+ [class.strct-rail__item--active]="item.id === activeId()"
884
+ [disabled]="item.disabled"
885
+ [attr.aria-current]="item.id === activeId() ? 'page' : null"
886
+ [attr.title]="collapsed() ? item.label : null"
887
+ (click)="pick(item)"
888
+ >
889
+ <strct-icon
890
+ class="strct-rail__icon"
891
+ [name]="item.icon"
892
+ [size]="18"
893
+ [strokeWidth]="1.6"
894
+ />
895
+ @if (!collapsed()) {
896
+ <span class="strct-rail__label">{{ item.label }}</span>
897
+ }
898
+ @if (item.badge !== undefined && item.badge !== null && item.badge !== '') {
899
+ <span
900
+ class="strct-rail__badge strct-rail__badge--{{ item.badgeStatus ?? 'accent' }}"
901
+ [class.strct-rail__badge--dot]="collapsed()"
902
+ >
903
+ @if (!collapsed()) {
904
+ {{ item.badge }}
905
+ }
906
+ </span>
907
+ }
908
+ </button>
909
+ }
910
+ </nav>
911
+
912
+ @if (collapsible()) {
913
+ <button
914
+ type="button"
915
+ class="strct-rail__toggle"
916
+ [attr.aria-label]="collapsed() ? 'Expand navigation' : 'Collapse navigation'"
917
+ [attr.aria-expanded]="!collapsed()"
918
+ (click)="collapsed.set(!collapsed())"
919
+ >
920
+ <strct-icon class="strct-rail__toggle-icon" name="chevronRight" [size]="16" />
921
+ @if (!collapsed()) {
922
+ <span class="strct-rail__toggle-label">Collapse</span>
923
+ }
924
+ </button>
925
+ }
926
+ `, host: {
927
+ class: 'strct-rail',
928
+ '[class.strct-rail--collapsed]': 'collapsed()',
929
+ }, styles: [".strct-rail{display:flex;flex-direction:column;width:232px;flex-shrink:0;background:var(--bg-1);border-right:1px solid var(--b2);overflow:hidden;transition:width .16s ease}.strct-rail--collapsed{width:60px}.strct-rail__nav{flex:1;display:flex;flex-direction:column;gap:2px;padding:8px;overflow-y:auto}.strct-rail__item{position:relative;display:flex;align-items:center;gap:11px;width:100%;padding:8px 10px;border:0;border-radius:8px;background:transparent;color:var(--t2);cursor:pointer;font-size:13.5px;font-family:var(--font);text-align:left;white-space:nowrap;transition:background .14s ease,color .14s ease}.strct-rail--collapsed .strct-rail__item{justify-content:center;padding:8px}.strct-rail__item:hover:not(:disabled){background:var(--bg-3);color:var(--t1)}.strct-rail__item--active{background:var(--acc-m);color:var(--acc)}.strct-rail__item--active .strct-rail__icon{color:var(--acc)}.strct-rail__item:disabled{opacity:.5;cursor:not-allowed}.strct-rail__item:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-rail__icon{flex-shrink:0}.strct-rail__label{flex:1;overflow:hidden;text-overflow:ellipsis}.strct-rail__badge{flex-shrink:0;min-width:18px;height:18px;padding:0 5px;display:inline-flex;align-items:center;justify-content:center;font-size:11px;font-weight:600;line-height:1;border-radius:9px;font-variant-numeric:tabular-nums}.strct-rail__badge--dot{position:absolute;top:5px;right:7px;min-width:8px;width:8px;height:8px;padding:0;border-radius:50%}.strct-rail__badge--accent{background:var(--acc-m);color:var(--acc)}.strct-rail__badge--success{background:var(--success-bg);color:var(--success)}.strct-rail__badge--warning{background:var(--warning-bg);color:var(--warning)}.strct-rail__badge--critical{background:var(--critical-bg);color:var(--critical)}.strct-rail__badge--dot.strct-rail__badge--accent{background:var(--acc)}.strct-rail__badge--dot.strct-rail__badge--success{background:var(--success)}.strct-rail__badge--dot.strct-rail__badge--warning{background:var(--warning)}.strct-rail__badge--dot.strct-rail__badge--critical{background:var(--critical)}.strct-rail__toggle{display:flex;align-items:center;gap:10px;padding:9px 14px;border:0;border-top:1px solid var(--b1);background:transparent;color:var(--t3);cursor:pointer;font-size:12.5px;font-family:var(--font)}.strct-rail--collapsed .strct-rail__toggle{justify-content:center;padding:9px}.strct-rail__toggle:hover{color:var(--t1);background:var(--bg-3)}.strct-rail__toggle-icon{transition:transform .16s ease}.strct-rail:not(.strct-rail--collapsed) .strct-rail__toggle-icon{transform:rotate(180deg)}\n"] }]
930
+ }], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], activeId: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeId", required: false }] }, { type: i0.Output, args: ["activeIdChange"] }], collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }, { type: i0.Output, args: ["collapsedChange"] }], collapsible: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsible", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], select: [{ type: i0.Output, args: ["select"] }] } });
931
+
796
932
  /**
797
933
  * Authentication layout. Two modes:
798
934
  * - default: a single centered column (drop a card + form inside).
@@ -1678,47 +1814,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
1678
1814
  }, styles: [".strct-menu-host{display:block}.strct-menu{min-width:180px;padding:4px;background:var(--bg-1);border:1px solid var(--b2);border-radius:7px;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:left}.strct-menu__item:hover:not(:disabled),.strct-menu__item--active:not(:disabled){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(:disabled),.strct-menu__item--critical.strct-menu__item--active:not(:disabled){background:var(--critical-bg)}.strct-menu__item:disabled{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;left:100%;margin-left:2px;z-index:1}.strct-menu__subpanel--flip{left:auto;right:100%;margin-left:0;margin-right:2px}@keyframes strct-menu-in{0%{opacity:0;transform:scale(.97)}}\n"] }]
1679
1815
  }], 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"] }] } });
1680
1816
  /**
1681
- * Right-click (context) menu driven by a data array. Attach to any trigger; the
1682
- * menu portals into `<body>` and runs each item's `action` on selection.
1683
- * <div [strctContextMenu]="menuFor(host)" [strctContextMenuData]="host"
1684
- * (menuSelect)="onPick($event)">…</div>
1817
+ * Imperatively opens the data-driven menu panel, portaled into `<body>`. Shared
1818
+ * by the `[strctContextMenu]` directive (right-click) and any click trigger such
1819
+ * as the datagrid row-action button. Only one menu is open at a time.
1685
1820
  */
1686
- class StrctContextMenuTrigger {
1821
+ class StrctMenuService {
1687
1822
  appRef = inject(ApplicationRef);
1688
1823
  envInjector = inject(EnvironmentInjector);
1689
1824
  zone = inject(NgZone);
1690
1825
  doc = inject(DOCUMENT$1);
1691
- /** Menu items to display. */
1692
- items = input.required({ ...(ngDevMode ? { debugName: "items" } : /* istanbul ignore next */ {}), alias: 'strctContextMenu' });
1693
- /** Arbitrary payload passed to item actions. */
1694
- data = input(undefined, { ...(ngDevMode ? { debugName: "data" } : /* istanbul ignore next */ {}), alias: 'strctContextMenuData' });
1695
- /** Emitted when a menu item is selected. */
1696
- menuSelect = output();
1697
1826
  ref = null;
1698
- onClose = () => this.zone.run(() => this.closeMenu());
1699
- onContextMenu(event) {
1700
- if (!this.items()?.length)
1827
+ open(opts) {
1828
+ this.close();
1829
+ if (!opts.items?.length)
1701
1830
  return;
1702
- event.preventDefault();
1703
- this.openAt(event.clientX, event.clientY);
1704
- }
1705
- openAt(x, y) {
1706
- this.closeMenu();
1707
1831
  const ref = createComponent(StrctMenuPanel, { environmentInjector: this.envInjector });
1708
- ref.setInput('items', this.items());
1709
- ref.setInput('data', this.data());
1710
- ref.setInput('x', x);
1711
- ref.setInput('y', y);
1832
+ ref.setInput('items', opts.items);
1833
+ ref.setInput('data', opts.data);
1834
+ ref.setInput('x', opts.x);
1835
+ ref.setInput('y', opts.y);
1712
1836
  ref.instance.select.subscribe((item) => {
1713
- item.action?.(this.data());
1714
- this.menuSelect.emit(item);
1715
- this.closeMenu();
1837
+ item.action?.(opts.data);
1838
+ opts.onSelect?.(item);
1839
+ this.close();
1716
1840
  });
1717
- ref.instance.close.subscribe(() => this.closeMenu());
1841
+ ref.instance.close.subscribe(() => this.close());
1718
1842
  this.appRef.attachView(ref.hostView);
1719
1843
  this.doc.body.appendChild(ref.location.nativeElement);
1720
1844
  this.ref = ref;
1721
- // Defer global listeners so the opening right-click doesn't immediately close.
1845
+ // Defer global listeners so the opening click doesn't immediately close it.
1722
1846
  setTimeout(() => {
1723
1847
  this.zone.runOutsideAngular(() => {
1724
1848
  this.doc.addEventListener('mousedown', this.onOutside, true);
@@ -1727,12 +1851,13 @@ class StrctContextMenuTrigger {
1727
1851
  });
1728
1852
  });
1729
1853
  }
1854
+ onClose = () => this.zone.run(() => this.close());
1730
1855
  onOutside = (event) => {
1731
1856
  if (this.ref && !this.ref.location.nativeElement.contains(event.target)) {
1732
1857
  this.onClose();
1733
1858
  }
1734
1859
  };
1735
- closeMenu() {
1860
+ close() {
1736
1861
  if (!this.ref)
1737
1862
  return;
1738
1863
  this.doc.removeEventListener('mousedown', this.onOutside, true);
@@ -1742,8 +1867,38 @@ class StrctContextMenuTrigger {
1742
1867
  this.ref.destroy();
1743
1868
  this.ref = null;
1744
1869
  }
1745
- ngOnDestroy() {
1746
- this.closeMenu();
1870
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctMenuService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1871
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctMenuService, providedIn: 'root' });
1872
+ }
1873
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctMenuService, decorators: [{
1874
+ type: Injectable,
1875
+ args: [{ providedIn: 'root' }]
1876
+ }] });
1877
+ /**
1878
+ * Right-click (context) menu driven by a data array. Attach to any trigger; the
1879
+ * menu portals into `<body>` and runs each item's `action` on selection.
1880
+ * <div [strctContextMenu]="menuFor(host)" [strctContextMenuData]="host"
1881
+ * (menuSelect)="onPick($event)">…</div>
1882
+ */
1883
+ class StrctContextMenuTrigger {
1884
+ menu = inject(StrctMenuService);
1885
+ /** Menu items to display. */
1886
+ items = input.required({ ...(ngDevMode ? { debugName: "items" } : /* istanbul ignore next */ {}), alias: 'strctContextMenu' });
1887
+ /** Arbitrary payload passed to item actions. */
1888
+ data = input(undefined, { ...(ngDevMode ? { debugName: "data" } : /* istanbul ignore next */ {}), alias: 'strctContextMenuData' });
1889
+ /** Emitted when a menu item is selected. */
1890
+ menuSelect = output();
1891
+ onContextMenu(event) {
1892
+ if (!this.items()?.length)
1893
+ return;
1894
+ event.preventDefault();
1895
+ this.menu.open({
1896
+ x: event.clientX,
1897
+ y: event.clientY,
1898
+ items: this.items(),
1899
+ data: this.data(),
1900
+ onSelect: (item) => this.menuSelect.emit(item),
1901
+ });
1747
1902
  }
1748
1903
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctContextMenuTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1749
1904
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.16", type: StrctContextMenuTrigger, isStandalone: true, selector: "[strctContextMenu]", inputs: { items: { classPropertyName: "items", publicName: "strctContextMenu", isSignal: true, isRequired: true, transformFunction: null }, data: { classPropertyName: "data", publicName: "strctContextMenuData", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { menuSelect: "menuSelect" }, host: { listeners: { "contextmenu": "onContextMenu($event)" } }, ngImport: i0 });
@@ -2199,6 +2354,130 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
2199
2354
  }, styles: [".strct-modal__overlay{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;padding:var(--space-5);background:#00000080;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px);animation:strct-modal-fade .12s ease}@media(max-width:768px){.strct-modal__overlay{padding:var(--space-3)}}.strct-modal__dialog{width:100%;max-width:min(460px,calc(100vw - 32px));max-height:calc(100vh - 48px);display:flex;flex-direction:column;background:var(--bg-1);border:1px solid var(--b2);border-radius:var(--radius-xl);box-shadow:var(--shadow-elevated);overflow:hidden;animation:strct-modal-rise .14s ease}.strct-modal__dialog--sm{max-width:min(360px,calc(100vw - 32px))}.strct-modal__dialog--lg{max-width:min(720px,calc(100vw - 32px))}.strct-modal__head{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);padding:var(--space-3) var(--space-4);border-bottom:1px solid var(--b1)}.strct-modal__title{font-size:14px;font-weight:600;color:var(--t1)}.strct-modal__close{display:inline-flex;padding:4px;border:0;border-radius:5px;background:transparent;color:var(--t3);cursor:pointer}.strct-modal__close:hover{color:var(--t1);background:var(--bg-3)}.strct-modal__body{padding:var(--space-4);overflow-y:auto;color:var(--t2);font-size:13px}.strct-modal__foot{display:flex;align-items:center;justify-content:flex-end;gap:var(--space-2);padding:var(--space-3) var(--space-4);border-top:1px solid var(--b1);background:var(--bg-2)}@keyframes strct-modal-fade{0%{opacity:0}}@keyframes strct-modal-rise{0%{opacity:0;transform:translateY(8px) scale(.98)}}\n"] }]
2200
2355
  }], ctorParameters: () => [], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], hideFooter: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideFooter", required: false }] }], dismissible: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissible", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
2201
2356
 
2357
+ /** Marks the drawer's footer action area: `<ng-container strctDrawerFooter>…`. */
2358
+ class StrctDrawerFooter {
2359
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctDrawerFooter, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2360
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.16", type: StrctDrawerFooter, isStandalone: true, selector: "[strctDrawerFooter]", ngImport: i0 });
2361
+ }
2362
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctDrawerFooter, decorators: [{
2363
+ type: Directive,
2364
+ args: [{ selector: '[strctDrawerFooter]' }]
2365
+ }] });
2366
+ /**
2367
+ * Slide-out overlay panel anchored to an edge of the viewport — for inspecting
2368
+ * or editing a record without losing the underlying table's scroll/selection.
2369
+ *
2370
+ * <strct-drawer [(open)]="editing" side="end" title="Virtual machine">
2371
+ * … body …
2372
+ * <ng-container strctDrawerFooter>
2373
+ * <button strct-button (click)="editing.set(false)">Cancel</button>
2374
+ * </ng-container>
2375
+ * </strct-drawer>
2376
+ */
2377
+ class StrctDrawer {
2378
+ /** Open state (two-way). */
2379
+ open = model(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
2380
+ /** Edge to anchor to. Defaults to `end` (right in LTR). */
2381
+ side = input('end', ...(ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []));
2382
+ /** Extent along the sliding axis. */
2383
+ size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
2384
+ /** Header title. */
2385
+ title = input('', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
2386
+ /** Show the close button and allow backdrop/Esc dismissal. */
2387
+ dismissable = input(true, { ...(ngDevMode ? { debugName: "dismissable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
2388
+ footerDef = contentChild(StrctDrawerFooter, ...(ngDevMode ? [{ debugName: "footerDef" }] : /* istanbul ignore next */ []));
2389
+ hasFooter = computed(() => !!this.footerDef(), ...(ngDevMode ? [{ debugName: "hasFooter" }] : /* istanbul ignore next */ []));
2390
+ onBackdrop() {
2391
+ if (this.dismissable())
2392
+ this.close();
2393
+ }
2394
+ onEscape() {
2395
+ if (this.dismissable())
2396
+ this.close();
2397
+ }
2398
+ close() {
2399
+ this.open.set(false);
2400
+ }
2401
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctDrawer, deps: [], target: i0.ɵɵFactoryTarget.Component });
2402
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: StrctDrawer, isStandalone: true, selector: "strct-drawer", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, side: { classPropertyName: "side", publicName: "side", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, dismissable: { classPropertyName: "dismissable", publicName: "dismissable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange" }, host: { classAttribute: "strct-drawer-host" }, queries: [{ propertyName: "footerDef", first: true, predicate: StrctDrawerFooter, descendants: true, isSignal: true }], ngImport: i0, template: `
2403
+ @if (open()) {
2404
+ <div
2405
+ class="strct-drawer__backdrop"
2406
+ [class.strct-drawer__backdrop--bare]="!dismissable()"
2407
+ (click)="onBackdrop()"
2408
+ (keydown.escape)="onEscape()"
2409
+ tabindex="-1"
2410
+ ></div>
2411
+ <aside
2412
+ class="strct-drawer strct-drawer--{{ side() }} strct-drawer--{{ size() }}"
2413
+ role="dialog"
2414
+ aria-modal="true"
2415
+ [attr.aria-label]="title() || 'Panel'"
2416
+ >
2417
+ @if (title() || dismissable()) {
2418
+ <header class="strct-drawer__head">
2419
+ <span class="strct-drawer__title">{{ title() }}</span>
2420
+ @if (dismissable()) {
2421
+ <button
2422
+ type="button"
2423
+ class="strct-drawer__close"
2424
+ aria-label="Close"
2425
+ (click)="close()"
2426
+ >
2427
+ <strct-icon name="close" [size]="15" />
2428
+ </button>
2429
+ }
2430
+ </header>
2431
+ }
2432
+ <div class="strct-drawer__body"><ng-content /></div>
2433
+ @if (hasFooter()) {
2434
+ <footer class="strct-drawer__foot"><ng-content select="[strctDrawerFooter]" /></footer>
2435
+ }
2436
+ </aside>
2437
+ }
2438
+ `, isInline: true, styles: [".strct-drawer__backdrop{position:fixed;inset:0;z-index:1100;background:#00000070;-webkit-backdrop-filter:blur(1px);backdrop-filter:blur(1px);animation:strct-drawer-fade .16s ease}.strct-drawer__backdrop--bare{background:transparent;-webkit-backdrop-filter:none;backdrop-filter:none}.strct-drawer{position:fixed;z-index:1101;display:flex;flex-direction:column;background:var(--bg-1);box-shadow:var(--shh)}.strct-drawer--start,.strct-drawer--end{top:0;bottom:0;border-radius:0}.strct-drawer--start{left:0;border-right:1px solid var(--b2);animation:strct-drawer-in-start .18s ease}.strct-drawer--end{right:0;border-left:1px solid var(--b2);animation:strct-drawer-in-end .18s ease}.strct-drawer--top,.strct-drawer--bottom{left:0;right:0}.strct-drawer--top{top:0;border-bottom:1px solid var(--b2);animation:strct-drawer-in-top .18s ease}.strct-drawer--bottom{bottom:0;border-top:1px solid var(--b2);animation:strct-drawer-in-bottom .18s ease}.strct-drawer--start.strct-drawer--sm,.strct-drawer--end.strct-drawer--sm{width:300px}.strct-drawer--start.strct-drawer--md,.strct-drawer--end.strct-drawer--md{width:420px}.strct-drawer--start.strct-drawer--lg,.strct-drawer--end.strct-drawer--lg{width:600px}.strct-drawer--top.strct-drawer--sm,.strct-drawer--bottom.strct-drawer--sm{height:220px}.strct-drawer--top.strct-drawer--md,.strct-drawer--bottom.strct-drawer--md{height:340px}.strct-drawer--top.strct-drawer--lg,.strct-drawer--bottom.strct-drawer--lg{height:480px}.strct-drawer{max-width:100vw;max-height:100vh}.strct-drawer__head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:14px 18px;border-bottom:1px solid var(--b1);flex-shrink:0}.strct-drawer__title{font-size:15px;font-weight:600;color:var(--t1)}.strct-drawer__close{display:inline-flex;padding:4px;border:0;border-radius:5px;background:transparent;color:var(--t3);cursor:pointer;transition:color .14s ease,background .14s ease}.strct-drawer__close:hover{color:var(--t1);background:var(--bg-3)}.strct-drawer__body{flex:1;min-height:0;overflow-y:auto;padding:16px 18px;font-size:13px;color:var(--t1)}.strct-drawer__foot{display:flex;align-items:center;justify-content:flex-end;gap:8px;padding:12px 18px;border-top:1px solid var(--b1);flex-shrink:0}@keyframes strct-drawer-fade{0%{opacity:0}}@keyframes strct-drawer-in-start{0%{transform:translate(-100%)}}@keyframes strct-drawer-in-end{0%{transform:translate(100%)}}@keyframes strct-drawer-in-top{0%{transform:translateY(-100%)}}@keyframes strct-drawer-in-bottom{0%{transform:translateY(100%)}}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "size", "strokeWidth", "badge", "ariaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
2439
+ }
2440
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctDrawer, decorators: [{
2441
+ type: Component,
2442
+ args: [{ selector: 'strct-drawer', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [StrctIcon], template: `
2443
+ @if (open()) {
2444
+ <div
2445
+ class="strct-drawer__backdrop"
2446
+ [class.strct-drawer__backdrop--bare]="!dismissable()"
2447
+ (click)="onBackdrop()"
2448
+ (keydown.escape)="onEscape()"
2449
+ tabindex="-1"
2450
+ ></div>
2451
+ <aside
2452
+ class="strct-drawer strct-drawer--{{ side() }} strct-drawer--{{ size() }}"
2453
+ role="dialog"
2454
+ aria-modal="true"
2455
+ [attr.aria-label]="title() || 'Panel'"
2456
+ >
2457
+ @if (title() || dismissable()) {
2458
+ <header class="strct-drawer__head">
2459
+ <span class="strct-drawer__title">{{ title() }}</span>
2460
+ @if (dismissable()) {
2461
+ <button
2462
+ type="button"
2463
+ class="strct-drawer__close"
2464
+ aria-label="Close"
2465
+ (click)="close()"
2466
+ >
2467
+ <strct-icon name="close" [size]="15" />
2468
+ </button>
2469
+ }
2470
+ </header>
2471
+ }
2472
+ <div class="strct-drawer__body"><ng-content /></div>
2473
+ @if (hasFooter()) {
2474
+ <footer class="strct-drawer__foot"><ng-content select="[strctDrawerFooter]" /></footer>
2475
+ }
2476
+ </aside>
2477
+ }
2478
+ `, host: { class: 'strct-drawer-host' }, styles: [".strct-drawer__backdrop{position:fixed;inset:0;z-index:1100;background:#00000070;-webkit-backdrop-filter:blur(1px);backdrop-filter:blur(1px);animation:strct-drawer-fade .16s ease}.strct-drawer__backdrop--bare{background:transparent;-webkit-backdrop-filter:none;backdrop-filter:none}.strct-drawer{position:fixed;z-index:1101;display:flex;flex-direction:column;background:var(--bg-1);box-shadow:var(--shh)}.strct-drawer--start,.strct-drawer--end{top:0;bottom:0;border-radius:0}.strct-drawer--start{left:0;border-right:1px solid var(--b2);animation:strct-drawer-in-start .18s ease}.strct-drawer--end{right:0;border-left:1px solid var(--b2);animation:strct-drawer-in-end .18s ease}.strct-drawer--top,.strct-drawer--bottom{left:0;right:0}.strct-drawer--top{top:0;border-bottom:1px solid var(--b2);animation:strct-drawer-in-top .18s ease}.strct-drawer--bottom{bottom:0;border-top:1px solid var(--b2);animation:strct-drawer-in-bottom .18s ease}.strct-drawer--start.strct-drawer--sm,.strct-drawer--end.strct-drawer--sm{width:300px}.strct-drawer--start.strct-drawer--md,.strct-drawer--end.strct-drawer--md{width:420px}.strct-drawer--start.strct-drawer--lg,.strct-drawer--end.strct-drawer--lg{width:600px}.strct-drawer--top.strct-drawer--sm,.strct-drawer--bottom.strct-drawer--sm{height:220px}.strct-drawer--top.strct-drawer--md,.strct-drawer--bottom.strct-drawer--md{height:340px}.strct-drawer--top.strct-drawer--lg,.strct-drawer--bottom.strct-drawer--lg{height:480px}.strct-drawer{max-width:100vw;max-height:100vh}.strct-drawer__head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:14px 18px;border-bottom:1px solid var(--b1);flex-shrink:0}.strct-drawer__title{font-size:15px;font-weight:600;color:var(--t1)}.strct-drawer__close{display:inline-flex;padding:4px;border:0;border-radius:5px;background:transparent;color:var(--t3);cursor:pointer;transition:color .14s ease,background .14s ease}.strct-drawer__close:hover{color:var(--t1);background:var(--bg-3)}.strct-drawer__body{flex:1;min-height:0;overflow-y:auto;padding:16px 18px;font-size:13px;color:var(--t1)}.strct-drawer__foot{display:flex;align-items:center;justify-content:flex-end;gap:8px;padding:12px 18px;border-top:1px solid var(--b1);flex-shrink:0}@keyframes strct-drawer-fade{0%{opacity:0}}@keyframes strct-drawer-in-start{0%{transform:translate(-100%)}}@keyframes strct-drawer-in-end{0%{transform:translate(100%)}}@keyframes strct-drawer-in-top{0%{transform:translateY(-100%)}}@keyframes strct-drawer-in-bottom{0%{transform:translateY(100%)}}\n"] }]
2479
+ }], propDecorators: { open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], side: [{ type: i0.Input, args: [{ isSignal: true, alias: "side", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], dismissable: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissable", required: false }] }], footerDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => StrctDrawerFooter), { isSignal: true }] }] } });
2480
+
2202
2481
  /**
2203
2482
  * Click-to-open menu:
2204
2483
  * <strct-dropdown align="end">
@@ -5520,10 +5799,19 @@ class StrctDatagrid {
5520
5799
  * that replace the row objects. Defaults to object identity.
5521
5800
  */
5522
5801
  rowId = input(null, ...(ngDevMode ? [{ debugName: "rowId" }] : /* istanbul ignore next */ []));
5802
+ /**
5803
+ * Per-row action menu resolver. When set, each row gets a trailing actions
5804
+ * column with a vertical-dots (kebab) button that opens this row's menu.
5805
+ * [rowActions]="(row) => [{ label: 'Open', action: () => open(row) }, …]"
5806
+ */
5807
+ rowActions = input(null, ...(ngDevMode ? [{ debugName: "rowActions" }] : /* istanbul ignore next */ []));
5523
5808
  /** Emitted when the selection changes. */
5524
5809
  selectionChange = output();
5525
5810
  /** Emitted when the refresh button is clicked. */
5526
5811
  syncChange = output();
5812
+ /** Emitted when a row's action-menu item is chosen. */
5813
+ rowAction = output();
5814
+ menu = inject(StrctMenuService);
5527
5815
  detailDef = contentChild(StrctRowDetailDef, ...(ngDevMode ? [{ debugName: "detailDef" }] : /* istanbul ignore next */ []));
5528
5816
  actionBarDef = contentChild(StrctDatagridActionBar, ...(ngDevMode ? [{ debugName: "actionBarDef" }] : /* istanbul ignore next */ []));
5529
5817
  cellDefs = contentChildren(StrctCellDef, ...(ngDevMode ? [{ debugName: "cellDefs" }] : /* istanbul ignore next */ []));
@@ -5584,6 +5872,8 @@ class StrctDatagrid {
5584
5872
  canExpand = computed(() => this.expandable() && !this.detailPane() && !!this.detailDef(), ...(ngDevMode ? [{ debugName: "canExpand" }] : /* istanbul ignore next */ []));
5585
5873
  canDetail = computed(() => this.detailPane() && !!this.detailDef(), ...(ngDevMode ? [{ debugName: "canDetail" }] : /* istanbul ignore next */ []));
5586
5874
  paneOpen = computed(() => this.detailPane() && !!this.detailDef() && !!this.activeRow(), ...(ngDevMode ? [{ debugName: "paneOpen" }] : /* istanbul ignore next */ []));
5875
+ /** Whether to render the trailing row-actions (kebab) column. */
5876
+ canActions = computed(() => !!this.rowActions() && !this.paneOpen(), ...(ngDevMode ? [{ debugName: "canActions" }] : /* istanbul ignore next */ []));
5587
5877
  /** Only the first column is shown while the detail pane is open. */
5588
5878
  visibleColumns = computed(() => {
5589
5879
  if (this.paneOpen())
@@ -5639,7 +5929,8 @@ class StrctDatagrid {
5639
5929
  return (this.visibleColumns().length +
5640
5930
  (this.selectable() ? 1 : 0) +
5641
5931
  (this.canExpand() ? 1 : 0) +
5642
- (this.canDetail() ? 1 : 0));
5932
+ (this.canDetail() ? 1 : 0) +
5933
+ (this.canActions() ? 1 : 0));
5643
5934
  }
5644
5935
  /** Toggle the detail pane for a row (triggered by its » button, not the row,
5645
5936
  * so row cells remain selectable for copy). */
@@ -5650,6 +5941,24 @@ class StrctDatagrid {
5650
5941
  closePane() {
5651
5942
  this.activeId.set(null);
5652
5943
  }
5944
+ /** Open the row-action menu next to the clicked kebab button. */
5945
+ openRowMenu(row, event) {
5946
+ event.stopPropagation();
5947
+ const fn = this.rowActions();
5948
+ if (!fn)
5949
+ return;
5950
+ const items = fn(row);
5951
+ if (!items.length)
5952
+ return;
5953
+ const rect = event.currentTarget.getBoundingClientRect();
5954
+ this.menu.open({
5955
+ x: rect.right,
5956
+ y: rect.bottom + 4,
5957
+ items,
5958
+ data: row,
5959
+ onSelect: (item) => this.rowAction.emit({ row, item }),
5960
+ });
5961
+ }
5653
5962
  sortBy(key) {
5654
5963
  const current = this.sort();
5655
5964
  if (current.key !== key) {
@@ -5742,7 +6051,7 @@ class StrctDatagrid {
5742
6051
  return String(a ?? '').localeCompare(String(b ?? ''), undefined, { numeric: true });
5743
6052
  }
5744
6053
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctDatagrid, deps: [], target: i0.ɵɵFactoryTarget.Component });
5745
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: StrctDatagrid, isStandalone: true, selector: "strct-datagrid", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: true, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, expandable: { classPropertyName: "expandable", publicName: "expandable", isSignal: true, isRequired: false, transformFunction: null }, detailPane: { classPropertyName: "detailPane", publicName: "detailPane", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, columnChooser: { classPropertyName: "columnChooser", publicName: "columnChooser", isSignal: true, isRequired: false, transformFunction: null }, sync: { classPropertyName: "sync", publicName: "sync", isSignal: true, isRequired: false, transformFunction: null }, footerActionsDisabled: { classPropertyName: "footerActionsDisabled", publicName: "footerActionsDisabled", isSignal: true, isRequired: false, transformFunction: null }, rowId: { classPropertyName: "rowId", publicName: "rowId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange", syncChange: "syncChange" }, host: { properties: { "class.strct-dg-host--compact": "compact()" }, classAttribute: "strct-dg-host" }, queries: [{ propertyName: "detailDef", first: true, predicate: StrctRowDetailDef, descendants: true, isSignal: true }, { propertyName: "actionBarDef", first: true, predicate: StrctDatagridActionBar, descendants: true, isSignal: true }, { propertyName: "cellDefs", predicate: StrctCellDef, isSignal: true }], ngImport: i0, template: `
6054
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.16", type: StrctDatagrid, isStandalone: true, selector: "strct-datagrid", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: true, transformFunction: null }, rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: true, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, selectable: { classPropertyName: "selectable", publicName: "selectable", isSignal: true, isRequired: false, transformFunction: null }, expandable: { classPropertyName: "expandable", publicName: "expandable", isSignal: true, isRequired: false, transformFunction: null }, detailPane: { classPropertyName: "detailPane", publicName: "detailPane", isSignal: true, isRequired: false, transformFunction: null }, compact: { classPropertyName: "compact", publicName: "compact", isSignal: true, isRequired: false, transformFunction: null }, emptyText: { classPropertyName: "emptyText", publicName: "emptyText", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, columnChooser: { classPropertyName: "columnChooser", publicName: "columnChooser", isSignal: true, isRequired: false, transformFunction: null }, sync: { classPropertyName: "sync", publicName: "sync", isSignal: true, isRequired: false, transformFunction: null }, footerActionsDisabled: { classPropertyName: "footerActionsDisabled", publicName: "footerActionsDisabled", isSignal: true, isRequired: false, transformFunction: null }, rowId: { classPropertyName: "rowId", publicName: "rowId", isSignal: true, isRequired: false, transformFunction: null }, rowActions: { classPropertyName: "rowActions", publicName: "rowActions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange", syncChange: "syncChange", rowAction: "rowAction" }, host: { properties: { "class.strct-dg-host--compact": "compact()" }, classAttribute: "strct-dg-host" }, queries: [{ propertyName: "detailDef", first: true, predicate: StrctRowDetailDef, descendants: true, isSignal: true }, { propertyName: "actionBarDef", first: true, predicate: StrctDatagridActionBar, descendants: true, isSignal: true }, { propertyName: "cellDefs", predicate: StrctCellDef, isSignal: true }], ngImport: i0, template: `
5746
6055
  @if (actionBarDef()) {
5747
6056
  <div class="strct-dg__toolbar"><ng-content select="[strctDatagridActionBar]" /></div>
5748
6057
  }
@@ -5797,6 +6106,9 @@ class StrctDatagrid {
5797
6106
  }
5798
6107
  </th>
5799
6108
  }
6109
+ @if (canActions()) {
6110
+ <th class="strct-dg__actioncol" aria-label="Actions"></th>
6111
+ }
5800
6112
  </tr>
5801
6113
  </thead>
5802
6114
  <tbody>
@@ -5817,6 +6129,9 @@ class StrctDatagrid {
5817
6129
  <div class="strct-dg__skeleton-block"></div>
5818
6130
  </td>
5819
6131
  }
6132
+ @if (canActions()) {
6133
+ <td class="strct-dg__actioncell"></td>
6134
+ }
5820
6135
  </tr>
5821
6136
  }
5822
6137
  } @else {
@@ -5878,6 +6193,18 @@ class StrctDatagrid {
5878
6193
  }
5879
6194
  </td>
5880
6195
  }
6196
+ @if (canActions()) {
6197
+ <td class="strct-dg__actioncell">
6198
+ <button
6199
+ type="button"
6200
+ class="strct-dg__kebab"
6201
+ aria-label="Row actions"
6202
+ (click)="openRowMenu(row, $event)"
6203
+ >
6204
+ <strct-icon name="dots" [size]="16" />
6205
+ </button>
6206
+ </td>
6207
+ }
5881
6208
  </tr>
5882
6209
  @if (canExpand() && isExpanded(row)) {
5883
6210
  <tr class="strct-dg__detailrow">
@@ -5982,7 +6309,7 @@ class StrctDatagrid {
5982
6309
  </div>
5983
6310
  </div>
5984
6311
  }
5985
- `, isInline: true, styles: [".strct-dg-host{display:block}.strct-dg__scroll{flex:1 1 auto;min-width:0;overflow-x:auto;-webkit-overflow-scrolling:touch}.strct-dg{width:100%;border-collapse:collapse;font-size:13px;border:1px solid var(--b2);border-radius:8px;overflow:hidden;box-shadow:var(--shadow-rest);background:var(--bg-2)}.strct-dg th,.strct-dg td{padding:9px 13px;text-align:left;border-bottom:1px solid var(--b1)}.strct-dg tbody td{background:var(--bg-1)}[data-theme=dark] .strct-dg tbody td{background:var(--bg-3)}.strct-dg-host--compact .strct-dg th,.strct-dg-host--compact .strct-dg td{padding:5px 11px}.strct-dg th{position:relative;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--t2);background:var(--bg-2);white-space:nowrap;-webkit-user-select:none;user-select:none}.strct-dg__th--sortable{cursor:pointer}.strct-dg__th--sortable:hover{color:var(--t1)}.strct-dg__th--sortable:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-dg__hd{display:inline-flex;align-items:center;gap:5px}.strct-dg__sorticon{color:var(--t3)}.strct-dg__th--sortable:hover .strct-dg__sorticon{color:var(--acc)}.strct-dg__resize{position:absolute;right:0;top:0;bottom:0;width:4px;cursor:col-resize;background:transparent;z-index:2}.strct-dg__resize:hover{background:var(--acc)}.strct-dg td{color:var(--t1)}.strct-dg tbody tr:last-child td{border-bottom:0}.strct-dg tbody tr:not(.strct-dg__detailrow):hover td{background:var(--acc-s)}.strct-dg__row--selected td{background:var(--acc-m)}.strct-dg__sel{width:1%;white-space:nowrap}.strct-dg__sel input{accent-color:var(--acc);width:15px;height:15px;cursor:pointer}.strct-dg__expandcol,.strct-dg__expandcell{width:1%;white-space:nowrap}.strct-dg__expandbtn{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;transition:transform .15s ease,color .15s ease}.strct-dg__expandbtn:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__expandbtn--open{transform:rotate(90deg);color:var(--acc)}.strct-dg__detailbtn{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;transition:color .14s ease,background .14s ease}.strct-dg__detailbtn:hover{color:var(--acc);background:var(--bg-3)}.strct-dg__detailbtn--active{color:var(--acc);background:var(--acc-m)}.strct-dg__detailrow td{background:var(--bg-2);padding:0}.strct-dg__detail{padding:14px 16px;font-size:13px;color:var(--t2)}.strct-dg__layout{display:flex;align-items:flex-start;min-width:0}.strct-dg__layout--paned{gap:0}.strct-dg__layout--paned .strct-dg__scroll{flex:0 0 auto;width:260px;min-width:260px;max-width:260px}.strct-dg__layout--paned .strct-dg{width:260px;min-width:260px;max-width:260px;flex-shrink:0;border-top-right-radius:0;border-bottom-right-radius:0}.strct-dg__row--clickable{cursor:pointer}.strct-dg__row--active td{background:var(--acc-m)}.strct-dg__layout--paned .strct-dg__row--active td:last-child{position:relative;padding-right:26px}.strct-dg__layout--paned .strct-dg__row--active td:last-child:after{content:\"\";position:absolute;right:11px;top:50%;width:6px;height:6px;border-top:1.6px solid var(--acc);border-right:1.6px solid var(--acc);transform:translateY(-50%) rotate(45deg)}.strct-dg__pane{flex:1;min-width:0;align-self:stretch;background:var(--bg-1);border:1px solid var(--b2);border-left:2px solid var(--acc);border-radius:0 8px 8px 0;overflow:hidden;animation:strct-dg-pane-in .14s ease}.strct-dg__pane-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:11px 14px;border-bottom:1px solid var(--b1);font-size:13px;font-weight:600;color:var(--t1)}.strct-dg__pane-close{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer}.strct-dg__pane-close:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__pane-body{padding:14px 16px;font-size:13px;color:var(--t2)}@keyframes strct-dg-pane-in{0%{opacity:0;transform:translate(8px)}}@keyframes strct-skeleton-pulse{0%,to{opacity:.4}50%{opacity:.7}}.strct-dg__skeleton-block{height:12px;background:var(--bg-3);border-radius:var(--radius-sm);animation:strct-skeleton-pulse 1.4s ease infinite}.strct-dg__skeleton-row td{border-bottom:1px solid var(--b1)}.strct-dg__empty{text-align:center;color:var(--t3);padding:22px}.strct-dg__toolbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:8px 0;margin-bottom:8px;border-bottom:1px solid var(--b1)}.strct-dg__foot{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:12px;flex-wrap:wrap}.strct-dg__foot-left,.strct-dg__foot-right{display:flex;align-items:center;gap:12px}.strct-dg__actions{position:relative}.strct-dg__chooser-menu{position:absolute;bottom:calc(100% + 6px);left:0;z-index:10;min-width:180px;background:var(--bg-1);border:1px solid var(--b2);border-radius:8px;box-shadow:var(--shadow-pop);padding:6px;display:flex;flex-direction:column;gap:2px}.strct-dg__chooser-menu--right{left:auto;right:0}.strct-dg__chooser-item{display:flex;align-items:center;gap:8px;padding:5px 8px;border-radius:6px;cursor:pointer;font-size:12px;color:var(--t1);transition:background .1s ease;-webkit-user-select:none;user-select:none}.strct-dg__chooser-item:hover{background:var(--bg-3)}.strct-dg__count{font-size:12px;color:var(--t2)}.strct-dg__count-sep{margin:0 8px;color:var(--b2)}.strct-dg__count-sel{color:var(--acc)}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "size", "strokeWidth", "badge", "ariaLabel"] }, { kind: "component", type: StrctPagination, selector: "strct-pagination", inputs: ["total", "pageSize", "page"], outputs: ["pageChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: StrctCheckbox, selector: "strct-checkbox", inputs: ["checked", "isDisabled", "disabled", "indeterminate", "ariaLabel"], outputs: ["checkedChange", "isDisabledChange"] }, { kind: "component", type: StrctButton, selector: "button[strct-button], a[strct-button]", inputs: ["variant", "size", "solid", "block", "iconOnly"] }, { kind: "component", type: StrctButtonGroup, selector: "strct-button-group" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
6312
+ `, isInline: true, styles: [".strct-dg-host{display:block}.strct-dg__scroll{flex:1 1 auto;min-width:0;overflow-x:auto;-webkit-overflow-scrolling:touch}.strct-dg{width:100%;border-collapse:collapse;font-size:13px;border:1px solid var(--b2);border-radius:8px;overflow:hidden;box-shadow:var(--shadow-rest);background:var(--bg-2)}.strct-dg th,.strct-dg td{padding:9px 13px;text-align:left;border-bottom:1px solid var(--b1)}.strct-dg tbody td{background:var(--bg-1)}[data-theme=dark] .strct-dg tbody td{background:var(--bg-3)}.strct-dg-host--compact .strct-dg th,.strct-dg-host--compact .strct-dg td{padding:5px 11px}.strct-dg th{position:relative;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--t2);background:var(--bg-2);white-space:nowrap;-webkit-user-select:none;user-select:none}.strct-dg__th--sortable{cursor:pointer}.strct-dg__th--sortable:hover{color:var(--t1)}.strct-dg__th--sortable:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-dg__hd{display:inline-flex;align-items:center;gap:5px}.strct-dg__sorticon{color:var(--t3)}.strct-dg__th--sortable:hover .strct-dg__sorticon{color:var(--acc)}.strct-dg__resize{position:absolute;right:0;top:0;bottom:0;width:4px;cursor:col-resize;background:transparent;z-index:2}.strct-dg__resize:hover{background:var(--acc)}.strct-dg td{color:var(--t1)}.strct-dg tbody tr:last-child td{border-bottom:0}.strct-dg tbody tr:not(.strct-dg__detailrow):hover td{background:var(--acc-s)}.strct-dg__row--selected td{background:var(--acc-m)}.strct-dg__sel{width:1%;white-space:nowrap}.strct-dg__sel input{accent-color:var(--acc);width:15px;height:15px;cursor:pointer}.strct-dg__expandcol,.strct-dg__expandcell{width:1%;white-space:nowrap}.strct-dg__actioncol,.strct-dg__actioncell{width:1%;white-space:nowrap;text-align:right}.strct-dg__kebab{display:inline-flex;padding:4px;border:0;border-radius:5px;background:transparent;color:var(--t3);cursor:pointer;transition:color .14s ease,background .14s ease}.strct-dg__kebab:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__expandbtn{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;transition:transform .15s ease,color .15s ease}.strct-dg__expandbtn:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__expandbtn--open{transform:rotate(90deg);color:var(--acc)}.strct-dg__detailbtn{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;transition:color .14s ease,background .14s ease}.strct-dg__detailbtn:hover{color:var(--acc);background:var(--bg-3)}.strct-dg__detailbtn--active{color:var(--acc);background:var(--acc-m)}.strct-dg__detailrow td{background:var(--bg-2);padding:0}.strct-dg__detail{padding:14px 16px;font-size:13px;color:var(--t2)}.strct-dg__layout{display:flex;align-items:flex-start;min-width:0}.strct-dg__layout--paned{gap:0}.strct-dg__layout--paned .strct-dg__scroll{flex:0 0 auto;width:260px;min-width:260px;max-width:260px}.strct-dg__layout--paned .strct-dg{width:260px;min-width:260px;max-width:260px;flex-shrink:0;border-top-right-radius:0;border-bottom-right-radius:0}.strct-dg__row--clickable{cursor:pointer}.strct-dg__row--active td{background:var(--acc-m)}.strct-dg__layout--paned .strct-dg__row--active td:last-child{position:relative;padding-right:26px}.strct-dg__layout--paned .strct-dg__row--active td:last-child:after{content:\"\";position:absolute;right:11px;top:50%;width:6px;height:6px;border-top:1.6px solid var(--acc);border-right:1.6px solid var(--acc);transform:translateY(-50%) rotate(45deg)}.strct-dg__pane{flex:1;min-width:0;align-self:stretch;background:var(--bg-1);border:1px solid var(--b2);border-left:2px solid var(--acc);border-radius:0 8px 8px 0;overflow:hidden;animation:strct-dg-pane-in .14s ease}.strct-dg__pane-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:11px 14px;border-bottom:1px solid var(--b1);font-size:13px;font-weight:600;color:var(--t1)}.strct-dg__pane-close{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer}.strct-dg__pane-close:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__pane-body{padding:14px 16px;font-size:13px;color:var(--t2)}@keyframes strct-dg-pane-in{0%{opacity:0;transform:translate(8px)}}@keyframes strct-skeleton-pulse{0%,to{opacity:.4}50%{opacity:.7}}.strct-dg__skeleton-block{height:12px;background:var(--bg-3);border-radius:var(--radius-sm);animation:strct-skeleton-pulse 1.4s ease infinite}.strct-dg__skeleton-row td{border-bottom:1px solid var(--b1)}.strct-dg__empty{text-align:center;color:var(--t3);padding:22px}.strct-dg__toolbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:8px 0;margin-bottom:8px;border-bottom:1px solid var(--b1)}.strct-dg__foot{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:12px;flex-wrap:wrap}.strct-dg__foot-left,.strct-dg__foot-right{display:flex;align-items:center;gap:12px}.strct-dg__actions{position:relative}.strct-dg__chooser-menu{position:absolute;bottom:calc(100% + 6px);left:0;z-index:10;min-width:180px;background:var(--bg-1);border:1px solid var(--b2);border-radius:8px;box-shadow:var(--shadow-pop);padding:6px;display:flex;flex-direction:column;gap:2px}.strct-dg__chooser-menu--right{left:auto;right:0}.strct-dg__chooser-item{display:flex;align-items:center;gap:8px;padding:5px 8px;border-radius:6px;cursor:pointer;font-size:12px;color:var(--t1);transition:background .1s ease;-webkit-user-select:none;user-select:none}.strct-dg__chooser-item:hover{background:var(--bg-3)}.strct-dg__count{font-size:12px;color:var(--t2)}.strct-dg__count-sep{margin:0 8px;color:var(--b2)}.strct-dg__count-sel{color:var(--acc)}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "size", "strokeWidth", "badge", "ariaLabel"] }, { kind: "component", type: StrctPagination, selector: "strct-pagination", inputs: ["total", "pageSize", "page"], outputs: ["pageChange"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: StrctCheckbox, selector: "strct-checkbox", inputs: ["checked", "isDisabled", "disabled", "indeterminate", "ariaLabel"], outputs: ["checkedChange", "isDisabledChange"] }, { kind: "component", type: StrctButton, selector: "button[strct-button], a[strct-button]", inputs: ["variant", "size", "solid", "block", "iconOnly"] }, { kind: "component", type: StrctButtonGroup, selector: "strct-button-group" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
5986
6313
  }
5987
6314
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctDatagrid, decorators: [{
5988
6315
  type: Component,
@@ -6048,6 +6375,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
6048
6375
  }
6049
6376
  </th>
6050
6377
  }
6378
+ @if (canActions()) {
6379
+ <th class="strct-dg__actioncol" aria-label="Actions"></th>
6380
+ }
6051
6381
  </tr>
6052
6382
  </thead>
6053
6383
  <tbody>
@@ -6068,6 +6398,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
6068
6398
  <div class="strct-dg__skeleton-block"></div>
6069
6399
  </td>
6070
6400
  }
6401
+ @if (canActions()) {
6402
+ <td class="strct-dg__actioncell"></td>
6403
+ }
6071
6404
  </tr>
6072
6405
  }
6073
6406
  } @else {
@@ -6129,6 +6462,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
6129
6462
  }
6130
6463
  </td>
6131
6464
  }
6465
+ @if (canActions()) {
6466
+ <td class="strct-dg__actioncell">
6467
+ <button
6468
+ type="button"
6469
+ class="strct-dg__kebab"
6470
+ aria-label="Row actions"
6471
+ (click)="openRowMenu(row, $event)"
6472
+ >
6473
+ <strct-icon name="dots" [size]="16" />
6474
+ </button>
6475
+ </td>
6476
+ }
6132
6477
  </tr>
6133
6478
  @if (canExpand() && isExpanded(row)) {
6134
6479
  <tr class="strct-dg__detailrow">
@@ -6236,8 +6581,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
6236
6581
  `, host: {
6237
6582
  class: 'strct-dg-host',
6238
6583
  '[class.strct-dg-host--compact]': 'compact()',
6239
- }, styles: [".strct-dg-host{display:block}.strct-dg__scroll{flex:1 1 auto;min-width:0;overflow-x:auto;-webkit-overflow-scrolling:touch}.strct-dg{width:100%;border-collapse:collapse;font-size:13px;border:1px solid var(--b2);border-radius:8px;overflow:hidden;box-shadow:var(--shadow-rest);background:var(--bg-2)}.strct-dg th,.strct-dg td{padding:9px 13px;text-align:left;border-bottom:1px solid var(--b1)}.strct-dg tbody td{background:var(--bg-1)}[data-theme=dark] .strct-dg tbody td{background:var(--bg-3)}.strct-dg-host--compact .strct-dg th,.strct-dg-host--compact .strct-dg td{padding:5px 11px}.strct-dg th{position:relative;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--t2);background:var(--bg-2);white-space:nowrap;-webkit-user-select:none;user-select:none}.strct-dg__th--sortable{cursor:pointer}.strct-dg__th--sortable:hover{color:var(--t1)}.strct-dg__th--sortable:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-dg__hd{display:inline-flex;align-items:center;gap:5px}.strct-dg__sorticon{color:var(--t3)}.strct-dg__th--sortable:hover .strct-dg__sorticon{color:var(--acc)}.strct-dg__resize{position:absolute;right:0;top:0;bottom:0;width:4px;cursor:col-resize;background:transparent;z-index:2}.strct-dg__resize:hover{background:var(--acc)}.strct-dg td{color:var(--t1)}.strct-dg tbody tr:last-child td{border-bottom:0}.strct-dg tbody tr:not(.strct-dg__detailrow):hover td{background:var(--acc-s)}.strct-dg__row--selected td{background:var(--acc-m)}.strct-dg__sel{width:1%;white-space:nowrap}.strct-dg__sel input{accent-color:var(--acc);width:15px;height:15px;cursor:pointer}.strct-dg__expandcol,.strct-dg__expandcell{width:1%;white-space:nowrap}.strct-dg__expandbtn{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;transition:transform .15s ease,color .15s ease}.strct-dg__expandbtn:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__expandbtn--open{transform:rotate(90deg);color:var(--acc)}.strct-dg__detailbtn{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;transition:color .14s ease,background .14s ease}.strct-dg__detailbtn:hover{color:var(--acc);background:var(--bg-3)}.strct-dg__detailbtn--active{color:var(--acc);background:var(--acc-m)}.strct-dg__detailrow td{background:var(--bg-2);padding:0}.strct-dg__detail{padding:14px 16px;font-size:13px;color:var(--t2)}.strct-dg__layout{display:flex;align-items:flex-start;min-width:0}.strct-dg__layout--paned{gap:0}.strct-dg__layout--paned .strct-dg__scroll{flex:0 0 auto;width:260px;min-width:260px;max-width:260px}.strct-dg__layout--paned .strct-dg{width:260px;min-width:260px;max-width:260px;flex-shrink:0;border-top-right-radius:0;border-bottom-right-radius:0}.strct-dg__row--clickable{cursor:pointer}.strct-dg__row--active td{background:var(--acc-m)}.strct-dg__layout--paned .strct-dg__row--active td:last-child{position:relative;padding-right:26px}.strct-dg__layout--paned .strct-dg__row--active td:last-child:after{content:\"\";position:absolute;right:11px;top:50%;width:6px;height:6px;border-top:1.6px solid var(--acc);border-right:1.6px solid var(--acc);transform:translateY(-50%) rotate(45deg)}.strct-dg__pane{flex:1;min-width:0;align-self:stretch;background:var(--bg-1);border:1px solid var(--b2);border-left:2px solid var(--acc);border-radius:0 8px 8px 0;overflow:hidden;animation:strct-dg-pane-in .14s ease}.strct-dg__pane-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:11px 14px;border-bottom:1px solid var(--b1);font-size:13px;font-weight:600;color:var(--t1)}.strct-dg__pane-close{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer}.strct-dg__pane-close:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__pane-body{padding:14px 16px;font-size:13px;color:var(--t2)}@keyframes strct-dg-pane-in{0%{opacity:0;transform:translate(8px)}}@keyframes strct-skeleton-pulse{0%,to{opacity:.4}50%{opacity:.7}}.strct-dg__skeleton-block{height:12px;background:var(--bg-3);border-radius:var(--radius-sm);animation:strct-skeleton-pulse 1.4s ease infinite}.strct-dg__skeleton-row td{border-bottom:1px solid var(--b1)}.strct-dg__empty{text-align:center;color:var(--t3);padding:22px}.strct-dg__toolbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:8px 0;margin-bottom:8px;border-bottom:1px solid var(--b1)}.strct-dg__foot{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:12px;flex-wrap:wrap}.strct-dg__foot-left,.strct-dg__foot-right{display:flex;align-items:center;gap:12px}.strct-dg__actions{position:relative}.strct-dg__chooser-menu{position:absolute;bottom:calc(100% + 6px);left:0;z-index:10;min-width:180px;background:var(--bg-1);border:1px solid var(--b2);border-radius:8px;box-shadow:var(--shadow-pop);padding:6px;display:flex;flex-direction:column;gap:2px}.strct-dg__chooser-menu--right{left:auto;right:0}.strct-dg__chooser-item{display:flex;align-items:center;gap:8px;padding:5px 8px;border-radius:6px;cursor:pointer;font-size:12px;color:var(--t1);transition:background .1s ease;-webkit-user-select:none;user-select:none}.strct-dg__chooser-item:hover{background:var(--bg-3)}.strct-dg__count{font-size:12px;color:var(--t2)}.strct-dg__count-sep{margin:0 8px;color:var(--b2)}.strct-dg__count-sel{color:var(--acc)}\n"] }]
6240
- }], ctorParameters: () => [], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: true }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], expandable: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandable", required: false }] }], detailPane: [{ type: i0.Input, args: [{ isSignal: true, alias: "detailPane", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], resizable: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizable", required: false }] }], columnChooser: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnChooser", required: false }] }], sync: [{ type: i0.Input, args: [{ isSignal: true, alias: "sync", required: false }] }], footerActionsDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "footerActionsDisabled", required: false }] }], rowId: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowId", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], syncChange: [{ type: i0.Output, args: ["syncChange"] }], detailDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => StrctRowDetailDef), { isSignal: true }] }], actionBarDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => StrctDatagridActionBar), { isSignal: true }] }], cellDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => StrctCellDef), { isSignal: true }] }] } });
6584
+ }, styles: [".strct-dg-host{display:block}.strct-dg__scroll{flex:1 1 auto;min-width:0;overflow-x:auto;-webkit-overflow-scrolling:touch}.strct-dg{width:100%;border-collapse:collapse;font-size:13px;border:1px solid var(--b2);border-radius:8px;overflow:hidden;box-shadow:var(--shadow-rest);background:var(--bg-2)}.strct-dg th,.strct-dg td{padding:9px 13px;text-align:left;border-bottom:1px solid var(--b1)}.strct-dg tbody td{background:var(--bg-1)}[data-theme=dark] .strct-dg tbody td{background:var(--bg-3)}.strct-dg-host--compact .strct-dg th,.strct-dg-host--compact .strct-dg td{padding:5px 11px}.strct-dg th{position:relative;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.4px;color:var(--t2);background:var(--bg-2);white-space:nowrap;-webkit-user-select:none;user-select:none}.strct-dg__th--sortable{cursor:pointer}.strct-dg__th--sortable:hover{color:var(--t1)}.strct-dg__th--sortable:focus-visible{outline:2px solid var(--acc50);outline-offset:-2px}.strct-dg__hd{display:inline-flex;align-items:center;gap:5px}.strct-dg__sorticon{color:var(--t3)}.strct-dg__th--sortable:hover .strct-dg__sorticon{color:var(--acc)}.strct-dg__resize{position:absolute;right:0;top:0;bottom:0;width:4px;cursor:col-resize;background:transparent;z-index:2}.strct-dg__resize:hover{background:var(--acc)}.strct-dg td{color:var(--t1)}.strct-dg tbody tr:last-child td{border-bottom:0}.strct-dg tbody tr:not(.strct-dg__detailrow):hover td{background:var(--acc-s)}.strct-dg__row--selected td{background:var(--acc-m)}.strct-dg__sel{width:1%;white-space:nowrap}.strct-dg__sel input{accent-color:var(--acc);width:15px;height:15px;cursor:pointer}.strct-dg__expandcol,.strct-dg__expandcell{width:1%;white-space:nowrap}.strct-dg__actioncol,.strct-dg__actioncell{width:1%;white-space:nowrap;text-align:right}.strct-dg__kebab{display:inline-flex;padding:4px;border:0;border-radius:5px;background:transparent;color:var(--t3);cursor:pointer;transition:color .14s ease,background .14s ease}.strct-dg__kebab:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__expandbtn{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;transition:transform .15s ease,color .15s ease}.strct-dg__expandbtn:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__expandbtn--open{transform:rotate(90deg);color:var(--acc)}.strct-dg__detailbtn{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer;transition:color .14s ease,background .14s ease}.strct-dg__detailbtn:hover{color:var(--acc);background:var(--bg-3)}.strct-dg__detailbtn--active{color:var(--acc);background:var(--acc-m)}.strct-dg__detailrow td{background:var(--bg-2);padding:0}.strct-dg__detail{padding:14px 16px;font-size:13px;color:var(--t2)}.strct-dg__layout{display:flex;align-items:flex-start;min-width:0}.strct-dg__layout--paned{gap:0}.strct-dg__layout--paned .strct-dg__scroll{flex:0 0 auto;width:260px;min-width:260px;max-width:260px}.strct-dg__layout--paned .strct-dg{width:260px;min-width:260px;max-width:260px;flex-shrink:0;border-top-right-radius:0;border-bottom-right-radius:0}.strct-dg__row--clickable{cursor:pointer}.strct-dg__row--active td{background:var(--acc-m)}.strct-dg__layout--paned .strct-dg__row--active td:last-child{position:relative;padding-right:26px}.strct-dg__layout--paned .strct-dg__row--active td:last-child:after{content:\"\";position:absolute;right:11px;top:50%;width:6px;height:6px;border-top:1.6px solid var(--acc);border-right:1.6px solid var(--acc);transform:translateY(-50%) rotate(45deg)}.strct-dg__pane{flex:1;min-width:0;align-self:stretch;background:var(--bg-1);border:1px solid var(--b2);border-left:2px solid var(--acc);border-radius:0 8px 8px 0;overflow:hidden;animation:strct-dg-pane-in .14s ease}.strct-dg__pane-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:11px 14px;border-bottom:1px solid var(--b1);font-size:13px;font-weight:600;color:var(--t1)}.strct-dg__pane-close{display:inline-flex;padding:3px;border:0;border-radius:4px;background:transparent;color:var(--t3);cursor:pointer}.strct-dg__pane-close:hover{color:var(--t1);background:var(--bg-3)}.strct-dg__pane-body{padding:14px 16px;font-size:13px;color:var(--t2)}@keyframes strct-dg-pane-in{0%{opacity:0;transform:translate(8px)}}@keyframes strct-skeleton-pulse{0%,to{opacity:.4}50%{opacity:.7}}.strct-dg__skeleton-block{height:12px;background:var(--bg-3);border-radius:var(--radius-sm);animation:strct-skeleton-pulse 1.4s ease infinite}.strct-dg__skeleton-row td{border-bottom:1px solid var(--b1)}.strct-dg__empty{text-align:center;color:var(--t3);padding:22px}.strct-dg__toolbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;padding:8px 0;margin-bottom:8px;border-bottom:1px solid var(--b1)}.strct-dg__foot{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:12px;flex-wrap:wrap}.strct-dg__foot-left,.strct-dg__foot-right{display:flex;align-items:center;gap:12px}.strct-dg__actions{position:relative}.strct-dg__chooser-menu{position:absolute;bottom:calc(100% + 6px);left:0;z-index:10;min-width:180px;background:var(--bg-1);border:1px solid var(--b2);border-radius:8px;box-shadow:var(--shadow-pop);padding:6px;display:flex;flex-direction:column;gap:2px}.strct-dg__chooser-menu--right{left:auto;right:0}.strct-dg__chooser-item{display:flex;align-items:center;gap:8px;padding:5px 8px;border-radius:6px;cursor:pointer;font-size:12px;color:var(--t1);transition:background .1s ease;-webkit-user-select:none;user-select:none}.strct-dg__chooser-item:hover{background:var(--bg-3)}.strct-dg__count{font-size:12px;color:var(--t2)}.strct-dg__count-sep{margin:0 8px;color:var(--b2)}.strct-dg__count-sel{color:var(--acc)}\n"] }]
6585
+ }], ctorParameters: () => [], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: true }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: true }] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }], selectable: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectable", required: false }] }], expandable: [{ type: i0.Input, args: [{ isSignal: true, alias: "expandable", required: false }] }], detailPane: [{ type: i0.Input, args: [{ isSignal: true, alias: "detailPane", required: false }] }], compact: [{ type: i0.Input, args: [{ isSignal: true, alias: "compact", required: false }] }], emptyText: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyText", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], resizable: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizable", required: false }] }], columnChooser: [{ type: i0.Input, args: [{ isSignal: true, alias: "columnChooser", required: false }] }], sync: [{ type: i0.Input, args: [{ isSignal: true, alias: "sync", required: false }] }], footerActionsDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "footerActionsDisabled", required: false }] }], rowId: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowId", required: false }] }], rowActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowActions", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], syncChange: [{ type: i0.Output, args: ["syncChange"] }], rowAction: [{ type: i0.Output, args: ["rowAction"] }], detailDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => StrctRowDetailDef), { isSignal: true }] }], actionBarDef: [{ type: i0.ContentChild, args: [i0.forwardRef(() => StrctDatagridActionBar), { isSignal: true }] }], cellDefs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => StrctCellDef), { isSignal: true }] }] } });
6241
6586
 
6242
6587
  /** Vertical timeline container. Wraps `<strct-timeline-item>` children. */
6243
6588
  class StrctTimeline {
@@ -7201,5 +7546,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
7201
7546
  * Generated bundle index. Do not edit.
7202
7547
  */
7203
7548
 
7204
- export { STRCT_ICONS, STRCT_ICON_GROUPS, STRCT_MASKS, STRCT_PALETTES, STRCT_RAW_ICONS, StrctAccordion, StrctAccordionPanel, StrctAlert, StrctAvatar, StrctBadge, StrctBreadcrumb, StrctBreadcrumbItem, StrctButton, StrctButtonGroup, StrctCard, StrctCardBlock, StrctCardFooter, StrctCardHeader, StrctCascadeHost, StrctCascadeNode, StrctCascadeSelect, StrctCellDef, StrctChart, StrctCheckbox, StrctChips, StrctColorPicker, StrctCombobox, StrctContextMenu, StrctContextMenuTrigger, StrctDatagrid, StrctDatagridActionBar, StrctDatepicker, StrctDivider, StrctDonut, StrctDropdown, StrctDropdownDivider, StrctDropdownItem, StrctField, StrctFile, StrctFooter, StrctGauge, StrctHeader, StrctIcon, StrctInput, StrctInputMask, StrctInputOtp, StrctKnob, StrctLogin, StrctMenuPanel, StrctModal, StrctNav, StrctNavItem, StrctOverlay, StrctPagination, StrctPassword, StrctProgress, StrctRadio, StrctRadioGroup, StrctRange, StrctRating, StrctRowDetailDef, StrctShell, StrctShellService, StrctSignpost, StrctSkeleton, StrctSparkline, StrctSpeedDial, StrctSpinner, StrctStack, StrctStackItem, StrctStep, StrctSubmenu, StrctTab, StrctTable, StrctTabs, StrctTag, StrctThemeService, StrctThemeSwitcher, StrctTimeline, StrctTimelineItem, StrctToastOutlet, StrctToastService, StrctToggle, StrctTooltip, StrctTree, StrctTreeNode, StrctVerticalNav, StrctWizard, registerStrctIcon };
7549
+ export { STRCT_ICONS, STRCT_ICON_GROUPS, STRCT_MASKS, STRCT_PALETTES, STRCT_RAW_ICONS, StrctAccordion, StrctAccordionPanel, StrctAlert, StrctAvatar, StrctBadge, StrctBreadcrumb, StrctBreadcrumbItem, StrctButton, StrctButtonGroup, StrctCard, StrctCardBlock, StrctCardFooter, StrctCardHeader, StrctCascadeHost, StrctCascadeNode, StrctCascadeSelect, StrctCellDef, StrctChart, StrctCheckbox, StrctChips, StrctColorPicker, StrctCombobox, StrctContextMenu, StrctContextMenuTrigger, StrctDatagrid, StrctDatagridActionBar, StrctDatepicker, StrctDivider, StrctDonut, StrctDrawer, StrctDrawerFooter, StrctDropdown, StrctDropdownDivider, StrctDropdownItem, StrctField, StrctFile, StrctFooter, StrctGauge, StrctHeader, StrctIcon, StrctInput, StrctInputMask, StrctInputOtp, StrctKnob, StrctLogin, StrctMenuPanel, StrctMenuService, StrctModal, StrctNav, StrctNavItem, StrctOverlay, StrctPagination, StrctPassword, StrctProgress, StrctRadio, StrctRadioGroup, StrctRail, StrctRange, StrctRating, StrctRowDetailDef, StrctShell, StrctShellService, StrctSignpost, StrctSkeleton, StrctSparkline, StrctSpeedDial, StrctSpinner, StrctStack, StrctStackItem, StrctStep, StrctSubmenu, StrctTab, StrctTable, StrctTabs, StrctTag, StrctThemeService, StrctThemeSwitcher, StrctTimeline, StrctTimelineItem, StrctToastOutlet, StrctToastService, StrctToggle, StrctTooltip, StrctTree, StrctTreeNode, StrctVerticalNav, StrctWizard, registerStrctIcon };
7205
7550
  //# sourceMappingURL=akcelik-strct.mjs.map