@smartnet360/svelte-grid 0.1.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/components/Cell.svelte +249 -0
- package/dist/components/Cell.svelte.d.ts +39 -0
- package/dist/components/Grid.svelte +504 -0
- package/dist/components/Grid.svelte.d.ts +80 -0
- package/dist/components/GridBody.svelte +194 -0
- package/dist/components/GridBody.svelte.d.ts +49 -0
- package/dist/components/GridHeader.svelte +99 -0
- package/dist/components/GridHeader.svelte.d.ts +31 -0
- package/dist/components/GroupHeader.svelte +192 -0
- package/dist/components/GroupHeader.svelte.d.ts +35 -0
- package/dist/components/HeaderCell.svelte +623 -0
- package/dist/components/HeaderCell.svelte.d.ts +40 -0
- package/dist/components/Menu.svelte +215 -0
- package/dist/components/Menu.svelte.d.ts +33 -0
- package/dist/components/Popup.svelte +189 -0
- package/dist/components/Popup.svelte.d.ts +18 -0
- package/dist/components/Row.svelte +115 -0
- package/dist/components/Row.svelte.d.ts +36 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +20 -0
- package/dist/state/gridState.svelte.d.ts +299 -0
- package/dist/state/gridState.svelte.js +1025 -0
- package/dist/themes.d.ts +61 -0
- package/dist/themes.js +192 -0
- package/dist/types.d.ts +291 -0
- package/dist/types.js +4 -0
- package/package.json +66 -0
package/dist/themes.d.ts
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grid Themes
|
|
3
|
+
*
|
|
4
|
+
* Predefined color themes using CSS custom properties.
|
|
5
|
+
* Inspired by Tailwind CSS color palette.
|
|
6
|
+
*/
|
|
7
|
+
export interface GridTheme {
|
|
8
|
+
/** Theme name */
|
|
9
|
+
name: string;
|
|
10
|
+
/** CSS variable overrides */
|
|
11
|
+
variables: Record<string, string>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Default light theme - Clean and minimal
|
|
15
|
+
*/
|
|
16
|
+
export declare const defaultTheme: GridTheme;
|
|
17
|
+
/**
|
|
18
|
+
* Tailwind Blue theme - Modern blue accents
|
|
19
|
+
*/
|
|
20
|
+
export declare const tailwindBlue: GridTheme;
|
|
21
|
+
/**
|
|
22
|
+
* Tailwind Emerald theme - Fresh green accents
|
|
23
|
+
*/
|
|
24
|
+
export declare const tailwindEmerald: GridTheme;
|
|
25
|
+
/**
|
|
26
|
+
* Tailwind Rose theme - Warm pink accents
|
|
27
|
+
*/
|
|
28
|
+
export declare const tailwindRose: GridTheme;
|
|
29
|
+
/**
|
|
30
|
+
* Tailwind Amber theme - Warm orange/yellow accents
|
|
31
|
+
*/
|
|
32
|
+
export declare const tailwindAmber: GridTheme;
|
|
33
|
+
/**
|
|
34
|
+
* Tailwind Slate theme - Neutral modern gray
|
|
35
|
+
*/
|
|
36
|
+
export declare const tailwindSlate: GridTheme;
|
|
37
|
+
/**
|
|
38
|
+
* Dark theme - For dark mode UIs
|
|
39
|
+
*/
|
|
40
|
+
export declare const darkTheme: GridTheme;
|
|
41
|
+
/**
|
|
42
|
+
* All available themes
|
|
43
|
+
*/
|
|
44
|
+
export declare const themes: {
|
|
45
|
+
readonly default: GridTheme;
|
|
46
|
+
readonly 'tailwind-blue': GridTheme;
|
|
47
|
+
readonly 'tailwind-emerald': GridTheme;
|
|
48
|
+
readonly 'tailwind-rose': GridTheme;
|
|
49
|
+
readonly 'tailwind-amber': GridTheme;
|
|
50
|
+
readonly 'tailwind-slate': GridTheme;
|
|
51
|
+
readonly dark: GridTheme;
|
|
52
|
+
};
|
|
53
|
+
export type ThemeName = keyof typeof themes;
|
|
54
|
+
/**
|
|
55
|
+
* Convert theme to CSS style string
|
|
56
|
+
*/
|
|
57
|
+
export declare function themeToStyle(theme: GridTheme): string;
|
|
58
|
+
/**
|
|
59
|
+
* Create a custom theme by extending an existing one
|
|
60
|
+
*/
|
|
61
|
+
export declare function createTheme(base: GridTheme, overrides: Record<string, string>): GridTheme;
|
package/dist/themes.js
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grid Themes
|
|
3
|
+
*
|
|
4
|
+
* Predefined color themes using CSS custom properties.
|
|
5
|
+
* Inspired by Tailwind CSS color palette.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Default light theme - Clean and minimal
|
|
9
|
+
*/
|
|
10
|
+
export const defaultTheme = {
|
|
11
|
+
name: 'default',
|
|
12
|
+
variables: {
|
|
13
|
+
'--sg-border-color': '#e2e8f0',
|
|
14
|
+
'--sg-header-bg': '#f8fafc',
|
|
15
|
+
'--sg-header-color': '#1e293b',
|
|
16
|
+
'--sg-row-bg': '#ffffff',
|
|
17
|
+
'--sg-row-alt-bg': '#f8fafc',
|
|
18
|
+
'--sg-row-hover-bg': '#f1f5f9',
|
|
19
|
+
'--sg-cell-padding-x': '12px',
|
|
20
|
+
'--sg-cell-padding-y': '8px',
|
|
21
|
+
'--sg-font-size': '14px',
|
|
22
|
+
'--sg-primary-color': '#3b82f6',
|
|
23
|
+
'--sg-frozen-border-color': '#cbd5e1',
|
|
24
|
+
'--sg-group-header-bg': '#f1f5f9',
|
|
25
|
+
'--sg-group-header-text': '#334155',
|
|
26
|
+
'--sg-group-header-hover-bg': '#e2e8f0',
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Tailwind Blue theme - Modern blue accents
|
|
31
|
+
*/
|
|
32
|
+
export const tailwindBlue = {
|
|
33
|
+
name: 'tailwind-blue',
|
|
34
|
+
variables: {
|
|
35
|
+
'--sg-border-color': '#e0e7ff',
|
|
36
|
+
'--sg-header-bg': 'linear-gradient(to bottom, #eef2ff, #e0e7ff)',
|
|
37
|
+
'--sg-header-color': '#312e81',
|
|
38
|
+
'--sg-row-bg': '#ffffff',
|
|
39
|
+
'--sg-row-alt-bg': '#f5f7ff',
|
|
40
|
+
'--sg-row-hover-bg': '#eef2ff',
|
|
41
|
+
'--sg-primary-color': '#4f46e5',
|
|
42
|
+
'--sg-frozen-border-color': '#a5b4fc',
|
|
43
|
+
'--sg-group-header-bg': '#e0e7ff',
|
|
44
|
+
'--sg-group-header-text': '#3730a3',
|
|
45
|
+
'--sg-group-header-hover-bg': '#c7d2fe',
|
|
46
|
+
'--sg-header-icon-color': '#6366f1',
|
|
47
|
+
'--sg-sort-active-color': '#4f46e5',
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Tailwind Emerald theme - Fresh green accents
|
|
52
|
+
*/
|
|
53
|
+
export const tailwindEmerald = {
|
|
54
|
+
name: 'tailwind-emerald',
|
|
55
|
+
variables: {
|
|
56
|
+
'--sg-border-color': '#d1fae5',
|
|
57
|
+
'--sg-header-bg': 'linear-gradient(to bottom, #ecfdf5, #d1fae5)',
|
|
58
|
+
'--sg-header-color': '#064e3b',
|
|
59
|
+
'--sg-row-bg': '#ffffff',
|
|
60
|
+
'--sg-row-alt-bg': '#f0fdf4',
|
|
61
|
+
'--sg-row-hover-bg': '#ecfdf5',
|
|
62
|
+
'--sg-primary-color': '#10b981',
|
|
63
|
+
'--sg-frozen-border-color': '#6ee7b7',
|
|
64
|
+
'--sg-group-header-bg': '#d1fae5',
|
|
65
|
+
'--sg-group-header-text': '#065f46',
|
|
66
|
+
'--sg-group-header-hover-bg': '#a7f3d0',
|
|
67
|
+
'--sg-header-icon-color': '#059669',
|
|
68
|
+
'--sg-sort-active-color': '#10b981',
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Tailwind Rose theme - Warm pink accents
|
|
73
|
+
*/
|
|
74
|
+
export const tailwindRose = {
|
|
75
|
+
name: 'tailwind-rose',
|
|
76
|
+
variables: {
|
|
77
|
+
'--sg-border-color': '#fce7f3',
|
|
78
|
+
'--sg-header-bg': 'linear-gradient(to bottom, #fdf2f8, #fce7f3)',
|
|
79
|
+
'--sg-header-color': '#831843',
|
|
80
|
+
'--sg-row-bg': '#ffffff',
|
|
81
|
+
'--sg-row-alt-bg': '#fdf2f8',
|
|
82
|
+
'--sg-row-hover-bg': '#fce7f3',
|
|
83
|
+
'--sg-primary-color': '#ec4899',
|
|
84
|
+
'--sg-frozen-border-color': '#f9a8d4',
|
|
85
|
+
'--sg-group-header-bg': '#fce7f3',
|
|
86
|
+
'--sg-group-header-text': '#9d174d',
|
|
87
|
+
'--sg-group-header-hover-bg': '#fbcfe8',
|
|
88
|
+
'--sg-header-icon-color': '#db2777',
|
|
89
|
+
'--sg-sort-active-color': '#ec4899',
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Tailwind Amber theme - Warm orange/yellow accents
|
|
94
|
+
*/
|
|
95
|
+
export const tailwindAmber = {
|
|
96
|
+
name: 'tailwind-amber',
|
|
97
|
+
variables: {
|
|
98
|
+
'--sg-border-color': '#fef3c7',
|
|
99
|
+
'--sg-header-bg': 'linear-gradient(to bottom, #fffbeb, #fef3c7)',
|
|
100
|
+
'--sg-header-color': '#78350f',
|
|
101
|
+
'--sg-row-bg': '#ffffff',
|
|
102
|
+
'--sg-row-alt-bg': '#fffbeb',
|
|
103
|
+
'--sg-row-hover-bg': '#fef3c7',
|
|
104
|
+
'--sg-primary-color': '#f59e0b',
|
|
105
|
+
'--sg-frozen-border-color': '#fcd34d',
|
|
106
|
+
'--sg-group-header-bg': '#fef3c7',
|
|
107
|
+
'--sg-group-header-text': '#92400e',
|
|
108
|
+
'--sg-group-header-hover-bg': '#fde68a',
|
|
109
|
+
'--sg-header-icon-color': '#d97706',
|
|
110
|
+
'--sg-sort-active-color': '#f59e0b',
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* Tailwind Slate theme - Neutral modern gray
|
|
115
|
+
*/
|
|
116
|
+
export const tailwindSlate = {
|
|
117
|
+
name: 'tailwind-slate',
|
|
118
|
+
variables: {
|
|
119
|
+
'--sg-border-color': '#e2e8f0',
|
|
120
|
+
'--sg-header-bg': 'linear-gradient(to bottom, #f8fafc, #f1f5f9)',
|
|
121
|
+
'--sg-header-color': '#0f172a',
|
|
122
|
+
'--sg-row-bg': '#ffffff',
|
|
123
|
+
'--sg-row-alt-bg': '#f8fafc',
|
|
124
|
+
'--sg-row-hover-bg': '#f1f5f9',
|
|
125
|
+
'--sg-primary-color': '#475569',
|
|
126
|
+
'--sg-frozen-border-color': '#94a3b8',
|
|
127
|
+
'--sg-group-header-bg': '#f1f5f9',
|
|
128
|
+
'--sg-group-header-text': '#1e293b',
|
|
129
|
+
'--sg-group-header-hover-bg': '#e2e8f0',
|
|
130
|
+
'--sg-header-icon-color': '#64748b',
|
|
131
|
+
'--sg-sort-active-color': '#334155',
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Dark theme - For dark mode UIs
|
|
136
|
+
*/
|
|
137
|
+
export const darkTheme = {
|
|
138
|
+
name: 'dark',
|
|
139
|
+
variables: {
|
|
140
|
+
'--sg-border-color': '#374151',
|
|
141
|
+
'--sg-header-bg': '#1f2937',
|
|
142
|
+
'--sg-header-color': '#f9fafb',
|
|
143
|
+
'--sg-row-bg': '#111827',
|
|
144
|
+
'--sg-row-alt-bg': '#1f2937',
|
|
145
|
+
'--sg-row-hover-bg': '#374151',
|
|
146
|
+
'--sg-primary-color': '#60a5fa',
|
|
147
|
+
'--sg-frozen-border-color': '#4b5563',
|
|
148
|
+
'--sg-group-header-bg': '#1f2937',
|
|
149
|
+
'--sg-group-header-text': '#e5e7eb',
|
|
150
|
+
'--sg-group-header-hover-bg': '#374151',
|
|
151
|
+
'--sg-group-header-collapsed-bg': '#1f2937',
|
|
152
|
+
'--sg-header-icon-color': '#9ca3af',
|
|
153
|
+
'--sg-sort-active-color': '#60a5fa',
|
|
154
|
+
'--sg-popup-bg': '#1f2937',
|
|
155
|
+
'--sg-popup-border': '#374151',
|
|
156
|
+
'--sg-group-toggle-color': '#9ca3af',
|
|
157
|
+
'--sg-group-toggle-hover-color': '#e5e7eb',
|
|
158
|
+
'--sg-group-field-color': '#9ca3af',
|
|
159
|
+
'--sg-group-key-color': '#f3f4f6',
|
|
160
|
+
'--sg-group-count-color': '#6b7280',
|
|
161
|
+
'--sg-group-agg-color': '#9ca3af',
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* All available themes
|
|
166
|
+
*/
|
|
167
|
+
export const themes = {
|
|
168
|
+
default: defaultTheme,
|
|
169
|
+
'tailwind-blue': tailwindBlue,
|
|
170
|
+
'tailwind-emerald': tailwindEmerald,
|
|
171
|
+
'tailwind-rose': tailwindRose,
|
|
172
|
+
'tailwind-amber': tailwindAmber,
|
|
173
|
+
'tailwind-slate': tailwindSlate,
|
|
174
|
+
dark: darkTheme,
|
|
175
|
+
};
|
|
176
|
+
/**
|
|
177
|
+
* Convert theme to CSS style string
|
|
178
|
+
*/
|
|
179
|
+
export function themeToStyle(theme) {
|
|
180
|
+
return Object.entries(theme.variables)
|
|
181
|
+
.map(([key, value]) => `${key}: ${value}`)
|
|
182
|
+
.join('; ');
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Create a custom theme by extending an existing one
|
|
186
|
+
*/
|
|
187
|
+
export function createTheme(base, overrides) {
|
|
188
|
+
return {
|
|
189
|
+
name: 'custom',
|
|
190
|
+
variables: { ...base.variables, ...overrides }
|
|
191
|
+
};
|
|
192
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core type definitions for svelte-grid
|
|
3
|
+
*/
|
|
4
|
+
import type { Snippet } from 'svelte';
|
|
5
|
+
/** Base type for grid row data - any object type */
|
|
6
|
+
export type RowData = {};
|
|
7
|
+
export interface ColumnDefinition<T = RowData> {
|
|
8
|
+
/** Unique field key matching data property */
|
|
9
|
+
field: string;
|
|
10
|
+
/** Display title in header */
|
|
11
|
+
title: string;
|
|
12
|
+
/** Column width in pixels or CSS value */
|
|
13
|
+
width?: number | string;
|
|
14
|
+
/** Minimum column width */
|
|
15
|
+
minWidth?: number;
|
|
16
|
+
/** Maximum column width */
|
|
17
|
+
maxWidth?: number;
|
|
18
|
+
/** Enable sorting for this column */
|
|
19
|
+
sortable?: boolean;
|
|
20
|
+
/** Enable header filter for this column */
|
|
21
|
+
headerFilter?: boolean;
|
|
22
|
+
/** Built-in formatter name or custom function */
|
|
23
|
+
formatter?: FormatterType | FormatterFunction<T>;
|
|
24
|
+
/** Horizontal alignment */
|
|
25
|
+
hAlign?: 'left' | 'center' | 'right';
|
|
26
|
+
/** Vertical alignment */
|
|
27
|
+
vAlign?: 'top' | 'middle' | 'bottom';
|
|
28
|
+
/** CSS class(es) for cells in this column */
|
|
29
|
+
cssClass?: string;
|
|
30
|
+
/** Whether column is visible */
|
|
31
|
+
visible?: boolean;
|
|
32
|
+
/** Whether column is frozen (pinned) - 'left', 'right', or true (same as 'left') */
|
|
33
|
+
frozen?: boolean | 'left' | 'right';
|
|
34
|
+
/** Header tooltip */
|
|
35
|
+
headerTooltip?: string;
|
|
36
|
+
/** Cell tooltip - can be static string or function */
|
|
37
|
+
tooltip?: string | ((cell: CellContext<T>) => string);
|
|
38
|
+
/** Header menu items (dropdown menu in header) */
|
|
39
|
+
headerMenu?: MenuItemDefinition<T>[] | ((column: ColumnDefinition<T>) => MenuItemDefinition<T>[]);
|
|
40
|
+
/** Header popup content (shown when clicking popup icon) */
|
|
41
|
+
headerPopup?: PopupContent<T>;
|
|
42
|
+
/** Show popup icon in header (set to true or custom icon string) */
|
|
43
|
+
headerPopupIcon?: boolean | string;
|
|
44
|
+
}
|
|
45
|
+
/** Menu item definition - either an action item or a separator */
|
|
46
|
+
export type MenuItemDefinition<T = RowData> = MenuItemAction<T> | MenuItemSeparator;
|
|
47
|
+
/** Regular menu item with action */
|
|
48
|
+
export interface MenuItemAction<T = RowData> {
|
|
49
|
+
/** Display label for menu item */
|
|
50
|
+
label: string;
|
|
51
|
+
/** Icon (HTML string or emoji) */
|
|
52
|
+
icon?: string;
|
|
53
|
+
/** Action to perform when clicked */
|
|
54
|
+
action?: MenuAction<T>;
|
|
55
|
+
/** Whether item is disabled */
|
|
56
|
+
disabled?: boolean | ((context: MenuContext<T>) => boolean);
|
|
57
|
+
/** Submenu items */
|
|
58
|
+
menu?: MenuItemDefinition<T>[];
|
|
59
|
+
/** CSS class for the menu item */
|
|
60
|
+
cssClass?: string;
|
|
61
|
+
/** Not a separator */
|
|
62
|
+
separator?: false;
|
|
63
|
+
}
|
|
64
|
+
/** Menu separator item */
|
|
65
|
+
export interface MenuItemSeparator {
|
|
66
|
+
/** Separator - renders as a divider */
|
|
67
|
+
separator: true;
|
|
68
|
+
}
|
|
69
|
+
/** Menu action callback */
|
|
70
|
+
export type MenuAction<T = RowData> = (context: MenuContext<T>) => void;
|
|
71
|
+
/** Context passed to menu actions */
|
|
72
|
+
export interface MenuContext<T = RowData> {
|
|
73
|
+
/** Column definition (for header menus) */
|
|
74
|
+
column?: ColumnDefinition<T>;
|
|
75
|
+
/** Row data (for row/cell context menus) */
|
|
76
|
+
row?: T;
|
|
77
|
+
/** Row index (for row/cell context menus) */
|
|
78
|
+
rowIndex?: number;
|
|
79
|
+
/** Cell context (for cell context menus) */
|
|
80
|
+
cell?: CellContext<T>;
|
|
81
|
+
/** Close the menu */
|
|
82
|
+
closeMenu: () => void;
|
|
83
|
+
}
|
|
84
|
+
/** Popup content - can be a string, Snippet, or function */
|
|
85
|
+
export type PopupContent<T = RowData> = string | Snippet<[PopupContext<T>]> | ((context: PopupContext<T>) => string);
|
|
86
|
+
/** Context passed to popup content */
|
|
87
|
+
export interface PopupContext<T = RowData> {
|
|
88
|
+
/** Column definition (for header popups) */
|
|
89
|
+
column?: ColumnDefinition<T>;
|
|
90
|
+
/** Row data (for row popups) */
|
|
91
|
+
row?: T;
|
|
92
|
+
/** Row index (for row popups) */
|
|
93
|
+
rowIndex?: number;
|
|
94
|
+
/** Cell context (for cell popups) */
|
|
95
|
+
cell?: CellContext<T>;
|
|
96
|
+
/** Close the popup */
|
|
97
|
+
closePopup: () => void;
|
|
98
|
+
}
|
|
99
|
+
export type FormatterType = 'text' | 'number' | 'money' | 'date' | 'datetime' | 'boolean' | 'link' | 'image' | 'progress';
|
|
100
|
+
export type FormatterFunction<T = RowData> = (cell: CellContext<T>) => string | number | undefined;
|
|
101
|
+
export interface CellContext<T = RowData> {
|
|
102
|
+
/** The cell's value */
|
|
103
|
+
value: unknown;
|
|
104
|
+
/** The entire row data */
|
|
105
|
+
row: T;
|
|
106
|
+
/** The column definition */
|
|
107
|
+
column: ColumnDefinition<T>;
|
|
108
|
+
/** Row index in the current view */
|
|
109
|
+
rowIndex: number;
|
|
110
|
+
/** Column index */
|
|
111
|
+
columnIndex: number;
|
|
112
|
+
}
|
|
113
|
+
export interface RowContext<T = RowData> {
|
|
114
|
+
/** The row data */
|
|
115
|
+
data: T;
|
|
116
|
+
/** Row index in the current view */
|
|
117
|
+
index: number;
|
|
118
|
+
/** Original index in raw data */
|
|
119
|
+
originalIndex: number;
|
|
120
|
+
}
|
|
121
|
+
export interface GridOptions<T = RowData> {
|
|
122
|
+
/** Array of data objects */
|
|
123
|
+
data: T[];
|
|
124
|
+
/** Column definitions */
|
|
125
|
+
columns: ColumnDefinition<T>[];
|
|
126
|
+
/** Unique key field in data for row identification */
|
|
127
|
+
rowKey?: keyof T | string;
|
|
128
|
+
/** Fixed height for the grid container */
|
|
129
|
+
height?: string | number;
|
|
130
|
+
/** Fixed row height in pixels (required for virtual scrolling) */
|
|
131
|
+
rowHeight?: number;
|
|
132
|
+
/** Placeholder text when no data */
|
|
133
|
+
placeholder?: string;
|
|
134
|
+
/** Enable/disable row hover highlighting */
|
|
135
|
+
rowHover?: boolean;
|
|
136
|
+
/** Enable/disable alternating row colors */
|
|
137
|
+
stripedRows?: boolean;
|
|
138
|
+
/** Enable/disable grid borders */
|
|
139
|
+
bordered?: boolean;
|
|
140
|
+
/** Grid density: compact, normal, comfortable */
|
|
141
|
+
density?: 'compact' | 'normal' | 'comfortable';
|
|
142
|
+
/** CSS class for the grid container */
|
|
143
|
+
cssClass?: string;
|
|
144
|
+
/** Number of rows to freeze at the top */
|
|
145
|
+
frozenRows?: number;
|
|
146
|
+
/** Row context menu (right-click) */
|
|
147
|
+
rowContextMenu?: MenuItemDefinition<T>[] | ((row: T, rowIndex: number) => MenuItemDefinition<T>[]);
|
|
148
|
+
/** Cell context menu (right-click on cell) */
|
|
149
|
+
cellContextMenu?: MenuItemDefinition<T>[] | ((cell: CellContext<T>) => MenuItemDefinition<T>[]);
|
|
150
|
+
/** Row click popup content */
|
|
151
|
+
rowClickPopup?: PopupContent<T>;
|
|
152
|
+
}
|
|
153
|
+
export type SortDirection = 'asc' | 'desc' | 'none';
|
|
154
|
+
export interface SortConfig {
|
|
155
|
+
/** Field to sort by */
|
|
156
|
+
field: string;
|
|
157
|
+
/** Sort direction */
|
|
158
|
+
direction: SortDirection;
|
|
159
|
+
}
|
|
160
|
+
export type FilterOperator = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'contains' | 'startswith' | 'endswith' | 'regex';
|
|
161
|
+
export interface FilterConfig {
|
|
162
|
+
/** Field to filter */
|
|
163
|
+
field: string;
|
|
164
|
+
/** Filter operator */
|
|
165
|
+
operator: FilterOperator;
|
|
166
|
+
/** Filter value */
|
|
167
|
+
value: unknown;
|
|
168
|
+
}
|
|
169
|
+
/** Group configuration - defines how to group rows */
|
|
170
|
+
export type GroupBy<T = RowData> = string | string[] | ((row: T) => string) | GroupConfig<T> | GroupConfig<T>[];
|
|
171
|
+
/** Detailed group configuration */
|
|
172
|
+
export interface GroupConfig<T = RowData> {
|
|
173
|
+
/** Field to group by, or function returning group key */
|
|
174
|
+
field: string | ((row: T) => string);
|
|
175
|
+
/** Whether groups start expanded - can be boolean or function */
|
|
176
|
+
startOpen?: boolean | ((group: GroupInfo<T>) => boolean);
|
|
177
|
+
/** Custom header content - string, function, or use groupHeader snippet */
|
|
178
|
+
header?: string | ((group: GroupInfo<T>) => string);
|
|
179
|
+
/** Sort direction for groups */
|
|
180
|
+
order?: 'asc' | 'desc' | ((a: string, b: string) => number);
|
|
181
|
+
}
|
|
182
|
+
/** Information about a group, passed to group header renderers */
|
|
183
|
+
export interface GroupInfo<T = RowData> {
|
|
184
|
+
/** The group key/value (e.g., "Engineering", "Sales") */
|
|
185
|
+
key: string;
|
|
186
|
+
/** The field name this group is based on */
|
|
187
|
+
field: string;
|
|
188
|
+
/** All rows belonging to this group */
|
|
189
|
+
rows: T[];
|
|
190
|
+
/** Nesting level for multi-level grouping (0 = top level) */
|
|
191
|
+
level: number;
|
|
192
|
+
/** Number of rows in this group (including nested) */
|
|
193
|
+
count: number;
|
|
194
|
+
/** Whether the group is currently expanded */
|
|
195
|
+
isOpen: boolean;
|
|
196
|
+
/** Toggle the group open/closed */
|
|
197
|
+
toggle: () => void;
|
|
198
|
+
/** Aggregated values per column field */
|
|
199
|
+
aggregates: GroupAggregates;
|
|
200
|
+
/** Parent group info (for nested groups) */
|
|
201
|
+
parent?: GroupInfo<T>;
|
|
202
|
+
/** Child groups (for nested groups) */
|
|
203
|
+
children?: GroupInfo<T>[];
|
|
204
|
+
}
|
|
205
|
+
/** Aggregated values for a group */
|
|
206
|
+
export interface GroupAggregates {
|
|
207
|
+
[field: string]: {
|
|
208
|
+
sum?: number;
|
|
209
|
+
avg?: number;
|
|
210
|
+
min?: number;
|
|
211
|
+
max?: number;
|
|
212
|
+
count: number;
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
/** A display row - either a data row or a group header */
|
|
216
|
+
export type DisplayRow<T = RowData> = {
|
|
217
|
+
type: 'row';
|
|
218
|
+
data: T;
|
|
219
|
+
index: number;
|
|
220
|
+
} | {
|
|
221
|
+
type: 'group';
|
|
222
|
+
group: GroupInfo<T>;
|
|
223
|
+
};
|
|
224
|
+
export interface GridState<T = RowData> {
|
|
225
|
+
/** Raw data array */
|
|
226
|
+
rawData: T[];
|
|
227
|
+
/** Column definitions */
|
|
228
|
+
columns: ColumnDefinition<T>[];
|
|
229
|
+
/** Current scroll position */
|
|
230
|
+
scrollTop: number;
|
|
231
|
+
/** Container dimensions */
|
|
232
|
+
containerHeight: number;
|
|
233
|
+
containerWidth: number;
|
|
234
|
+
/** Row height */
|
|
235
|
+
rowHeight: number;
|
|
236
|
+
}
|
|
237
|
+
export interface TablePlugin<T = RowData> {
|
|
238
|
+
/** Unique plugin name */
|
|
239
|
+
name: string;
|
|
240
|
+
/** Plugin initialization */
|
|
241
|
+
init: (context: PluginContext<T>) => PluginInstance<T>;
|
|
242
|
+
}
|
|
243
|
+
export interface PluginContext<T = RowData> {
|
|
244
|
+
/** Access to grid state */
|
|
245
|
+
getState: () => GridState<T>;
|
|
246
|
+
/** Update state */
|
|
247
|
+
updateState: (updates: Partial<GridState<T>>) => void;
|
|
248
|
+
/** Subscribe to state changes */
|
|
249
|
+
subscribe: (callback: () => void) => () => void;
|
|
250
|
+
}
|
|
251
|
+
export interface PluginInstance<T = RowData> {
|
|
252
|
+
/** Data pipeline handler with priority */
|
|
253
|
+
dataPipeline?: {
|
|
254
|
+
priority: number;
|
|
255
|
+
handler: (data: T[]) => T[];
|
|
256
|
+
};
|
|
257
|
+
/** Header cell enhancements */
|
|
258
|
+
headerCell?: (column: ColumnDefinition<T>) => Record<string, unknown>;
|
|
259
|
+
/** Cell enhancements */
|
|
260
|
+
cell?: (cell: CellContext<T>) => Record<string, unknown>;
|
|
261
|
+
/** Public API methods exposed on grid instance */
|
|
262
|
+
api?: Record<string, (...args: unknown[]) => unknown>;
|
|
263
|
+
/** Cleanup function */
|
|
264
|
+
destroy?: () => void;
|
|
265
|
+
}
|
|
266
|
+
export interface GridEvents<T = RowData> {
|
|
267
|
+
/** Row click event */
|
|
268
|
+
rowclick?: (row: T, index: number, event: MouseEvent) => void;
|
|
269
|
+
/** Row double-click event */
|
|
270
|
+
rowdblclick?: (row: T, index: number, event: MouseEvent) => void;
|
|
271
|
+
/** Cell click event */
|
|
272
|
+
cellclick?: (cell: CellContext<T>, event: MouseEvent) => void;
|
|
273
|
+
/** Header click event */
|
|
274
|
+
headerclick?: (column: ColumnDefinition<T>, event: MouseEvent) => void;
|
|
275
|
+
/** Data changed event */
|
|
276
|
+
datachanged?: (data: T[]) => void;
|
|
277
|
+
/** Scroll event */
|
|
278
|
+
scroll?: (scrollTop: number, scrollLeft: number) => void;
|
|
279
|
+
}
|
|
280
|
+
export interface GridSnippets<T = RowData> {
|
|
281
|
+
/** Custom cell renderer */
|
|
282
|
+
cell?: Snippet<[CellContext<T>]>;
|
|
283
|
+
/** Custom header cell renderer */
|
|
284
|
+
headerCell?: Snippet<[ColumnDefinition<T>]>;
|
|
285
|
+
/** Custom row renderer */
|
|
286
|
+
row?: Snippet<[RowContext<T>]>;
|
|
287
|
+
/** Empty state renderer */
|
|
288
|
+
empty?: Snippet<[]>;
|
|
289
|
+
/** Loading state renderer */
|
|
290
|
+
loading?: Snippet<[]>;
|
|
291
|
+
}
|
package/dist/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@smartnet360/svelte-grid",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A Svelte 5 table/grid library inspired by Tabulator",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "vite dev",
|
|
7
|
+
"build": "vite build && npm run prepack",
|
|
8
|
+
"preview": "vite preview",
|
|
9
|
+
"prepare": "svelte-kit sync || echo ''",
|
|
10
|
+
"prepack": "svelte-kit sync && svelte-package && publint",
|
|
11
|
+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
12
|
+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
13
|
+
"format": "prettier --write .",
|
|
14
|
+
"lint": "prettier --check . && eslint .",
|
|
15
|
+
"release:patch": "npm version patch && npm publish --access public",
|
|
16
|
+
"release:minor": "npm version minor && npm publish --access public",
|
|
17
|
+
"release:major": "npm version major && npm publish --access public"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"!dist/**/*.md"
|
|
22
|
+
],
|
|
23
|
+
"sideEffects": [
|
|
24
|
+
"**/*.css"
|
|
25
|
+
],
|
|
26
|
+
"svelte": "./dist/index.js",
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"type": "module",
|
|
29
|
+
"exports": {
|
|
30
|
+
".": {
|
|
31
|
+
"types": "./dist/index.d.ts",
|
|
32
|
+
"svelte": "./dist/index.js"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"svelte": "^5.0.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@eslint/compat": "^1.2.5",
|
|
40
|
+
"@eslint/js": "^9.18.0",
|
|
41
|
+
"@sveltejs/adapter-auto": "^6.0.0",
|
|
42
|
+
"@sveltejs/kit": "^2.22.0",
|
|
43
|
+
"@sveltejs/package": "^2.0.0",
|
|
44
|
+
"@sveltejs/vite-plugin-svelte": "^6.0.0",
|
|
45
|
+
"eslint": "^9.18.0",
|
|
46
|
+
"eslint-config-prettier": "^10.0.1",
|
|
47
|
+
"eslint-plugin-svelte": "^3.0.0",
|
|
48
|
+
"globals": "^16.0.0",
|
|
49
|
+
"prettier": "^3.4.2",
|
|
50
|
+
"prettier-plugin-svelte": "^3.3.3",
|
|
51
|
+
"publint": "^0.3.2",
|
|
52
|
+
"svelte": "^5.0.0",
|
|
53
|
+
"svelte-check": "^4.0.0",
|
|
54
|
+
"typescript": "^5.0.0",
|
|
55
|
+
"typescript-eslint": "^8.20.0",
|
|
56
|
+
"vite": "^7.0.4"
|
|
57
|
+
},
|
|
58
|
+
"keywords": [
|
|
59
|
+
"svelte",
|
|
60
|
+
"svelte5",
|
|
61
|
+
"grid",
|
|
62
|
+
"table",
|
|
63
|
+
"datagrid",
|
|
64
|
+
"datatable"
|
|
65
|
+
]
|
|
66
|
+
}
|