@chefuicore/core 1.0.1 → 1.0.2

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.
@@ -41,6 +41,11 @@ export declare class ChefUiDataGrid extends LitElement {
41
41
  private _containerHeight;
42
42
  private _activeFilterColumn;
43
43
  private _filterPopoverField;
44
+ private _filterPopoverX;
45
+ private _filterPopoverY;
46
+ private _columnMenuField;
47
+ private _columnMenuX;
48
+ private _columnMenuY;
44
49
  private _densityMenuOpen;
45
50
  private _columnsMenuOpen;
46
51
  private _exportMenuOpen;
@@ -73,6 +78,13 @@ export declare class ChefUiDataGrid extends LitElement {
73
78
  private _computeAggregation;
74
79
  private _handleSort;
75
80
  private _openFilterPopover;
81
+ private _openColumnMenu;
82
+ private _closeColumnMenu;
83
+ private _columnMenuSort;
84
+ private _columnMenuUnsort;
85
+ private _columnMenuFilter;
86
+ private _columnMenuHide;
87
+ private _columnMenuManageColumns;
76
88
  private _updateFilter;
77
89
  private _removeFilter;
78
90
  private _handleQuickFilter;
@@ -99,6 +111,7 @@ export declare class ChefUiDataGrid extends LitElement {
99
111
  private _exportCsv;
100
112
  private _exportExcel;
101
113
  private _changeDensity;
114
+ private _handleGridClick;
102
115
  private _getColumnWidth;
103
116
  private _getCellValue;
104
117
  private _getDisplayValue;
@@ -108,9 +121,12 @@ export declare class ChefUiDataGrid extends LitElement {
108
121
  private _getFilterForField;
109
122
  static styles: import("lit").CSSResult;
110
123
  render(): import("lit-html").TemplateResult<1>;
124
+ private _renderFilterPopoverOverlay;
125
+ private _renderColumnMenu;
111
126
  private _renderToolbar;
112
127
  private _renderHeader;
113
128
  private _renderHeaderCell;
129
+ private _renderColumnsPanel;
114
130
  private _renderFilterPopover;
115
131
  private _renderBody;
116
132
  private _renderRow;
@@ -1 +1 @@
1
- {"version":3,"file":"chef-ui-data-grid.d.ts","sourceRoot":"","sources":["../../src/components/chef-ui-data-grid.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"chef-ui-data-grid.d.ts","sourceRoot":"","sources":["../../src/components/chef-ui-data-grid.ts"],"names":[],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -11897,6 +11897,11 @@ exports.ChefUiDataGrid = class ChefUiDataGrid extends i {
11897
11897
  // UI state
11898
11898
  this._activeFilterColumn = null;
11899
11899
  this._filterPopoverField = null;
11900
+ this._filterPopoverX = 0;
11901
+ this._filterPopoverY = 0;
11902
+ this._columnMenuField = null;
11903
+ this._columnMenuX = 0;
11904
+ this._columnMenuY = 0;
11900
11905
  this._densityMenuOpen = false;
11901
11906
  this._columnsMenuOpen = false;
11902
11907
  this._exportMenuOpen = false;
@@ -12166,9 +12171,94 @@ exports.ChefUiDataGrid = class ChefUiDataGrid extends i {
12166
12171
  this.dispatchEvent(new CustomEvent('sort-change', { detail: { sortModel: this._sortModel } }));
12167
12172
  }
12168
12173
  // ── Filtering ──
12169
- _openFilterPopover(field) {
12170
- this._filterPopoverField = this._filterPopoverField === field ? null : field;
12171
- this._closeAllMenus('filter');
12174
+ _openFilterPopover(field, e) {
12175
+ // Close other menus first
12176
+ this._densityMenuOpen = false;
12177
+ this._columnsMenuOpen = false;
12178
+ this._exportMenuOpen = false;
12179
+ this._contextMenuField = null;
12180
+ if (this._filterPopoverField === field) {
12181
+ this._filterPopoverField = null;
12182
+ return;
12183
+ }
12184
+ // Calculate position relative to grid-container
12185
+ const icon = e.currentTarget;
12186
+ const gridContainer = this.shadowRoot.querySelector('.grid-container');
12187
+ if (icon && gridContainer) {
12188
+ const iconRect = icon.getBoundingClientRect();
12189
+ const gridRect = gridContainer.getBoundingClientRect();
12190
+ this._filterPopoverX = iconRect.left - gridRect.left;
12191
+ this._filterPopoverY = iconRect.bottom - gridRect.top + 4;
12192
+ }
12193
+ this._filterPopoverField = field;
12194
+ }
12195
+ // ── Column Header Menu ──
12196
+ _openColumnMenu(field, e) {
12197
+ e.stopPropagation();
12198
+ // Close other menus
12199
+ this._filterPopoverField = null;
12200
+ this._densityMenuOpen = false;
12201
+ this._columnsMenuOpen = false;
12202
+ this._exportMenuOpen = false;
12203
+ if (this._columnMenuField === field) {
12204
+ this._columnMenuField = null;
12205
+ return;
12206
+ }
12207
+ const btn = e.currentTarget;
12208
+ const gridContainer = this.shadowRoot.querySelector('.grid-container');
12209
+ if (btn && gridContainer) {
12210
+ const btnRect = btn.getBoundingClientRect();
12211
+ const gridRect = gridContainer.getBoundingClientRect();
12212
+ this._columnMenuX = btnRect.left - gridRect.left;
12213
+ this._columnMenuY = btnRect.bottom - gridRect.top + 4;
12214
+ }
12215
+ this._columnMenuField = field;
12216
+ }
12217
+ _closeColumnMenu() {
12218
+ this._columnMenuField = null;
12219
+ }
12220
+ _columnMenuSort(field, dir) {
12221
+ // Set sort to specific direction
12222
+ this._sortModel = [{ field, sort: dir }];
12223
+ this.dispatchEvent(new CustomEvent('sort-change', { detail: { sortModel: this._sortModel } }));
12224
+ this._closeColumnMenu();
12225
+ }
12226
+ _columnMenuUnsort(field) {
12227
+ this._sortModel = this._sortModel.filter(s => s.field !== field);
12228
+ this.dispatchEvent(new CustomEvent('sort-change', { detail: { sortModel: this._sortModel } }));
12229
+ this._closeColumnMenu();
12230
+ }
12231
+ _columnMenuFilter(field) {
12232
+ this._closeColumnMenu();
12233
+ // Open filter popover — we need to calculate position from the header cell
12234
+ const headerCells = this.shadowRoot.querySelectorAll('.header-cell');
12235
+ const gridContainer = this.shadowRoot.querySelector('.grid-container');
12236
+ const col = this._visibleColumns.find(c => c.field === field);
12237
+ if (!col || !gridContainer)
12238
+ return;
12239
+ const colIdx = this._visibleColumns.indexOf(col);
12240
+ const adjustedIdx = this.checkboxSelection ? colIdx + 1 : colIdx;
12241
+ const headerCell = headerCells[adjustedIdx];
12242
+ if (headerCell) {
12243
+ const cellRect = headerCell.getBoundingClientRect();
12244
+ const gridRect = gridContainer.getBoundingClientRect();
12245
+ this._filterPopoverX = cellRect.left - gridRect.left;
12246
+ this._filterPopoverY = cellRect.bottom - gridRect.top + 4;
12247
+ }
12248
+ this._filterPopoverField = field;
12249
+ }
12250
+ _columnMenuHide(field) {
12251
+ const newHidden = new Set(this._hiddenColumns);
12252
+ newHidden.add(field);
12253
+ this._hiddenColumns = newHidden;
12254
+ this.dispatchEvent(new CustomEvent('column-visibility-change', {
12255
+ detail: { hiddenColumns: Array.from(newHidden) },
12256
+ }));
12257
+ this._closeColumnMenu();
12258
+ }
12259
+ _columnMenuManageColumns() {
12260
+ this._closeColumnMenu();
12261
+ this._columnsMenuOpen = true;
12172
12262
  }
12173
12263
  _updateFilter(field, operator, value) {
12174
12264
  const items = this._filterModel.items.filter(i => i.field !== field);
@@ -12447,6 +12537,20 @@ exports.ChefUiDataGrid = class ChefUiDataGrid extends i {
12447
12537
  this.density = d;
12448
12538
  this._densityMenuOpen = false;
12449
12539
  }
12540
+ // ── Grid Click ──
12541
+ _handleGridClick(e) {
12542
+ const path = e.composedPath();
12543
+ // Don't close menus if user clicked inside an overlay/popover/dropdown
12544
+ const insideOverlay = path.some(el => el instanceof HTMLElement && (el.classList?.contains('filter-popover') ||
12545
+ el.classList?.contains('column-menu') ||
12546
+ el.classList?.contains('dropdown') ||
12547
+ el.classList?.contains('filter-icon') ||
12548
+ el.classList?.contains('toolbar-btn') ||
12549
+ el.classList?.contains('column-menu-btn')));
12550
+ if (!insideOverlay) {
12551
+ this._closeAllMenus();
12552
+ }
12553
+ }
12450
12554
  // ── Helpers ──
12451
12555
  _getColumnWidth(field) {
12452
12556
  if (this._columnWidths.has(field))
@@ -12480,6 +12584,8 @@ exports.ChefUiDataGrid = class ChefUiDataGrid extends i {
12480
12584
  this._exportMenuOpen = false;
12481
12585
  if (except !== 'context')
12482
12586
  this._contextMenuField = null;
12587
+ if (except !== 'columnMenu')
12588
+ this._columnMenuField = null;
12483
12589
  }
12484
12590
  _getSortDirection(field) {
12485
12591
  const s = this._sortModel.find(s => s.field === field);
@@ -12505,7 +12611,7 @@ exports.ChefUiDataGrid = class ChefUiDataGrid extends i {
12505
12611
  aria-rowcount="${this._totalRowCount}"
12506
12612
  aria-colcount="${this._visibleColumns.length}"
12507
12613
  @keydown="${this._handleGridKeydown}"
12508
- @click="${() => this._closeAllMenus()}"
12614
+ @click="${(e) => this._handleGridClick(e)}"
12509
12615
  >
12510
12616
  ${this.showToolbar ? this._renderToolbar() : A}
12511
12617
  ${this._renderHeader()}
@@ -12524,6 +12630,86 @@ exports.ChefUiDataGrid = class ChefUiDataGrid extends i {
12524
12630
  ` : this._renderBody()}
12525
12631
  </div>
12526
12632
  ${this._renderFooter()}
12633
+ ${this._filterPopoverField ? this._renderFilterPopoverOverlay() : A}
12634
+ ${this._columnMenuField ? this._renderColumnMenu() : A}
12635
+ ${this._columnsMenuOpen && !this.showToolbar ? this._renderColumnsPanel() : A}
12636
+ </div>
12637
+ `;
12638
+ }
12639
+ // ── Filter Popover Overlay ──
12640
+ _renderFilterPopoverOverlay() {
12641
+ const col = this.columns.find(c => c.field === this._filterPopoverField);
12642
+ if (!col)
12643
+ return A;
12644
+ return this._renderFilterPopover(col);
12645
+ }
12646
+ // ── Column Header Menu ──
12647
+ _renderColumnMenu() {
12648
+ const field = this._columnMenuField;
12649
+ const col = this.columns.find(c => c.field === field);
12650
+ if (!col)
12651
+ return A;
12652
+ const sortDir = this._getSortDirection(field);
12653
+ const isSortable = this.sortable && col.sortable !== false;
12654
+ const isFilterable = this.filterable && col.filterable !== false;
12655
+ const isPinnable = col.pinnable !== false;
12656
+ const isHideable = col.hideable !== false;
12657
+ const isPinnedLeft = (this.pinnedColumns.left || []).includes(field);
12658
+ const isPinnedRight = (this.pinnedColumns.right || []).includes(field);
12659
+ return b `
12660
+ <div class="column-menu"
12661
+ style="left:${this._columnMenuX}px; top:${this._columnMenuY}px"
12662
+ @click="${(e) => e.stopPropagation()}">
12663
+
12664
+ ${isSortable ? b `
12665
+ <button class="column-menu-item" @click="${() => this._columnMenuSort(field, 'asc')}">
12666
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 19V5M5 12l7-7 7 7"/></svg>
12667
+ Sort by ASC
12668
+ </button>
12669
+ <button class="column-menu-item" @click="${() => this._columnMenuSort(field, 'desc')}">
12670
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 5v14M19 12l-7 7-7-7"/></svg>
12671
+ Sort by DESC
12672
+ </button>
12673
+ ${sortDir ? b `
12674
+ <button class="column-menu-item" @click="${() => this._columnMenuUnsort(field)}">
12675
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
12676
+ Unsort
12677
+ </button>
12678
+ ` : A}
12679
+ <div class="column-menu-divider"></div>
12680
+ ` : A}
12681
+
12682
+ ${isPinnable ? b `
12683
+ <button class="column-menu-item" @click="${() => { this._pinColumn(field, isPinnedLeft ? 'none' : 'left'); this._closeColumnMenu(); }}">
12684
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M15 4.5L7.5 12l3 3L18 7.5"/><path d="M2 22l5.5-5.5"/></svg>
12685
+ ${isPinnedLeft ? 'Unpin from left' : 'Pin to left'}
12686
+ </button>
12687
+ <button class="column-menu-item" @click="${() => { this._pinColumn(field, isPinnedRight ? 'none' : 'right'); this._closeColumnMenu(); }}">
12688
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 4.5L16.5 12l-3 3L6 7.5"/><path d="M22 22l-5.5-5.5"/></svg>
12689
+ ${isPinnedRight ? 'Unpin from right' : 'Pin to right'}
12690
+ </button>
12691
+ <div class="column-menu-divider"></div>
12692
+ ` : A}
12693
+
12694
+ ${isFilterable ? b `
12695
+ <button class="column-menu-item" @click="${() => this._columnMenuFilter(field)}">
12696
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/></svg>
12697
+ Filter
12698
+ </button>
12699
+ <div class="column-menu-divider"></div>
12700
+ ` : A}
12701
+
12702
+ ${isHideable ? b `
12703
+ <button class="column-menu-item" @click="${() => this._columnMenuHide(field)}">
12704
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M17.94 17.94A10.07 10.07 0 0112 20c-7 0-11-8-11-8a18.45 18.45 0 015.06-5.94"/><path d="M9.9 4.24A9.12 9.12 0 0112 4c7 0 11 8 11 8a18.5 18.5 0 01-2.16 3.19"/><line x1="1" y1="1" x2="23" y2="23"/></svg>
12705
+ Hide column
12706
+ </button>
12707
+ ` : A}
12708
+
12709
+ <button class="column-menu-item" @click="${() => this._columnMenuManageColumns()}">
12710
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/></svg>
12711
+ Manage columns
12712
+ </button>
12527
12713
  </div>
12528
12714
  `;
12529
12715
  }
@@ -12624,11 +12810,10 @@ exports.ChefUiDataGrid = class ChefUiDataGrid extends i {
12624
12810
  const sortDir = this._getSortDirection(col.field);
12625
12811
  const sortIdx = this._getSortIndex(col.field);
12626
12812
  const isSortable = this.sortable && col.sortable !== false;
12627
- const isFilterable = this.filterable && col.filterable !== false;
12628
12813
  const hasFilter = this._getFilterForField(col.field) !== undefined;
12629
12814
  const isReorderable = this.reorderableColumns;
12630
12815
  const isResizable = this.resizableColumns && col.resizable !== false;
12631
- const isFilterOpen = this._filterPopoverField === col.field;
12816
+ const isMenuOpen = this._columnMenuField === col.field;
12632
12817
  return b `
12633
12818
  <div class="header-cell ${isSortable ? 'sortable' : ''}"
12634
12819
  style="width:${width}px; height:${this._effectiveHeaderHeight}px; text-align:${col.headerAlign || col.align || 'left'}"
@@ -12646,20 +12831,31 @@ exports.ChefUiDataGrid = class ChefUiDataGrid extends i {
12646
12831
  <span class="sort-icon">${sortDir === 'asc' ? '↑' : '↓'}</span>
12647
12832
  ${this._sortModel.length > 1 ? b `<span class="sort-index">${sortIdx + 1}</span>` : A}
12648
12833
  ` : A}
12834
+ ${hasFilter ? b `<span class="sort-icon" style="color:var(--dg-primary);font-size:10px">⧫</span>` : A}
12649
12835
 
12650
- ${isFilterable ? b `
12651
- <svg class="filter-icon ${hasFilter || isFilterOpen ? 'active' : ''}"
12652
- viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
12653
- @click="${(e) => { e.stopPropagation(); this._openFilterPopover(col.field); }}">
12654
- <polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"></polygon>
12655
- </svg>
12656
- ` : A}
12836
+ <button class="column-menu-btn ${isMenuOpen ? 'active' : ''}"
12837
+ @click="${(e) => this._openColumnMenu(col.field, e)}">⋮</button>
12657
12838
 
12658
12839
  ${isResizable ? b `
12659
12840
  <div class="resize-handle" @mousedown="${(e) => this._startResize(col.field, e)}"></div>
12660
12841
  ` : A}
12661
-
12662
- ${isFilterOpen ? this._renderFilterPopover(col) : A}
12842
+ </div>
12843
+ `;
12844
+ }
12845
+ // ── Standalone Columns Panel ──
12846
+ _renderColumnsPanel() {
12847
+ return b `
12848
+ <div class="column-menu"
12849
+ style="right:8px; top:${this._effectiveHeaderHeight + 8}px; left:auto; max-height:300px; overflow-y:auto"
12850
+ @click="${(e) => e.stopPropagation()}">
12851
+ ${this.columns.filter(c => c.hideable !== false).map(col => b `
12852
+ <label class="column-menu-item" style="cursor:pointer">
12853
+ <input type="checkbox" style="cursor:pointer"
12854
+ ?checked="${!this._hiddenColumns.has(col.field)}"
12855
+ @change="${() => this._toggleColumnVisibility(col.field)}" />
12856
+ ${col.headerName || col.field}
12857
+ </label>
12858
+ `)}
12663
12859
  </div>
12664
12860
  `;
12665
12861
  }
@@ -12671,7 +12867,9 @@ exports.ChefUiDataGrid = class ChefUiDataGrid extends i {
12671
12867
  const currentOp = existing?.operator || getDefaultOperator(type);
12672
12868
  const currentVal = existing?.value ?? '';
12673
12869
  return b `
12674
- <div class="filter-popover" @click="${(e) => e.stopPropagation()}">
12870
+ <div class="filter-popover"
12871
+ style="left:${this._filterPopoverX}px; top:${this._filterPopoverY}px"
12872
+ @click="${(e) => e.stopPropagation()}">
12675
12873
  <div class="filter-popover-title">Filter: ${col.headerName || col.field}</div>
12676
12874
  <select
12677
12875
  .value="${currentOp}"
@@ -12946,7 +13144,7 @@ exports.ChefUiDataGrid.styles = i$3 `
12946
13144
  .grid-container {
12947
13145
  border: 1px solid var(--dg-border);
12948
13146
  border-radius: 4px;
12949
- overflow: hidden;
13147
+ overflow: visible;
12950
13148
  position: relative;
12951
13149
  background: #fff;
12952
13150
  }
@@ -13049,6 +13247,7 @@ exports.ChefUiDataGrid.styles = i$3 `
13049
13247
  position: sticky;
13050
13248
  top: 0;
13051
13249
  z-index: 10;
13250
+ overflow: visible;
13052
13251
  }
13053
13252
 
13054
13253
  .header-cell {
@@ -13061,7 +13260,7 @@ exports.ChefUiDataGrid.styles = i$3 `
13061
13260
  border-right: 1px solid var(--dg-border);
13062
13261
  position: relative;
13063
13262
  user-select: none;
13064
- overflow: hidden;
13263
+ overflow: visible;
13065
13264
  flex-shrink: 0;
13066
13265
  }
13067
13266
 
@@ -13255,16 +13454,14 @@ exports.ChefUiDataGrid.styles = i$3 `
13255
13454
  /* ── Filter Popover ── */
13256
13455
  .filter-popover {
13257
13456
  position: absolute;
13258
- top: 100%;
13259
- left: 0;
13260
- margin-top: 4px;
13261
13457
  background: #fff;
13262
13458
  border: 1px solid var(--dg-border);
13263
13459
  border-radius: 8px;
13264
- box-shadow: 0 4px 20px rgba(0,0,0,0.15);
13265
- z-index: 200;
13460
+ box-shadow: 0 8px 32px rgba(0,0,0,0.18);
13461
+ z-index: 1000;
13266
13462
  padding: 16px;
13267
13463
  min-width: 280px;
13464
+ max-width: 340px;
13268
13465
  }
13269
13466
 
13270
13467
  .filter-popover-title {
@@ -13349,24 +13546,48 @@ exports.ChefUiDataGrid.styles = i$3 `
13349
13546
  font-size: 14px;
13350
13547
  }
13351
13548
 
13352
- /* ── Context Menu ── */
13353
- .header-context-menu {
13549
+ /* ── Column Menu Button ── */
13550
+ .column-menu-btn {
13551
+ display: flex;
13552
+ align-items: center;
13553
+ justify-content: center;
13554
+ width: 24px;
13555
+ height: 24px;
13556
+ border: none;
13557
+ background: none;
13558
+ cursor: pointer;
13559
+ border-radius: 4px;
13560
+ color: #999;
13561
+ font-size: 16px;
13562
+ flex-shrink: 0;
13563
+ margin-left: 2px;
13564
+ padding: 0;
13565
+ transition: background 0.15s, color 0.15s;
13566
+ font-family: var(--dg-font);
13567
+ line-height: 1;
13568
+ }
13569
+
13570
+ .column-menu-btn:hover { background: rgba(0,0,0,0.08); color: var(--dg-text); }
13571
+ .column-menu-btn.active { background: rgba(0,0,0,0.08); color: var(--dg-primary); }
13572
+
13573
+ /* ── Column Menu ── */
13574
+ .column-menu {
13354
13575
  position: absolute;
13355
- top: 100%;
13356
- right: 4px;
13357
13576
  background: #fff;
13358
13577
  border: 1px solid var(--dg-border);
13359
- border-radius: 6px;
13360
- box-shadow: 0 4px 16px rgba(0,0,0,0.12);
13361
- z-index: 200;
13362
- padding: 4px 0;
13363
- min-width: 140px;
13578
+ border-radius: 8px;
13579
+ box-shadow: 0 8px 32px rgba(0,0,0,0.18);
13580
+ z-index: 1000;
13581
+ padding: 6px 0;
13582
+ min-width: 200px;
13364
13583
  }
13365
13584
 
13366
- .context-item {
13367
- display: block;
13585
+ .column-menu-item {
13586
+ display: flex;
13587
+ align-items: center;
13588
+ gap: 10px;
13368
13589
  width: 100%;
13369
- padding: 8px 16px;
13590
+ padding: 9px 16px;
13370
13591
  border: none;
13371
13592
  background: none;
13372
13593
  cursor: pointer;
@@ -13375,11 +13596,21 @@ exports.ChefUiDataGrid.styles = i$3 `
13375
13596
  transition: background 0.15s;
13376
13597
  font-family: var(--dg-font);
13377
13598
  color: var(--dg-text);
13599
+ white-space: nowrap;
13600
+ }
13601
+
13602
+ .column-menu-item:hover { background: #f5f5f5; }
13603
+
13604
+ .column-menu-item svg {
13605
+ width: 18px;
13606
+ height: 18px;
13607
+ flex-shrink: 0;
13608
+ color: #666;
13378
13609
  }
13379
13610
 
13380
- .context-item:hover { background: #f5f5f5; }
13611
+ .column-menu-item:hover svg { color: var(--dg-text); }
13381
13612
 
13382
- .context-divider {
13613
+ .column-menu-divider {
13383
13614
  height: 1px;
13384
13615
  background: var(--dg-border);
13385
13616
  margin: 4px 0;
@@ -13515,6 +13746,21 @@ __decorate([
13515
13746
  __decorate([
13516
13747
  r()
13517
13748
  ], exports.ChefUiDataGrid.prototype, "_filterPopoverField", void 0);
13749
+ __decorate([
13750
+ r()
13751
+ ], exports.ChefUiDataGrid.prototype, "_filterPopoverX", void 0);
13752
+ __decorate([
13753
+ r()
13754
+ ], exports.ChefUiDataGrid.prototype, "_filterPopoverY", void 0);
13755
+ __decorate([
13756
+ r()
13757
+ ], exports.ChefUiDataGrid.prototype, "_columnMenuField", void 0);
13758
+ __decorate([
13759
+ r()
13760
+ ], exports.ChefUiDataGrid.prototype, "_columnMenuX", void 0);
13761
+ __decorate([
13762
+ r()
13763
+ ], exports.ChefUiDataGrid.prototype, "_columnMenuY", void 0);
13518
13764
  __decorate([
13519
13765
  r()
13520
13766
  ], exports.ChefUiDataGrid.prototype, "_densityMenuOpen", void 0);