@alaarab/ogrid-vue-radix 2.0.15 → 2.0.16

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.
@@ -54,14 +54,14 @@
54
54
  --ogrid-header-hover-bg: rgba(255, 255, 255, 0.1);
55
55
  --ogrid-muted: var(--ogrid-fg-muted);
56
56
  }
57
- .ogrid-table-wrapper[data-v-7b1fd360] {
57
+ .ogrid-table-wrapper[data-v-18aa4567] {
58
58
  position: relative;
59
59
  flex: 1;
60
60
  min-height: 0;
61
61
  display: flex;
62
62
  flex-direction: column;
63
63
  }
64
- .ogrid-loading[data-v-7b1fd360] {
64
+ .ogrid-loading[data-v-18aa4567] {
65
65
  display: flex;
66
66
  align-items: center;
67
67
  justify-content: center;
@@ -69,19 +69,19 @@
69
69
  color: var(--ogrid-muted, #888);
70
70
  font-size: 14px;
71
71
  }
72
- .ogrid-table-container[data-v-7b1fd360] {
72
+ .ogrid-table-container[data-v-18aa4567] {
73
73
  flex: 1;
74
74
  overflow: auto;
75
75
  position: relative;
76
76
  }
77
- .ogrid-table[data-v-7b1fd360] {
77
+ .ogrid-table[data-v-18aa4567] {
78
78
  width: 100%;
79
79
  border-collapse: collapse;
80
80
  font-size: 14px;
81
81
  background: var(--ogrid-bg, #fff);
82
82
  color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
83
83
  }
84
- .ogrid-table th[data-v-7b1fd360] {
84
+ .ogrid-table th[data-v-18aa4567] {
85
85
  position: sticky;
86
86
  top: 0;
87
87
  background: var(--ogrid-header-bg, #f5f5f5);
@@ -91,38 +91,38 @@
91
91
  font-weight: 600;
92
92
  z-index: 2;
93
93
  }
94
- .ogrid-table th.sortable[data-v-7b1fd360] {
94
+ .ogrid-table th.sortable[data-v-18aa4567] {
95
95
  cursor: pointer;
96
96
  user-select: none;
97
97
  }
98
- .ogrid-table th.sortable[data-v-7b1fd360]:hover {
98
+ .ogrid-table th.sortable[data-v-18aa4567]:hover {
99
99
  background: var(--ogrid-header-hover-bg, #f0f0f0);
100
100
  }
101
- .ogrid-table td[data-v-7b1fd360] {
101
+ .ogrid-table td[data-v-18aa4567] {
102
102
  padding: 8px 12px;
103
103
  border-bottom: 1px solid var(--ogrid-border, #e0e0e0);
104
104
  }
105
- .ogrid-table td.active-cell[data-v-7b1fd360] {
105
+ .ogrid-table td.active-cell[data-v-18aa4567] {
106
106
  outline: 2px solid var(--ogrid-active-border, #0078d4);
107
107
  outline-offset: -2px;
108
108
  }
109
- .ogrid-table td.editable[data-v-7b1fd360] {
109
+ .ogrid-table td.editable[data-v-18aa4567] {
110
110
  cursor: cell;
111
111
  }
112
- .ogrid-table tr[data-v-7b1fd360]:hover {
112
+ .ogrid-table tr[data-v-18aa4567]:hover {
113
113
  background: var(--ogrid-hover-bg, #f9f9f9);
114
114
  }
115
- .ogrid-table tr.selected-row[data-v-7b1fd360] {
115
+ .ogrid-table tr.selected-row[data-v-18aa4567] {
116
116
  background: var(--ogrid-selected-bg, #e3f2fd);
117
117
  }
118
- .ogrid-wrapper[data-v-7b1fd360] {
118
+ .ogrid-wrapper[data-v-18aa4567] {
119
119
  position: relative;
120
120
  flex: 1;
121
121
  min-height: 0;
122
122
  display: flex;
123
123
  flex-direction: column;
124
124
  }
125
- .ogrid-table-container[data-v-7b1fd360] {
125
+ .ogrid-table-container[data-v-18aa4567] {
126
126
  flex: 1;
127
127
  position: relative;
128
128
  outline: none;
@@ -131,10 +131,10 @@
131
131
  }
132
132
 
133
133
  /* Drag-range highlight applied via DOM attributes during drag (bypasses Vue for performance) */
134
- [data-v-7b1fd360] [data-drag-range] {
134
+ [data-v-18aa4567] [data-drag-range] {
135
135
  background: var(--ogrid-range-bg, rgba(33, 115, 70, 0.12)) !important;
136
136
  }
137
- .ogrid-drop-indicator[data-v-7b1fd360] {
137
+ .ogrid-drop-indicator[data-v-18aa4567] {
138
138
  position: absolute;
139
139
  top: 0;
140
140
  bottom: 0;
@@ -143,16 +143,16 @@
143
143
  pointer-events: none;
144
144
  z-index: 100;
145
145
  }
146
- .ogrid-table[data-v-7b1fd360] {
146
+ .ogrid-table[data-v-18aa4567] {
147
147
  border-collapse: collapse;
148
148
  font-size: 14px;
149
149
  background: var(--ogrid-bg, #fff);
150
150
  }
151
- .ogrid-header-row[data-v-7b1fd360] {
151
+ .ogrid-header-row[data-v-18aa4567] {
152
152
  z-index: 8;
153
153
  background: var(--ogrid-header-bg, #f5f5f5);
154
154
  }
155
- .ogrid-header-cell[data-v-7b1fd360] {
155
+ .ogrid-header-cell[data-v-18aa4567] {
156
156
  position: sticky;
157
157
  top: 0;
158
158
  background: var(--ogrid-header-bg, #f5f5f5);
@@ -165,39 +165,39 @@
165
165
  user-select: none;
166
166
  cursor: grab;
167
167
  }
168
- .ogrid-header-cell[data-v-7b1fd360]:last-child {
168
+ .ogrid-header-cell[data-v-18aa4567]:last-child {
169
169
  border-right: none;
170
170
  }
171
- .ogrid-header-cell[data-v-7b1fd360]:active {
171
+ .ogrid-header-cell[data-v-18aa4567]:active {
172
172
  cursor: grabbing;
173
173
  }
174
- .ogrid-header-cell[data-v-7b1fd360]:focus-visible {
174
+ .ogrid-header-cell[data-v-18aa4567]:focus-visible {
175
175
  outline: 2px solid var(--ogrid-accent, #0078d4);
176
176
  outline-offset: -2px;
177
177
  z-index: 11;
178
178
  }
179
- .ogrid-group-header[data-v-7b1fd360] {
179
+ .ogrid-group-header[data-v-18aa4567] {
180
180
  text-align: center;
181
181
  border-bottom: 2px solid var(--ogrid-border, #e0e0e0);
182
182
  cursor: default;
183
183
  }
184
- .ogrid-group-header[data-v-7b1fd360]:active {
184
+ .ogrid-group-header[data-v-18aa4567]:active {
185
185
  cursor: default;
186
186
  }
187
- .ogrid-header-content[data-v-7b1fd360] {
187
+ .ogrid-header-content[data-v-18aa4567] {
188
188
  display: flex;
189
189
  align-items: center;
190
190
  gap: 4px;
191
191
  width: 100%;
192
192
  }
193
- .ogrid-header-label[data-v-7b1fd360] {
193
+ .ogrid-header-label[data-v-18aa4567] {
194
194
  flex: 1;
195
195
  min-width: 0;
196
196
  overflow: hidden;
197
197
  text-overflow: ellipsis;
198
198
  white-space: nowrap;
199
199
  }
200
- .ogrid-header-menu-btn[data-v-7b1fd360] {
200
+ .ogrid-header-menu-btn[data-v-18aa4567] {
201
201
  background: none;
202
202
  border: none;
203
203
  cursor: pointer;
@@ -214,15 +214,15 @@
214
214
  height: 24px;
215
215
  transition: background-color 0.15s;
216
216
  }
217
- .ogrid-header-menu-btn[data-v-7b1fd360]:hover {
217
+ .ogrid-header-menu-btn[data-v-18aa4567]:hover {
218
218
  background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04));
219
219
  color: var(--ogrid-fg, rgba(0, 0, 0, 0.8));
220
220
  }
221
- .ogrid-header-menu-btn[data-v-7b1fd360]:focus-visible {
221
+ .ogrid-header-menu-btn[data-v-18aa4567]:focus-visible {
222
222
  outline: 2px solid var(--ogrid-accent, #0078d4);
223
223
  outline-offset: 2px;
224
224
  }
225
- .ogrid-resize-handle[data-v-7b1fd360] {
225
+ .ogrid-resize-handle[data-v-18aa4567] {
226
226
  position: absolute;
227
227
  right: -3px;
228
228
  top: 0;
@@ -232,36 +232,50 @@
232
232
  z-index: 10;
233
233
  user-select: none;
234
234
  }
235
- .ogrid-row[data-v-7b1fd360]:hover {
235
+ .ogrid-row[data-v-18aa4567]:hover {
236
236
  background: var(--ogrid-hover-bg, #f9f9f9);
237
237
  }
238
- .ogrid-selected-row[data-v-7b1fd360] {
238
+ .ogrid-selected-row[data-v-18aa4567] {
239
239
  background: var(--ogrid-selected-bg, #e3f2fd);
240
240
  }
241
- .ogrid-cell[data-v-7b1fd360] {
241
+ .ogrid-cell[data-v-18aa4567] {
242
242
  padding: 0;
243
243
  border-bottom: 1px solid var(--ogrid-border, #e0e0e0);
244
244
  border-right: 1px solid var(--ogrid-border, #e0e0e0);
245
245
  position: relative;
246
246
  height: 1px;
247
247
  }
248
- .ogrid-cell[data-v-7b1fd360]:last-child {
248
+ .ogrid-cell[data-v-18aa4567]:last-child {
249
249
  border-right: none;
250
250
  }
251
- .ogrid-cell[data-v-7b1fd360]:focus-visible {
251
+ .ogrid-cell[data-v-18aa4567]:focus-visible {
252
252
  outline: 2px solid var(--ogrid-accent, #0078d4);
253
253
  outline-offset: -2px;
254
254
  z-index: 3;
255
255
  }
256
- .ogrid-active-cell[data-v-7b1fd360] {
256
+ .ogrid-active-cell[data-v-18aa4567] {
257
257
  outline: 2px solid var(--ogrid-active-border, #0078d4);
258
258
  outline-offset: -2px;
259
259
  z-index: 1;
260
260
  }
261
- .ogrid-selected-cell[data-v-7b1fd360] {
261
+ .ogrid-selected-cell[data-v-18aa4567] {
262
262
  background: var(--ogrid-bg-range, rgba(33, 115, 70, 0.12));
263
263
  }
264
- .ogrid-fill-handle[data-v-7b1fd360] {
264
+ .ogrid-editing-cell[data-v-18aa4567] {
265
+ width: 100%;
266
+ height: 100%;
267
+ display: flex;
268
+ align-items: center;
269
+ box-sizing: border-box;
270
+ outline: 2px solid var(--ogrid-selection-color, #217346);
271
+ outline-offset: -1px;
272
+ z-index: 2;
273
+ position: relative;
274
+ background: var(--ogrid-bg, #fff);
275
+ overflow: visible;
276
+ padding: 0;
277
+ }
278
+ .ogrid-fill-handle[data-v-18aa4567] {
265
279
  position: absolute;
266
280
  right: -3px;
267
281
  bottom: -3px;
@@ -274,14 +288,14 @@
274
288
  pointer-events: auto;
275
289
  z-index: 3;
276
290
  }
277
- .ogrid-selection-header[data-v-7b1fd360],
278
- .ogrid-selection-cell[data-v-7b1fd360] {
291
+ .ogrid-selection-header[data-v-18aa4567],
292
+ .ogrid-selection-cell[data-v-18aa4567] {
279
293
  width: 40px;
280
294
  text-align: center;
281
295
  padding: 8px;
282
296
  }
283
- .ogrid-row-number-header[data-v-7b1fd360],
284
- .ogrid-row-number-cell[data-v-7b1fd360] {
297
+ .ogrid-row-number-header[data-v-18aa4567],
298
+ .ogrid-row-number-cell[data-v-18aa4567] {
285
299
  width: 40px;
286
300
  text-align: center;
287
301
  padding: 6px;
@@ -290,27 +304,27 @@
290
304
  color: var(--ogrid-muted, #888);
291
305
  background: var(--ogrid-header-bg, #f5f5f5);
292
306
  }
293
- .ogrid-checkbox[data-v-7b1fd360] {
307
+ .ogrid-checkbox[data-v-18aa4567] {
294
308
  cursor: pointer;
295
309
  width: 16px;
296
310
  height: 16px;
297
311
  }
298
- .ogrid-empty-state[data-v-7b1fd360] {
312
+ .ogrid-empty-state[data-v-18aa4567] {
299
313
  padding: 32px 16px;
300
314
  text-align: center;
301
315
  border-top: 1px solid var(--ogrid-border, #e0e0e0);
302
316
  background: var(--ogrid-statusbar-bg, #f5f5f5);
303
317
  }
304
- .ogrid-empty-title[data-v-7b1fd360] {
318
+ .ogrid-empty-title[data-v-18aa4567] {
305
319
  font-size: 1.25rem;
306
320
  font-weight: 600;
307
321
  margin-bottom: 8px;
308
322
  }
309
- .ogrid-empty-message[data-v-7b1fd360] {
323
+ .ogrid-empty-message[data-v-18aa4567] {
310
324
  font-size: 0.875rem;
311
325
  color: var(--ogrid-muted, #888);
312
326
  }
313
- .ogrid-empty-clear-btn[data-v-7b1fd360] {
327
+ .ogrid-empty-clear-btn[data-v-18aa4567] {
314
328
  background: none;
315
329
  border: none;
316
330
  color: var(--ogrid-primary, #0066cc);
@@ -319,10 +333,10 @@
319
333
  padding: 0;
320
334
  font: inherit;
321
335
  }
322
- .ogrid-empty-clear-btn[data-v-7b1fd360]:hover {
336
+ .ogrid-empty-clear-btn[data-v-18aa4567]:hover {
323
337
  color: var(--ogrid-primary-hover, #005a9e);
324
338
  }
325
- .ogrid-loading-overlay[data-v-7b1fd360] {
339
+ .ogrid-loading-overlay[data-v-18aa4567] {
326
340
  position: absolute;
327
341
  inset: 0;
328
342
  z-index: 2;
@@ -331,7 +345,7 @@
331
345
  justify-content: center;
332
346
  background-color: rgba(255, 255, 255, 0.7);
333
347
  }
334
- .ogrid-loading-content[data-v-7b1fd360] {
348
+ .ogrid-loading-content[data-v-18aa4567] {
335
349
  display: flex;
336
350
  flex-direction: column;
337
351
  align-items: center;
@@ -343,15 +357,15 @@
343
357
  font-size: 0.875rem;
344
358
  color: var(--ogrid-muted, #888);
345
359
  }
346
- .loading-spinner[data-v-7b1fd360] {
360
+ .loading-spinner[data-v-18aa4567] {
347
361
  width: 24px;
348
362
  height: 24px;
349
363
  border: 3px solid var(--ogrid-border, #e0e0e0);
350
364
  border-top-color: var(--ogrid-primary, #0066cc);
351
365
  border-radius: 50%;
352
- animation: spin-7b1fd360 0.8s linear infinite;
366
+ animation: spin-18aa4567 0.8s linear infinite;
353
367
  }
354
- @keyframes spin-7b1fd360 {
368
+ @keyframes spin-18aa4567 {
355
369
  to {
356
370
  transform: rotate(360deg);
357
371
  }
@@ -1,7 +1,7 @@
1
1
  import _sfc_main from "./DataGridTable.vue2.js";
2
2
  import './DataGridTable.css';
3
3
  import _export_sfc from "../_virtual/_plugin-vue_export-helper.js";
4
- const DataGridTable = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-7b1fd360"]]);
4
+ const DataGridTable = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-18aa4567"]]);
5
5
  export {
6
6
  DataGridTable as default
7
7
  };
@@ -26,16 +26,20 @@ const _hoisted_14 = {
26
26
  };
27
27
  const _hoisted_15 = ["data-column-id", "data-row-index", "data-col-index", "onMousedown"];
28
28
  const _hoisted_16 = {
29
+ key: 0,
30
+ class: "ogrid-editing-cell"
31
+ };
32
+ const _hoisted_17 = {
29
33
  key: 0,
30
34
  class: "ogrid-empty-state"
31
35
  };
32
- const _hoisted_17 = { key: 1 };
33
- const _hoisted_18 = { class: "ogrid-empty-message" };
34
- const _hoisted_19 = {
36
+ const _hoisted_18 = { key: 1 };
37
+ const _hoisted_19 = { class: "ogrid-empty-message" };
38
+ const _hoisted_20 = {
35
39
  key: 0,
36
40
  class: "ogrid-loading-overlay"
37
41
  };
38
- const _hoisted_20 = { class: "ogrid-loading-content" };
42
+ const _hoisted_21 = { class: "ogrid-loading-content" };
39
43
  const _sfc_main = /* @__PURE__ */ defineComponent({
40
44
  __name: "DataGridTable",
41
45
  props: {
@@ -142,10 +146,15 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
142
146
  const getCellStyle = (item, col, rowIndex, colIndex) => {
143
147
  const descriptor = getCellRenderDescriptor(item, col, rowIndex, colIndex, viewModels.value.cellDescriptorInput);
144
148
  const columnWidth = getColumnWidth(col);
149
+ const layoutValue = layout.value;
150
+ const hasResizeOverride = !!layoutValue.columnSizingOverrides[col.columnId];
151
+ const measuredW = layoutValue.measuredColumnWidths[col.columnId];
152
+ const baseMinWidth = col.minWidth ?? DEFAULT_MIN_COLUMN_WIDTH;
153
+ const effectiveMinWidth = hasResizeOverride ? columnWidth : Math.max(baseMinWidth, measuredW ?? 0);
145
154
  const style = {
146
155
  position: "relative",
147
156
  padding: "0",
148
- minWidth: `${col.minWidth ?? DEFAULT_MIN_COLUMN_WIDTH}px`,
157
+ minWidth: `${effectiveMinWidth}px`,
149
158
  width: `${columnWidth}px`,
150
159
  maxWidth: `${columnWidth}px`
151
160
  };
@@ -185,9 +194,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
185
194
  const isFreezeCol = freezeCols != null && freezeCols >= 1 && colIndex < freezeCols;
186
195
  const isPinnedLeft = col.pinned === "left";
187
196
  const isPinnedRight = col.pinned === "right";
197
+ const layoutValue = layout.value;
198
+ const hasResizeOverride = !!layoutValue.columnSizingOverrides[col.columnId];
199
+ const measuredW = layoutValue.measuredColumnWidths[col.columnId];
200
+ const baseMinWidth = col.minWidth ?? DEFAULT_MIN_COLUMN_WIDTH;
201
+ const effectiveMinWidth = hasResizeOverride ? columnWidth : Math.max(baseMinWidth, measuredW ?? 0);
188
202
  const style = {
189
203
  width: `${columnWidth}px`,
190
- minWidth: `${col.minWidth ?? DEFAULT_MIN_COLUMN_WIDTH}px`,
204
+ minWidth: `${effectiveMinWidth}px`,
191
205
  maxWidth: `${columnWidth}px`
192
206
  };
193
207
  if (isPinnedLeft || isFreezeCol && colIndex === 0) {
@@ -303,6 +317,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
303
317
  }, [
304
318
  __props.gridProps.rowSelection === "multiple" ? (openBlock(), createElementBlock("input", {
305
319
  key: 0,
320
+ ref_for: true,
321
+ ref: (el) => {
322
+ if (el) el.indeterminate = rowSel.value.someSelected && !rowSel.value.allSelected;
323
+ },
306
324
  type: "checkbox",
307
325
  checked: rowSel.value.allSelected,
308
326
  onChange: _cache[0] || (_cache[0] = //@ts-ignore
@@ -343,7 +361,12 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
343
361
  cell.columnDef && cell.columnDef.resizable !== false ? (openBlock(), createElementBlock("div", {
344
362
  key: 0,
345
363
  class: "ogrid-resize-handle",
346
- onMousedown: withModifiers((e) => unref(handleResizeStart)(e, cell.columnDef), ["stop"])
364
+ onMousedown: withModifiers((e) => {
365
+ interaction.value.setActiveCell(null);
366
+ interaction.value.setSelectionRange(null);
367
+ unref(wrapperRef)?.focus({ preventScroll: true });
368
+ unref(handleResizeStart)(e, cell.columnDef);
369
+ }, ["stop"])
347
370
  }, null, 40, _hoisted_10)) : createCommentVNode("", true)
348
371
  ], 46, _hoisted_6);
349
372
  }), 128))
@@ -396,10 +419,9 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
396
419
  createElementVNode("div", {
397
420
  style: normalizeStyle(getCellContentStyle(col, item, rowIndex, layout.value.colOffset + colIndex))
398
421
  }, [
399
- getCellRenderData(item, col, rowIndex, layout.value.colOffset + colIndex).type === "editor" ? (openBlock(), createBlock(resolveDynamicComponent(InlineCellEditor), mergeProps({
400
- key: 0,
401
- ref_for: true
402
- }, getCellRenderData(item, col, rowIndex, layout.value.colOffset + colIndex).props), null, 16)) : getCellRenderData(item, col, rowIndex, layout.value.colOffset + colIndex).type === "popover-editor" ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [
422
+ getCellRenderData(item, col, rowIndex, layout.value.colOffset + colIndex).type === "editor" ? (openBlock(), createElementBlock("div", _hoisted_16, [
423
+ (openBlock(), createBlock(resolveDynamicComponent(InlineCellEditor), mergeProps({ ref_for: true }, getCellRenderData(item, col, rowIndex, layout.value.colOffset + colIndex).props), null, 16))
424
+ ])) : getCellRenderData(item, col, rowIndex, layout.value.colOffset + colIndex).type === "popover-editor" ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [
403
425
  createElementVNode("div", {
404
426
  ref_for: true,
405
427
  ref: (el) => {
@@ -434,10 +456,10 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
434
456
  }, null, 4)) : createCommentVNode("", true)
435
457
  ])) : createCommentVNode("", true)
436
458
  ], 12, _hoisted_3),
437
- viewModels.value.showEmptyInGrid && __props.gridProps.emptyState ? (openBlock(), createElementBlock("div", _hoisted_16, [
438
- __props.gridProps.emptyState.render ? (openBlock(), createBlock(resolveDynamicComponent({ render: __props.gridProps.emptyState.render }), { key: 0 })) : (openBlock(), createElementBlock("div", _hoisted_17, [
459
+ viewModels.value.showEmptyInGrid && __props.gridProps.emptyState ? (openBlock(), createElementBlock("div", _hoisted_17, [
460
+ __props.gridProps.emptyState.render ? (openBlock(), createBlock(resolveDynamicComponent({ render: __props.gridProps.emptyState.render }), { key: 0 })) : (openBlock(), createElementBlock("div", _hoisted_18, [
439
461
  _cache[9] || (_cache[9] = createElementVNode("div", { class: "ogrid-empty-title" }, "No results found", -1)),
440
- createElementVNode("div", _hoisted_18, [
462
+ createElementVNode("div", _hoisted_19, [
441
463
  __props.gridProps.emptyState.message ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
442
464
  createTextVNode(toDisplayString(__props.gridProps.emptyState.message), 1)
443
465
  ], 64)) : __props.gridProps.emptyState.hasActiveFilters ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [
@@ -467,8 +489,8 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
467
489
  }, null, 8, ["containerRef", "selectionRange", "copyRange", "cutRange", "colOffset", "items", "visibleColumns", "columnSizingOverrides", "columnOrder"])
468
490
  ], 512)
469
491
  ], 44, _hoisted_2),
470
- __props.gridProps.isLoading ? (openBlock(), createElementBlock("div", _hoisted_19, [
471
- createElementVNode("div", _hoisted_20, [
492
+ __props.gridProps.isLoading ? (openBlock(), createElementBlock("div", _hoisted_20, [
493
+ createElementVNode("div", _hoisted_21, [
472
494
  _cache[10] || (_cache[10] = createElementVNode("div", { class: "loading-spinner" }, null, -1)),
473
495
  createElementVNode("span", null, toDisplayString(__props.gridProps.loadingMessage || "Loading..."), 1)
474
496
  ])
@@ -1,5 +1,4 @@
1
- .editor-wrapper[data-v-cf3c3944],
2
- .select-wrapper[data-v-cf3c3944] {
1
+ .editor-wrapper[data-v-ddf20238] {
3
2
  width: 100%;
4
3
  height: 100%;
5
4
  display: flex;
@@ -9,8 +8,7 @@
9
8
  overflow: hidden;
10
9
  min-width: 0;
11
10
  }
12
- .editor-input[data-v-cf3c3944],
13
- .select-editor[data-v-cf3c3944] {
11
+ .editor-input[data-v-ddf20238] {
14
12
  width: 100%;
15
13
  padding: 0;
16
14
  border: none;
@@ -21,10 +19,52 @@
21
19
  outline: none;
22
20
  min-width: 0;
23
21
  }
24
- .select-editor[data-v-cf3c3944] {
22
+ .custom-select-wrapper[data-v-ddf20238] {
23
+ width: 100%;
24
+ height: 100%;
25
+ display: flex;
26
+ align-items: center;
27
+ padding: 6px 10px;
28
+ box-sizing: border-box;
29
+ min-width: 0;
30
+ position: relative;
31
+ outline: none;
32
+ }
33
+ .custom-select-display[data-v-ddf20238] {
34
+ display: flex;
35
+ align-items: center;
36
+ justify-content: space-between;
37
+ width: 100%;
38
+ cursor: pointer;
39
+ font-size: 13px;
40
+ color: inherit;
41
+ }
42
+ .custom-select-chevron[data-v-ddf20238] {
43
+ margin-left: 4px;
44
+ font-size: 10px;
45
+ opacity: 0.5;
46
+ }
47
+ .custom-select-dropdown[data-v-ddf20238] {
48
+ position: absolute;
49
+ top: 100%;
50
+ left: 0;
51
+ right: 0;
52
+ max-height: 200px;
53
+ overflow-y: auto;
54
+ background: var(--ogrid-bg, #fff);
55
+ border: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
56
+ z-index: 10;
57
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
58
+ }
59
+ .custom-select-option[data-v-ddf20238] {
60
+ padding: 6px 8px;
25
61
  cursor: pointer;
62
+ color: var(--ogrid-fg, #242424);
63
+ }
64
+ .custom-select-option.highlighted[data-v-ddf20238] {
65
+ background: var(--ogrid-bg-hover, #e8f0fe);
26
66
  }
27
- .rich-select-wrapper[data-v-cf3c3944] {
67
+ .rich-select-wrapper[data-v-ddf20238] {
28
68
  width: 100%;
29
69
  height: 100%;
30
70
  display: flex;
@@ -35,7 +75,7 @@
35
75
  min-width: 0;
36
76
  position: relative;
37
77
  }
38
- .rich-select-input[data-v-cf3c3944] {
78
+ .rich-select-input[data-v-ddf20238] {
39
79
  width: 100%;
40
80
  padding: 0;
41
81
  border: none;
@@ -46,7 +86,7 @@
46
86
  outline: none;
47
87
  min-width: 0;
48
88
  }
49
- .rich-select-dropdown[data-v-cf3c3944] {
89
+ .rich-select-dropdown[data-v-ddf20238] {
50
90
  position: absolute;
51
91
  top: 100%;
52
92
  left: 0;
@@ -58,26 +98,26 @@
58
98
  z-index: 10;
59
99
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
60
100
  }
61
- .rich-select-option[data-v-cf3c3944] {
101
+ .rich-select-option[data-v-ddf20238] {
62
102
  padding: 6px 8px;
63
103
  cursor: pointer;
64
104
  color: var(--ogrid-fg, #242424);
65
105
  }
66
- .rich-select-option.highlighted[data-v-cf3c3944] {
106
+ .rich-select-option.highlighted[data-v-ddf20238] {
67
107
  background: var(--ogrid-bg-hover, #e8f0fe);
68
108
  }
69
- .rich-select-no-matches[data-v-cf3c3944] {
109
+ .rich-select-no-matches[data-v-ddf20238] {
70
110
  padding: 6px 8px;
71
111
  color: var(--ogrid-muted, #999);
72
112
  }
73
- .checkbox-editor-wrapper[data-v-cf3c3944] {
113
+ .checkbox-editor-wrapper[data-v-ddf20238] {
74
114
  display: flex;
75
115
  align-items: center;
76
116
  justify-content: center;
77
117
  width: 100%;
78
118
  height: 100%;
79
119
  }
80
- .checkbox-editor[data-v-cf3c3944] {
120
+ .checkbox-editor[data-v-ddf20238] {
81
121
  width: 18px;
82
122
  height: 18px;
83
123
  cursor: pointer;
@@ -1,7 +1,7 @@
1
1
  import _sfc_main from "./InlineCellEditor.vue2.js";
2
2
  import './InlineCellEditor.css';
3
3
  import _export_sfc from "../_virtual/_plugin-vue_export-helper.js";
4
- const InlineCellEditor = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-cf3c3944"]]);
4
+ const InlineCellEditor = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-ddf20238"]]);
5
5
  export {
6
6
  InlineCellEditor as default
7
7
  };
@@ -1,4 +1,4 @@
1
- import { defineComponent, ref, computed, onMounted, openBlock, createElementBlock, createElementVNode, unref, Fragment, renderList, normalizeClass, toDisplayString, createCommentVNode, withKeys, withModifiers } from "vue";
1
+ import { defineComponent, ref, computed, onMounted, openBlock, createElementBlock, createElementVNode, unref, Fragment, renderList, normalizeClass, toDisplayString, createCommentVNode, withKeys, withModifiers, nextTick } from "vue";
2
2
  import { useInlineCellEditorState, useRichSelectState } from "@alaarab/ogrid-vue";
3
3
  const _hoisted_1 = ["value"];
4
4
  const _hoisted_2 = {
@@ -15,14 +15,10 @@ const _hoisted_5 = {
15
15
  class: "checkbox-editor-wrapper"
16
16
  };
17
17
  const _hoisted_6 = ["checked"];
18
- const _hoisted_7 = {
19
- key: 2,
20
- class: "select-wrapper"
21
- };
22
- const _hoisted_8 = ["value"];
18
+ const _hoisted_7 = { class: "custom-select-display" };
19
+ const _hoisted_8 = ["aria-selected", "onClick"];
23
20
  const _hoisted_9 = ["value"];
24
21
  const _hoisted_10 = ["value"];
25
- const _hoisted_11 = ["value"];
26
22
  const _sfc_main = /* @__PURE__ */ defineComponent({
27
23
  __name: "InlineCellEditor",
28
24
  props: {
@@ -62,11 +58,84 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
62
58
  const handleCheckboxChange = (val) => {
63
59
  commit(val);
64
60
  };
65
- const handleSelectChange = (e) => {
66
- const target = e.target;
67
- commit(target.value);
61
+ const selectWrapperRef = ref(null);
62
+ const selectDropdownRef = ref(null);
63
+ const highlightedIndex = ref(0);
64
+ const initIdx = selectValues.value.findIndex((v) => String(v) === String(props.value));
65
+ highlightedIndex.value = Math.max(initIdx, 0);
66
+ const getDisplayText = (value) => {
67
+ const formatValue = props.column.cellEditorParams?.formatValue;
68
+ if (formatValue) return formatValue(value);
69
+ return value != null ? String(value) : "";
70
+ };
71
+ const scrollHighlightedIntoView = () => {
72
+ nextTick(() => {
73
+ const dropdown = selectDropdownRef.value;
74
+ if (!dropdown) return;
75
+ const highlighted = dropdown.children[highlightedIndex.value];
76
+ highlighted?.scrollIntoView({ block: "nearest" });
77
+ });
78
+ };
79
+ const handleSelectKeyDown = (e) => {
80
+ const options = selectValues.value;
81
+ switch (e.key) {
82
+ case "ArrowDown":
83
+ e.preventDefault();
84
+ highlightedIndex.value = Math.min(highlightedIndex.value + 1, options.length - 1);
85
+ scrollHighlightedIntoView();
86
+ break;
87
+ case "ArrowUp":
88
+ e.preventDefault();
89
+ highlightedIndex.value = Math.max(highlightedIndex.value - 1, 0);
90
+ scrollHighlightedIntoView();
91
+ break;
92
+ case "Enter":
93
+ e.preventDefault();
94
+ e.stopPropagation();
95
+ if (options.length > 0 && highlightedIndex.value < options.length) {
96
+ commit(options[highlightedIndex.value]);
97
+ }
98
+ break;
99
+ case "Tab":
100
+ e.preventDefault();
101
+ if (options.length > 0 && highlightedIndex.value < options.length) {
102
+ commit(options[highlightedIndex.value]);
103
+ }
104
+ break;
105
+ case "Escape":
106
+ e.preventDefault();
107
+ e.stopPropagation();
108
+ cancel();
109
+ break;
110
+ }
111
+ };
112
+ const positionDropdown = () => {
113
+ const wrapper = selectWrapperRef.value;
114
+ const dropdown = selectDropdownRef.value;
115
+ if (!wrapper || !dropdown) return;
116
+ const rect = wrapper.getBoundingClientRect();
117
+ const maxH = 200;
118
+ const spaceBelow = window.innerHeight - rect.bottom;
119
+ const flipUp = spaceBelow < maxH && rect.top > spaceBelow;
120
+ dropdown.style.position = "fixed";
121
+ dropdown.style.left = `${rect.left}px`;
122
+ dropdown.style.width = `${rect.width}px`;
123
+ dropdown.style.maxHeight = `${maxH}px`;
124
+ dropdown.style.zIndex = "9999";
125
+ dropdown.style.right = "auto";
126
+ if (flipUp) {
127
+ dropdown.style.top = "auto";
128
+ dropdown.style.bottom = `${window.innerHeight - rect.top}px`;
129
+ } else {
130
+ dropdown.style.top = `${rect.bottom}px`;
131
+ }
68
132
  };
69
133
  onMounted(() => {
134
+ if (selectWrapperRef.value) {
135
+ selectWrapperRef.value.focus();
136
+ positionDropdown();
137
+ return;
138
+ }
70
139
  const input = wrapperRef.value?.querySelector("input");
71
140
  if (input) {
72
141
  input.focus();
@@ -115,26 +184,35 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
115
184
  class: "checkbox-editor",
116
185
  autofocus: ""
117
186
  }, null, 40, _hoisted_6)
118
- ])) : __props.editorType === "select" ? (openBlock(), createElementBlock("div", _hoisted_7, [
119
- createElementVNode("select", {
120
- value: __props.value !== null && __props.value !== void 0 ? String(__props.value) : "",
121
- onChange: handleSelectChange,
122
- onKeydown: _cache[4] || (_cache[4] = withKeys(withModifiers(
123
- //@ts-ignore
124
- (...args) => unref(cancel) && unref(cancel)(...args),
125
- ["prevent"]
126
- ), ["esc"])),
127
- class: "select-editor",
128
- autofocus: ""
187
+ ])) : __props.editorType === "select" ? (openBlock(), createElementBlock("div", {
188
+ key: 2,
189
+ ref_key: "selectWrapperRef",
190
+ ref: selectWrapperRef,
191
+ tabindex: "0",
192
+ class: "custom-select-wrapper",
193
+ onKeydown: handleSelectKeyDown
194
+ }, [
195
+ createElementVNode("div", _hoisted_7, [
196
+ createElementVNode("span", null, toDisplayString(getDisplayText(__props.value)), 1),
197
+ _cache[10] || (_cache[10] = createElementVNode("span", { class: "custom-select-chevron" }, "▾", -1))
198
+ ]),
199
+ createElementVNode("div", {
200
+ ref_key: "selectDropdownRef",
201
+ ref: selectDropdownRef,
202
+ role: "listbox",
203
+ class: "custom-select-dropdown"
129
204
  }, [
130
- (openBlock(true), createElementBlock(Fragment, null, renderList(selectValues.value, (v) => {
131
- return openBlock(), createElementBlock("option", {
205
+ (openBlock(true), createElementBlock(Fragment, null, renderList(selectValues.value, (v, i) => {
206
+ return openBlock(), createElementBlock("div", {
132
207
  key: String(v),
133
- value: String(v)
134
- }, toDisplayString(String(v)), 9, _hoisted_9);
208
+ role: "option",
209
+ "aria-selected": i === highlightedIndex.value,
210
+ class: normalizeClass(["custom-select-option", { highlighted: i === highlightedIndex.value }]),
211
+ onClick: () => unref(commit)(v)
212
+ }, toDisplayString(getDisplayText(v)), 11, _hoisted_8);
135
213
  }), 128))
136
- ], 40, _hoisted_8)
137
- ])) : __props.editorType === "date" ? (openBlock(), createElementBlock("div", {
214
+ ], 512)
215
+ ], 544)) : __props.editorType === "date" ? (openBlock(), createElementBlock("div", {
138
216
  key: 3,
139
217
  ref_key: "wrapperRef",
140
218
  ref: wrapperRef,
@@ -143,14 +221,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
143
221
  createElementVNode("input", {
144
222
  type: "date",
145
223
  value: unref(localValue),
146
- onInput: _cache[5] || (_cache[5] = (e) => unref(setLocalValue)(e.target.value)),
147
- onBlur: _cache[6] || (_cache[6] = //@ts-ignore
224
+ onInput: _cache[4] || (_cache[4] = (e) => unref(setLocalValue)(e.target.value)),
225
+ onBlur: _cache[5] || (_cache[5] = //@ts-ignore
148
226
  (...args) => unref(handleBlur) && unref(handleBlur)(...args)),
149
- onKeydown: _cache[7] || (_cache[7] = //@ts-ignore
227
+ onKeydown: _cache[6] || (_cache[6] = //@ts-ignore
150
228
  (...args) => unref(handleKeyDown) && unref(handleKeyDown)(...args)),
151
229
  class: "editor-input",
152
230
  autofocus: ""
153
- }, null, 40, _hoisted_10)
231
+ }, null, 40, _hoisted_9)
154
232
  ], 512)) : (openBlock(), createElementBlock("div", {
155
233
  key: 4,
156
234
  ref_key: "wrapperRef",
@@ -160,14 +238,14 @@ const _sfc_main = /* @__PURE__ */ defineComponent({
160
238
  createElementVNode("input", {
161
239
  type: "text",
162
240
  value: unref(localValue),
163
- onInput: _cache[8] || (_cache[8] = (e) => unref(setLocalValue)(e.target.value)),
164
- onBlur: _cache[9] || (_cache[9] = //@ts-ignore
241
+ onInput: _cache[7] || (_cache[7] = (e) => unref(setLocalValue)(e.target.value)),
242
+ onBlur: _cache[8] || (_cache[8] = //@ts-ignore
165
243
  (...args) => unref(handleBlur) && unref(handleBlur)(...args)),
166
- onKeydown: _cache[10] || (_cache[10] = //@ts-ignore
244
+ onKeydown: _cache[9] || (_cache[9] = //@ts-ignore
167
245
  (...args) => unref(handleKeyDown) && unref(handleKeyDown)(...args)),
168
246
  class: "editor-input",
169
247
  autofocus: ""
170
- }, null, 40, _hoisted_11)
248
+ }, null, 40, _hoisted_10)
171
249
  ], 512));
172
250
  };
173
251
  }
@@ -11,5 +11,7 @@ export interface InlineCellEditorProps<T = any> {
11
11
  type __VLS_Props = InlineCellEditorProps;
12
12
  declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
13
13
  wrapperRef: HTMLDivElement;
14
+ selectWrapperRef: HTMLDivElement;
15
+ selectDropdownRef: HTMLDivElement;
14
16
  }, any>;
15
17
  export default _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alaarab/ogrid-vue-radix",
3
- "version": "2.0.15",
3
+ "version": "2.0.16",
4
4
  "description": "OGrid Vue Radix – Lightweight data grid with sorting, filtering, pagination, column chooser, and CSV export. Built with Headless UI Vue.",
5
5
  "main": "dist/esm/index.js",
6
6
  "module": "dist/esm/index.js",