@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
@@ -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 'selection' ? 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;
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
- () => props[group]?.[key] ?? defaults[key]
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
- () => props[group]?.[key] ?? defaults[key]
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: "fitCell" }
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: "fitGrid", maintainWidth: true }
36
+ layout: { scrollbars: "native", autoSize: "fill" }
37
37
  },
38
38
  /**
39
39
  * Analytics grid optimized for large read-only datasets
@@ -22,6 +22,8 @@ export declare const nuGridTheme: {
22
22
  sortHandleHover: string;
23
23
  rowDragIcon: string;
24
24
  headerContainer: string;
25
+ headerControls: string;
26
+ columnMenu: string;
25
27
  footerContent: string;
26
28
  groupHeader: string;
27
29
  groupHeaderLeft: string;
@@ -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
- root: "relative overflow-auto h-full",
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 overflow-hidden 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
+ 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 shrink-0 items-center justify-center w-4 cursor-col-resize select-none touch-none opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity duration-200 relative z-10 hover:bg-primary-500/10 [&:hover_.col-resizer]:bg-primary-500/80",
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",
@@ -25,6 +25,8 @@ export declare const nuGridThemeCompact: {
25
25
  sortHandleHover: string;
26
26
  rowDragIcon: string;
27
27
  headerContainer: string;
28
+ headerControls: string;
29
+ columnMenu: string;
28
30
  footerContent: string;
29
31
  groupHeader: string;
30
32
  groupHeaderLeft: string;
@@ -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
- root: "relative overflow-auto h-full",
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 overflow-hidden 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
+ 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 shrink-0 items-center justify-center w-3 cursor-col-resize select-none touch-none opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity duration-200 relative z-10 hover:bg-blue-500/10 [&:hover_.col-resizer]:bg-blue-500/80",
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?: 'fitCell' | 'fitGrid') => void;
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
- * Built-in types: 'text', 'number', 'date', 'boolean', 'selection', 'action-menu', 'lookup'
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 'text'
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 = 'fitCell' | 'fitGrid' | false;
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
- * - 'fitCell': Fit cell contents
320
- * - 'fitGrid': Fit cell contents and scale to grid width
321
- * - false: Disable auto-sizing
322
- * @defaultValue false
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
- * Maintain table width during column resize
327
- * @defaultValue false
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
- maintainWidth?: boolean;
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
- * selection: {
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
- * selection: {
122
+ * rowSelection: {
115
123
  * mode: 'single',
116
124
  * rowSelectionEnabled: (row) => row.original.selectable
117
125
  * }
118
126
  */
119
- selection?: false | 'single' | 'multi' | NuGridSelectionOptions<T>;
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: 'fitGrid'
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
- * Columns to skip when autosizing
363
- * Provide an array of column IDs that should not be auto-sized
364
- * @defaultValue []
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
- skipAutoSizeColumns?: string[];
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
- * @defaultValue 'text'
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
@@ -1,2 +1,3 @@
1
1
  export * from './columnHelper.js';
2
+ export { extractColumnValues, inferCellDataType } from './inferCellDataType.js';
2
3
  export * from './standardSchema.js';
@@ -1,2 +1,3 @@
1
1
  export * from "./columnHelper.js";
2
+ export { extractColumnValues, inferCellDataType } from "./inferCellDataType.js";
2
3
  export * from "./standardSchema.js";
@@ -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
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@nu-grid/nuxt",
3
3
  "type": "module",
4
- "version": "0.2.0",
4
+ "version": "0.3.0",
5
5
  "description": "A powerful data grid component for Nuxt with virtualization, cell editing, and TanStack Table integration",
6
6
  "license": "MIT",
7
7
  "homepage": "https://www.nu-grid.dev",