@nu-grid/nuxt 0.1.4 → 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.
- package/dist/module.json +1 -1
- package/dist/runtime/cell-types/action-menu/ActionMenuRenderer.d.vue.ts +1 -1
- package/dist/runtime/cell-types/action-menu/ActionMenuRenderer.vue +1 -0
- package/dist/runtime/cell-types/action-menu/ActionMenuRenderer.vue.d.ts +1 -1
- package/dist/runtime/cell-types/date/index.d.ts +1 -1
- package/dist/runtime/cell-types/date/index.js +15 -1
- package/dist/runtime/cell-types/index.d.ts +2 -1
- package/dist/runtime/cell-types/index.js +3 -0
- package/dist/runtime/cell-types/lookup/LookupRenderer.vue +1 -1
- package/dist/runtime/cell-types/number/NumberFilter.vue +1 -1
- package/dist/runtime/cell-types/percentage/PercentageEditor.d.vue.ts +15 -0
- package/dist/runtime/cell-types/percentage/PercentageEditor.vue +56 -0
- package/dist/runtime/cell-types/percentage/PercentageEditor.vue.d.ts +15 -0
- package/dist/runtime/cell-types/percentage/PercentageFilter.d.vue.ts +7 -0
- package/dist/runtime/cell-types/percentage/PercentageFilter.vue +79 -0
- package/dist/runtime/cell-types/percentage/PercentageFilter.vue.d.ts +7 -0
- package/dist/runtime/cell-types/percentage/index.d.ts +10 -0
- package/dist/runtime/cell-types/percentage/index.js +38 -0
- package/dist/runtime/cell-types/selection/SelectionEditor.vue +1 -1
- package/dist/runtime/cell-types/selection/SelectionRenderer.vue +1 -0
- package/dist/runtime/components/NuGrid.d.vue.ts +8 -5
- package/dist/runtime/components/NuGrid.vue +41 -9
- package/dist/runtime/components/NuGrid.vue.d.ts +8 -5
- package/dist/runtime/components/_internal/NuGridBase.vue +128 -82
- package/dist/runtime/components/_internal/NuGridCellContent.vue +21 -1
- package/dist/runtime/components/_internal/NuGridColumnMenu.vue +2 -2
- package/dist/runtime/components/_internal/NuGridGroup.vue +22 -15
- package/dist/runtime/components/_internal/NuGridHeaderSortButton.vue +1 -0
- package/dist/runtime/components/_internal/NuGridRow.vue +13 -5
- package/dist/runtime/components/_internal/NuGridSplitGroup.vue +22 -16
- package/dist/runtime/components/_internal/NuGridTooltip.vue +1 -0
- package/dist/runtime/composables/_internal/column-flex-style.d.ts +22 -0
- package/dist/runtime/composables/_internal/column-flex-style.js +84 -0
- package/dist/runtime/composables/_internal/index.d.ts +1 -0
- package/dist/runtime/composables/_internal/index.js +1 -0
- package/dist/runtime/composables/_internal/useNuGridAddRow.js +5 -1
- package/dist/runtime/composables/_internal/useNuGridAutosize.d.ts +6 -3
- package/dist/runtime/composables/_internal/useNuGridAutosize.js +91 -9
- package/dist/runtime/composables/_internal/useNuGridCellEditing.js +3 -2
- package/dist/runtime/composables/_internal/useNuGridColumnResize.d.ts +17 -7
- package/dist/runtime/composables/_internal/useNuGridColumnResize.js +219 -8
- package/dist/runtime/composables/_internal/useNuGridCore.d.ts +1 -1
- package/dist/runtime/composables/_internal/useNuGridCore.js +16 -5
- package/dist/runtime/composables/_internal/useNuGridFocus.js +1 -1
- package/dist/runtime/composables/_internal/useNuGridRowSelection.js +1 -1
- package/dist/runtime/composables/_internal/useNuGridStatePersistence.d.ts +14 -1
- package/dist/runtime/composables/_internal/useNuGridStatePersistence.js +66 -3
- package/dist/runtime/composables/_internal/useNuGridUI.d.ts +116 -0
- package/dist/runtime/config/_internal/options-defaults.d.ts +3 -4
- package/dist/runtime/config/_internal/options-defaults.js +3 -4
- package/dist/runtime/config/_internal/prop-utils.d.ts +7 -1
- package/dist/runtime/config/_internal/prop-utils.js +20 -6
- package/dist/runtime/config/presets.js +2 -2
- package/dist/runtime/themes/nuGridTheme.d.ts +2 -0
- package/dist/runtime/themes/nuGridTheme.js +7 -4
- package/dist/runtime/themes/nuGridThemeCompact.d.ts +2 -0
- package/dist/runtime/themes/nuGridThemeCompact.js +7 -4
- package/dist/runtime/types/_internal/contexts/resize.d.ts +1 -0
- package/dist/runtime/types/_internal/contexts/ui-config.d.ts +4 -2
- package/dist/runtime/types/autosize.d.ts +4 -1
- package/dist/runtime/types/column.d.ts +41 -3
- package/dist/runtime/types/index.d.ts +2 -1
- package/dist/runtime/types/option-groups.d.ts +26 -8
- package/dist/runtime/types/props.d.ts +34 -9
- package/dist/runtime/types/resize.d.ts +2 -0
- package/dist/runtime/types/slots.d.ts +32 -0
- package/dist/runtime/types/slots.js +0 -0
- package/dist/runtime/types/tanstack-table.d.ts +3 -2
- package/dist/runtime/utils/index.d.ts +1 -0
- package/dist/runtime/utils/index.js +1 -0
- package/dist/runtime/utils/inferCellDataType.d.ts +27 -0
- package/dist/runtime/utils/inferCellDataType.js +91 -0
- package/package.json +3 -2
- package/dist/runtime/components/NuGridGroup.d.vue.ts +0 -20
- package/dist/runtime/components/NuGridGroup.vue +0 -650
- package/dist/runtime/components/NuGridGroup.vue.d.ts +0 -20
|
@@ -7,7 +7,7 @@ import { nuGridDefaults } from './options-defaults.js';
|
|
|
7
7
|
* Keys must match nuGridDefaults - TypeScript will error if they diverge.
|
|
8
8
|
*/
|
|
9
9
|
type OptionsTypeMap = {
|
|
10
|
-
[K in keyof typeof nuGridDefaults]: K extends 'focus' ? NuGridFocusOptions : K extends 'editing' ? NuGridEditingOptions : K extends 'validation' ? NuGridValidationOptions : K extends '
|
|
10
|
+
[K in keyof typeof nuGridDefaults]: K extends 'focus' ? NuGridFocusOptions : K extends 'editing' ? NuGridEditingOptions : K extends 'validation' ? NuGridValidationOptions : K extends 'rowSelection' ? NuGridSelectionOptions : K extends 'layout' ? NuGridLayoutOptions : K extends 'virtualization' ? NuGridVirtualizerOptions : K extends 'tooltip' ? NuGridTooltipOptions : K extends 'multiRow' ? NuGridMultiRowOptions : K extends 'animation' ? NuGridAnimationOptions : K extends 'paging' ? NuGridPagingOptions : never;
|
|
11
11
|
};
|
|
12
12
|
type DefaultsKey = {
|
|
13
13
|
[K in keyof OptionsTypeMap]: OptionsTypeMap[K] extends never ? never : K;
|
|
@@ -22,6 +22,9 @@ export declare function getDefaults<K extends DefaultsKey>(key: K): DefaultsGrou
|
|
|
22
22
|
* Creates a computed ref that extracts a prop value with fallback to nuGridDefaults.
|
|
23
23
|
* Defaults are automatically sourced from the centralized nuGridDefaults.
|
|
24
24
|
*
|
|
25
|
+
* Supports boolean shorthand for props like `editing: true` which means
|
|
26
|
+
* "enable editing with default settings".
|
|
27
|
+
*
|
|
25
28
|
* @param props - The props object (reactive)
|
|
26
29
|
* @param group - The defaults group key (e.g., 'focus', 'editing', 'validation')
|
|
27
30
|
* @param key - The key to extract from the prop group
|
|
@@ -36,6 +39,9 @@ export declare function usePropWithDefault<G extends DefaultsKey, K extends keyo
|
|
|
36
39
|
* Creates multiple computed refs for a prop group with defaults from nuGridDefaults.
|
|
37
40
|
* Useful when extracting several properties from the same group.
|
|
38
41
|
*
|
|
42
|
+
* Supports boolean shorthand for props like `editing: true` which means
|
|
43
|
+
* "enable editing with default settings".
|
|
44
|
+
*
|
|
39
45
|
* @param props - The props object (reactive)
|
|
40
46
|
* @param group - The defaults group key
|
|
41
47
|
* @param keys - Array of keys to extract
|
|
@@ -3,19 +3,33 @@ import { nuGridDefaults } from "./options-defaults.js";
|
|
|
3
3
|
export function getDefaults(key) {
|
|
4
4
|
return nuGridDefaults[key];
|
|
5
5
|
}
|
|
6
|
+
function normalizePropGroup(propValue) {
|
|
7
|
+
if (propValue === true) {
|
|
8
|
+
return {};
|
|
9
|
+
}
|
|
10
|
+
if (propValue === false || propValue === void 0 || propValue === null) {
|
|
11
|
+
return void 0;
|
|
12
|
+
}
|
|
13
|
+
if (typeof propValue === "object") {
|
|
14
|
+
return propValue;
|
|
15
|
+
}
|
|
16
|
+
return void 0;
|
|
17
|
+
}
|
|
6
18
|
export function usePropWithDefault(props, group, key) {
|
|
7
19
|
const defaults = nuGridDefaults[group];
|
|
8
|
-
return computed(
|
|
9
|
-
|
|
10
|
-
|
|
20
|
+
return computed(() => {
|
|
21
|
+
const normalized = normalizePropGroup(props[group]);
|
|
22
|
+
return normalized?.[key] ?? defaults[key];
|
|
23
|
+
});
|
|
11
24
|
}
|
|
12
25
|
export function usePropsWithDefaults(props, group, keys) {
|
|
13
26
|
const defaults = nuGridDefaults[group];
|
|
14
27
|
const result = {};
|
|
15
28
|
for (const key of keys) {
|
|
16
|
-
result[key] = computed(
|
|
17
|
-
|
|
18
|
-
|
|
29
|
+
result[key] = computed(() => {
|
|
30
|
+
const normalized = normalizePropGroup(props[group]);
|
|
31
|
+
return normalized?.[key] ?? defaults[key];
|
|
32
|
+
});
|
|
19
33
|
}
|
|
20
34
|
return result;
|
|
21
35
|
}
|
|
@@ -14,7 +14,7 @@ const presets = {
|
|
|
14
14
|
editable: {
|
|
15
15
|
focus: { mode: "cell", retain: true },
|
|
16
16
|
editing: { enabled: true },
|
|
17
|
-
layout: { stickyHeaders: true, autoSize: "
|
|
17
|
+
layout: { stickyHeaders: true, autoSize: "content" }
|
|
18
18
|
},
|
|
19
19
|
/**
|
|
20
20
|
* Kanban-style grouped grid with row navigation
|
|
@@ -33,7 +33,7 @@ const presets = {
|
|
|
33
33
|
focus: { mode: "cell", retain: true, cmdArrows: "firstlast", pageStep: 5 },
|
|
34
34
|
editing: { enabled: true, startClicks: "single" },
|
|
35
35
|
validation: { validateOn: "blur" },
|
|
36
|
-
layout: { scrollbars: "native", autoSize: "
|
|
36
|
+
layout: { scrollbars: "native", autoSize: "fill" }
|
|
37
37
|
},
|
|
38
38
|
/**
|
|
39
39
|
* Analytics grid optimized for large read-only datasets
|
|
@@ -4,7 +4,8 @@ export const nuGridTheme = {
|
|
|
4
4
|
slots: {
|
|
5
5
|
...theme.slots,
|
|
6
6
|
// Root container - extends base with height to fill parent container
|
|
7
|
-
|
|
7
|
+
// min-h-0 allows shrinking in flex contexts (overrides default min-height: auto)
|
|
8
|
+
root: "relative overflow-auto h-full min-h-0",
|
|
8
9
|
// style the checkboxes to match compact theme
|
|
9
10
|
checkboxBase: "",
|
|
10
11
|
checkboxIndicator: "",
|
|
@@ -14,7 +15,7 @@ export const nuGridTheme = {
|
|
|
14
15
|
base: "flex flex-col pb-3 w-max min-w-0 border-separate border-spacing-0",
|
|
15
16
|
// Scrollbar styling - uses tailwind-scrollbar plugin
|
|
16
17
|
scrollbar: "scrollbar-thin scrollbar-track-transparent scrollbar-thumb-gray-400/50 hover:scrollbar-thumb-gray-500/60 dark:scrollbar-thumb-gray-500/50 dark:hover:scrollbar-thumb-gray-400/60 scrollbar-thumb-rounded",
|
|
17
|
-
th: "flex shrink-0 items-stretch
|
|
18
|
+
th: "flex shrink-0 items-stretch p-0! group text-left rtl:text-right text-sm font-semibold text-highlighted py-2 first:rounded-l-lg last:rounded-r-lg border-y border-default first:border-l last:border-r",
|
|
18
19
|
td: "flex shrink-0 items-center overflow-hidden p-4 whitespace-nowrap text-sm text-muted outline-none! focus-visible:outline-none! border-b border-default",
|
|
19
20
|
tr: "flex outline-none! focus-visible:outline-none!",
|
|
20
21
|
loading: "flex-1",
|
|
@@ -22,14 +23,16 @@ export const nuGridTheme = {
|
|
|
22
23
|
separator: "flex-1 h-0",
|
|
23
24
|
// Additional NuGrid-specific slots
|
|
24
25
|
rowDragHandle: "flex shrink-0 items-center justify-center px-2 w-10 min-w-10 max-w-10",
|
|
25
|
-
colResizeHandle: "flex
|
|
26
|
+
colResizeHandle: "flex items-center justify-center w-4 h-full cursor-col-resize select-none touch-none opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity duration-200 hover:bg-primary-500/10 [&:hover_.col-resizer]:bg-primary-500/80",
|
|
26
27
|
colResizer: "w-0.5 h-3/5 rounded-sm transition-colors duration-200 bg-gray-400/60 col-resizer",
|
|
27
28
|
rowDragHeaderHandle: "shrink-0 w-10 min-w-10 max-w-10",
|
|
28
29
|
thInner: "flex flex-1 items-center px-3 py-2 truncate",
|
|
29
30
|
sortHandle: "flex shrink-0 items-center px-1 cursor-pointer select-none opacity-100 hover:text-primary-500 transition-opacity duration-200",
|
|
30
31
|
sortHandleHover: "flex shrink-0 items-center px-1 cursor-pointer select-none text-gray-400/60 opacity-0 group-hover:opacity-100 focus-within:opacity-100 hover:text-primary-500 transition-opacity duration-200",
|
|
31
32
|
rowDragIcon: "inline-block w-4 h-4",
|
|
32
|
-
headerContainer: "flex items-stretch w-full h-full",
|
|
33
|
+
headerContainer: "relative flex items-stretch w-full h-full",
|
|
34
|
+
headerControls: "absolute right-0 inset-y-0 flex items-center z-10 bg-inherit",
|
|
35
|
+
columnMenu: "flex items-center px-1 transition-opacity duration-200",
|
|
33
36
|
footerContent: "w-full truncate",
|
|
34
37
|
groupHeader: "flex items-stretch cursor-pointer bg-primary/10 hover:bg-primary/15 transition-colors",
|
|
35
38
|
groupHeaderLeft: "sticky left-0 z-50 flex items-center gap-3 px-4 py-3 border-b-0 border-l-4 border-primary",
|
|
@@ -4,7 +4,8 @@ export const nuGridThemeCompact = {
|
|
|
4
4
|
slots: {
|
|
5
5
|
...theme.slots,
|
|
6
6
|
// Root container - extends base with height to fill parent container
|
|
7
|
-
|
|
7
|
+
// min-h-0 allows shrinking in flex contexts (overrides default min-height: auto)
|
|
8
|
+
root: "relative overflow-auto h-full min-h-0",
|
|
8
9
|
checkboxBase: "ring-blue-800 dark:ring-blue-400",
|
|
9
10
|
checkboxIndicator: "bg-blue-800! dark:bg-blue-400",
|
|
10
11
|
checkboxContainer: "",
|
|
@@ -13,7 +14,7 @@ export const nuGridThemeCompact = {
|
|
|
13
14
|
// Base slots with div mode styles merged in
|
|
14
15
|
base: "flex flex-col bg-white dark:bg-gray-900",
|
|
15
16
|
// Tighter spacing: px-2 py-1.5 instead of px-4 py-3.5
|
|
16
|
-
th: "flex shrink-0 items-stretch
|
|
17
|
+
th: "flex shrink-0 items-stretch p-0! group bg-gray-50 dark:bg-gray-800 border-r border-gray-300 dark:border-gray-600 last:border-r-0 text-left rtl:text-right text-xs font-semibold text-gray-700 dark:text-gray-300 uppercase tracking-wide",
|
|
17
18
|
// Tighter cell padding: px-2 py-1 instead of p-4
|
|
18
19
|
td: "flex shrink-0 items-center overflow-hidden border-r border-gray-300/50 dark:border-gray-600/50 last:border-r-0 px-2 py-1 whitespace-nowrap text-sm text-gray-900 dark:text-white outline-none! focus-visible:outline-none!",
|
|
19
20
|
tr: "flex border-b border-gray-300 dark:border-gray-600 hover:bg-gray-100 dark:hover:bg-gray-700 outline-none! focus-visible:outline-none!",
|
|
@@ -22,7 +23,7 @@ export const nuGridThemeCompact = {
|
|
|
22
23
|
separator: "flex-1",
|
|
23
24
|
// Additional NuGrid-specific slots
|
|
24
25
|
rowDragHandle: "flex shrink-0 items-center justify-center px-1 w-8 min-w-8 max-w-8",
|
|
25
|
-
colResizeHandle: "flex
|
|
26
|
+
colResizeHandle: "flex items-center justify-center w-3 h-full cursor-col-resize select-none touch-none opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity duration-200 hover:bg-blue-500/10 [&:hover_.col-resizer]:bg-blue-500/80",
|
|
26
27
|
colResizer: "w-0.5 h-3/5 rounded-sm transition-colors duration-200 bg-gray-400/60 col-resizer",
|
|
27
28
|
rowDragHeaderHandle: "shrink-0 w-8 min-w-8 max-w-8",
|
|
28
29
|
// Tighter header inner: px-2 py-1 instead of px-3 py-2
|
|
@@ -30,7 +31,9 @@ export const nuGridThemeCompact = {
|
|
|
30
31
|
sortHandle: "flex shrink-0 items-center px-1 cursor-pointer select-none opacity-100 hover:text-blue-500 transition-opacity duration-200",
|
|
31
32
|
sortHandleHover: "flex shrink-0 items-center px-1 cursor-pointer select-none text-gray-400/60 opacity-0 group-hover:opacity-100 focus-within:opacity-100 hover:text-blue-500 transition-opacity duration-200",
|
|
32
33
|
rowDragIcon: "inline-block w-3.5 h-3.5",
|
|
33
|
-
headerContainer: "flex items-stretch w-full h-full bg-gray-50 dark:bg-gray-800",
|
|
34
|
+
headerContainer: "relative flex items-stretch w-full h-full bg-gray-50 dark:bg-gray-800",
|
|
35
|
+
headerControls: "absolute right-0 inset-y-0 flex items-center z-10 bg-inherit",
|
|
36
|
+
columnMenu: "flex items-center px-1 transition-opacity duration-200",
|
|
34
37
|
footerContent: "w-full truncate",
|
|
35
38
|
// Group header styling
|
|
36
39
|
groupHeader: "flex items-stretch cursor-pointer bg-blue-500/6 hover:bg-blue-500/10 dark:bg-blue-500/12 dark:hover:bg-blue-500/18 transition-colors",
|
|
@@ -9,4 +9,5 @@ export interface NuGridResizeContext<T extends TableData = TableData> {
|
|
|
9
9
|
handleGroupResizeStart: NuGridColumnResize<T>['handleGroupResizeStart'];
|
|
10
10
|
resizingGroupId: NuGridColumnResize<T>['resizingGroupId'];
|
|
11
11
|
resizingColumnId: NuGridColumnResize<T>['resizingColumnId'];
|
|
12
|
+
manuallyResizedColumns: NuGridColumnResize<T>['manuallyResizedColumns'];
|
|
12
13
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { TableData } from '@nuxt/ui';
|
|
2
|
-
import type { ComputedRef } from 'vue';
|
|
2
|
+
import type { ComputedRef, Ref } from 'vue';
|
|
3
3
|
import type { NuGridUIReturn } from '../../../composables/_internal/useNuGridUI.js';
|
|
4
4
|
import type { NuGridColumnMenuItemsCallback } from '../../column.js';
|
|
5
|
-
import type { NuGridColumnMenuButton } from '../../option-groups.js';
|
|
5
|
+
import type { NuGridAutoSizeStrategy, NuGridColumnMenuButton, NuGridResizeMode } from '../../option-groups.js';
|
|
6
6
|
import type { NuGridScrollbars } from '../../props.js';
|
|
7
7
|
import type { NuGridSortIcon } from '../../sort-icon.js';
|
|
8
8
|
/**
|
|
@@ -18,4 +18,6 @@ export interface NuGridUIConfigContext<T extends TableData = TableData> {
|
|
|
18
18
|
showColumnVisibility: ComputedRef<boolean>;
|
|
19
19
|
columnMenuButton: ComputedRef<NuGridColumnMenuButton | undefined>;
|
|
20
20
|
checkboxTheme: NuGridUIReturn['checkboxTheme'];
|
|
21
|
+
autoSizeMode?: Ref<NuGridAutoSizeStrategy>;
|
|
22
|
+
resizeMode?: Ref<NuGridResizeMode>;
|
|
21
23
|
}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import type { Ref } from 'vue';
|
|
1
2
|
/**
|
|
2
3
|
* Type for nugrid-autosizefns injection
|
|
3
4
|
* Provides column autosize functionality
|
|
4
5
|
*/
|
|
5
6
|
export interface NuGridAutosize {
|
|
6
|
-
autoSizeColumns: (mode?: '
|
|
7
|
+
autoSizeColumns: (mode?: 'content' | 'fill') => void;
|
|
7
8
|
autoSizeColumn: (columnId: string) => void;
|
|
9
|
+
/** Whether the initial autosize has completed (grid is ready to show) */
|
|
10
|
+
autosizeReady: Ref<boolean>;
|
|
8
11
|
}
|
|
@@ -64,11 +64,13 @@ export type NuGridColumn<T extends TableData> = TableColumn<T> & {
|
|
|
64
64
|
enableFocusing?: boolean | ((row: Row<T>) => boolean);
|
|
65
65
|
/**
|
|
66
66
|
* Data type for the cell, determines which default editor to use
|
|
67
|
-
*
|
|
67
|
+
* - Automatically inferred from row data if not specified (when dataTypeInference is enabled)
|
|
68
|
+
* - Set to `false` to disable inference and use default text rendering
|
|
69
|
+
* Built-in types: 'text', 'number', 'date', 'boolean', 'currency', 'percentage', 'selection', 'action-menu', 'lookup'
|
|
68
70
|
* Custom types can be registered via cellTypes prop
|
|
69
|
-
* @defaultValue
|
|
71
|
+
* @defaultValue undefined (inferred from data)
|
|
70
72
|
*/
|
|
71
|
-
cellDataType?: string;
|
|
73
|
+
cellDataType?: string | false;
|
|
72
74
|
/**
|
|
73
75
|
* Lookup/dropdown configuration for cells using cellDataType: 'lookup'
|
|
74
76
|
* Provides a dropdown selection interface using Nuxt UI's SelectMenu
|
|
@@ -245,4 +247,40 @@ export type NuGridColumn<T extends TableData> = TableColumn<T> & {
|
|
|
245
247
|
* span: '*'
|
|
246
248
|
*/
|
|
247
249
|
span?: number | '*';
|
|
250
|
+
/**
|
|
251
|
+
* Controls whether the column participates in flex distribution in fill mode
|
|
252
|
+
* - true (default): Column flexes to fill available space (uses widthPercentage or equal share)
|
|
253
|
+
* - false: Column uses its fixed `size` and doesn't grow/shrink
|
|
254
|
+
*
|
|
255
|
+
* Use grow: false for columns that should have a fixed width regardless of container size,
|
|
256
|
+
* such as checkbox columns, ID columns, or action columns.
|
|
257
|
+
* @defaultValue true
|
|
258
|
+
* @example
|
|
259
|
+
* // Fixed-width columns that don't grow
|
|
260
|
+
* { id: 'select', size: 50, grow: false } // Checkbox column
|
|
261
|
+
* { accessorKey: 'id', size: 80, grow: false } // ID column
|
|
262
|
+
* { accessorKey: 'status', size: 120, grow: false } // Status badge column
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* // Flex columns that share remaining space (default behavior)
|
|
266
|
+
* { accessorKey: 'name' } // Grows with equal share
|
|
267
|
+
* { accessorKey: 'email' } // Grows with equal share
|
|
268
|
+
*/
|
|
269
|
+
grow?: boolean;
|
|
270
|
+
/**
|
|
271
|
+
* Weighted flex-grow value for proportional distribution in fill mode
|
|
272
|
+
* Columns with higher values take more space relative to other flex columns
|
|
273
|
+
* Only applies when grow !== false (flex columns only)
|
|
274
|
+
* @example
|
|
275
|
+
* // Name takes 40%, Email takes 40%, Location takes 20% of flex space
|
|
276
|
+
* { accessorKey: 'name', widthPercentage: 40 }
|
|
277
|
+
* { accessorKey: 'email', widthPercentage: 40 }
|
|
278
|
+
* { accessorKey: 'location', widthPercentage: 20 }
|
|
279
|
+
*
|
|
280
|
+
* @example
|
|
281
|
+
* // Without widthPercentage, flex columns share space equally (flex-grow: 1)
|
|
282
|
+
* { accessorKey: 'name' } // Equal share
|
|
283
|
+
* { accessorKey: 'email' } // Equal share
|
|
284
|
+
*/
|
|
285
|
+
widthPercentage?: number;
|
|
248
286
|
};
|
|
@@ -6,10 +6,11 @@ export type { NuGridColumn, NuGridColumnMenuItem, NuGridColumnMenuItemsCallback
|
|
|
6
6
|
export type { RowDragEvent } from './drag-drop.js';
|
|
7
7
|
export type { NUGRID_EVENTS_KEY, NuGridCellClickEvent, NuGridCellEditingCancelledEvent, NuGridCellEditingStartedEvent, NuGridCellValueChangedEvent, NuGridEventEmitter, NuGridFilterChangedEvent, NuGridFocusedCellChangedEvent, NuGridFocusedRowChangedEvent, NuGridRowClickEvent, NuGridSortChangedEvent, } from './events.js';
|
|
8
8
|
export type { NuGridGroupingOptions } from './grouping.js';
|
|
9
|
-
export type { NuGridActionsOptions, NuGridAnimationOptions, NuGridAnimationPreset, NuGridAutoSizeStrategy, NuGridColumnMenuOptions, NuGridColumnMenuPreset, NuGridColumnPlacement, NuGridEditingOptions, NuGridExcelExportOptions, NuGridFocusOptions, NuGridLayoutMode, NuGridLayoutOptions, NuGridLookupItem, NuGridLookupOptions, NuGridMultiRowOptions, NuGridPagingOptions, NuGridSelectionOptions, NuGridStateOptions, NuGridStatePart, NuGridStorageType, NuGridTooltipOptions, } from './option-groups.js';
|
|
9
|
+
export type { NuGridActionsOptions, NuGridAnimationOptions, NuGridAnimationPreset, NuGridAutoSizeStrategy, NuGridColumnMenuOptions, NuGridColumnMenuPreset, NuGridColumnPlacement, NuGridEditingOptions, NuGridExcelExportOptions, NuGridFocusOptions, NuGridLayoutMode, NuGridLayoutOptions, NuGridLookupItem, NuGridLookupOptions, NuGridMultiRowOptions, NuGridPagingOptions, NuGridResizeMode, NuGridSelectionOptions, NuGridStateOptions, NuGridStatePart, NuGridStorageType, NuGridTooltipOptions, } from './option-groups.js';
|
|
10
10
|
export type { NuGridProps, NuGridScrollbars } from './props.js';
|
|
11
11
|
export type { NuGridRow } from './row.js';
|
|
12
12
|
export type { NuGridRowSelectOptions } from './row-selection.js';
|
|
13
|
+
export type { NuGridCellSlotProps } from './slots.js';
|
|
13
14
|
export type { NuGridSortIcon } from './sort-icon.js';
|
|
14
15
|
export type { NuGridTheme, NuGridThemeDefinition } from './theme.js';
|
|
15
16
|
export type { NuGridOnInvalid, NuGridShowErrors, NuGridValidateOn, NuGridValidationOptions, } from './validation.js';
|
|
@@ -290,8 +290,17 @@ export interface NuGridColumnDefaultsOptions<T extends TableData = TableData> {
|
|
|
290
290
|
export type NuGridLayoutMode = 'div' | 'group' | 'splitgroup';
|
|
291
291
|
/**
|
|
292
292
|
* Auto-size strategy
|
|
293
|
+
* - 'fill': Columns fill container using CSS flex
|
|
294
|
+
* - 'content': Columns size to cell content
|
|
295
|
+
* - false: No auto-sizing
|
|
293
296
|
*/
|
|
294
|
-
export type NuGridAutoSizeStrategy = '
|
|
297
|
+
export type NuGridAutoSizeStrategy = 'fill' | 'content' | false;
|
|
298
|
+
/**
|
|
299
|
+
* Column resize mode
|
|
300
|
+
* - 'shift': Resizing a column shifts adjacent columns to maintain table width
|
|
301
|
+
* - 'expand': Resizing a column expands/shrinks the table width
|
|
302
|
+
*/
|
|
303
|
+
export type NuGridResizeMode = 'shift' | 'expand';
|
|
295
304
|
/**
|
|
296
305
|
* Layout and display configuration
|
|
297
306
|
*/
|
|
@@ -316,17 +325,26 @@ export interface NuGridLayoutOptions {
|
|
|
316
325
|
scrollbars?: NuGridScrollbars;
|
|
317
326
|
/**
|
|
318
327
|
* Auto-size strategy for columns
|
|
319
|
-
* - '
|
|
320
|
-
*
|
|
321
|
-
*
|
|
322
|
-
*
|
|
328
|
+
* - 'fill': Columns fill container using CSS flex distribution.
|
|
329
|
+
* Use `grow: false` for fixed-width columns, `widthPercentage` for weighted distribution.
|
|
330
|
+
* Instant layout with no JavaScript measurement delay.
|
|
331
|
+
* - 'content': Measure cell contents and set exact pixel widths.
|
|
332
|
+
* Ignores `grow` and `widthPercentage` settings.
|
|
333
|
+
* May cause visual flash on initial load due to measurement.
|
|
334
|
+
* - false: No auto-sizing, columns use their defined `size` values.
|
|
335
|
+
* @defaultValue 'fill'
|
|
323
336
|
*/
|
|
324
337
|
autoSize?: NuGridAutoSizeStrategy;
|
|
325
338
|
/**
|
|
326
|
-
*
|
|
327
|
-
*
|
|
339
|
+
* Column resize behavior
|
|
340
|
+
* - 'shift': Resizing a column shifts adjacent columns to maintain table width (default)
|
|
341
|
+
* - 'expand': Resizing a column expands/shrinks the table width
|
|
342
|
+
*
|
|
343
|
+
* With `autoSize: 'fill'` + `resizeMode: 'expand'`: Grid fills container initially,
|
|
344
|
+
* but user can resize columns to expand beyond the container (enabling horizontal scroll).
|
|
345
|
+
* @defaultValue 'shift'
|
|
328
346
|
*/
|
|
329
|
-
|
|
347
|
+
resizeMode?: NuGridResizeMode;
|
|
330
348
|
}
|
|
331
349
|
/**
|
|
332
350
|
* State persistence parts
|
|
@@ -61,6 +61,10 @@ export interface NuGridProps<T extends TableData = TableData> extends Omit<Table
|
|
|
61
61
|
* Groups editing-related settings including start triggers and behaviors
|
|
62
62
|
*
|
|
63
63
|
* @example
|
|
64
|
+
* // Enable editing with defaults
|
|
65
|
+
* editing: true
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
64
68
|
* // Enable editing with custom triggers
|
|
65
69
|
* editing: {
|
|
66
70
|
* enabled: true,
|
|
@@ -70,7 +74,7 @@ export interface NuGridProps<T extends TableData = TableData> extends Omit<Table
|
|
|
70
74
|
* canEdit: (row, columnId) => row.original.status !== 'locked'
|
|
71
75
|
* }
|
|
72
76
|
*/
|
|
73
|
-
editing?: NuGridEditingOptions<T>;
|
|
77
|
+
editing?: boolean | NuGridEditingOptions<T>;
|
|
74
78
|
/**
|
|
75
79
|
* Enhanced validation configuration
|
|
76
80
|
* Supports schema validation, row rules, and flexible validation modes
|
|
@@ -102,8 +106,12 @@ export interface NuGridProps<T extends TableData = TableData> extends Omit<Table
|
|
|
102
106
|
* Provides preset-based setup with sync callback for external state
|
|
103
107
|
*
|
|
104
108
|
* @example
|
|
109
|
+
* // Enable selection with defaults (multi-select)
|
|
110
|
+
* rowSelection: true
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
105
113
|
* // Multi-select with sync callback
|
|
106
|
-
*
|
|
114
|
+
* rowSelection: {
|
|
107
115
|
* mode: 'multi',
|
|
108
116
|
* placement: 'start',
|
|
109
117
|
* sync: (ids) => { selectedIds.value = ids }
|
|
@@ -111,12 +119,12 @@ export interface NuGridProps<T extends TableData = TableData> extends Omit<Table
|
|
|
111
119
|
*
|
|
112
120
|
* @example
|
|
113
121
|
* // Single select with conditional enabling
|
|
114
|
-
*
|
|
122
|
+
* rowSelection: {
|
|
115
123
|
* mode: 'single',
|
|
116
124
|
* rowSelectionEnabled: (row) => row.original.selectable
|
|
117
125
|
* }
|
|
118
126
|
*/
|
|
119
|
-
|
|
127
|
+
rowSelection?: boolean | 'single' | 'multi' | NuGridSelectionOptions<T>;
|
|
120
128
|
/**
|
|
121
129
|
* Actions column configuration
|
|
122
130
|
* Simplified API with placement options and defaults to hidden when no getActions provided
|
|
@@ -169,7 +177,7 @@ export interface NuGridProps<T extends TableData = TableData> extends Omit<Table
|
|
|
169
177
|
* mode: 'group',
|
|
170
178
|
* stickyHeaders: true,
|
|
171
179
|
* scrollbars: 'scroll',
|
|
172
|
-
* autoSize: '
|
|
180
|
+
* autoSize: 'fill'
|
|
173
181
|
* }
|
|
174
182
|
*/
|
|
175
183
|
layout?: NuGridLayoutOptions;
|
|
@@ -359,11 +367,28 @@ export interface NuGridProps<T extends TableData = TableData> extends Omit<Table
|
|
|
359
367
|
*/
|
|
360
368
|
cellTypes?: NuGridCellType<T>[];
|
|
361
369
|
/**
|
|
362
|
-
*
|
|
363
|
-
*
|
|
364
|
-
*
|
|
370
|
+
* Enable automatic data type inference from row data
|
|
371
|
+
* When enabled, columns without explicit cellDataType will have their
|
|
372
|
+
* type inferred from the actual values (number, boolean, date, currency, percentage, etc.)
|
|
373
|
+
*
|
|
374
|
+
* Detection is based on:
|
|
375
|
+
* - JavaScript types (boolean, Date objects, numbers)
|
|
376
|
+
* - String patterns (currency symbols, percentage signs)
|
|
377
|
+
* - Column name heuristics (e.g., 'price' columns with 2 decimal numbers become currency)
|
|
378
|
+
*
|
|
379
|
+
* @defaultValue true
|
|
380
|
+
*
|
|
381
|
+
* @example
|
|
382
|
+
* // Disable type inference globally
|
|
383
|
+
* dataTypeInference: false
|
|
384
|
+
*
|
|
385
|
+
* @example
|
|
386
|
+
* // Disable inference for a specific column
|
|
387
|
+
* columns: [
|
|
388
|
+
* { accessorKey: 'score', cellDataType: false } // No inference, use default text
|
|
389
|
+
* ]
|
|
365
390
|
*/
|
|
366
|
-
|
|
391
|
+
dataTypeInference?: boolean;
|
|
367
392
|
/**
|
|
368
393
|
* Row dragging configuration
|
|
369
394
|
* Enables drag and drop reordering of rows
|
|
@@ -11,4 +11,6 @@ export interface NuGridColumnResize<T extends TableData = TableData> {
|
|
|
11
11
|
handleResizeEnd: () => void;
|
|
12
12
|
resizingGroupId: Ref<string | null>;
|
|
13
13
|
resizingColumnId: Ref<string | null>;
|
|
14
|
+
/** Set of column IDs that have been manually resized by the user */
|
|
15
|
+
manuallyResizedColumns: Ref<Set<string>>;
|
|
14
16
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Cell, Column, Row } from '@tanstack/vue-table';
|
|
2
|
+
/**
|
|
3
|
+
* Props passed to cell template slots (#[columnId]-cell)
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```vue
|
|
7
|
+
* <NuGrid :columns="columns" :data="data">
|
|
8
|
+
* <template #name-cell="{ value, row }">
|
|
9
|
+
* <div class="flex items-center gap-2">
|
|
10
|
+
* <UAvatar :src="row.original.avatar" size="xs" />
|
|
11
|
+
* <span>{{ value }}</span>
|
|
12
|
+
* </div>
|
|
13
|
+
* </template>
|
|
14
|
+
* </NuGrid>
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export interface NuGridCellSlotProps<T> {
|
|
18
|
+
/** TanStack cell object */
|
|
19
|
+
cell: Cell<T, unknown>;
|
|
20
|
+
/** TanStack row object */
|
|
21
|
+
row: Row<T>;
|
|
22
|
+
/** TanStack column definition */
|
|
23
|
+
column: Column<T, unknown>;
|
|
24
|
+
/** Index of cell in the row */
|
|
25
|
+
cellIndex: number;
|
|
26
|
+
/** Cell value (shortcut for cell.getValue()) */
|
|
27
|
+
value: unknown;
|
|
28
|
+
/** Whether cell is currently in edit mode */
|
|
29
|
+
isEditing: boolean;
|
|
30
|
+
/** Whether cell has validation error */
|
|
31
|
+
isInvalid: boolean;
|
|
32
|
+
}
|
|
File without changes
|
|
@@ -40,9 +40,10 @@ declare module '@tanstack/vue-table' {
|
|
|
40
40
|
* Data type for the cell, determines which default editor to use
|
|
41
41
|
* Built-in types: 'text', 'number', 'date', 'boolean', 'selection', 'action-menu'
|
|
42
42
|
* Custom types can be registered via cellTypes prop
|
|
43
|
-
*
|
|
43
|
+
* Set to `false` to disable type inference for this column
|
|
44
|
+
* @defaultValue undefined (inferred from data)
|
|
44
45
|
*/
|
|
45
|
-
cellDataType?: string
|
|
46
|
+
cellDataType?: string | false
|
|
46
47
|
|
|
47
48
|
/**
|
|
48
49
|
* Sort icon configuration for this column's header
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regular expressions for type detection
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Infer the cell data type from an array of values and optional column name
|
|
6
|
+
*
|
|
7
|
+
* Detection priority:
|
|
8
|
+
* 1. boolean - typeof value === 'boolean'
|
|
9
|
+
* 2. date - value instanceof Date
|
|
10
|
+
* 3. currency - string pattern OR number with 2 decimals + column name heuristic
|
|
11
|
+
* 4. percentage - string pattern OR number 0-1 + column name heuristic
|
|
12
|
+
* 5. number - typeof value === 'number' && !isNaN(value)
|
|
13
|
+
* 6. text - default for strings
|
|
14
|
+
*
|
|
15
|
+
* @param values - Array of values from the column
|
|
16
|
+
* @param columnName - Optional column name for heuristic detection
|
|
17
|
+
* @returns The inferred cell data type, or undefined if no type could be inferred
|
|
18
|
+
*/
|
|
19
|
+
export declare function inferCellDataType(values: unknown[], columnName?: string): string | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Extract values from data array for a given accessor key
|
|
22
|
+
*
|
|
23
|
+
* @param data - The data array
|
|
24
|
+
* @param accessorKey - The key to extract values from
|
|
25
|
+
* @returns Array of values for the specified key
|
|
26
|
+
*/
|
|
27
|
+
export declare function extractColumnValues<T>(data: T[], accessorKey: string): unknown[];
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
const CURRENCY_STRING_PATTERN = /^[$€£¥]\s?[\d,]+(?:\.\d{2})?$/;
|
|
2
|
+
const PERCENTAGE_STRING_PATTERN = /^\d+(?:\.\d+)?%$/;
|
|
3
|
+
const CURRENCY_COLUMN_PATTERN = /price|cost|amount|total|fee|salary|wage|revenue|income|expense|payment|balance|budget/i;
|
|
4
|
+
const PERCENTAGE_COLUMN_PATTERN = /percent|rate|ratio|pct/i;
|
|
5
|
+
const MAX_SAMPLE_SIZE = 10;
|
|
6
|
+
function hasTwoDecimalPlaces(value) {
|
|
7
|
+
if (!Number.isFinite(value)) return false;
|
|
8
|
+
const str = value.toString();
|
|
9
|
+
const decimalIndex = str.indexOf(".");
|
|
10
|
+
if (decimalIndex === -1) return false;
|
|
11
|
+
const decimals = str.slice(decimalIndex + 1);
|
|
12
|
+
return decimals.length === 2;
|
|
13
|
+
}
|
|
14
|
+
function isPercentageRange(value) {
|
|
15
|
+
return value >= 0 && value <= 1;
|
|
16
|
+
}
|
|
17
|
+
export function inferCellDataType(values, columnName) {
|
|
18
|
+
const samples = values.filter((v) => v !== null && v !== void 0).slice(0, MAX_SAMPLE_SIZE);
|
|
19
|
+
if (samples.length === 0) {
|
|
20
|
+
return void 0;
|
|
21
|
+
}
|
|
22
|
+
let booleanCount = 0;
|
|
23
|
+
let dateCount = 0;
|
|
24
|
+
let currencyStringCount = 0;
|
|
25
|
+
let currencyNumberCount = 0;
|
|
26
|
+
let percentageStringCount = 0;
|
|
27
|
+
let percentageNumberCount = 0;
|
|
28
|
+
let numberCount = 0;
|
|
29
|
+
let stringCount = 0;
|
|
30
|
+
const isCurrencyColumn = columnName ? CURRENCY_COLUMN_PATTERN.test(columnName) : false;
|
|
31
|
+
const isPercentageColumn = columnName ? PERCENTAGE_COLUMN_PATTERN.test(columnName) : false;
|
|
32
|
+
for (const value of samples) {
|
|
33
|
+
if (typeof value === "boolean") {
|
|
34
|
+
booleanCount++;
|
|
35
|
+
} else if (value instanceof Date) {
|
|
36
|
+
dateCount++;
|
|
37
|
+
} else if (typeof value === "number" && !Number.isNaN(value)) {
|
|
38
|
+
if (isCurrencyColumn && hasTwoDecimalPlaces(value)) {
|
|
39
|
+
currencyNumberCount++;
|
|
40
|
+
} else if (isPercentageColumn && isPercentageRange(value)) {
|
|
41
|
+
percentageNumberCount++;
|
|
42
|
+
} else {
|
|
43
|
+
numberCount++;
|
|
44
|
+
}
|
|
45
|
+
} else if (typeof value === "string") {
|
|
46
|
+
if (CURRENCY_STRING_PATTERN.test(value)) {
|
|
47
|
+
currencyStringCount++;
|
|
48
|
+
} else if (PERCENTAGE_STRING_PATTERN.test(value)) {
|
|
49
|
+
percentageStringCount++;
|
|
50
|
+
} else {
|
|
51
|
+
stringCount++;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const total = samples.length;
|
|
56
|
+
const threshold = 0.8;
|
|
57
|
+
if (booleanCount / total >= threshold) {
|
|
58
|
+
return "boolean";
|
|
59
|
+
}
|
|
60
|
+
if (dateCount / total >= threshold) {
|
|
61
|
+
return "date";
|
|
62
|
+
}
|
|
63
|
+
const totalCurrency = currencyStringCount + currencyNumberCount;
|
|
64
|
+
if (totalCurrency / total >= threshold) {
|
|
65
|
+
return "currency";
|
|
66
|
+
}
|
|
67
|
+
const totalPercentage = percentageStringCount + percentageNumberCount;
|
|
68
|
+
if (totalPercentage / total >= threshold) {
|
|
69
|
+
return "percentage";
|
|
70
|
+
}
|
|
71
|
+
const totalNumbers = numberCount + currencyNumberCount + percentageNumberCount;
|
|
72
|
+
if (totalNumbers / total >= threshold) {
|
|
73
|
+
return "number";
|
|
74
|
+
}
|
|
75
|
+
const totalStrings = stringCount + currencyStringCount + percentageStringCount;
|
|
76
|
+
if (totalStrings / total >= threshold) {
|
|
77
|
+
return "text";
|
|
78
|
+
}
|
|
79
|
+
return void 0;
|
|
80
|
+
}
|
|
81
|
+
export function extractColumnValues(data, accessorKey) {
|
|
82
|
+
return data.slice(0, MAX_SAMPLE_SIZE).map((row) => {
|
|
83
|
+
const keys = accessorKey.split(".");
|
|
84
|
+
let value = row;
|
|
85
|
+
for (const key of keys) {
|
|
86
|
+
if (value === null || value === void 0) break;
|
|
87
|
+
value = value[key];
|
|
88
|
+
}
|
|
89
|
+
return value;
|
|
90
|
+
});
|
|
91
|
+
}
|