@reforgium/data-grid 2.2.3 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -593,42 +593,82 @@ import { DataGridColumnManager } from '@reforgium/data-grid/column-manager';
593
593
  <re-data-grid [columns]="managedColumns()" ... />
594
594
  ```
595
595
 
596
- Custom trigger template:
597
-
598
- ```html
599
-
600
- <ng-template #cmTrigger let-label let-visible="visible" let-total="total">
601
- <span>{{ label }}</span>
602
- <strong>{{ visible }}/{{ total }}</strong>
603
- </ng-template>
604
-
605
- <re-data-grid-column-manager
606
- [columns]="managedColumns()"
607
- [triggerTemplate]="cmTrigger"
608
- (columnsChange)="managedColumns.set($event)"
609
- />
610
- ```
611
-
612
- Trigger template context:
613
-
614
- - `$implicit` - trigger label
615
- - `visible` - visible columns count
616
- - `total` - total columns count
617
-
618
- Inputs:
619
-
620
- - `columns: GridColumn<T>[]`
621
- - `triggerLabel?: string`
622
- - `triggerTemplate?: TemplateRef<{ $implicit: string; visible: number; total: number }>`
623
- - `controlsVisible?: boolean` - hides search and "show all / hide optional" panel
624
- - `searchable?: boolean`
625
- - `allowReorder?: boolean`
626
- - `allowPin?: boolean`
627
- - `allowVisibility?: boolean`
628
-
629
- Outputs:
630
-
631
- - `columnsChange: GridColumn<T>[]`
596
+ Custom trigger via content projection:
597
+
598
+ ```html
599
+
600
+ <re-data-grid-column-manager
601
+ triggerLabel="Columns"
602
+ [columns]="managedColumns()"
603
+ (columnsChange)="managedColumns.set($event)"
604
+ >
605
+ <span reDataGridColumnManagerTrigger>Manage columns</span>
606
+ </re-data-grid-column-manager>
607
+ ```
608
+
609
+ Custom column title template (controls stay built-in):
610
+
611
+ ```html
612
+ <re-data-grid-column-manager
613
+ [columns]="managedColumns()"
614
+ (columnsChange)="managedColumns.set($event)"
615
+ >
616
+ <ng-template reDataGridColumnManagerColumnTitle let-title let-column="column">
617
+ <span class="font-medium">{{ title }}</span>
618
+ </ng-template>
619
+ </re-data-grid-column-manager>
620
+ ```
621
+
622
+ `reDataGridColumnManagerColumnTitle` context:
623
+
624
+ - `$implicit` / `title` - resolved column title (`header || key`)
625
+ - `column` - current `GridColumn<T>`
626
+
627
+ Standalone imports for custom trigger/title markers:
628
+
629
+ ```ts
630
+ import {
631
+ DataGridColumnManager,
632
+ DataGridColumnManagerColumnTitleDirective,
633
+ DataGridColumnManagerTriggerDirective,
634
+ } from '@reforgium/data-grid/column-manager';
635
+ ```
636
+
637
+ ```ts
638
+ @Component({
639
+ imports: [
640
+ DataGridColumnManager,
641
+ DataGridColumnManagerTriggerDirective,
642
+ DataGridColumnManagerColumnTitleDirective,
643
+ ],
644
+ })
645
+ export class ExampleComponent {}
646
+ ```
647
+
648
+ Example with both trigger and column title customizations:
649
+
650
+ ```html
651
+ <re-data-grid-column-manager [columns]="managedColumns()" (columnsChange)="managedColumns.set($event)">
652
+ <span reDataGridColumnManagerTrigger>Manage columns</span>
653
+ <ng-template reDataGridColumnManagerColumnTitle let-title>
654
+ <span>{{ title }}</span>
655
+ </ng-template>
656
+ </re-data-grid-column-manager>
657
+ ```
658
+
659
+ Inputs:
660
+
661
+ - `columns: GridColumn<T>[]`
662
+ - `triggerLabel?: string`
663
+ - `controlsVisible?: boolean` - hides search and "show all / hide optional" panel
664
+ - `searchable?: boolean`
665
+ - `allowReorder?: boolean`
666
+ - `allowPin?: boolean`
667
+ - `allowVisibility?: boolean`
668
+
669
+ Outputs:
670
+
671
+ - `columnsChange: GridColumn<T>[]`
632
672
 
633
673
  ### Column manager CSS Variables
634
674
 
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Component, input, booleanAttribute, output, signal, viewChild, computed, effect } from '@angular/core';
2
+ import { inject, TemplateRef, Directive, Component, input, booleanAttribute, ElementRef, output, contentChild, signal, viewChild, computed, effect, afterNextRender } from '@angular/core';
3
3
  import { NgTemplateOutlet } from '@angular/common';
4
4
 
5
5
  const isVisible = (column) => column.visible !== false;
@@ -61,31 +61,52 @@ function setColumnVisibility(columns, key, visible) {
61
61
  return next;
62
62
  }
63
63
 
64
+ class DataGridColumnManagerColumnTitleDirective {
65
+ template = inject((TemplateRef));
66
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridColumnManagerColumnTitleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
67
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.1", type: DataGridColumnManagerColumnTitleDirective, isStandalone: true, selector: "ng-template[reDataGridColumnManagerColumnTitle]", ngImport: i0 });
68
+ }
69
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridColumnManagerColumnTitleDirective, decorators: [{
70
+ type: Directive,
71
+ args: [{
72
+ selector: 'ng-template[reDataGridColumnManagerColumnTitle]',
73
+ standalone: true,
74
+ }]
75
+ }] });
76
+
77
+ class DataGridColumnManagerTriggerDirective {
78
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridColumnManagerTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
79
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.1", type: DataGridColumnManagerTriggerDirective, isStandalone: true, selector: "[reDataGridColumnManagerTrigger]", ngImport: i0 });
80
+ }
81
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridColumnManagerTriggerDirective, decorators: [{
82
+ type: Directive,
83
+ args: [{
84
+ selector: '[reDataGridColumnManagerTrigger]',
85
+ standalone: true,
86
+ }]
87
+ }] });
88
+
64
89
  class CrossIcon {
65
90
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: CrossIcon, deps: [], target: i0.ɵɵFactoryTarget.Component });
66
91
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.1", type: CrossIcon, isStandalone: true, selector: "re-cross-ic", ngImport: i0, template: `
67
- <svg width="16" height="16" viewBox="0 0 20 18" fill="none" xmlns="http://www.w3.org/2000/svg">
68
- <svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
69
- <path
70
- d="M10.1958 7.3658L14.4358 3.1258C14.5295 3.03284 14.6039 2.92223 14.6547 2.80037C14.7055 2.67852 14.7316 2.54781 14.7316 2.4158C14.7316 2.28379 14.7055 2.15308 14.6547 2.03122C14.6039 1.90936 14.5295 1.79876 14.4358 1.7058L13.0258 0.295798C12.9328 0.20207 12.8222 0.127676 12.7004 0.0769072C12.5785 0.0261385 12.4478 0 12.3158 0C12.1838 0 12.0531 0.0261385 11.9312 0.0769072C11.8094 0.127676 11.6988 0.20207 11.6058 0.295798L7.3658 4.5358L3.1258 0.295798C3.03284 0.20207 2.92223 0.127676 2.80037 0.0769072C2.67852 0.0261385 2.54781 0 2.4158 0C2.28379 0 2.15308 0.0261385 2.03122 0.0769072C1.90936 0.127676 1.79876 0.20207 1.7058 0.295798L0.295798 1.7058C0.20207 1.79876 0.127676 1.90936 0.0769072 2.03122C0.0261385 2.15308 0 2.28379 0 2.4158C0 2.54781 0.0261385 2.67852 0.0769072 2.80037C0.127676 2.92223 0.20207 3.03284 0.295798 3.1258L4.5358 7.3658L0.295798 11.6058C0.20207 11.6988 0.127676 11.8094 0.0769072 11.9312C0.0261385 12.0531 0 12.1838 0 12.3158C0 12.4478 0.0261385 12.5785 0.0769072 12.7004C0.127676 12.8222 0.20207 12.9328 0.295798 13.0258L1.7058 14.4358C1.79876 14.5295 1.90936 14.6039 2.03122 14.6547C2.15308 14.7055 2.28379 14.7316 2.4158 14.7316C2.54781 14.7316 2.67852 14.7055 2.80037 14.6547C2.92223 14.6039 3.03284 14.5295 3.1258 14.4358L7.3658 10.1958L11.6058 14.4358C11.6988 14.5295 11.8094 14.6039 11.9312 14.6547C12.0531 14.7055 12.1838 14.7316 12.3158 14.7316C12.4478 14.7316 12.5785 14.7055 12.7004 14.6547C12.8222 14.6039 12.9328 14.5295 13.0258 14.4358L14.4358 13.0258C14.5295 12.9328 14.6039 12.8222 14.6547 12.7004C14.7055 12.5785 14.7316 12.4478 14.7316 12.3158C14.7316 12.1838 14.7055 12.0531 14.6547 11.9312C14.6039 11.8094 14.5295 11.6988 14.4358 11.6058L10.1958 7.3658Z"
71
- fill="var(--re-data-grid-cross-ic-surface)"
72
- />
73
- </svg>
92
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
93
+ <path
94
+ d="M10.3052 8L13.759 4.5462C13.8354 4.47048 13.896 4.38038 13.9374 4.28111C13.9787 4.18186 14 4.07538 14 3.96785C14 3.86032 13.9787 3.75385 13.9374 3.65458C13.896 3.55532 13.8354 3.46523 13.759 3.3895L12.6105 2.24095C12.5347 2.1646 12.4447 2.104 12.3454 2.06265C12.2461 2.02129 12.1397 2 12.0321 2C11.9246 2 11.8182 2.02129 11.7189 2.06265C11.6196 2.104 11.5296 2.1646 11.4538 2.24095L8 5.69475L4.5462 2.24095C4.47048 2.1646 4.38038 2.104 4.28111 2.06265C4.18186 2.02129 4.07538 2 3.96785 2C3.86032 2 3.75385 2.02129 3.65458 2.06265C3.55532 2.104 3.46523 2.1646 3.3895 2.24095L2.24095 3.3895C2.1646 3.46523 2.104 3.55532 2.06265 3.65458C2.02129 3.75385 2 3.86032 2 3.96785C2 4.07538 2.02129 4.18186 2.06265 4.28111C2.104 4.38038 2.1646 4.47048 2.24095 4.5462L5.69475 8L2.24095 11.4538C2.1646 11.5296 2.104 11.6196 2.06265 11.7189C2.02129 11.8182 2 11.9246 2 12.0321C2 12.1397 2.02129 12.2461 2.06265 12.3454C2.104 12.4447 2.1646 12.5347 2.24095 12.6105L3.3895 13.759C3.46523 13.8354 3.55532 13.896 3.65458 13.9374C3.75385 13.9787 3.86032 14 3.96785 14C4.07538 14 4.18186 13.9787 4.28111 13.9374C4.38038 13.896 4.47048 13.8354 4.5462 13.759L8 10.3052L11.4538 13.759C11.5296 13.8354 11.6196 13.896 11.7189 13.9374C11.8182 13.9787 11.9246 14 12.0321 14C12.1397 14 12.2461 13.9787 12.3454 13.9374C12.4447 13.896 12.5347 13.8354 12.6105 13.759L13.759 12.6105C13.8354 12.5347 13.896 12.4447 13.9374 12.3454C13.9787 12.2461 14 12.1397 14 12.0321C14 11.9246 13.9787 11.8182 13.9374 11.7189C13.896 11.6196 13.8354 11.5296 13.759 11.4538L10.3052 8Z"
95
+ fill="var(--re-data-grid-cross-ic-surface)"
96
+ />
74
97
  </svg>
75
- `, isInline: true, styles: [":host{--re-data-grid-cross-ic-surface: currentColor}\n"] });
98
+ `, isInline: true, styles: [":host{--re-data-grid-cross-ic-surface: currentColor;display:inline-block;width:16px;height:16px}\n"] });
76
99
  }
77
100
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: CrossIcon, decorators: [{
78
101
  type: Component,
79
102
  args: [{ selector: 're-cross-ic', template: `
80
- <svg width="16" height="16" viewBox="0 0 20 18" fill="none" xmlns="http://www.w3.org/2000/svg">
81
- <svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
82
- <path
83
- d="M10.1958 7.3658L14.4358 3.1258C14.5295 3.03284 14.6039 2.92223 14.6547 2.80037C14.7055 2.67852 14.7316 2.54781 14.7316 2.4158C14.7316 2.28379 14.7055 2.15308 14.6547 2.03122C14.6039 1.90936 14.5295 1.79876 14.4358 1.7058L13.0258 0.295798C12.9328 0.20207 12.8222 0.127676 12.7004 0.0769072C12.5785 0.0261385 12.4478 0 12.3158 0C12.1838 0 12.0531 0.0261385 11.9312 0.0769072C11.8094 0.127676 11.6988 0.20207 11.6058 0.295798L7.3658 4.5358L3.1258 0.295798C3.03284 0.20207 2.92223 0.127676 2.80037 0.0769072C2.67852 0.0261385 2.54781 0 2.4158 0C2.28379 0 2.15308 0.0261385 2.03122 0.0769072C1.90936 0.127676 1.79876 0.20207 1.7058 0.295798L0.295798 1.7058C0.20207 1.79876 0.127676 1.90936 0.0769072 2.03122C0.0261385 2.15308 0 2.28379 0 2.4158C0 2.54781 0.0261385 2.67852 0.0769072 2.80037C0.127676 2.92223 0.20207 3.03284 0.295798 3.1258L4.5358 7.3658L0.295798 11.6058C0.20207 11.6988 0.127676 11.8094 0.0769072 11.9312C0.0261385 12.0531 0 12.1838 0 12.3158C0 12.4478 0.0261385 12.5785 0.0769072 12.7004C0.127676 12.8222 0.20207 12.9328 0.295798 13.0258L1.7058 14.4358C1.79876 14.5295 1.90936 14.6039 2.03122 14.6547C2.15308 14.7055 2.28379 14.7316 2.4158 14.7316C2.54781 14.7316 2.67852 14.7055 2.80037 14.6547C2.92223 14.6039 3.03284 14.5295 3.1258 14.4358L7.3658 10.1958L11.6058 14.4358C11.6988 14.5295 11.8094 14.6039 11.9312 14.6547C12.0531 14.7055 12.1838 14.7316 12.3158 14.7316C12.4478 14.7316 12.5785 14.7055 12.7004 14.6547C12.8222 14.6039 12.9328 14.5295 13.0258 14.4358L14.4358 13.0258C14.5295 12.9328 14.6039 12.8222 14.6547 12.7004C14.7055 12.5785 14.7316 12.4478 14.7316 12.3158C14.7316 12.1838 14.7055 12.0531 14.6547 11.9312C14.6039 11.8094 14.5295 11.6988 14.4358 11.6058L10.1958 7.3658Z"
84
- fill="var(--re-data-grid-cross-ic-surface)"
85
- />
86
- </svg>
103
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
104
+ <path
105
+ d="M10.3052 8L13.759 4.5462C13.8354 4.47048 13.896 4.38038 13.9374 4.28111C13.9787 4.18186 14 4.07538 14 3.96785C14 3.86032 13.9787 3.75385 13.9374 3.65458C13.896 3.55532 13.8354 3.46523 13.759 3.3895L12.6105 2.24095C12.5347 2.1646 12.4447 2.104 12.3454 2.06265C12.2461 2.02129 12.1397 2 12.0321 2C11.9246 2 11.8182 2.02129 11.7189 2.06265C11.6196 2.104 11.5296 2.1646 11.4538 2.24095L8 5.69475L4.5462 2.24095C4.47048 2.1646 4.38038 2.104 4.28111 2.06265C4.18186 2.02129 4.07538 2 3.96785 2C3.86032 2 3.75385 2.02129 3.65458 2.06265C3.55532 2.104 3.46523 2.1646 3.3895 2.24095L2.24095 3.3895C2.1646 3.46523 2.104 3.55532 2.06265 3.65458C2.02129 3.75385 2 3.86032 2 3.96785C2 4.07538 2.02129 4.18186 2.06265 4.28111C2.104 4.38038 2.1646 4.47048 2.24095 4.5462L5.69475 8L2.24095 11.4538C2.1646 11.5296 2.104 11.6196 2.06265 11.7189C2.02129 11.8182 2 11.9246 2 12.0321C2 12.1397 2.02129 12.2461 2.06265 12.3454C2.104 12.4447 2.1646 12.5347 2.24095 12.6105L3.3895 13.759C3.46523 13.8354 3.55532 13.896 3.65458 13.9374C3.75385 13.9787 3.86032 14 3.96785 14C4.07538 14 4.18186 13.9787 4.28111 13.9374C4.38038 13.896 4.47048 13.8354 4.5462 13.759L8 10.3052L11.4538 13.759C11.5296 13.8354 11.6196 13.896 11.7189 13.9374C11.8182 13.9787 11.9246 14 12.0321 14C12.1397 14 12.2461 13.9787 12.3454 13.9374C12.4447 13.896 12.5347 13.8354 12.6105 13.759L13.759 12.6105C13.8354 12.5347 13.896 12.4447 13.9374 12.3454C13.9787 12.2461 14 12.1397 14 12.0321C14 11.9246 13.9787 11.8182 13.9374 11.7189C13.896 11.6196 13.8354 11.5296 13.759 11.4538L10.3052 8Z"
106
+ fill="var(--re-data-grid-cross-ic-surface)"
107
+ />
87
108
  </svg>
88
- `, styles: [":host{--re-data-grid-cross-ic-surface: currentColor}\n"] }]
109
+ `, styles: [":host{--re-data-grid-cross-ic-surface: currentColor;display:inline-block;width:16px;height:16px}\n"] }]
89
110
  }] });
90
111
 
91
112
  class EyeIcon {
@@ -147,7 +168,7 @@ class PinIcon {
147
168
  fill="var(--re-data-grid-pin-ic-surface)"
148
169
  />
149
170
  </svg>
150
- `, isInline: true, styles: [":host{--re-data-grid-pin-ic-surface: currentColor}.toRight{transform:rotate(-90deg)}\n"] });
171
+ `, isInline: true, styles: [":host{--re-data-grid-pin-ic-surface: currentColor;display:inline-block;width:16px;height:16px}.toRight{transform:rotate(-90deg)}\n"] });
151
172
  }
152
173
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: PinIcon, decorators: [{
153
174
  type: Component,
@@ -165,14 +186,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
165
186
  fill="var(--re-data-grid-pin-ic-surface)"
166
187
  />
167
188
  </svg>
168
- `, styles: [":host{--re-data-grid-pin-ic-surface: currentColor}.toRight{transform:rotate(-90deg)}\n"] }]
189
+ `, styles: [":host{--re-data-grid-pin-ic-surface: currentColor;display:inline-block;width:16px;height:16px}.toRight{transform:rotate(-90deg)}\n"] }]
169
190
  }], propDecorators: { toRight: [{ type: i0.Input, args: [{ isSignal: true, alias: "toRight", required: false }] }] } });
170
191
 
171
- // noinspection CssUnresolvedCustomProperty
172
192
  class DataGridColumnManager {
193
+ host = inject((ElementRef));
173
194
  columns = input([], ...(ngDevMode ? [{ debugName: "columns" }] : []));
174
195
  triggerLabel = input('Columns', ...(ngDevMode ? [{ debugName: "triggerLabel" }] : []));
175
- triggerTemplate = input(undefined, ...(ngDevMode ? [{ debugName: "triggerTemplate" }] : []));
176
196
  controlsVisible = input(true, { ...(ngDevMode ? { debugName: "controlsVisible" } : {}), transform: booleanAttribute });
177
197
  searchable = input(true, { ...(ngDevMode ? { debugName: "searchable" } : {}), transform: booleanAttribute });
178
198
  searchPlaceholder = input('Search columns...', ...(ngDevMode ? [{ debugName: "searchPlaceholder" }] : []));
@@ -180,11 +200,17 @@ class DataGridColumnManager {
180
200
  allowPin = input(true, { ...(ngDevMode ? { debugName: "allowPin" } : {}), transform: booleanAttribute });
181
201
  allowVisibility = input(true, { ...(ngDevMode ? { debugName: "allowVisibility" } : {}), transform: booleanAttribute });
182
202
  columnsChange = output();
203
+ triggerDirective = contentChild(DataGridColumnManagerTriggerDirective, ...(ngDevMode ? [{ debugName: "triggerDirective" }] : []));
204
+ columnTitleTemplate = contentChild((DataGridColumnManagerColumnTitleDirective), ...(ngDevMode ? [{ debugName: "columnTitleTemplate" }] : []));
183
205
  state = signal([], ...(ngDevMode ? [{ debugName: "state" }] : []));
184
206
  searchQuery = signal('', ...(ngDevMode ? [{ debugName: "searchQuery" }] : []));
185
207
  draggingKey = signal(null, ...(ngDevMode ? [{ debugName: "draggingKey" }] : []));
186
208
  opened = signal(false, ...(ngDevMode ? [{ debugName: "opened" }] : []));
209
+ openedPinMenuKey = signal(null, ...(ngDevMode ? [{ debugName: "openedPinMenuKey" }] : []));
210
+ panelLeft = signal(0, ...(ngDevMode ? [{ debugName: "panelLeft" }] : []));
211
+ hasCustomTrigger = signal(false, ...(ngDevMode ? [{ debugName: "hasCustomTrigger" }] : []));
187
212
  root = viewChild('root', ...(ngDevMode ? [{ debugName: "root" }] : []));
213
+ panel = viewChild('panel', ...(ngDevMode ? [{ debugName: "panel" }] : []));
188
214
  filteredColumns = computed(() => {
189
215
  const query = this.searchQuery().trim().toLowerCase();
190
216
  if (!query) {
@@ -201,20 +227,59 @@ class DataGridColumnManager {
201
227
  effect(() => {
202
228
  this.state.set(cloneColumns(this.columns()));
203
229
  });
230
+ afterNextRender(() => this.syncCustomTriggerState());
231
+ }
232
+ ngAfterContentChecked() {
233
+ this.syncCustomTriggerState();
204
234
  }
205
235
  pin = (key) => resolvePinState(this.state(), key);
206
236
  toggleOpen() {
207
- this.opened.update((current) => !current);
237
+ const nextOpened = !this.opened();
238
+ this.opened.set(nextOpened);
239
+ if (nextOpened) {
240
+ this.schedulePanelPositioning();
241
+ }
242
+ else {
243
+ this.openedPinMenuKey.set(null);
244
+ this.panelLeft.set(0);
245
+ }
246
+ }
247
+ onWindowResize() {
248
+ if (!this.opened()) {
249
+ return;
250
+ }
251
+ this.schedulePanelPositioning();
208
252
  }
209
253
  onDocumentMouseDown(target) {
254
+ if (target instanceof Node && this.openedPinMenuKey() && !this.isInsidePinMenu(target)) {
255
+ this.openedPinMenuKey.set(null);
256
+ }
210
257
  if (!this.opened()) {
211
258
  return;
212
259
  }
213
260
  const root = this.root()?.nativeElement;
214
261
  if (root && target instanceof Node && !root.contains(target)) {
262
+ this.openedPinMenuKey.set(null);
215
263
  this.opened.set(false);
216
264
  }
217
265
  }
266
+ togglePinMenu(event, key) {
267
+ event.stopPropagation();
268
+ this.openedPinMenuKey.update((current) => (current === key ? null : key));
269
+ }
270
+ selectPin(key, pin) {
271
+ this.onPin(key, pin);
272
+ this.openedPinMenuKey.set(null);
273
+ }
274
+ pinLabel(pin) {
275
+ if (pin === 'left') {
276
+ return 'Pin left';
277
+ }
278
+ if (pin === 'right') {
279
+ return 'Pin right';
280
+ }
281
+ return 'Unpinned';
282
+ }
218
283
  onSearch(event) {
219
284
  const target = event.target;
220
285
  this.searchQuery.set(target?.value ?? '');
@@ -343,267 +408,60 @@ class DataGridColumnManager {
343
408
  this.state.set(next);
344
409
  this.columnsChange.emit(cloneColumns(next));
345
410
  }
411
+ hasProjectedTrigger() {
412
+ return !!this.host.nativeElement.querySelector('[reDataGridColumnManagerTrigger]');
413
+ }
414
+ syncCustomTriggerState() {
415
+ const hasCustom = !!this.triggerDirective() || this.hasProjectedTrigger();
416
+ if (this.hasCustomTrigger() !== hasCustom) {
417
+ this.hasCustomTrigger.set(hasCustom);
418
+ }
419
+ }
420
+ isInsidePinMenu(target) {
421
+ return target instanceof Element && !!target.closest('[data-pin-menu]');
422
+ }
423
+ buildColumnTitleContext(column) {
424
+ const title = String(column.header || column.key);
425
+ return {
426
+ $implicit: title,
427
+ title,
428
+ column,
429
+ };
430
+ }
431
+ schedulePanelPositioning() {
432
+ afterNextRender(() => this.positionPanel());
433
+ }
434
+ positionPanel() {
435
+ const root = this.root()?.nativeElement;
436
+ const panel = this.panel()?.nativeElement;
437
+ if (!root || !panel || typeof window === 'undefined') {
438
+ this.panelLeft.set(0);
439
+ return;
440
+ }
441
+ const viewportPadding = 8;
442
+ const rootRect = root.getBoundingClientRect();
443
+ const panelWidth = panel.getBoundingClientRect().width;
444
+ const minLeft = viewportPadding - rootRect.left;
445
+ const maxLeft = window.innerWidth - viewportPadding - rootRect.left - panelWidth;
446
+ const lower = Math.min(minLeft, maxLeft);
447
+ const upper = Math.max(minLeft, maxLeft);
448
+ const nextLeft = Math.min(Math.max(0, lower), upper);
449
+ this.panelLeft.set(Number.isFinite(nextLeft) ? nextLeft : 0);
450
+ }
346
451
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridColumnManager, deps: [], target: i0.ɵɵFactoryTarget.Component });
347
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: DataGridColumnManager, isStandalone: true, selector: "re-data-grid-column-manager", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, triggerLabel: { classPropertyName: "triggerLabel", publicName: "triggerLabel", isSignal: true, isRequired: false, transformFunction: null }, triggerTemplate: { classPropertyName: "triggerTemplate", publicName: "triggerTemplate", isSignal: true, isRequired: false, transformFunction: null }, controlsVisible: { classPropertyName: "controlsVisible", publicName: "controlsVisible", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, allowReorder: { classPropertyName: "allowReorder", publicName: "allowReorder", isSignal: true, isRequired: false, transformFunction: null }, allowPin: { classPropertyName: "allowPin", publicName: "allowPin", isSignal: true, isRequired: false, transformFunction: null }, allowVisibility: { classPropertyName: "allowVisibility", publicName: "allowVisibility", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { columnsChange: "columnsChange" }, host: { attributes: { "document:mousedown": "onDocumentMouseDown($event.target)" } }, viewQueries: [{ propertyName: "root", first: true, predicate: ["root"], descendants: true, isSignal: true }], ngImport: i0, template: `
348
- <div class="re-dg-cm" #root>
349
- <button
350
- type="button"
351
- class="re-dg-cm__trigger"
352
- [class.re-dg-cm__trigger--open]="opened()"
353
- [attr.aria-expanded]="opened()"
354
- [attr.aria-haspopup]="'dialog'"
355
- (click)="toggleOpen()"
356
- >
357
- @if (triggerTemplate()) {
358
- <ng-container
359
- [ngTemplateOutlet]="triggerTemplate()!"
360
- [ngTemplateOutletContext]="{
361
- $implicit: triggerLabel(),
362
- visible: visibleColumnsCount(),
363
- total: state().length,
364
- }"
365
- />
366
- } @else {
367
- <span class="re-dg-cm__trigger-label">{{ triggerLabel() }}</span>
368
- <span class="re-dg-cm__trigger-count">{{ visibleColumnsCount() }}/{{ state().length }}</span>
369
- }
370
- </button>
371
-
372
- @if (opened()) {
373
- <div class="re-dg-cm__panel" role="dialog">
374
- @let list = filteredColumns();
375
-
376
- @if (controlsVisible() && searchable()) {
377
- <label class="re-dg-cm__search">
378
- <input
379
- type="search"
380
- [value]="searchQuery()"
381
- [placeholder]="searchPlaceholder()"
382
- (input)="onSearch($event)"
383
- />
384
- </label>
385
- }
386
-
387
- <div class="re-dg-cm__title-row">
388
- @if (controlsVisible()) {
389
- <div class="re-dg-cm__tools">
390
- <button type="button" (click)="showAll()">Show all</button>
391
- <button type="button" (click)="hideOptional()">Hide All</button>
392
- </div>
393
- } @else {
394
- <span></span>
395
- }
396
-
397
- <span class="re-dg-cm__meta">{{ visibleColumnsCount() }} / {{ state().length }}</span>
398
- </div>
399
-
400
- <div class="re-dg-cm__list">
401
- @for (column of list; track column.key) {
402
- @let currentPin = pin(column.key);
403
- @let disabled = !!column.disabled;
404
- @let canHideValue = canHideColumn(column.key);
405
-
406
- <div
407
- class="re-dg-cm__row"
408
- [attr.draggable]="allowReorder() && !disabled"
409
- [class.re-dg-cm__row--disabled]="disabled"
410
- [class.re-dg-cm__row--dragging]="draggingKey() === column.key"
411
- (dragstart)="onDragStart($event, column.key)"
412
- (dragover)="onDragOver($event)"
413
- (drop)="onDrop($event, column.key)"
414
- (dragend)="draggingKey.set(null)"
415
- >
416
- <span class="re-dg-cm__drag" title="Reorder">::</span>
417
-
418
- <label class="re-dg-cm__checkbox">
419
- <button
420
- [class.active]="column.visible !== false"
421
- [disabled]="disabled || !canHideValue"
422
- (click)="onVisibleChange(column.key)"
423
- >
424
- <re-eye-ic [open]="column.visible !== false" />
425
- </button>
426
- <span>{{ column.header || column.key }}</span>
427
- </label>
428
-
429
- <div class="re-dg-cm__actions">
430
- @if (allowPin()) {
431
- <button
432
- type="button"
433
- class="pin-button"
434
- [class.re-dg-cm__action--active]="currentPin === 'left'"
435
- [disabled]="disabled"
436
- (click)="onPin(column.key, 'left')"
437
- title="Pin left"
438
- >
439
- <re-pin-ic />
440
- </button>
441
-
442
- <button
443
- type="button"
444
- class="pin-button"
445
- [class.re-dg-cm__action--active]="currentPin === 'none'"
446
- [disabled]="disabled"
447
- (click)="onPin(column.key, 'none')"
448
- title="Unpin"
449
- >
450
- <re-cross-ic />
451
- </button>
452
-
453
- <button
454
- type="button"
455
- class="pin-button"
456
- [class.re-dg-cm__action--active]="currentPin === 'right'"
457
- [disabled]="disabled"
458
- (click)="onPin(column.key, 'right')"
459
- title="Pin right"
460
- >
461
- <re-pin-ic toRight />
462
- </button>
463
- }
464
- </div>
465
- </div>
466
- }
467
- </div>
468
- </div>
469
- }
470
- </div>
471
- `, isInline: true, styles: [":host{--re-data-grid-cm-gap: .5rem;--re-data-grid-cm-rounded: .625rem;--re-data-grid-cm-border: 1px solid var(--surface-border, #dfe1e6);--re-data-grid-cm-surface: var(--surface-neutral, #fff);--re-data-grid-cm-muted: var(--text-muted, #64748b);--re-data-grid-cm-active: var(--primary-color, #2a90f4);--re-data-grid-cm-shadow: 0 12px 30px rgba(15, 23, 42, .18);display:inline-block;position:relative}.re-dg-cm{position:relative;display:inline-flex;flex-direction:column;gap:var(--re-data-grid-cm-gap)}.re-dg-cm__trigger{display:inline-flex;align-items:center;gap:.5rem;height:2.25rem;padding:0 .75rem;border:var(--re-data-grid-cm-border);border-radius:999px;background:var(--re-data-grid-cm-surface);color:inherit;cursor:pointer}.re-dg-cm__trigger--open{box-shadow:0 0 0 2px color-mix(in srgb,var(--re-data-grid-cm-active) 25%,transparent)}.re-dg-cm__trigger-label{font-size:.8125rem;font-weight:600}.re-dg-cm__trigger-count{font-size:.75rem;color:var(--re-data-grid-cm-muted)}.re-dg-cm__panel{position:absolute;top:calc(100% + .5rem);left:0;z-index:50;min-width:18rem;width:max-content;max-width:min(24rem,85vw);display:grid;gap:var(--re-data-grid-cm-gap);padding:.75rem;border:var(--re-data-grid-cm-border);border-radius:var(--re-data-grid-cm-rounded);background:var(--re-data-grid-cm-surface);box-shadow:var(--re-data-grid-cm-shadow)}.re-dg-cm__tools,.re-dg-cm__row,.re-dg-cm__actions{display:flex;align-items:center}.re-dg-cm__meta{color:var(--re-data-grid-cm-muted);font-size:.75rem}.re-dg-cm__search input{width:100%;height:2rem;border-radius:.5rem;border:var(--re-data-grid-cm-border);padding:0 .625rem;background:var(--re-data-grid-cm-surface);color:inherit}.re-dg-cm__tools{gap:.5rem}.re-dg-cm__title-row{display:flex;justify-content:space-between}.re-dg-cm__tools button,.re-dg-cm__actions button{color:inherit;cursor:pointer;font-size:.75rem;line-height:1}.re-dg-cm__tools button{height:1.8rem;padding:0 .5rem}.re-dg-cm__actions button{width:1.7rem;height:1.7rem}.re-dg-cm__list{display:grid;gap:.375rem;max-height:22rem;overflow:auto;padding-right:.125rem}.re-dg-cm__row{gap:.5rem;padding:.375rem .5rem;border:var(--re-data-grid-cm-border);border-radius:.5rem;background:color-mix(in srgb,var(--re-data-grid-cm-surface) 88%,#f8fafc)}.re-dg-cm__row--dragging{opacity:.55}.re-dg-cm__row--disabled{opacity:.6}.re-dg-cm__drag{width:1rem;color:var(--re-data-grid-cm-muted);cursor:grab;-webkit-user-select:none;user-select:none}.re-dg-cm__checkbox{display:inline-flex;align-items:center;gap:.5rem;flex:1 1 auto;min-width:0;font-size:.8125rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.re-dg-cm__checkbox>button{color:var(--re-data-grid-cm-muted)}.re-dg-cm__checkbox>button.active{color:var(--re-data-grid-cm-active)}.re-dg-cm__actions{gap:.25rem;margin-left:auto}.re-dg-cm__action--active{color:var(--re-data-grid-cm-active)!important;font-weight:700}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: EyeIcon, selector: "re-eye-ic", inputs: ["open"] }, { kind: "component", type: CrossIcon, selector: "re-cross-ic" }, { kind: "component", type: PinIcon, selector: "re-pin-ic", inputs: ["toRight"] }] });
452
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.1", type: DataGridColumnManager, isStandalone: true, selector: "re-data-grid-column-manager", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, triggerLabel: { classPropertyName: "triggerLabel", publicName: "triggerLabel", isSignal: true, isRequired: false, transformFunction: null }, controlsVisible: { classPropertyName: "controlsVisible", publicName: "controlsVisible", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, allowReorder: { classPropertyName: "allowReorder", publicName: "allowReorder", isSignal: true, isRequired: false, transformFunction: null }, allowPin: { classPropertyName: "allowPin", publicName: "allowPin", isSignal: true, isRequired: false, transformFunction: null }, allowVisibility: { classPropertyName: "allowVisibility", publicName: "allowVisibility", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { columnsChange: "columnsChange" }, host: { attributes: { "document:mousedown": "onDocumentMouseDown($event.target)", "window:resize": "onWindowResize()" } }, queries: [{ propertyName: "triggerDirective", first: true, predicate: DataGridColumnManagerTriggerDirective, descendants: true, isSignal: true }, { propertyName: "columnTitleTemplate", first: true, predicate: (DataGridColumnManagerColumnTitleDirective), descendants: true, isSignal: true }], viewQueries: [{ propertyName: "root", first: true, predicate: ["root"], descendants: true, isSignal: true }, { propertyName: "panel", first: true, predicate: ["panel"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"re-dg-cm\" #root>\n <button\n type=\"button\"\n class=\"re-dg-cm__trigger\"\n [class.re-dg-cm__trigger--open]=\"opened()\"\n [attr.aria-expanded]=\"opened()\"\n [attr.aria-haspopup]=\"'dialog'\"\n (click)=\"toggleOpen()\"\n >\n @if (hasCustomTrigger()) {\n <ng-content select=\"[reDataGridColumnManagerTrigger]\" />\n } @else {\n <span class=\"re-dg-cm__trigger-label\">{{ triggerLabel() }}</span>\n <span class=\"re-dg-cm__trigger-count\">{{ visibleColumnsCount() }}/{{ state().length }}</span>\n }\n </button>\n\n @if (opened()) {\n <div class=\"re-dg-cm__panel\" #panel role=\"dialog\" [style.left.px]=\"panelLeft()\">\n @let list = filteredColumns();\n\n @if (controlsVisible() && searchable()) {\n <label class=\"re-dg-cm__search\">\n <input\n type=\"search\"\n [value]=\"searchQuery()\"\n [placeholder]=\"searchPlaceholder()\"\n (input)=\"onSearch($event)\"\n />\n </label>\n }\n\n <div class=\"re-dg-cm__title-row\">\n @if (controlsVisible()) {\n <div class=\"re-dg-cm__tools\">\n <button type=\"button\" (click)=\"showAll()\">Show all</button>\n <button type=\"button\" (click)=\"hideOptional()\">Hide All</button>\n </div>\n } @else {\n <span></span>\n }\n\n <span class=\"re-dg-cm__meta\">{{ visibleColumnsCount() }} / {{ state().length }}</span>\n </div>\n\n <div class=\"re-dg-cm__list\">\n @for (column of list; track column.key) {\n @let currentPin = pin(column.key);\n @let disabled = !!column.disabled;\n @let canHideValue = canHideColumn(column.key);\n\n <div\n class=\"re-dg-cm__row\"\n [attr.draggable]=\"allowReorder() && !disabled\"\n [class.re-dg-cm__row--disabled]=\"disabled\"\n [class.re-dg-cm__row--dragging]=\"draggingKey() === column.key\"\n (dragstart)=\"onDragStart($event, column.key)\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDrop($event, column.key)\"\n (dragend)=\"draggingKey.set(null)\"\n >\n <span class=\"re-dg-cm__drag\" title=\"Reorder\">::</span>\n\n <label class=\"re-dg-cm__checkbox\">\n <button\n [class.active]=\"column.visible !== false\"\n [disabled]=\"disabled || !canHideValue\"\n (click)=\"onVisibleChange(column.key)\"\n >\n <re-eye-ic [open]=\"column.visible !== false\" />\n </button>\n @if (columnTitleTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"columnTitleTemplate()!.template\"\n [ngTemplateOutletContext]=\"buildColumnTitleContext(column)\"\n />\n } @else {\n <span>{{ column.header || column.key }}</span>\n }\n </label>\n\n <div class=\"re-dg-cm__actions\">\n @if (allowPin()) {\n <div class=\"re-dg-cm__pin-menu\" data-pin-menu>\n <button\n type=\"button\"\n class=\"re-dg-cm__pin-current\"\n [disabled]=\"disabled\"\n [class.re-dg-cm__action--active]=\"currentPin !== 'none'\"\n [attr.aria-expanded]=\"openedPinMenuKey() === column.key\"\n (click)=\"togglePinMenu($event, column.key)\"\n [title]=\"pinLabel(currentPin)\"\n >\n @if (currentPin === 'left') {\n <re-pin-ic />\n } @else if (currentPin === 'right') {\n <re-pin-ic toRight />\n } @else {\n <re-cross-ic />\n }\n </button>\n\n @if (openedPinMenuKey() === column.key && !disabled) {\n <div class=\"re-dg-cm__pin-popover\" data-pin-menu role=\"menu\">\n <button\n type=\"button\"\n class=\"pin-button\"\n [class.re-dg-cm__action--active]=\"currentPin === 'left'\"\n (click)=\"selectPin(column.key, 'left')\"\n title=\"Pin left\"\n >\n <re-pin-ic />\n </button>\n\n <button\n type=\"button\"\n class=\"pin-button\"\n [class.re-dg-cm__action--active]=\"currentPin === 'none'\"\n (click)=\"selectPin(column.key, 'none')\"\n title=\"Unpin\"\n >\n <re-cross-ic />\n </button>\n\n <button\n type=\"button\"\n class=\"pin-button\"\n [class.re-dg-cm__action--active]=\"currentPin === 'right'\"\n (click)=\"selectPin(column.key, 'right')\"\n title=\"Pin right\"\n >\n <re-pin-ic toRight />\n </button>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n }\n</div>\n", styles: [":host{--re-data-grid-cm-gap: .5rem;--re-data-grid-cm-rounded: .625rem;--re-data-grid-cm-border: 1px solid var(--surface-border, #dfe1e6);--re-data-grid-cm-surface: var(--surface-neutral, #fff);--re-data-grid-cm-muted: var(--text-muted, #64748b);--re-data-grid-cm-active: var(--primary-color, #2a90f4);--re-data-grid-cm-shadow: 0 12px 30px rgba(15, 23, 42, .18);display:inline-block;position:relative}.re-dg-cm{position:relative;display:inline-flex;flex-direction:column;gap:var(--re-data-grid-cm-gap)}.re-dg-cm__trigger{display:inline-flex;align-items:center;gap:.5rem;height:2.25rem;padding:0 .75rem;border:var(--re-data-grid-cm-border);border-radius:999px;background:var(--re-data-grid-cm-surface);color:inherit;cursor:pointer}.re-dg-cm__trigger--open{box-shadow:0 0 0 2px color-mix(in srgb,var(--re-data-grid-cm-active) 25%,transparent)}.re-dg-cm__trigger-label{font-size:.8125rem;font-weight:600}.re-dg-cm__trigger-count{font-size:.75rem;color:var(--re-data-grid-cm-muted)}.re-dg-cm__panel{position:absolute;top:calc(100% + .5rem);left:0;z-index:50;min-width:18rem;width:max-content;max-width:min(24rem,85vw);display:grid;gap:var(--re-data-grid-cm-gap);padding:.75rem;border:var(--re-data-grid-cm-border);border-radius:var(--re-data-grid-cm-rounded);background:var(--re-data-grid-cm-surface);box-shadow:var(--re-data-grid-cm-shadow)}.re-dg-cm__tools,.re-dg-cm__row,.re-dg-cm__actions{display:flex;align-items:center}.re-dg-cm__meta{color:var(--re-data-grid-cm-muted);font-size:.75rem}.re-dg-cm__search input{width:100%;height:2rem;border-radius:.5rem;border:var(--re-data-grid-cm-border);padding:0 .625rem;background:var(--re-data-grid-cm-surface);color:inherit}.re-dg-cm__tools{gap:.5rem}.re-dg-cm__title-row{display:flex;justify-content:space-between}.re-dg-cm__tools button,.re-dg-cm__actions button{color:inherit;cursor:pointer;font-size:.75rem;line-height:1}.re-dg-cm__tools button{height:1.8rem;padding:0 .5rem}.re-dg-cm__actions button{width:1.7rem;height:1.7rem}.re-dg-cm__list{display:grid;gap:.375rem;max-height:22rem;overflow:auto;padding-right:.125rem}.re-dg-cm__row{gap:.5rem;padding:.375rem .5rem;border:var(--re-data-grid-cm-border);border-radius:.5rem;background:color-mix(in srgb,var(--re-data-grid-cm-surface) 88%,#f8fafc)}.re-dg-cm__row--dragging{opacity:.55}.re-dg-cm__row--disabled{opacity:.6}.re-dg-cm__drag{width:1rem;color:var(--re-data-grid-cm-muted);cursor:grab;-webkit-user-select:none;user-select:none}.re-dg-cm__checkbox{display:inline-flex;align-items:center;gap:.5rem;flex:1 1 auto;min-width:0;font-size:.8125rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.re-dg-cm__checkbox>button{color:var(--re-data-grid-cm-muted)}.re-dg-cm__checkbox>button.active{color:var(--re-data-grid-cm-active)}.re-dg-cm__actions{gap:.25rem;margin-left:auto}.re-dg-cm__pin-menu{position:relative}.re-dg-cm__pin-current{width:1.7rem;height:1.7rem}.re-dg-cm__pin-popover{position:absolute;right:0;top:calc(100% + .25rem);z-index:2;display:flex;align-items:center;gap:.25rem;padding:.25rem;border:var(--re-data-grid-cm-border);border-radius:.5rem;background:var(--re-data-grid-cm-surface);box-shadow:var(--re-data-grid-cm-shadow)}.re-dg-cm__action--active{color:var(--re-data-grid-cm-active)!important;font-weight:700}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: EyeIcon, selector: "re-eye-ic", inputs: ["open"] }, { kind: "component", type: CrossIcon, selector: "re-cross-ic" }, { kind: "component", type: PinIcon, selector: "re-pin-ic", inputs: ["toRight"] }] });
472
453
  }
473
454
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImport: i0, type: DataGridColumnManager, decorators: [{
474
455
  type: Component,
475
- args: [{ selector: 're-data-grid-column-manager', standalone: true, template: `
476
- <div class="re-dg-cm" #root>
477
- <button
478
- type="button"
479
- class="re-dg-cm__trigger"
480
- [class.re-dg-cm__trigger--open]="opened()"
481
- [attr.aria-expanded]="opened()"
482
- [attr.aria-haspopup]="'dialog'"
483
- (click)="toggleOpen()"
484
- >
485
- @if (triggerTemplate()) {
486
- <ng-container
487
- [ngTemplateOutlet]="triggerTemplate()!"
488
- [ngTemplateOutletContext]="{
489
- $implicit: triggerLabel(),
490
- visible: visibleColumnsCount(),
491
- total: state().length,
492
- }"
493
- />
494
- } @else {
495
- <span class="re-dg-cm__trigger-label">{{ triggerLabel() }}</span>
496
- <span class="re-dg-cm__trigger-count">{{ visibleColumnsCount() }}/{{ state().length }}</span>
497
- }
498
- </button>
499
-
500
- @if (opened()) {
501
- <div class="re-dg-cm__panel" role="dialog">
502
- @let list = filteredColumns();
503
-
504
- @if (controlsVisible() && searchable()) {
505
- <label class="re-dg-cm__search">
506
- <input
507
- type="search"
508
- [value]="searchQuery()"
509
- [placeholder]="searchPlaceholder()"
510
- (input)="onSearch($event)"
511
- />
512
- </label>
513
- }
514
-
515
- <div class="re-dg-cm__title-row">
516
- @if (controlsVisible()) {
517
- <div class="re-dg-cm__tools">
518
- <button type="button" (click)="showAll()">Show all</button>
519
- <button type="button" (click)="hideOptional()">Hide All</button>
520
- </div>
521
- } @else {
522
- <span></span>
523
- }
524
-
525
- <span class="re-dg-cm__meta">{{ visibleColumnsCount() }} / {{ state().length }}</span>
526
- </div>
527
-
528
- <div class="re-dg-cm__list">
529
- @for (column of list; track column.key) {
530
- @let currentPin = pin(column.key);
531
- @let disabled = !!column.disabled;
532
- @let canHideValue = canHideColumn(column.key);
533
-
534
- <div
535
- class="re-dg-cm__row"
536
- [attr.draggable]="allowReorder() && !disabled"
537
- [class.re-dg-cm__row--disabled]="disabled"
538
- [class.re-dg-cm__row--dragging]="draggingKey() === column.key"
539
- (dragstart)="onDragStart($event, column.key)"
540
- (dragover)="onDragOver($event)"
541
- (drop)="onDrop($event, column.key)"
542
- (dragend)="draggingKey.set(null)"
543
- >
544
- <span class="re-dg-cm__drag" title="Reorder">::</span>
545
-
546
- <label class="re-dg-cm__checkbox">
547
- <button
548
- [class.active]="column.visible !== false"
549
- [disabled]="disabled || !canHideValue"
550
- (click)="onVisibleChange(column.key)"
551
- >
552
- <re-eye-ic [open]="column.visible !== false" />
553
- </button>
554
- <span>{{ column.header || column.key }}</span>
555
- </label>
556
-
557
- <div class="re-dg-cm__actions">
558
- @if (allowPin()) {
559
- <button
560
- type="button"
561
- class="pin-button"
562
- [class.re-dg-cm__action--active]="currentPin === 'left'"
563
- [disabled]="disabled"
564
- (click)="onPin(column.key, 'left')"
565
- title="Pin left"
566
- >
567
- <re-pin-ic />
568
- </button>
569
-
570
- <button
571
- type="button"
572
- class="pin-button"
573
- [class.re-dg-cm__action--active]="currentPin === 'none'"
574
- [disabled]="disabled"
575
- (click)="onPin(column.key, 'none')"
576
- title="Unpin"
577
- >
578
- <re-cross-ic />
579
- </button>
580
-
581
- <button
582
- type="button"
583
- class="pin-button"
584
- [class.re-dg-cm__action--active]="currentPin === 'right'"
585
- [disabled]="disabled"
586
- (click)="onPin(column.key, 'right')"
587
- title="Pin right"
588
- >
589
- <re-pin-ic toRight />
590
- </button>
591
- }
592
- </div>
593
- </div>
594
- }
595
- </div>
596
- </div>
597
- }
598
- </div>
599
- `, host: {
456
+ args: [{ selector: 're-data-grid-column-manager', standalone: true, host: {
600
457
  'document:mousedown': 'onDocumentMouseDown($event.target)',
601
- }, imports: [NgTemplateOutlet, EyeIcon, CrossIcon, PinIcon], styles: [":host{--re-data-grid-cm-gap: .5rem;--re-data-grid-cm-rounded: .625rem;--re-data-grid-cm-border: 1px solid var(--surface-border, #dfe1e6);--re-data-grid-cm-surface: var(--surface-neutral, #fff);--re-data-grid-cm-muted: var(--text-muted, #64748b);--re-data-grid-cm-active: var(--primary-color, #2a90f4);--re-data-grid-cm-shadow: 0 12px 30px rgba(15, 23, 42, .18);display:inline-block;position:relative}.re-dg-cm{position:relative;display:inline-flex;flex-direction:column;gap:var(--re-data-grid-cm-gap)}.re-dg-cm__trigger{display:inline-flex;align-items:center;gap:.5rem;height:2.25rem;padding:0 .75rem;border:var(--re-data-grid-cm-border);border-radius:999px;background:var(--re-data-grid-cm-surface);color:inherit;cursor:pointer}.re-dg-cm__trigger--open{box-shadow:0 0 0 2px color-mix(in srgb,var(--re-data-grid-cm-active) 25%,transparent)}.re-dg-cm__trigger-label{font-size:.8125rem;font-weight:600}.re-dg-cm__trigger-count{font-size:.75rem;color:var(--re-data-grid-cm-muted)}.re-dg-cm__panel{position:absolute;top:calc(100% + .5rem);left:0;z-index:50;min-width:18rem;width:max-content;max-width:min(24rem,85vw);display:grid;gap:var(--re-data-grid-cm-gap);padding:.75rem;border:var(--re-data-grid-cm-border);border-radius:var(--re-data-grid-cm-rounded);background:var(--re-data-grid-cm-surface);box-shadow:var(--re-data-grid-cm-shadow)}.re-dg-cm__tools,.re-dg-cm__row,.re-dg-cm__actions{display:flex;align-items:center}.re-dg-cm__meta{color:var(--re-data-grid-cm-muted);font-size:.75rem}.re-dg-cm__search input{width:100%;height:2rem;border-radius:.5rem;border:var(--re-data-grid-cm-border);padding:0 .625rem;background:var(--re-data-grid-cm-surface);color:inherit}.re-dg-cm__tools{gap:.5rem}.re-dg-cm__title-row{display:flex;justify-content:space-between}.re-dg-cm__tools button,.re-dg-cm__actions button{color:inherit;cursor:pointer;font-size:.75rem;line-height:1}.re-dg-cm__tools button{height:1.8rem;padding:0 .5rem}.re-dg-cm__actions button{width:1.7rem;height:1.7rem}.re-dg-cm__list{display:grid;gap:.375rem;max-height:22rem;overflow:auto;padding-right:.125rem}.re-dg-cm__row{gap:.5rem;padding:.375rem .5rem;border:var(--re-data-grid-cm-border);border-radius:.5rem;background:color-mix(in srgb,var(--re-data-grid-cm-surface) 88%,#f8fafc)}.re-dg-cm__row--dragging{opacity:.55}.re-dg-cm__row--disabled{opacity:.6}.re-dg-cm__drag{width:1rem;color:var(--re-data-grid-cm-muted);cursor:grab;-webkit-user-select:none;user-select:none}.re-dg-cm__checkbox{display:inline-flex;align-items:center;gap:.5rem;flex:1 1 auto;min-width:0;font-size:.8125rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.re-dg-cm__checkbox>button{color:var(--re-data-grid-cm-muted)}.re-dg-cm__checkbox>button.active{color:var(--re-data-grid-cm-active)}.re-dg-cm__actions{gap:.25rem;margin-left:auto}.re-dg-cm__action--active{color:var(--re-data-grid-cm-active)!important;font-weight:700}\n"] }]
602
- }], ctorParameters: () => [], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], triggerLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerLabel", required: false }] }], triggerTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerTemplate", required: false }] }], controlsVisible: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlsVisible", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], allowReorder: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowReorder", required: false }] }], allowPin: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowPin", required: false }] }], allowVisibility: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowVisibility", required: false }] }], columnsChange: [{ type: i0.Output, args: ["columnsChange"] }], root: [{ type: i0.ViewChild, args: ['root', { isSignal: true }] }] } });
458
+ 'window:resize': 'onWindowResize()',
459
+ }, imports: [NgTemplateOutlet, EyeIcon, CrossIcon, PinIcon], template: "<div class=\"re-dg-cm\" #root>\n <button\n type=\"button\"\n class=\"re-dg-cm__trigger\"\n [class.re-dg-cm__trigger--open]=\"opened()\"\n [attr.aria-expanded]=\"opened()\"\n [attr.aria-haspopup]=\"'dialog'\"\n (click)=\"toggleOpen()\"\n >\n @if (hasCustomTrigger()) {\n <ng-content select=\"[reDataGridColumnManagerTrigger]\" />\n } @else {\n <span class=\"re-dg-cm__trigger-label\">{{ triggerLabel() }}</span>\n <span class=\"re-dg-cm__trigger-count\">{{ visibleColumnsCount() }}/{{ state().length }}</span>\n }\n </button>\n\n @if (opened()) {\n <div class=\"re-dg-cm__panel\" #panel role=\"dialog\" [style.left.px]=\"panelLeft()\">\n @let list = filteredColumns();\n\n @if (controlsVisible() && searchable()) {\n <label class=\"re-dg-cm__search\">\n <input\n type=\"search\"\n [value]=\"searchQuery()\"\n [placeholder]=\"searchPlaceholder()\"\n (input)=\"onSearch($event)\"\n />\n </label>\n }\n\n <div class=\"re-dg-cm__title-row\">\n @if (controlsVisible()) {\n <div class=\"re-dg-cm__tools\">\n <button type=\"button\" (click)=\"showAll()\">Show all</button>\n <button type=\"button\" (click)=\"hideOptional()\">Hide All</button>\n </div>\n } @else {\n <span></span>\n }\n\n <span class=\"re-dg-cm__meta\">{{ visibleColumnsCount() }} / {{ state().length }}</span>\n </div>\n\n <div class=\"re-dg-cm__list\">\n @for (column of list; track column.key) {\n @let currentPin = pin(column.key);\n @let disabled = !!column.disabled;\n @let canHideValue = canHideColumn(column.key);\n\n <div\n class=\"re-dg-cm__row\"\n [attr.draggable]=\"allowReorder() && !disabled\"\n [class.re-dg-cm__row--disabled]=\"disabled\"\n [class.re-dg-cm__row--dragging]=\"draggingKey() === column.key\"\n (dragstart)=\"onDragStart($event, column.key)\"\n (dragover)=\"onDragOver($event)\"\n (drop)=\"onDrop($event, column.key)\"\n (dragend)=\"draggingKey.set(null)\"\n >\n <span class=\"re-dg-cm__drag\" title=\"Reorder\">::</span>\n\n <label class=\"re-dg-cm__checkbox\">\n <button\n [class.active]=\"column.visible !== false\"\n [disabled]=\"disabled || !canHideValue\"\n (click)=\"onVisibleChange(column.key)\"\n >\n <re-eye-ic [open]=\"column.visible !== false\" />\n </button>\n @if (columnTitleTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"columnTitleTemplate()!.template\"\n [ngTemplateOutletContext]=\"buildColumnTitleContext(column)\"\n />\n } @else {\n <span>{{ column.header || column.key }}</span>\n }\n </label>\n\n <div class=\"re-dg-cm__actions\">\n @if (allowPin()) {\n <div class=\"re-dg-cm__pin-menu\" data-pin-menu>\n <button\n type=\"button\"\n class=\"re-dg-cm__pin-current\"\n [disabled]=\"disabled\"\n [class.re-dg-cm__action--active]=\"currentPin !== 'none'\"\n [attr.aria-expanded]=\"openedPinMenuKey() === column.key\"\n (click)=\"togglePinMenu($event, column.key)\"\n [title]=\"pinLabel(currentPin)\"\n >\n @if (currentPin === 'left') {\n <re-pin-ic />\n } @else if (currentPin === 'right') {\n <re-pin-ic toRight />\n } @else {\n <re-cross-ic />\n }\n </button>\n\n @if (openedPinMenuKey() === column.key && !disabled) {\n <div class=\"re-dg-cm__pin-popover\" data-pin-menu role=\"menu\">\n <button\n type=\"button\"\n class=\"pin-button\"\n [class.re-dg-cm__action--active]=\"currentPin === 'left'\"\n (click)=\"selectPin(column.key, 'left')\"\n title=\"Pin left\"\n >\n <re-pin-ic />\n </button>\n\n <button\n type=\"button\"\n class=\"pin-button\"\n [class.re-dg-cm__action--active]=\"currentPin === 'none'\"\n (click)=\"selectPin(column.key, 'none')\"\n title=\"Unpin\"\n >\n <re-cross-ic />\n </button>\n\n <button\n type=\"button\"\n class=\"pin-button\"\n [class.re-dg-cm__action--active]=\"currentPin === 'right'\"\n (click)=\"selectPin(column.key, 'right')\"\n title=\"Pin right\"\n >\n <re-pin-ic toRight />\n </button>\n </div>\n }\n </div>\n }\n </div>\n </div>\n }\n </div>\n </div>\n }\n</div>\n", styles: [":host{--re-data-grid-cm-gap: .5rem;--re-data-grid-cm-rounded: .625rem;--re-data-grid-cm-border: 1px solid var(--surface-border, #dfe1e6);--re-data-grid-cm-surface: var(--surface-neutral, #fff);--re-data-grid-cm-muted: var(--text-muted, #64748b);--re-data-grid-cm-active: var(--primary-color, #2a90f4);--re-data-grid-cm-shadow: 0 12px 30px rgba(15, 23, 42, .18);display:inline-block;position:relative}.re-dg-cm{position:relative;display:inline-flex;flex-direction:column;gap:var(--re-data-grid-cm-gap)}.re-dg-cm__trigger{display:inline-flex;align-items:center;gap:.5rem;height:2.25rem;padding:0 .75rem;border:var(--re-data-grid-cm-border);border-radius:999px;background:var(--re-data-grid-cm-surface);color:inherit;cursor:pointer}.re-dg-cm__trigger--open{box-shadow:0 0 0 2px color-mix(in srgb,var(--re-data-grid-cm-active) 25%,transparent)}.re-dg-cm__trigger-label{font-size:.8125rem;font-weight:600}.re-dg-cm__trigger-count{font-size:.75rem;color:var(--re-data-grid-cm-muted)}.re-dg-cm__panel{position:absolute;top:calc(100% + .5rem);left:0;z-index:50;min-width:18rem;width:max-content;max-width:min(24rem,85vw);display:grid;gap:var(--re-data-grid-cm-gap);padding:.75rem;border:var(--re-data-grid-cm-border);border-radius:var(--re-data-grid-cm-rounded);background:var(--re-data-grid-cm-surface);box-shadow:var(--re-data-grid-cm-shadow)}.re-dg-cm__tools,.re-dg-cm__row,.re-dg-cm__actions{display:flex;align-items:center}.re-dg-cm__meta{color:var(--re-data-grid-cm-muted);font-size:.75rem}.re-dg-cm__search input{width:100%;height:2rem;border-radius:.5rem;border:var(--re-data-grid-cm-border);padding:0 .625rem;background:var(--re-data-grid-cm-surface);color:inherit}.re-dg-cm__tools{gap:.5rem}.re-dg-cm__title-row{display:flex;justify-content:space-between}.re-dg-cm__tools button,.re-dg-cm__actions button{color:inherit;cursor:pointer;font-size:.75rem;line-height:1}.re-dg-cm__tools button{height:1.8rem;padding:0 .5rem}.re-dg-cm__actions button{width:1.7rem;height:1.7rem}.re-dg-cm__list{display:grid;gap:.375rem;max-height:22rem;overflow:auto;padding-right:.125rem}.re-dg-cm__row{gap:.5rem;padding:.375rem .5rem;border:var(--re-data-grid-cm-border);border-radius:.5rem;background:color-mix(in srgb,var(--re-data-grid-cm-surface) 88%,#f8fafc)}.re-dg-cm__row--dragging{opacity:.55}.re-dg-cm__row--disabled{opacity:.6}.re-dg-cm__drag{width:1rem;color:var(--re-data-grid-cm-muted);cursor:grab;-webkit-user-select:none;user-select:none}.re-dg-cm__checkbox{display:inline-flex;align-items:center;gap:.5rem;flex:1 1 auto;min-width:0;font-size:.8125rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.re-dg-cm__checkbox>button{color:var(--re-data-grid-cm-muted)}.re-dg-cm__checkbox>button.active{color:var(--re-data-grid-cm-active)}.re-dg-cm__actions{gap:.25rem;margin-left:auto}.re-dg-cm__pin-menu{position:relative}.re-dg-cm__pin-current{width:1.7rem;height:1.7rem}.re-dg-cm__pin-popover{position:absolute;right:0;top:calc(100% + .25rem);z-index:2;display:flex;align-items:center;gap:.25rem;padding:.25rem;border:var(--re-data-grid-cm-border);border-radius:.5rem;background:var(--re-data-grid-cm-surface);box-shadow:var(--re-data-grid-cm-shadow)}.re-dg-cm__action--active{color:var(--re-data-grid-cm-active)!important;font-weight:700}\n"] }]
460
+ }], ctorParameters: () => [], propDecorators: { columns: [{ type: i0.Input, args: [{ isSignal: true, alias: "columns", required: false }] }], triggerLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "triggerLabel", required: false }] }], controlsVisible: [{ type: i0.Input, args: [{ isSignal: true, alias: "controlsVisible", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], allowReorder: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowReorder", required: false }] }], allowPin: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowPin", required: false }] }], allowVisibility: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowVisibility", required: false }] }], columnsChange: [{ type: i0.Output, args: ["columnsChange"] }], triggerDirective: [{ type: i0.ContentChild, args: [i0.forwardRef(() => DataGridColumnManagerTriggerDirective), { isSignal: true }] }], columnTitleTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => DataGridColumnManagerColumnTitleDirective), { isSignal: true }] }], root: [{ type: i0.ViewChild, args: ['root', { isSignal: true }] }], panel: [{ type: i0.ViewChild, args: ['panel', { isSignal: true }] }] } });
603
461
 
604
462
  /**
605
463
  * Generated bundle index. Do not edit.
606
464
  */
607
465
 
608
- export { DataGridColumnManager };
466
+ export { DataGridColumnManager, DataGridColumnManagerColumnTitleDirective, DataGridColumnManagerTriggerDirective };
609
467
  //# sourceMappingURL=reforgium-data-grid-column-manager.mjs.map
@@ -1,4 +1,4 @@
1
- import { c as computeScrollbarState, a as clampThumbTop, m as mapThumbTopToScrollTop } from './reforgium-data-grid-reforgium-data-grid-Op6gjm7A.mjs';
1
+ import { c as computeScrollbarState, a as clampThumbTop, m as mapThumbTopToScrollTop } from './reforgium-data-grid-reforgium-data-grid-YSzBRJ5h.mjs';
2
2
 
3
3
  function createGridOverlayScrollFeature(ctx) {
4
4
  const showScrollbar = () => {
@@ -76,4 +76,4 @@ function createGridOverlayScrollFeature(ctx) {
76
76
  }
77
77
 
78
78
  export { createGridOverlayScrollFeature };
79
- //# sourceMappingURL=reforgium-data-grid-grid-overlay-scroll.feature-BSdC3IrC.mjs.map
79
+ //# sourceMappingURL=reforgium-data-grid-grid-overlay-scroll.feature-C-_Cnt4M.mjs.map
@@ -3097,12 +3097,6 @@ class DataGrid {
3097
3097
  this.currentSortOrder = last.order;
3098
3098
  return;
3099
3099
  }
3100
- const firstSortable = this.extendedColumns()?.find((c) => !!c.sortKey);
3101
- if (firstSortable) {
3102
- this.currentSortField = firstSortable.sortKey;
3103
- this.currentSortOrder = 'asc';
3104
- this.setCurrentSorts([{ key: firstSortable.sortKey, order: 'asc' }]);
3105
- }
3106
3100
  }
3107
3101
  initScroll() {
3108
3102
  void this.loadOverlayScrollFeature();
@@ -3165,7 +3159,7 @@ class DataGrid {
3165
3159
  if (this.overlayScrollFeaturePromise) {
3166
3160
  return this.overlayScrollFeaturePromise;
3167
3161
  }
3168
- this.overlayScrollFeaturePromise = import('./reforgium-data-grid-grid-overlay-scroll.feature-BSdC3IrC.mjs').then(({ createGridOverlayScrollFeature }) => {
3162
+ this.overlayScrollFeaturePromise = import('./reforgium-data-grid-grid-overlay-scroll.feature-C-_Cnt4M.mjs').then(({ createGridOverlayScrollFeature }) => {
3169
3163
  const feature = createGridOverlayScrollFeature({
3170
3164
  getScrollElement: () => this.scrollEl()?.nativeElement ?? null,
3171
3165
  getThumbTop: () => this.vm.thumbTopPx(),
@@ -3290,4 +3284,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
3290
3284
  */
3291
3285
 
3292
3286
  export { DataGridTypeCellTemplateDirective as D, clampThumbTop as a, DataGridCellTemplateDirective as b, computeScrollbarState as c, DataGridHeaderTemplateDirective as d, DataGridRowDirective as e, DataGridDeclarativeColumn as f, DataGridDeclarativeHeaderDirective as g, DataGridDeclarativeCellDirective as h, DataGridCellEmptyDirective as i, DataGridCellLoadingDirective as j, DataGridStickyRowDirective as k, DataGridSortIconDirective as l, mapThumbTopToScrollTop as m, DataGridExpanderIconDirective as n, DATA_GRID_CONFIG as o, DEFAULT_DATA_GRID_DEFAULTS as p, provideDataGridDefaults as q, DataGrid as r };
3293
- //# sourceMappingURL=reforgium-data-grid-reforgium-data-grid-Op6gjm7A.mjs.map
3287
+ //# sourceMappingURL=reforgium-data-grid-reforgium-data-grid-YSzBRJ5h.mjs.map
@@ -1,2 +1,2 @@
1
- export { o as DATA_GRID_CONFIG, p as DEFAULT_DATA_GRID_DEFAULTS, r as DataGrid, i as DataGridCellEmptyDirective, j as DataGridCellLoadingDirective, b as DataGridCellTemplateDirective, h as DataGridDeclarativeCellDirective, f as DataGridDeclarativeColumn, g as DataGridDeclarativeHeaderDirective, n as DataGridExpanderIconDirective, d as DataGridHeaderTemplateDirective, e as DataGridRowDirective, l as DataGridSortIconDirective, k as DataGridStickyRowDirective, D as DataGridTypeCellTemplateDirective, q as provideDataGridDefaults } from './reforgium-data-grid-reforgium-data-grid-Op6gjm7A.mjs';
1
+ export { o as DATA_GRID_CONFIG, p as DEFAULT_DATA_GRID_DEFAULTS, r as DataGrid, i as DataGridCellEmptyDirective, j as DataGridCellLoadingDirective, b as DataGridCellTemplateDirective, h as DataGridDeclarativeCellDirective, f as DataGridDeclarativeColumn, g as DataGridDeclarativeHeaderDirective, n as DataGridExpanderIconDirective, d as DataGridHeaderTemplateDirective, e as DataGridRowDirective, l as DataGridSortIconDirective, k as DataGridStickyRowDirective, D as DataGridTypeCellTemplateDirective, q as provideDataGridDefaults } from './reforgium-data-grid-reforgium-data-grid-YSzBRJ5h.mjs';
2
2
  //# sourceMappingURL=reforgium-data-grid.mjs.map
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.2.3",
2
+ "version": "2.3.0",
3
3
  "name": "@reforgium/data-grid",
4
4
  "description": "reforgium DataGrid component",
5
5
  "author": "rtommievich",
@@ -1,18 +1,26 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { TemplateRef } from '@angular/core';
2
+ import { TemplateRef, AfterContentChecked } from '@angular/core';
3
3
  import { GridColumn } from '@reforgium/data-grid';
4
4
 
5
5
  type GridColumnPin = 'none' | 'left' | 'right';
6
6
 
7
+ type RowLike$1 = Record<string, unknown>;
8
+ type DataGridColumnManagerColumnTitleContext<Data extends RowLike$1 = RowLike$1> = {
9
+ $implicit: string;
10
+ title: string;
11
+ column: GridColumn<Data>;
12
+ };
13
+ declare class DataGridColumnManagerColumnTitleDirective<Data extends RowLike$1 = RowLike$1> {
14
+ readonly template: TemplateRef<any>;
15
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DataGridColumnManagerColumnTitleDirective<any>, never>;
16
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DataGridColumnManagerColumnTitleDirective<any>, "ng-template[reDataGridColumnManagerColumnTitle]", never, {}, {}, never, never, true, never>;
17
+ }
18
+
7
19
  type RowLike = Record<string, unknown>;
8
- declare class DataGridColumnManager<Data extends RowLike = RowLike> {
20
+ declare class DataGridColumnManager<Data extends RowLike = RowLike> implements AfterContentChecked {
21
+ private host;
9
22
  columns: _angular_core.InputSignal<GridColumn<Data>[]>;
10
23
  triggerLabel: _angular_core.InputSignal<string>;
11
- triggerTemplate: _angular_core.InputSignal<TemplateRef<{
12
- $implicit: string;
13
- visible: number;
14
- total: number;
15
- }> | undefined>;
16
24
  controlsVisible: _angular_core.InputSignalWithTransform<boolean, unknown>;
17
25
  searchable: _angular_core.InputSignalWithTransform<boolean, unknown>;
18
26
  searchPlaceholder: _angular_core.InputSignal<string>;
@@ -20,17 +28,28 @@ declare class DataGridColumnManager<Data extends RowLike = RowLike> {
20
28
  allowPin: _angular_core.InputSignalWithTransform<boolean, unknown>;
21
29
  allowVisibility: _angular_core.InputSignalWithTransform<boolean, unknown>;
22
30
  columnsChange: _angular_core.OutputEmitterRef<GridColumn<Data>[]>;
31
+ private triggerDirective;
32
+ protected columnTitleTemplate: _angular_core.Signal<DataGridColumnManagerColumnTitleDirective<any> | undefined>;
23
33
  protected state: _angular_core.WritableSignal<GridColumn<Data>[]>;
24
34
  protected searchQuery: _angular_core.WritableSignal<string>;
25
35
  protected draggingKey: _angular_core.WritableSignal<string | null>;
26
36
  protected opened: _angular_core.WritableSignal<boolean>;
37
+ protected openedPinMenuKey: _angular_core.WritableSignal<string | null>;
38
+ protected panelLeft: _angular_core.WritableSignal<number>;
39
+ protected hasCustomTrigger: _angular_core.WritableSignal<boolean>;
27
40
  private root;
41
+ private panel;
28
42
  protected filteredColumns: _angular_core.Signal<GridColumn<Data>[]>;
29
43
  protected visibleColumnsCount: _angular_core.Signal<number>;
30
44
  constructor();
45
+ ngAfterContentChecked(): void;
31
46
  protected pin: (key: string) => GridColumnPin;
32
47
  protected toggleOpen(): void;
48
+ protected onWindowResize(): void;
33
49
  protected onDocumentMouseDown(target: EventTarget | null): void;
50
+ protected togglePinMenu(event: MouseEvent, key: string): void;
51
+ protected selectPin(key: string, pin: GridColumnPin): void;
52
+ protected pinLabel(pin: GridColumnPin): string;
34
53
  protected onSearch(event: Event): void;
35
54
  protected canHideColumn(key: string): boolean;
36
55
  protected onVisibleChange(key: string): void;
@@ -44,10 +63,21 @@ declare class DataGridColumnManager<Data extends RowLike = RowLike> {
44
63
  private reorderByKey;
45
64
  private findColumn;
46
65
  private commit;
66
+ private hasProjectedTrigger;
67
+ private syncCustomTriggerState;
68
+ private isInsidePinMenu;
69
+ protected buildColumnTitleContext(column: GridColumn<Data>): DataGridColumnManagerColumnTitleContext<Data>;
70
+ private schedulePanelPositioning;
71
+ private positionPanel;
47
72
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<DataGridColumnManager<any>, never>;
48
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<DataGridColumnManager<any>, "re-data-grid-column-manager", never, { "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "triggerLabel": { "alias": "triggerLabel"; "required": false; "isSignal": true; }; "triggerTemplate": { "alias": "triggerTemplate"; "required": false; "isSignal": true; }; "controlsVisible": { "alias": "controlsVisible"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "searchPlaceholder": { "alias": "searchPlaceholder"; "required": false; "isSignal": true; }; "allowReorder": { "alias": "allowReorder"; "required": false; "isSignal": true; }; "allowPin": { "alias": "allowPin"; "required": false; "isSignal": true; }; "allowVisibility": { "alias": "allowVisibility"; "required": false; "isSignal": true; }; }, { "columnsChange": "columnsChange"; }, never, never, true, never>;
73
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DataGridColumnManager<any>, "re-data-grid-column-manager", never, { "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "triggerLabel": { "alias": "triggerLabel"; "required": false; "isSignal": true; }; "controlsVisible": { "alias": "controlsVisible"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "searchPlaceholder": { "alias": "searchPlaceholder"; "required": false; "isSignal": true; }; "allowReorder": { "alias": "allowReorder"; "required": false; "isSignal": true; }; "allowPin": { "alias": "allowPin"; "required": false; "isSignal": true; }; "allowVisibility": { "alias": "allowVisibility"; "required": false; "isSignal": true; }; }, { "columnsChange": "columnsChange"; }, ["triggerDirective", "columnTitleTemplate"], ["[reDataGridColumnManagerTrigger]"], true, never>;
74
+ }
75
+
76
+ declare class DataGridColumnManagerTriggerDirective {
77
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DataGridColumnManagerTriggerDirective, never>;
78
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DataGridColumnManagerTriggerDirective, "[reDataGridColumnManagerTrigger]", never, {}, {}, never, never, true, never>;
49
79
  }
50
80
 
51
- export { DataGridColumnManager };
52
- export type { GridColumnPin };
81
+ export { DataGridColumnManager, DataGridColumnManagerColumnTitleDirective, DataGridColumnManagerTriggerDirective };
82
+ export type { DataGridColumnManagerColumnTitleContext, GridColumnPin };
53
83
  //# sourceMappingURL=reforgium-data-grid-column-manager.d.ts.map