@akcelik/strct 0.5.7 → 0.5.9

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.
@@ -1334,7 +1334,7 @@ class StrctTabs {
1334
1334
  }
1335
1335
  </div>
1336
1336
  <div class="strct-tabs__panels"><ng-content /></div>
1337
- `, isInline: true, styles: [".strct-tabs{display:block}.strct-tabs__bar{display:flex;gap:2px;border-bottom:1px solid var(--b2);overflow-x:auto;white-space:nowrap;scrollbar-width:none}.strct-tabs__btn{appearance:none;border:0;background:transparent;cursor:pointer;font-family:var(--font);font-size:13px;font-weight:500;color:var(--t2);padding:9px 14px;border-bottom:2px solid transparent;margin-bottom:-1px;transition:color .14s ease,border-color .14s ease}.strct-tabs__btn:hover{color:var(--t1)}.strct-tabs__btn--active{color:var(--acc);border-bottom-color:var(--acc)}.strct-tabs__btn:disabled{color:var(--t4);cursor:not-allowed}.strct-tabs__panels{padding-top:16px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
1337
+ `, isInline: true, styles: [".strct-tabs{display:block}.strct-tabs__bar{display:flex;gap:2px;border-bottom:1px solid var(--b2);overflow-x:auto;white-space:nowrap;scrollbar-width:none}.strct-tabs__btn{appearance:none;background:transparent;border:0;cursor:pointer;font-family:var(--font);font-size:13px;font-weight:500;color:var(--t2);padding:9px 14px;border-bottom:2px solid transparent;margin-bottom:-1px;transition:color .14s ease,border-color .14s ease}.strct-tabs__btn:hover{color:var(--t1)}.strct-tabs__btn--active{color:var(--acc);border-bottom-color:var(--acc)}.strct-tabs__btn:disabled{color:var(--t4);cursor:not-allowed}.strct-tabs__panels{padding-top:16px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
1338
1338
  }
1339
1339
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctTabs, decorators: [{
1340
1340
  type: Component,
@@ -1362,7 +1362,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
1362
1362
  }
1363
1363
  </div>
1364
1364
  <div class="strct-tabs__panels"><ng-content /></div>
1365
- `, host: { class: 'strct-tabs' }, styles: [".strct-tabs{display:block}.strct-tabs__bar{display:flex;gap:2px;border-bottom:1px solid var(--b2);overflow-x:auto;white-space:nowrap;scrollbar-width:none}.strct-tabs__btn{appearance:none;border:0;background:transparent;cursor:pointer;font-family:var(--font);font-size:13px;font-weight:500;color:var(--t2);padding:9px 14px;border-bottom:2px solid transparent;margin-bottom:-1px;transition:color .14s ease,border-color .14s ease}.strct-tabs__btn:hover{color:var(--t1)}.strct-tabs__btn--active{color:var(--acc);border-bottom-color:var(--acc)}.strct-tabs__btn:disabled{color:var(--t4);cursor:not-allowed}.strct-tabs__panels{padding-top:16px}\n"] }]
1365
+ `, host: { class: 'strct-tabs' }, styles: [".strct-tabs{display:block}.strct-tabs__bar{display:flex;gap:2px;border-bottom:1px solid var(--b2);overflow-x:auto;white-space:nowrap;scrollbar-width:none}.strct-tabs__btn{appearance:none;background:transparent;border:0;cursor:pointer;font-family:var(--font);font-size:13px;font-weight:500;color:var(--t2);padding:9px 14px;border-bottom:2px solid transparent;margin-bottom:-1px;transition:color .14s ease,border-color .14s ease}.strct-tabs__btn:hover{color:var(--t1)}.strct-tabs__btn--active{color:var(--acc);border-bottom-color:var(--acc)}.strct-tabs__btn:disabled{color:var(--t4);cursor:not-allowed}.strct-tabs__panels{padding-top:16px}\n"] }]
1366
1366
  }], ctorParameters: () => [], propDecorators: { tabs: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => StrctTab), { isSignal: true }] }] } });
1367
1367
 
1368
1368
  /**
@@ -5477,6 +5477,8 @@ class StrctDatagrid {
5477
5477
  loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
5478
5478
  /** Enable column resizing by dragging column headers. */
5479
5479
  resizable = input(false, { ...(ngDevMode ? { debugName: "resizable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
5480
+ /** Show a column-chooser dropdown in the footer. */
5481
+ columnChooser = input(false, { ...(ngDevMode ? { debugName: "columnChooser" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
5480
5482
  /**
5481
5483
  * Stable row identity (property key or function). Set this for live-refreshing
5482
5484
  * data so selection, expansion and the active detail row survive re-fetches
@@ -5501,6 +5503,8 @@ class StrctDatagrid {
5501
5503
  selectedCount = computed(() => this.selected().size, ...(ngDevMode ? [{ debugName: "selectedCount" }] : /* istanbul ignore next */ []));
5502
5504
  expandedRows = signal(new Set(), ...(ngDevMode ? [{ debugName: "expandedRows" }] : /* istanbul ignore next */ []));
5503
5505
  columnWidths = signal(new Map(), ...(ngDevMode ? [{ debugName: "columnWidths" }] : /* istanbul ignore next */ []));
5506
+ hiddenColumns = signal(new Set(), ...(ngDevMode ? [{ debugName: "hiddenColumns" }] : /* istanbul ignore next */ []));
5507
+ chooserOpen = signal(false, ...(ngDevMode ? [{ debugName: "chooserOpen" }] : /* istanbul ignore next */ []));
5504
5508
  resizeState = null;
5505
5509
  onMove = (e) => this.onResizeMove(e);
5506
5510
  onUp = () => this.onResizeEnd();
@@ -5544,7 +5548,12 @@ class StrctDatagrid {
5544
5548
  canDetail = computed(() => this.detailPane() && !!this.detailDef(), ...(ngDevMode ? [{ debugName: "canDetail" }] : /* istanbul ignore next */ []));
5545
5549
  paneOpen = computed(() => this.detailPane() && !!this.detailDef() && !!this.activeRow(), ...(ngDevMode ? [{ debugName: "paneOpen" }] : /* istanbul ignore next */ []));
5546
5550
  /** Only the first column is shown while the detail pane is open. */
5547
- visibleColumns = computed(() => this.paneOpen() ? this.columns().slice(0, 1) : this.columns(), ...(ngDevMode ? [{ debugName: "visibleColumns" }] : /* istanbul ignore next */ []));
5551
+ visibleColumns = computed(() => {
5552
+ if (this.paneOpen())
5553
+ return this.columns().slice(0, 1);
5554
+ const hidden = this.hiddenColumns();
5555
+ return this.columns().filter((c) => !hidden.has(c.key));
5556
+ }, ...(ngDevMode ? [{ debugName: "visibleColumns" }] : /* istanbul ignore next */ []));
5548
5557
  sorted = computed(() => {
5549
5558
  const { key, dir } = this.sort();
5550
5559
  const data = [...this.rows()];
@@ -5632,6 +5641,16 @@ class StrctDatagrid {
5632
5641
  event.preventDefault(); // stop page scroll
5633
5642
  this.sortBy(key);
5634
5643
  }
5644
+ toggleColumn(key, visible) {
5645
+ this.hiddenColumns.update((set) => {
5646
+ const next = new Set(set);
5647
+ if (visible)
5648
+ next.delete(key);
5649
+ else
5650
+ next.add(key);
5651
+ return next;
5652
+ });
5653
+ }
5635
5654
  isSelected(row) {
5636
5655
  return this.selected().has(this.idOf(row));
5637
5656
  }
@@ -5686,7 +5705,7 @@ class StrctDatagrid {
5686
5705
  return String(a ?? '').localeCompare(String(b ?? ''), undefined, { numeric: true });
5687
5706
  }
5688
5707
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctDatagrid, deps: [], target: i0.ɵɵFactoryTarget.Component });
5689
- 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 }, rowId: { classPropertyName: "rowId", publicName: "rowId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange" }, 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: `
5708
+ 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 }, rowId: { classPropertyName: "rowId", publicName: "rowId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange" }, 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: `
5690
5709
  @if (actionBarDef()) {
5691
5710
  <div class="strct-dg__toolbar"><ng-content select="[strctDatagridActionBar]" /></div>
5692
5711
  }
@@ -5870,21 +5889,51 @@ class StrctDatagrid {
5870
5889
 
5871
5890
  @if (pageSize() > 0 && !loading()) {
5872
5891
  <div class="strct-dg__foot">
5873
- <span class="strct-dg__count">
5874
- {{ sorted().length }} {{ sorted().length === 1 ? 'row' : 'rows' }}
5875
- @if (selectedCount()) {
5876
- <span class="strct-dg__count-sep">|</span>
5877
- <span class="strct-dg__count-sel">{{ selectedCount() }} selected</span>
5892
+ <div class="strct-dg__foot-left">
5893
+ <span class="strct-dg__count">
5894
+ {{ sorted().length }} {{ sorted().length === 1 ? 'row' : 'rows' }}
5895
+ @if (selectedCount()) {
5896
+ <span class="strct-dg__count-sep">|</span>
5897
+ <span class="strct-dg__count-sel">{{ selectedCount() }} selected</span>
5898
+ }
5899
+ </span>
5900
+ </div>
5901
+ <div class="strct-dg__foot-right">
5902
+ <strct-pagination [total]="sorted().length" [pageSize]="pageSize()" [(page)]="page" />
5903
+ @if (columnChooser()) {
5904
+ <div class="strct-dg__chooser">
5905
+ <button
5906
+ strct-button
5907
+ size="sm"
5908
+ [class.is-open]="chooserOpen()"
5909
+ aria-label="Choose columns"
5910
+ (click)="chooserOpen.set(!chooserOpen())"
5911
+ >
5912
+ <strct-icon name="settings" [size]="14" />
5913
+ </button>
5914
+ @if (chooserOpen()) {
5915
+ <div class="strct-dg__chooser-menu strct-dg__chooser-menu--right">
5916
+ @for (col of columns(); track col.key) {
5917
+ <div class="strct-dg__chooser-item">
5918
+ <strct-checkbox
5919
+ [checked]="!hiddenColumns().has(col.key)"
5920
+ (checkedChange)="toggleColumn(col.key, $event)"
5921
+ />
5922
+ <span>{{ col.label }}</span>
5923
+ </div>
5924
+ }
5925
+ </div>
5926
+ }
5927
+ </div>
5878
5928
  }
5879
- </span>
5880
- <strct-pagination [total]="sorted().length" [pageSize]="pageSize()" [(page)]="page" />
5929
+ </div>
5881
5930
  </div>
5882
5931
  }
5883
- `, 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__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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
5932
+ `, 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__chooser{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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
5884
5933
  }
5885
5934
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImport: i0, type: StrctDatagrid, decorators: [{
5886
5935
  type: Component,
5887
- args: [{ selector: 'strct-datagrid', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [StrctIcon, StrctPagination, NgTemplateOutlet, StrctCheckbox], template: `
5936
+ args: [{ selector: 'strct-datagrid', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [StrctIcon, StrctPagination, NgTemplateOutlet, StrctCheckbox, StrctButton], template: `
5888
5937
  @if (actionBarDef()) {
5889
5938
  <div class="strct-dg__toolbar"><ng-content select="[strctDatagridActionBar]" /></div>
5890
5939
  }
@@ -6068,21 +6117,51 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
6068
6117
 
6069
6118
  @if (pageSize() > 0 && !loading()) {
6070
6119
  <div class="strct-dg__foot">
6071
- <span class="strct-dg__count">
6072
- {{ sorted().length }} {{ sorted().length === 1 ? 'row' : 'rows' }}
6073
- @if (selectedCount()) {
6074
- <span class="strct-dg__count-sep">|</span>
6075
- <span class="strct-dg__count-sel">{{ selectedCount() }} selected</span>
6120
+ <div class="strct-dg__foot-left">
6121
+ <span class="strct-dg__count">
6122
+ {{ sorted().length }} {{ sorted().length === 1 ? 'row' : 'rows' }}
6123
+ @if (selectedCount()) {
6124
+ <span class="strct-dg__count-sep">|</span>
6125
+ <span class="strct-dg__count-sel">{{ selectedCount() }} selected</span>
6126
+ }
6127
+ </span>
6128
+ </div>
6129
+ <div class="strct-dg__foot-right">
6130
+ <strct-pagination [total]="sorted().length" [pageSize]="pageSize()" [(page)]="page" />
6131
+ @if (columnChooser()) {
6132
+ <div class="strct-dg__chooser">
6133
+ <button
6134
+ strct-button
6135
+ size="sm"
6136
+ [class.is-open]="chooserOpen()"
6137
+ aria-label="Choose columns"
6138
+ (click)="chooserOpen.set(!chooserOpen())"
6139
+ >
6140
+ <strct-icon name="settings" [size]="14" />
6141
+ </button>
6142
+ @if (chooserOpen()) {
6143
+ <div class="strct-dg__chooser-menu strct-dg__chooser-menu--right">
6144
+ @for (col of columns(); track col.key) {
6145
+ <div class="strct-dg__chooser-item">
6146
+ <strct-checkbox
6147
+ [checked]="!hiddenColumns().has(col.key)"
6148
+ (checkedChange)="toggleColumn(col.key, $event)"
6149
+ />
6150
+ <span>{{ col.label }}</span>
6151
+ </div>
6152
+ }
6153
+ </div>
6154
+ }
6155
+ </div>
6076
6156
  }
6077
- </span>
6078
- <strct-pagination [total]="sorted().length" [pageSize]="pageSize()" [(page)]="page" />
6157
+ </div>
6079
6158
  </div>
6080
6159
  }
6081
6160
  `, host: {
6082
6161
  class: 'strct-dg-host',
6083
6162
  '[class.strct-dg-host--compact]': 'compact()',
6084
- }, 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__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"] }]
6085
- }], 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 }] }], rowId: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowId", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], 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 }] }] } });
6163
+ }, 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__chooser{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"] }]
6164
+ }], 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 }] }], rowId: [{ type: i0.Input, args: [{ isSignal: true, alias: "rowId", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }], 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 }] }] } });
6086
6165
 
6087
6166
  /** Vertical timeline container. Wraps `<strct-timeline-item>` children. */
6088
6167
  class StrctTimeline {