@nu-grid/nuxt 0.2.0 → 0.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.
Files changed (68) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/cell-types/date/index.d.ts +1 -1
  3. package/dist/runtime/cell-types/date/index.js +15 -1
  4. package/dist/runtime/cell-types/index.d.ts +2 -1
  5. package/dist/runtime/cell-types/index.js +3 -0
  6. package/dist/runtime/cell-types/number/NumberFilter.vue +1 -1
  7. package/dist/runtime/cell-types/percentage/PercentageEditor.d.vue.ts +15 -0
  8. package/dist/runtime/cell-types/percentage/PercentageEditor.vue +56 -0
  9. package/dist/runtime/cell-types/percentage/PercentageEditor.vue.d.ts +15 -0
  10. package/dist/runtime/cell-types/percentage/PercentageFilter.d.vue.ts +7 -0
  11. package/dist/runtime/cell-types/percentage/PercentageFilter.vue +79 -0
  12. package/dist/runtime/cell-types/percentage/PercentageFilter.vue.d.ts +7 -0
  13. package/dist/runtime/cell-types/percentage/index.d.ts +10 -0
  14. package/dist/runtime/cell-types/percentage/index.js +38 -0
  15. package/dist/runtime/components/NuGrid.d.vue.ts +8 -5
  16. package/dist/runtime/components/NuGrid.vue +41 -9
  17. package/dist/runtime/components/NuGrid.vue.d.ts +8 -5
  18. package/dist/runtime/components/_internal/NuGridBase.vue +128 -82
  19. package/dist/runtime/components/_internal/NuGridCellContent.vue +21 -1
  20. package/dist/runtime/components/_internal/NuGridColumnMenu.vue +2 -2
  21. package/dist/runtime/components/_internal/NuGridGroup.vue +22 -15
  22. package/dist/runtime/components/_internal/NuGridRow.vue +12 -4
  23. package/dist/runtime/components/_internal/NuGridSplitGroup.vue +22 -16
  24. package/dist/runtime/composables/_internal/column-flex-style.d.ts +22 -0
  25. package/dist/runtime/composables/_internal/column-flex-style.js +84 -0
  26. package/dist/runtime/composables/_internal/index.d.ts +1 -0
  27. package/dist/runtime/composables/_internal/index.js +1 -0
  28. package/dist/runtime/composables/_internal/useNuGridAddRow.js +5 -1
  29. package/dist/runtime/composables/_internal/useNuGridAutosize.d.ts +6 -3
  30. package/dist/runtime/composables/_internal/useNuGridAutosize.js +91 -9
  31. package/dist/runtime/composables/_internal/useNuGridCellEditing.js +3 -2
  32. package/dist/runtime/composables/_internal/useNuGridColumnResize.d.ts +17 -7
  33. package/dist/runtime/composables/_internal/useNuGridColumnResize.js +219 -8
  34. package/dist/runtime/composables/_internal/useNuGridCore.d.ts +1 -1
  35. package/dist/runtime/composables/_internal/useNuGridCore.js +16 -5
  36. package/dist/runtime/composables/_internal/useNuGridFocus.js +1 -1
  37. package/dist/runtime/composables/_internal/useNuGridRowSelection.js +1 -1
  38. package/dist/runtime/composables/_internal/useNuGridStatePersistence.d.ts +14 -1
  39. package/dist/runtime/composables/_internal/useNuGridStatePersistence.js +66 -3
  40. package/dist/runtime/composables/_internal/useNuGridUI.d.ts +116 -0
  41. package/dist/runtime/config/_internal/options-defaults.d.ts +3 -4
  42. package/dist/runtime/config/_internal/options-defaults.js +3 -4
  43. package/dist/runtime/config/_internal/prop-utils.d.ts +7 -1
  44. package/dist/runtime/config/_internal/prop-utils.js +20 -6
  45. package/dist/runtime/config/presets.js +2 -2
  46. package/dist/runtime/themes/nuGridTheme.d.ts +2 -0
  47. package/dist/runtime/themes/nuGridTheme.js +7 -4
  48. package/dist/runtime/themes/nuGridThemeCompact.d.ts +2 -0
  49. package/dist/runtime/themes/nuGridThemeCompact.js +7 -4
  50. package/dist/runtime/types/_internal/contexts/resize.d.ts +1 -0
  51. package/dist/runtime/types/_internal/contexts/ui-config.d.ts +4 -2
  52. package/dist/runtime/types/autosize.d.ts +4 -1
  53. package/dist/runtime/types/column.d.ts +41 -3
  54. package/dist/runtime/types/index.d.ts +2 -1
  55. package/dist/runtime/types/option-groups.d.ts +26 -8
  56. package/dist/runtime/types/props.d.ts +34 -9
  57. package/dist/runtime/types/resize.d.ts +2 -0
  58. package/dist/runtime/types/slots.d.ts +32 -0
  59. package/dist/runtime/types/slots.js +0 -0
  60. package/dist/runtime/types/tanstack-table.d.ts +3 -2
  61. package/dist/runtime/utils/index.d.ts +1 -0
  62. package/dist/runtime/utils/index.js +1 -0
  63. package/dist/runtime/utils/inferCellDataType.d.ts +27 -0
  64. package/dist/runtime/utils/inferCellDataType.js +91 -0
  65. package/package.json +1 -1
  66. package/dist/runtime/components/NuGridGroup.d.vue.ts +0 -20
  67. package/dist/runtime/components/NuGridGroup.vue +0 -650
  68. package/dist/runtime/components/NuGridGroup.vue.d.ts +0 -20
@@ -1,20 +0,0 @@
1
- import type { TableData, TableSlots } from '@nuxt/ui';
2
- import type { NuGridProps } from '../types/index.js';
3
- declare const __VLS_export: <T extends TableData>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
4
- props: import("vue").PublicProps & __VLS_PrettifyLocal<NuGridProps<T>> & (typeof globalThis extends {
5
- __VLS_PROPS_FALLBACK: infer P;
6
- } ? P : {});
7
- expose: (exposed: {}) => void;
8
- attrs: any;
9
- slots: TableSlots<T>;
10
- emit: {};
11
- }>) => import("vue").VNode & {
12
- __ctx?: Awaited<typeof __VLS_setup>;
13
- };
14
- declare const _default: typeof __VLS_export;
15
- export default _default;
16
- type __VLS_PrettifyLocal<T> = (T extends any ? {
17
- [K in keyof T]: T[K];
18
- } : {
19
- [K in keyof T as K]: T[K];
20
- }) & {};
@@ -1,650 +0,0 @@
1
- <script setup>
2
- import { FlexRender } from "@tanstack/vue-table";
3
- import { createReusableTemplate, useElementSize } from "@vueuse/core";
4
- import { Primitive } from "reka-ui";
5
- import { upperFirst } from "scule";
6
- import { computed, inject, ref, toValue } from "vue";
7
- import {
8
- getHeaderEffectivePinning,
9
- getHeaderPinningStyle,
10
- resolveStyleObject,
11
- resolveValue,
12
- useNuGridGroupSelection
13
- } from "../composables/_internal";
14
- import NuGridAddRow from "./_internal/NuGridAddRow.vue";
15
- import NuGridColumnMenu from "./_internal/NuGridColumnMenu.vue";
16
- import NuGridGroupCheckbox from "./_internal/NuGridGroupCheckbox.vue";
17
- import NuGridHeaderSortButton from "./_internal/NuGridHeaderSortButton.vue";
18
- import NuGridRow from "./_internal/NuGridRow.vue";
19
- defineOptions({ inheritAttrs: false });
20
- const props = defineProps({
21
- ui: { type: null, required: false },
22
- preset: { type: String, required: false },
23
- focus: { type: Object, required: false },
24
- editing: { type: Object, required: false },
25
- validation: { type: [Boolean, Object], required: false },
26
- selection: { type: [Boolean, String, Object], required: false },
27
- actions: { type: [Boolean, Object], required: false },
28
- columnDefaults: { type: Object, required: false },
29
- layout: { type: Object, required: false },
30
- tooltip: { type: [Boolean, Object], required: false },
31
- multiRow: { type: [Boolean, Object], required: false },
32
- animation: { type: [Boolean, Object], required: false },
33
- paging: { type: [Boolean, Object], required: false },
34
- state: { type: [Boolean, Object], required: false },
35
- theme: { type: [String, Object], required: false },
36
- virtualization: { type: [Boolean, Object], required: false },
37
- cellTypes: { type: Array, required: false },
38
- skipAutoSizeColumns: { type: Array, required: false },
39
- rowDragOptions: { type: Object, required: false },
40
- rowId: { type: [String, Function], required: false },
41
- addNewRow: { type: [Boolean, Object], required: false },
42
- as: { type: null, required: false },
43
- data: { type: Array, required: false },
44
- columns: { type: Array, required: false },
45
- caption: { type: String, required: false },
46
- meta: { type: Object, required: false },
47
- empty: { type: String, required: false },
48
- sticky: { type: [Boolean, String], required: false },
49
- loading: { type: Boolean, required: false },
50
- loadingColor: { type: null, required: false },
51
- loadingAnimation: { type: null, required: false },
52
- watchOptions: { type: Object, required: false },
53
- globalFilterOptions: { type: Object, required: false },
54
- columnFiltersOptions: { type: Object, required: false },
55
- columnPinningOptions: { type: Object, required: false },
56
- columnSizingOptions: { type: Object, required: false },
57
- visibilityOptions: { type: Object, required: false },
58
- sortingOptions: { type: Object, required: false },
59
- groupingOptions: { type: Object, required: false },
60
- expandedOptions: { type: Object, required: false },
61
- rowSelectionOptions: { type: Object, required: false },
62
- rowPinningOptions: { type: Object, required: false },
63
- paginationOptions: { type: Object, required: false },
64
- facetedOptions: { type: Object, required: false },
65
- onSelect: { type: Function, required: false },
66
- onHover: { type: Function, required: false },
67
- onContextmenu: { type: [Function, Array], required: false },
68
- class: { type: null, required: false },
69
- onStateChange: { type: Function, required: false },
70
- renderFallbackValue: { type: null, required: false },
71
- _features: { type: Array, required: false },
72
- autoResetAll: { type: Boolean, required: false },
73
- debugAll: { type: Boolean, required: false },
74
- debugCells: { type: Boolean, required: false },
75
- debugColumns: { type: Boolean, required: false },
76
- debugHeaders: { type: Boolean, required: false },
77
- debugRows: { type: Boolean, required: false },
78
- debugTable: { type: Boolean, required: false },
79
- defaultColumn: { type: Object, required: false },
80
- getRowId: { type: Function, required: false },
81
- getSubRows: { type: Function, required: false },
82
- initialState: { type: Object, required: false },
83
- mergeOptions: { type: Function, required: false }
84
- });
85
- const slots = defineSlots();
86
- const coreContext = inject("nugrid-core");
87
- const dragContext = inject("nugrid-drag");
88
- const resizeContext = inject("nugrid-resize");
89
- const virtualizationContext = inject("nugrid-virtualization");
90
- const groupingContext = inject("nugrid-grouping");
91
- const performanceContext = inject("nugrid-performance");
92
- const uiConfigContext = inject("nugrid-ui-config");
93
- const rowInteractionsContext = inject("nugrid-row-interactions");
94
- const addRowContext = inject("nugrid-add-row");
95
- if (!coreContext || !dragContext || !resizeContext || !virtualizationContext || !groupingContext || !performanceContext || !uiConfigContext || !rowInteractionsContext || !addRowContext) {
96
- throw new Error("NuGridGroup must be used within a NuGrid component.");
97
- }
98
- const { tableRef, rootRef, tableApi, ui, hasFooter, propsUi } = coreContext;
99
- const { dragFns, rowDragOptions } = dragContext;
100
- const { handleGroupResizeStart, resizingGroupId, resizingColumnId } = resizeContext;
101
- const { stickyEnabled } = virtualizationContext;
102
- const { groupingFns } = groupingContext;
103
- const { headerGroups, headerGroupsLength, footerGroups } = performanceContext;
104
- const {
105
- sortIcons: gridSortIcons,
106
- scrollbarClass,
107
- scrollbarThemeClass,
108
- scrollbarAttr
109
- } = uiConfigContext;
110
- const { rowSelectionMode } = rowInteractionsContext;
111
- const [DefineTableTemplate, ReuseNuGridTemplate] = createReusableTemplate({ inheritAttrs: false });
112
- const [DefineGroupSubheaderTemplate, ReuseGroupSubheaderTemplate] = createReusableTemplate({ inheritAttrs: false });
113
- const [DefineHeaderCellTemplate, ReuseHeaderCellTemplate] = createReusableTemplate({ inheritAttrs: false });
114
- if (!groupingFns) {
115
- throw new Error(
116
- 'NuGridGroup requires groupingFns from context. Ensure gridMode="group" is set on NuGrid.'
117
- );
118
- }
119
- const {
120
- groupRows,
121
- groupedRows,
122
- virtualRowItems,
123
- virtualizer,
124
- virtualizationEnabled,
125
- toggleGroup,
126
- isGroupExpanded,
127
- getVirtualItemHeight,
128
- stickyOffsets,
129
- groupingRowHeights,
130
- headerGroupCount
131
- } = groupingFns;
132
- const { toggleAllGroupRows, getGroupCheckboxState } = useNuGridGroupSelection(tableApi, groupedRows);
133
- const rowSelectionEnabled = computed(() => {
134
- const mode = rowSelectionMode.value;
135
- return mode === true || mode === "single" || mode === "multi" || typeof mode === "object" && !mode.hidden;
136
- });
137
- const dynamicRowHeightsEnabled = computed(() => {
138
- if (!virtualizer || !virtualizer.value.dynamicRowHeightsEnabled) {
139
- return false;
140
- }
141
- return !!virtualizer.value.dynamicRowHeightsEnabled.value;
142
- });
143
- const columnHeadersRef = ref(null);
144
- const { height: measuredColumnHeaderHeight } = useElementSize(columnHeadersRef);
145
- const nonVirtStickyTop = computed(() => {
146
- if (measuredColumnHeaderHeight.value > 0) {
147
- return measuredColumnHeaderHeight.value;
148
- }
149
- return headerGroupCount.value * groupingRowHeights.value.columnHeader;
150
- });
151
- function virtStyle(virtualRow) {
152
- const item = virtualRowItems.value[virtualRow.index];
153
- const useDynamicHeight = dynamicRowHeightsEnabled.value;
154
- const stickyTop = stickyOffsets.value.get(virtualRow.index);
155
- const resolvedHeight = getVirtualItemHeight(virtualRow.index);
156
- if (stickyEnabled.value && item?.type === "column-headers") {
157
- if (stickyTop !== void 0) {
158
- return {
159
- position: "sticky",
160
- top: `${stickyTop}px`,
161
- left: 0,
162
- width: "100%",
163
- zIndex: 30,
164
- ...useDynamicHeight ? {} : { height: `${resolvedHeight}px` },
165
- backgroundColor: "var(--ui-bg)",
166
- // Shadow extends only above to cover subpixel gap at top
167
- boxShadow: "0 -1px 0 var(--ui-bg)"
168
- };
169
- }
170
- return {
171
- position: "absolute",
172
- top: 0,
173
- width: "100%",
174
- zIndex: 30,
175
- ...useDynamicHeight ? {} : { height: `${resolvedHeight}px` },
176
- transform: `translateY(${virtualRow.start}px)`,
177
- backgroundColor: "var(--ui-bg)"
178
- };
179
- }
180
- if (stickyEnabled.value && item?.type === "group-header") {
181
- if (stickyTop !== void 0) {
182
- return {
183
- position: "sticky",
184
- top: `${stickyTop}px`,
185
- width: "100%",
186
- zIndex: 20,
187
- ...useDynamicHeight ? {} : { height: `${resolvedHeight}px` },
188
- backgroundColor: "var(--ui-bg)"
189
- };
190
- }
191
- return {
192
- position: "absolute",
193
- top: 0,
194
- width: "100%",
195
- zIndex: 20,
196
- ...useDynamicHeight ? {} : { height: `${resolvedHeight}px` },
197
- transform: `translateY(${virtualRow.start}px)`,
198
- backgroundColor: "var(--ui-bg)"
199
- };
200
- }
201
- return {
202
- position: "absolute",
203
- top: 0,
204
- width: "100%",
205
- ...useDynamicHeight ? {} : { height: `${resolvedHeight}px` },
206
- transform: `translateY(${virtualRow.start}px)`
207
- };
208
- }
209
- function measureElementRef(el) {
210
- if (el && virtualizer && virtualizer.value.dynamicRowHeightsEnabled.value) {
211
- virtualizer.value.measureElement(el);
212
- }
213
- }
214
- </script>
215
-
216
- <template>
217
- <!-- Reusable Group Subheader Template -->
218
- <DefineGroupSubheaderTemplate v-slot="{ groupId, groupRow, itemCount, depth = 0 }">
219
- <div
220
- :data-group-header="groupId"
221
- :class="ui.groupHeader({ class: [propsUi?.groupHeader] })"
222
- :style="{ width: `${tableApi.getTotalSize()}px` }"
223
- >
224
- <!-- Fixed left part (doesn't scroll horizontally) -->
225
- <div
226
- :class="ui.groupHeaderLeft({ class: [propsUi?.groupHeaderLeft] })"
227
- :style="{ paddingLeft: depth > 0 ? `${depth * 24}px` : void 0 }"
228
- >
229
- <!-- Group selection checkbox -->
230
- <NuGridGroupCheckbox
231
- v-if="rowSelectionEnabled"
232
- :model-value="getGroupCheckboxState(groupId)"
233
- :aria-label="`Select all in group ${groupId}`"
234
- class="mr-2"
235
- @click.stop
236
- @update:model-value="
237
- (value) => toggleAllGroupRows(groupId, !!value)
238
- "
239
- />
240
- <div class="flex cursor-pointer items-center gap-3" @click="toggleGroup(groupId)">
241
- <UIcon
242
- :name="isGroupExpanded(groupId) ? 'i-lucide-chevron-down' : 'i-lucide-chevron-right'"
243
- :class="ui.groupIcon({ class: [propsUi?.groupIcon] })"
244
- />
245
- <template v-if="groupRow?.groupingColumnId">
246
- <span :class="ui.groupLabel({ class: [propsUi?.groupLabel] })">
247
- {{ upperFirst(groupRow.groupingColumnId) }}:
248
- </span>
249
- <span class="text-base font-semibold">
250
- {{ groupRow.getGroupingValue(groupRow.groupingColumnId) }}
251
- </span>
252
- </template>
253
- <span :class="ui.groupLabel({ class: [propsUi?.groupLabel] })">
254
- ({{ itemCount }} items)
255
- </span>
256
- </div>
257
- </div>
258
- <!-- Spacer that scrolls (optional, for visual continuity) -->
259
- <div :class="ui.groupHeaderSpacer({ class: [propsUi?.groupHeaderSpacer] })" />
260
- </div>
261
- </DefineGroupSubheaderTemplate>
262
-
263
- <!-- Reusable Header Cell Template -->
264
- <DefineHeaderCellTemplate v-slot="{ header, rowIndex }">
265
- <div
266
- :data-column-id="header.column.id"
267
- :data-pinned="header.column.getIsPinned()"
268
- :data-dragging="toValue(dragFns.draggedColumnId) === header.column.id"
269
- :data-drop-target="toValue(dragFns.dropTargetColumnId) === header.column.id"
270
- :data-drop-position="
271
- toValue(dragFns.dropTargetColumnId) === header.column.id ? toValue(dragFns.dropPosition) : void 0
272
- "
273
- :class="[
274
- ui.th({
275
- class: [
276
- propsUi?.th,
277
- rowIndex < headerGroupsLength - 1 ? 'rounded-b-none!' : '',
278
- headerGroupsLength > 1 && rowIndex === headerGroupsLength - 1 ? 'rounded-t-none!' : '',
279
- resolveValue(header.column.columnDef.meta?.class?.th, header)
280
- ],
281
- pinned: !!getHeaderEffectivePinning(header),
282
- colDragging: toValue(dragFns.draggedColumnId) === header.column.id,
283
- colDropTarget: toValue(dragFns.dropTargetColumnId) === header.column.id
284
- })
285
- ]"
286
- :style="{
287
- ...resolveStyleObject(header.column.columnDef.meta?.style?.th, header),
288
- width: `${header.getSize()}px`,
289
- minWidth: `${header.getSize()}px`,
290
- maxWidth: `${header.getSize()}px`,
291
- ...getHeaderPinningStyle(header),
292
- ...header.rowSpan > 1 ? { alignSelf: 'stretch' } : {}
293
- }"
294
- @dragover="
295
- (e) => dragFns.isHeaderDraggable(header) && dragFns.handleColumnDragOver(e, header.column.id)
296
- "
297
- @dragenter="dragFns.handleColumnDragEnter"
298
- @drop="
299
- (e) => dragFns.isHeaderDraggable(header) && dragFns.handleColumnDrop(e, header.column.id)
300
- "
301
- @dragend="dragFns.handleColumnDragEnd"
302
- @dragleave="dragFns.handleColumnDragLeave"
303
- >
304
- <div :class="ui.headerContainer({ class: [propsUi?.headerContainer] })">
305
- <div
306
- :draggable="dragFns.isHeaderDraggable(header)"
307
- :class="
308
- ui.thInner({
309
- class: [propsUi?.thInner],
310
- colDraggable: dragFns.isHeaderDraggable(header)
311
- })
312
- "
313
- @dragstart="
314
- (e) => dragFns.isHeaderDraggable(header) && dragFns.handleColumnDragStart(e, header.column.id)
315
- "
316
- >
317
- <slot :name="`${header.id}-header`" v-bind="header.getContext()">
318
- <FlexRender
319
- v-if="!header.isPlaceholder"
320
- :render="header.column.columnDef.header"
321
- :props="header.getContext()"
322
- />
323
- </slot>
324
- <NuGridHeaderSortButton
325
- v-if="
326
- (header.column.columnDef.sortIcons?.position ?? gridSortIcons?.position ?? 'edge') === 'inline'
327
- "
328
- :header="header"
329
- :sort-icons="header.column.columnDef.sortIcons"
330
- />
331
- </div>
332
- <NuGridHeaderSortButton
333
- v-if="
334
- (header.column.columnDef.sortIcons?.position ?? gridSortIcons?.position ?? 'edge') === 'edge'
335
- "
336
- :header="header"
337
- :sort-icons="header.column.columnDef.sortIcons"
338
- />
339
- <NuGridColumnMenu
340
- v-if="header.colSpan === 1 && rowIndex === headerGroupsLength - 1"
341
- :header="header"
342
- />
343
-
344
- <!-- Column resize handle (works for both regular columns and column groups) -->
345
- <div
346
- v-if="header.column.getCanResize() || header.colSpan > 1"
347
- :class="
348
- ui.colResizeHandle({
349
- class: [propsUi?.colResizeHandle],
350
- colResizing: header.colSpan > 1 ? resizingGroupId === header.id : resizingColumnId === header.column.id || header.column.getIsResizing()
351
- })
352
- "
353
- :data-col-resizing="
354
- header.colSpan > 1 ? resizingGroupId === header.id : resizingColumnId === header.column.id || header.column.getIsResizing() ? 'true' : void 0
355
- "
356
- @mousedown="handleGroupResizeStart($event, header)"
357
- @touchstart.passive="handleGroupResizeStart($event, header)"
358
- >
359
- <div
360
- :class="
361
- ui.colResizer({
362
- class: [propsUi?.colResizer],
363
- colResizing: header.colSpan > 1 ? resizingGroupId === header.id : resizingColumnId === header.column.id || header.column.getIsResizing()
364
- })
365
- "
366
- :data-col-resizing="
367
- header.colSpan > 1 ? resizingGroupId === header.id : resizingColumnId === header.column.id || header.column.getIsResizing() ? 'true' : void 0
368
- "
369
- />
370
- </div>
371
- </div>
372
- </div>
373
- </DefineHeaderCellTemplate>
374
-
375
- <DefineTableTemplate>
376
- <div ref="tableRef" :class="ui.base({ class: [propsUi?.base] })">
377
- <div v-if="caption || !!slots.caption" :class="ui.caption({ class: [propsUi?.caption] })">
378
- <slot name="caption">
379
- {{ caption }}
380
- </slot>
381
- </div>
382
-
383
- <!-- Column headers shown once at the top (non-virtualized) -->
384
- <div
385
- v-if="!virtualizationEnabled"
386
- ref="columnHeadersRef"
387
- :class="[
388
- ui.thead({ class: [propsUi?.thead] }),
389
- stickyEnabled ? ui.stickyColumnHeader({ class: [propsUi?.stickyColumnHeader] }) : {}
390
- ]"
391
- :data-sticky-header="stickyEnabled ? 'true' : void 0"
392
- >
393
- <div
394
- v-for="(headerGroup, rowIndex) in headerGroups"
395
- :key="headerGroup.id"
396
- :class="ui.tr({ class: propsUi?.tr })"
397
- >
398
- <!-- Drag handle header placeholder -->
399
- <div
400
- v-if="rowDragOptions.enabled"
401
- :class="[
402
- ui.th({ class: [propsUi?.th] }),
403
- ui.rowDragHeaderHandle({ class: [propsUi?.rowDragHeaderHandle] })
404
- ]"
405
- />
406
- <ReuseHeaderCellTemplate
407
- v-for="header in headerGroup.headers"
408
- :key="header.id"
409
- :header="header"
410
- :row-index="rowIndex"
411
- />
412
- </div>
413
- <div :class="ui.separator({ class: [propsUi?.separator] })" />
414
- </div>
415
-
416
- <div
417
- data-tbody
418
- :class="ui.tbody({ class: [propsUi?.tbody] })"
419
- :style="
420
- virtualizationEnabled && virtualizer ? {
421
- height: `${virtualizer.getTotalSize()}px`,
422
- position: 'relative'
423
- } : void 0
424
- "
425
- >
426
- <slot name="body-top" />
427
-
428
- <template v-if="groupRows.length">
429
- <!-- Virtualized rendering -->
430
- <template v-if="virtualizationEnabled && virtualizer">
431
- <template v-for="virtualRow in virtualizer.getVirtualItems()" :key="virtualRow.index">
432
- <div
433
- :ref="
434
- virtualizer && virtualizer.dynamicRowHeightsEnabled.value ? measureElementRef : void 0
435
- "
436
- :data-index="virtualRow.index"
437
- :style="virtStyle(virtualRow)"
438
- >
439
- <template v-if="virtualRowItems[virtualRow.index]">
440
- <!-- Column Headers (shown once at top in virtualized mode) -->
441
- <template v-if="virtualRowItems[virtualRow.index]?.type === 'column-headers'">
442
- <div
443
- :class="[
444
- ui.thead({ class: [propsUi?.thead] }),
445
- stickyEnabled ? ui.stickyColumnHeader({ class: [propsUi?.stickyColumnHeader] }) : {}
446
- ]"
447
- :data-sticky-header="stickyEnabled ? 'true' : void 0"
448
- >
449
- <div
450
- v-for="(headerGroup, rowIndex) in headerGroups"
451
- :key="headerGroup.id"
452
- :class="ui.tr({ class: propsUi?.tr })"
453
- >
454
- <!-- Drag handle header placeholder -->
455
- <div
456
- v-if="rowDragOptions.enabled"
457
- :class="[
458
- 'w-10 max-w-10 min-w-10 shrink-0',
459
- ui.th({ class: [propsUi?.th] })
460
- ]"
461
- />
462
- <ReuseHeaderCellTemplate
463
- v-for="header in headerGroup.headers"
464
- :key="header.id"
465
- :header="header"
466
- :row-index="rowIndex"
467
- />
468
- </div>
469
- </div>
470
- </template>
471
-
472
- <!-- Group Subheader -->
473
- <ReuseGroupSubheaderTemplate
474
- v-else-if="virtualRowItems[virtualRow.index]?.type === 'group-header'"
475
- :group-id="virtualRowItems[virtualRow.index]?.groupId"
476
- :group-row="virtualRowItems[virtualRow.index]?.groupRow"
477
- :item-count="
478
- groupedRows[virtualRowItems[virtualRow.index]?.groupId]?.filter(
479
- (row) => !addRowContext.isAddRowRow(row)
480
- ).length || 0
481
- "
482
- :depth="virtualRowItems[virtualRow.index]?.depth ?? 0"
483
- />
484
-
485
- <!-- Data Row -->
486
- <component
487
- :is="
488
- addRowContext.isAddRowRow(virtualRowItems[virtualRow.index]?.dataRow) ? NuGridAddRow : NuGridRow
489
- "
490
- v-else-if="
491
- virtualRowItems[virtualRow.index]?.type === 'data' && virtualRowItems[virtualRow.index]?.dataRow
492
- "
493
- :row="virtualRowItems[virtualRow.index]?.dataRow"
494
- />
495
-
496
- <!-- Footer Row -->
497
- <div
498
- v-else-if="virtualRowItems[virtualRow.index]?.type === 'footer'"
499
- :class="ui.tfoot({ class: [propsUi?.tfoot] })"
500
- >
501
- <div :class="ui.separator({ class: [propsUi?.separator] })" />
502
- <div
503
- v-for="footerGroup in footerGroups"
504
- :key="footerGroup.id"
505
- :class="ui.tr({ class: [propsUi?.tr] })"
506
- >
507
- <div
508
- v-for="header in footerGroup.headers"
509
- :key="header.id"
510
- :data-pinned="header.column.getIsPinned()"
511
- :class="[
512
- ui.th({
513
- class: [
514
- propsUi?.th,
515
- resolveValue(header.column.columnDef.meta?.class?.th, header)
516
- ],
517
- pinned: !!getHeaderEffectivePinning(header)
518
- })
519
- ]"
520
- :style="{
521
- ...resolveStyleObject(header.column.columnDef.meta?.style?.th, header),
522
- width: `${header.getSize()}px`,
523
- minWidth: `${header.getSize()}px`,
524
- maxWidth: `${header.getSize()}px`,
525
- ...getHeaderPinningStyle(header),
526
- ...header.colSpan > 1 ? { flexGrow: header.colSpan } : {},
527
- ...header.rowSpan > 1 ? { alignSelf: 'stretch' } : {}
528
- }"
529
- >
530
- <div :class="ui.footerContent({ class: [propsUi?.footerContent] })">
531
- <slot :name="`${header.id}-footer`" v-bind="header.getContext()">
532
- <FlexRender
533
- v-if="!header.isPlaceholder"
534
- :render="header.column.columnDef.footer"
535
- :props="header.getContext()"
536
- />
537
- </slot>
538
- </div>
539
- </div>
540
- </div>
541
- </div>
542
- </template>
543
- </div>
544
- </template>
545
- </template>
546
-
547
- <!-- Non-virtualized rendering -->
548
- <template v-else>
549
- <template v-for="item in virtualRowItems" :key="item.index">
550
- <!-- Group Subheader Row - uses measured column header height for accurate sticky positioning -->
551
- <div
552
- v-if="item.type === 'group-header'"
553
- :class="[stickyEnabled ? 'sticky top-(--header-height,0px) z-20 bg-default' : '']"
554
- :style="stickyEnabled ? { '--header-height': `${nonVirtStickyTop}px` } : {}"
555
- >
556
- <ReuseGroupSubheaderTemplate
557
- :group-id="item.groupId"
558
- :group-row="item.groupRow"
559
- :item-count="
560
- groupedRows[item.groupId]?.filter((row) => !addRowContext.isAddRowRow(row)).length || 0
561
- "
562
- :depth="item.depth ?? 0"
563
- />
564
- </div>
565
-
566
- <!-- Data rows for this group (only if expanded) -->
567
- <template v-else-if="item.type === 'data' && item.dataRow">
568
- <component
569
- :is="addRowContext.isAddRowRow(item.dataRow) ? NuGridAddRow : NuGridRow"
570
- :key="item.dataRow.id"
571
- :row="item.dataRow"
572
- />
573
- </template>
574
- </template>
575
- </template>
576
- </template>
577
-
578
- <div v-else-if="loading && !!slots.loading" :class="ui.tr({ class: propsUi?.tr })">
579
- <div :class="ui.loading({ class: propsUi?.loading })">
580
- <slot name="loading" />
581
- </div>
582
- </div>
583
-
584
- <div v-else :class="ui.tr({ class: propsUi?.tr })">
585
- <div :class="ui.empty({ class: propsUi?.empty })">
586
- <slot name="empty">
587
- {{ empty || "No data available." }}
588
- </slot>
589
- </div>
590
- </div>
591
-
592
- <slot name="body-bottom" />
593
- </div>
594
-
595
- <!-- Footer (non-virtualized, only when not in groups or no data) -->
596
- <div
597
- v-if="hasFooter && !virtualizationEnabled && groupRows.length === 0"
598
- :class="ui.tfoot({ class: [propsUi?.tfoot] })"
599
- >
600
- <div :class="ui.separator({ class: [propsUi?.separator] })" />
601
-
602
- <div
603
- v-for="footerGroup in footerGroups"
604
- :key="footerGroup.id"
605
- :class="ui.tr({ class: [propsUi?.tr] })"
606
- >
607
- <div
608
- v-for="header in footerGroup.headers"
609
- :key="header.id"
610
- :data-pinned="header.column.getIsPinned()"
611
- :class="[
612
- ui.th({
613
- class: [propsUi?.th, resolveValue(header.column.columnDef.meta?.class?.th, header)],
614
- pinned: !!getHeaderEffectivePinning(header)
615
- })
616
- ]"
617
- :style="{
618
- ...resolveStyleObject(header.column.columnDef.meta?.style?.th, header),
619
- width: `${header.getSize()}px`,
620
- minWidth: `${header.getSize()}px`,
621
- maxWidth: `${header.getSize()}px`,
622
- ...getHeaderPinningStyle(header),
623
- ...header.colSpan > 1 ? { flexGrow: header.colSpan } : {},
624
- ...header.rowSpan > 1 ? { alignSelf: 'stretch' } : {}
625
- }"
626
- >
627
- <div :class="ui.footerContent({ class: [propsUi?.footerContent] })">
628
- <slot :name="`${header.id}-footer`" v-bind="header.getContext()">
629
- <FlexRender
630
- v-if="!header.isPlaceholder"
631
- :render="header.column.columnDef.footer"
632
- :props="header.getContext()"
633
- />
634
- </slot>
635
- </div>
636
- </div>
637
- </div>
638
- </div>
639
- </div>
640
- </DefineTableTemplate>
641
-
642
- <Primitive
643
- ref="rootRef"
644
- :as="as"
645
- :class="[ui.root({ class: [propsUi?.root, props.class] }), scrollbarThemeClass, scrollbarClass]"
646
- :data-scrollbars="scrollbarAttr"
647
- >
648
- <ReuseNuGridTemplate />
649
- </Primitive>
650
- </template>
@@ -1,20 +0,0 @@
1
- import type { TableData, TableSlots } from '@nuxt/ui';
2
- import type { NuGridProps } from '../types/index.js';
3
- declare const __VLS_export: <T extends TableData>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_exposed?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
4
- props: import("vue").PublicProps & __VLS_PrettifyLocal<NuGridProps<T>> & (typeof globalThis extends {
5
- __VLS_PROPS_FALLBACK: infer P;
6
- } ? P : {});
7
- expose: (exposed: {}) => void;
8
- attrs: any;
9
- slots: TableSlots<T>;
10
- emit: {};
11
- }>) => import("vue").VNode & {
12
- __ctx?: Awaited<typeof __VLS_setup>;
13
- };
14
- declare const _default: typeof __VLS_export;
15
- export default _default;
16
- type __VLS_PrettifyLocal<T> = (T extends any ? {
17
- [K in keyof T]: T[K];
18
- } : {
19
- [K in keyof T as K]: T[K];
20
- }) & {};