@keenmate/web-grid 1.0.0-rc05 → 1.0.0-rc07
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/component-variables.manifest.json +182 -172
- package/dist/grid.d.ts +107 -11
- package/dist/index.d.ts +1 -1
- package/dist/modules/contextmenu/index.d.ts +1 -1
- package/dist/modules/editing/index.d.ts +1 -1
- package/dist/modules/editing/lifecycle.d.ts +5 -0
- package/dist/modules/navigation/focus.d.ts +10 -3
- package/dist/modules/rendering/cell.d.ts +19 -0
- package/dist/modules/rendering/index.d.ts +2 -0
- package/dist/modules/toolbar/index.d.ts +10 -2
- package/dist/types.d.ts +86 -6
- package/dist/web-component.d.ts +93 -7
- package/dist/web-grid.js +3724 -2898
- package/dist/web-grid.umd.js +184 -150
- package/package.json +78 -78
- package/src/css/_cells.css +4 -0
- package/src/css/_dialogs.css +20 -2
- package/src/css/_editors.css +4 -2
- package/src/css/_header.css +1 -0
- package/src/css/_navigation.css +1 -1
- package/src/css/_pagination.css +2 -0
- package/src/css/_row-locking.css +38 -0
- package/src/css/_shortcuts.css +126 -0
- package/src/css/_table.css +1 -1
- package/src/css/_toolbar.css +75 -1
- package/src/css/_variables.css +16 -6
- package/src/css/main.css +3 -0
package/dist/grid.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Column, CellValidationState, RowToolbarConfig, ContextMenuItem, RowChangeDetail, ToolbarClickDetail, RowActionClickDetail, ContextMenuContext, EditTrigger, EditStartSelection, EditingCell, FocusedCell, SortMode, SortState, DataRequestDetail, DataRequestTrigger, BeforeCommitResult, GridMode, ToggleVisibility, PaginationLabelsCallback, SummaryContentCallback, ValidationTooltipContext } from './types.js';
|
|
1
|
+
import type { Column, CellValidationState, RowToolbarConfig, ContextMenuItem, RowShortcut, RowChangeDetail, ToolbarClickDetail, RowActionClickDetail, ContextMenuContext, EditTrigger, EditStartSelection, EditingCell, FocusedCell, SortMode, SortState, DataRequestDetail, DataRequestTrigger, BeforeCommitResult, GridMode, ToggleVisibility, PaginationLabelsCallback, SummaryContentCallback, ValidationTooltipContext, ToolbarPosition, GridLabels, RowLockInfo, RowLockingOptions, RowLockChangeDetail } from './types.js';
|
|
2
2
|
/**
|
|
3
3
|
* WebGrid - Core logic class for the data grid
|
|
4
4
|
*
|
|
@@ -27,11 +27,23 @@ export declare class WebGrid<T = unknown> {
|
|
|
27
27
|
protected _invalidCells: CellValidationState[];
|
|
28
28
|
protected _showRowToolbar: boolean;
|
|
29
29
|
protected _rowToolbar: RowToolbarConfig<T>[];
|
|
30
|
-
protected
|
|
31
|
-
protected
|
|
30
|
+
protected _toolbarVerticalAlign: 'top' | 'center' | 'bottom';
|
|
31
|
+
protected _toolbarHorizontalAlign: 'start' | 'center' | 'end' | 'cursor';
|
|
32
32
|
protected _toolbarTrigger: 'hover' | 'click' | 'button';
|
|
33
|
-
protected _toolbarPosition:
|
|
33
|
+
protected _toolbarPosition: ToolbarPosition;
|
|
34
|
+
protected _inlineActionsTitle: string;
|
|
34
35
|
protected _contextMenu: ContextMenuItem<T>[] | undefined;
|
|
36
|
+
protected _contextMenuXOffset: number;
|
|
37
|
+
protected _contextMenuYOffset: number;
|
|
38
|
+
protected _rowShortcuts: RowShortcut<T>[] | undefined;
|
|
39
|
+
protected _showShortcutsHelp: boolean;
|
|
40
|
+
protected _shortcutsHelpPosition: 'top-right' | 'top-left';
|
|
41
|
+
protected _shortcutsHelpContentCallback: (() => string) | undefined;
|
|
42
|
+
protected _idValueMember: keyof T | undefined;
|
|
43
|
+
protected _idValueCallback: ((row: T) => unknown) | undefined;
|
|
44
|
+
protected _rowLocking: RowLockingOptions<T> | undefined;
|
|
45
|
+
protected _externalLocks: Map<unknown, RowLockInfo>;
|
|
46
|
+
protected _onrowlockchange: ((detail: RowLockChangeDetail<T>) => void) | undefined;
|
|
35
47
|
protected _onrowchange: ((detail: RowChangeDetail<T>) => void) | undefined;
|
|
36
48
|
protected _onroweditstart: ((detail: {
|
|
37
49
|
row: T;
|
|
@@ -72,6 +84,7 @@ export declare class WebGrid<T = unknown> {
|
|
|
72
84
|
protected _summaryInline: boolean;
|
|
73
85
|
protected _customStylesCallback?: () => string;
|
|
74
86
|
protected _rowClassCallback?: (row: T, rowIndex: number) => string | null;
|
|
87
|
+
protected _labels: GridLabels;
|
|
75
88
|
protected _virtualScroll: boolean;
|
|
76
89
|
protected _virtualScrollThreshold: number;
|
|
77
90
|
protected _virtualScrollRowHeight: number;
|
|
@@ -87,15 +100,17 @@ export declare class WebGrid<T = unknown> {
|
|
|
87
100
|
protected _focusedCell: FocusedCell;
|
|
88
101
|
protected _isCommittingFromKeyboard: boolean;
|
|
89
102
|
protected _skipNextDropdownAutoEdit: boolean;
|
|
103
|
+
protected _hoveredRowIndex: number | null;
|
|
104
|
+
protected _onInteractionChange: ((type: 'hoveredRow' | 'focusedCell' | 'editingCell', detail: {
|
|
105
|
+
prev: any;
|
|
106
|
+
current: any;
|
|
107
|
+
}) => void) | null;
|
|
90
108
|
get items(): T[];
|
|
91
109
|
set items(value: T[]);
|
|
92
110
|
get columns(): Column<T>[];
|
|
93
111
|
set columns(value: Column<T>[]);
|
|
94
112
|
get sortMode(): SortMode;
|
|
95
113
|
set sortMode(value: SortMode);
|
|
96
|
-
/** @deprecated Use sortMode instead. sortable=true maps to sortMode="multi", sortable=false maps to sortMode="none" */
|
|
97
|
-
get sortable(): boolean;
|
|
98
|
-
set sortable(value: boolean);
|
|
99
114
|
get filterable(): boolean;
|
|
100
115
|
set filterable(value: boolean);
|
|
101
116
|
get pageable(): boolean;
|
|
@@ -139,20 +154,39 @@ export declare class WebGrid<T = unknown> {
|
|
|
139
154
|
get editingCell(): EditingCell;
|
|
140
155
|
get isValidating(): boolean;
|
|
141
156
|
get currentCellError(): string | null;
|
|
157
|
+
get hoveredRowIndex(): number | null;
|
|
142
158
|
get showRowToolbar(): boolean;
|
|
143
159
|
set showRowToolbar(value: boolean);
|
|
144
160
|
get rowToolbar(): RowToolbarConfig<T>[];
|
|
145
161
|
set rowToolbar(value: RowToolbarConfig<T>[]);
|
|
146
|
-
get
|
|
147
|
-
set
|
|
162
|
+
get toolbarVerticalAlign(): 'top' | 'center' | 'bottom';
|
|
163
|
+
set toolbarVerticalAlign(value: 'top' | 'center' | 'bottom');
|
|
164
|
+
get toolbarHorizontalAlign(): 'start' | 'center' | 'end' | 'cursor';
|
|
165
|
+
set toolbarHorizontalAlign(value: 'start' | 'center' | 'end' | 'cursor');
|
|
166
|
+
get toolbarAlign(): 'top' | 'center' | 'bottom';
|
|
167
|
+
set toolbarAlign(value: 'top' | 'center' | 'bottom');
|
|
148
168
|
get toolbarTopPosition(): 'start' | 'center' | 'end' | 'cursor';
|
|
149
169
|
set toolbarTopPosition(value: 'start' | 'center' | 'end' | 'cursor');
|
|
150
170
|
get toolbarTrigger(): 'hover' | 'click' | 'button';
|
|
151
171
|
set toolbarTrigger(value: 'hover' | 'click' | 'button');
|
|
152
|
-
get toolbarPosition():
|
|
153
|
-
set toolbarPosition(value:
|
|
172
|
+
get toolbarPosition(): ToolbarPosition;
|
|
173
|
+
set toolbarPosition(value: ToolbarPosition);
|
|
174
|
+
get inlineActionsTitle(): string;
|
|
175
|
+
set inlineActionsTitle(value: string);
|
|
154
176
|
get contextMenu(): ContextMenuItem<T>[] | undefined;
|
|
155
177
|
set contextMenu(value: ContextMenuItem<T>[] | undefined);
|
|
178
|
+
get contextMenuXOffset(): number;
|
|
179
|
+
set contextMenuXOffset(value: number);
|
|
180
|
+
get contextMenuYOffset(): number;
|
|
181
|
+
set contextMenuYOffset(value: number);
|
|
182
|
+
get rowShortcuts(): RowShortcut<T>[] | undefined;
|
|
183
|
+
set rowShortcuts(value: RowShortcut<T>[] | undefined);
|
|
184
|
+
get showShortcutsHelp(): boolean;
|
|
185
|
+
set showShortcutsHelp(value: boolean);
|
|
186
|
+
get shortcutsHelpPosition(): 'top-right' | 'top-left';
|
|
187
|
+
set shortcutsHelpPosition(value: 'top-right' | 'top-left');
|
|
188
|
+
get shortcutsHelpContentCallback(): (() => string) | undefined;
|
|
189
|
+
set shortcutsHelpContentCallback(value: (() => string) | undefined);
|
|
156
190
|
get sort(): SortState[];
|
|
157
191
|
set sort(value: SortState[]);
|
|
158
192
|
get currentPage(): number;
|
|
@@ -179,6 +213,8 @@ export declare class WebGrid<T = unknown> {
|
|
|
179
213
|
set customStylesCallback(value: (() => string) | undefined);
|
|
180
214
|
get rowClassCallback(): ((row: T, rowIndex: number) => string | null) | undefined;
|
|
181
215
|
set rowClassCallback(value: ((row: T, rowIndex: number) => string | null) | undefined);
|
|
216
|
+
get labels(): GridLabels;
|
|
217
|
+
set labels(value: Partial<GridLabels>);
|
|
182
218
|
get virtualScroll(): boolean;
|
|
183
219
|
set virtualScroll(value: boolean);
|
|
184
220
|
get virtualScrollThreshold(): number;
|
|
@@ -236,6 +272,14 @@ export declare class WebGrid<T = unknown> {
|
|
|
236
272
|
rowIndex: number;
|
|
237
273
|
row: T;
|
|
238
274
|
}) => void) | undefined);
|
|
275
|
+
get idValueMember(): keyof T | undefined;
|
|
276
|
+
set idValueMember(value: keyof T | undefined);
|
|
277
|
+
get idValueCallback(): ((row: T) => unknown) | undefined;
|
|
278
|
+
set idValueCallback(value: ((row: T) => unknown) | undefined);
|
|
279
|
+
get rowLocking(): RowLockingOptions<T> | undefined;
|
|
280
|
+
set rowLocking(value: RowLockingOptions<T> | undefined);
|
|
281
|
+
get onrowlockchange(): ((detail: RowLockChangeDetail<T>) => void) | undefined;
|
|
282
|
+
set onrowlockchange(value: ((detail: RowLockChangeDetail<T>) => void) | undefined);
|
|
239
283
|
get isNavigateMode(): boolean;
|
|
240
284
|
get filteredItems(): T[];
|
|
241
285
|
get sortedItems(): T[];
|
|
@@ -327,5 +371,57 @@ export declare class WebGrid<T = unknown> {
|
|
|
327
371
|
* NOTE: Does NOT call requestUpdate() - GridElement handles DOM updates surgically
|
|
328
372
|
*/
|
|
329
373
|
clearFocusedCell(): void;
|
|
374
|
+
/**
|
|
375
|
+
* Set the hovered row index (for toolbar/shortcuts)
|
|
376
|
+
* NOTE: Does NOT call requestUpdate() - GridElement handles UI updates
|
|
377
|
+
*/
|
|
378
|
+
setHoveredRow(rowIndex: number | null): void;
|
|
379
|
+
/**
|
|
380
|
+
* Get the unique ID for a row using configured idValueMember/idValueCallback
|
|
381
|
+
*/
|
|
382
|
+
getRowId(row: T): unknown | undefined;
|
|
383
|
+
/**
|
|
384
|
+
* Find a row by its ID
|
|
385
|
+
*/
|
|
386
|
+
findRowById(id: unknown): {
|
|
387
|
+
row: T;
|
|
388
|
+
index: number;
|
|
389
|
+
} | null;
|
|
390
|
+
/**
|
|
391
|
+
* Get lock info for a row (combines all sources: external, callback, property)
|
|
392
|
+
*/
|
|
393
|
+
getRowLockInfo(rowOrId: T | unknown): RowLockInfo | null;
|
|
394
|
+
/**
|
|
395
|
+
* Check if a row is locked
|
|
396
|
+
*/
|
|
397
|
+
isRowLocked(rowOrId: T | unknown): boolean;
|
|
398
|
+
/**
|
|
399
|
+
* Lock a row by ID (external lock for WebSocket scenarios)
|
|
400
|
+
*/
|
|
401
|
+
lockRowById(id: unknown, lockerInfo?: Partial<RowLockInfo>): boolean;
|
|
402
|
+
/**
|
|
403
|
+
* Unlock a row by ID
|
|
404
|
+
*/
|
|
405
|
+
unlockRowById(id: unknown): boolean;
|
|
406
|
+
/**
|
|
407
|
+
* Get all external locks (for debugging/inspection)
|
|
408
|
+
*/
|
|
409
|
+
getExternalLocks(): Map<unknown, RowLockInfo>;
|
|
410
|
+
/**
|
|
411
|
+
* Clear all external locks
|
|
412
|
+
*/
|
|
413
|
+
clearExternalLocks(): void;
|
|
414
|
+
/**
|
|
415
|
+
* Update a row's data by ID (partial update, preserves other fields)
|
|
416
|
+
*/
|
|
417
|
+
updateRowById(id: unknown, newData: Partial<T>): boolean;
|
|
418
|
+
/**
|
|
419
|
+
* Replace entire row by ID
|
|
420
|
+
*/
|
|
421
|
+
replaceRowById(id: unknown, newRow: T): boolean;
|
|
422
|
+
/**
|
|
423
|
+
* Check if a cell can be edited (respects lock state)
|
|
424
|
+
*/
|
|
425
|
+
canEditCell(rowIndex: number, field: string): boolean;
|
|
330
426
|
}
|
|
331
427
|
export default WebGrid;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { GridElement } from './web-component.js';
|
|
2
2
|
export { WebGrid } from './grid.js';
|
|
3
|
-
export type { EditorType, EditTrigger, OptionsLoadTrigger, DateOutputFormat, EditorOption, EditorOptions, CustomEditorContext, CellValidationState, ValidationResult, BeforeCommitContext, BeforeCommitResult, Column, CellRenderCallback, RowChangeDetail, PredefinedToolbarItemType, RowToolbarItem, RowToolbarConfig, NormalizedToolbarItem, ToolbarClickDetail, RowActionType, RowActionClickDetail, ContextMenuContext, ContextMenuItem, QuickGridProps, SortState, DataRequestDetail, DataRequestTrigger, EditingCell, FocusedCell, SortDirection, ToolbarRowGroup, PopupPosition, ConnectorArrowDir } from './types.js';
|
|
3
|
+
export type { EditorType, EditTrigger, OptionsLoadTrigger, DateOutputFormat, EditorOption, EditorOptions, CustomEditorContext, CellValidationState, ValidationResult, BeforeCommitContext, BeforeCommitResult, Column, CellRenderCallback, RowChangeDetail, PredefinedToolbarItemType, ToolbarPosition, ToolbarTooltip, RowToolbarItem, RowToolbarConfig, NormalizedToolbarItem, ToolbarClickDetail, RowActionType, RowActionClickDetail, ContextMenuContext, ContextMenuItem, QuickGridProps, SortState, DataRequestDetail, DataRequestTrigger, GridLabels, RowLockInfo, RowLockingOptions, RowLockChangeDetail, LockedRowEditBehavior, EditingCell, FocusedCell, SortDirection, ToolbarRowGroup, PopupPosition, ConnectorArrowDir } from './types.js';
|
|
4
4
|
export { GridElement as default } from './web-component.js';
|
|
@@ -3,7 +3,7 @@ import type { GridContext } from '../types.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* Open context menu at position
|
|
5
5
|
*/
|
|
6
|
-
export declare function openContextMenu<T>(ctx: GridContext<T>, x: number, y: number, items: ContextMenuItem<T>[], menuContext: ContextMenuContext<T>, onItemClick: (itemId: string) => void, onClose: () => void): HTMLElement | null;
|
|
6
|
+
export declare function openContextMenu<T>(ctx: GridContext<T>, x: number, y: number, xOffset: number, yOffset: number, items: ContextMenuItem<T>[], menuContext: ContextMenuContext<T>, onItemClick: (itemId: string) => void, onClose: () => void): HTMLElement | null;
|
|
7
7
|
/**
|
|
8
8
|
* Close context menu and cleanup
|
|
9
9
|
*/
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { commitCurrentEditor, handleCheckboxChange, toggleCheckboxAndMove, handleEditorBlur, moveFocusAfterCommit, focusCellAfterCancel } from './lifecycle.js';
|
|
1
|
+
export { commitCurrentEditor, handleCheckboxChange, toggleCheckboxAndMove, handleEditorBlur, moveFocusAfterCommit, focusCellAfterCancel, restoreCellToDisplayMode } from './lifecycle.js';
|
|
2
2
|
export { renderCellEditor, renderTextEditor, renderNumberEditor, renderCheckboxEditor, renderSelectEditor, renderComboboxEditor, renderAutocompleteEditor } from './renderers.js';
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import type { GridContext } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Surgically restore a cell from editing mode to display mode.
|
|
4
|
+
* Uses centralized renderCell() to ensure all states are correct.
|
|
5
|
+
*/
|
|
6
|
+
export declare function restoreCellToDisplayMode<T>(ctx: GridContext<T>, rowIndex: number, colIndex: number): void;
|
|
2
7
|
/**
|
|
3
8
|
* Commit the value from the current editor
|
|
4
9
|
*/
|
|
@@ -12,15 +12,21 @@ export declare function focusCellElement<T>(ctx: GridContext<T>, rowIndex: numbe
|
|
|
12
12
|
export declare function scrollToRowPosition<T>(ctx: GridContext<T>, rowIndex: number): void;
|
|
13
13
|
/**
|
|
14
14
|
* Update focus visual state surgically (without full re-render)
|
|
15
|
-
*
|
|
15
|
+
* Uses centralized renderCell() to ensure all states are correct
|
|
16
16
|
*/
|
|
17
17
|
export declare function updateFocusVisual<T>(ctx: GridContext<T>, oldFocus: FocusedCell | null, newFocus: FocusedCell | null): void;
|
|
18
18
|
/**
|
|
19
19
|
* Surgically remove the editing visual (blue border) from current editing cell.
|
|
20
|
-
* Call this BEFORE cancelEdit() to ensure the DOM class is removed immediately
|
|
21
|
-
*
|
|
20
|
+
* Call this BEFORE cancelEdit() to ensure the DOM class is removed immediately.
|
|
21
|
+
* NOTE: This just removes the class - full cell restoration happens via renderCell()
|
|
22
|
+
* after cancelEdit() clears the state.
|
|
22
23
|
*/
|
|
23
24
|
export declare function clearEditingVisual<T>(ctx: GridContext<T>): void;
|
|
25
|
+
/**
|
|
26
|
+
* Fully restore an editing cell to display mode.
|
|
27
|
+
* Must be called AFTER cancelEdit() so the cell renders in display mode.
|
|
28
|
+
*/
|
|
29
|
+
export declare function restoreEditingCellToDisplayMode<T>(ctx: GridContext<T>, rowIndex: number, colIndex: number): void;
|
|
24
30
|
/**
|
|
25
31
|
* Handle cell focus event
|
|
26
32
|
*/
|
|
@@ -31,6 +37,7 @@ export declare function handleCellFocus<T>(ctx: GridContext<T>, rowIndex: number
|
|
|
31
37
|
export declare function moveFocus<T>(ctx: GridContext<T>, newRowIndex: number, newColIndex: number): void;
|
|
32
38
|
/**
|
|
33
39
|
* Try to start editing a cell (checks if editable first)
|
|
40
|
+
* Uses centralized renderCell() for surgical DOM update
|
|
34
41
|
*/
|
|
35
42
|
export declare function tryStartEdit<T>(ctx: GridContext<T>, rowIndex: number, colIndex: number, options?: {
|
|
36
43
|
initialSearchQuery?: string;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { GridContext } from '../types.js';
|
|
2
|
+
export type RenderCellOptions = {
|
|
3
|
+
/** Focus the editor after rendering (for edit mode) */
|
|
4
|
+
focusEditor?: boolean;
|
|
5
|
+
/** Cursor position for text inputs */
|
|
6
|
+
cursorPosition?: number;
|
|
7
|
+
/** Initial search query (type-to-start) */
|
|
8
|
+
initialSearchQuery?: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Surgically update a single cell's DOM based on current grid state.
|
|
12
|
+
* This is the single source of truth for cell appearance.
|
|
13
|
+
*
|
|
14
|
+
* Handles:
|
|
15
|
+
* - All CSS classes (focused, editing, editable, invalid, etc.)
|
|
16
|
+
* - Cell content (editor vs display mode)
|
|
17
|
+
* - Editor focus and cursor positioning
|
|
18
|
+
*/
|
|
19
|
+
export declare function renderCell<T>(ctx: GridContext<T>, rowIndex: number, colIndex: number, options?: RenderCellOptions): void;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export { getContainerClasses, renderHeaderRow, renderDataRows, renderDataRowsVirtual, renderPagination, renderSummary } from './table.js';
|
|
2
2
|
export type { VirtualScrollParams } from './table.js';
|
|
3
3
|
export { renderCellDisplay } from './display.js';
|
|
4
|
+
export { renderCell } from './cell.js';
|
|
5
|
+
export type { RenderCellOptions } from './cell.js';
|
|
@@ -12,10 +12,18 @@ export type ConnectorState = {
|
|
|
12
12
|
* Convert toolbar config (strings or objects) to normalized items
|
|
13
13
|
*/
|
|
14
14
|
export declare function normalizeToolbarItems<T>(config: RowToolbarConfig<T>[]): NormalizedToolbarItem<T>[];
|
|
15
|
+
/**
|
|
16
|
+
* Build rich tooltip HTML for a toolbar item
|
|
17
|
+
* @param item - The toolbar item
|
|
18
|
+
* @param shortcutKey - Optional keyboard shortcut from rowShortcuts
|
|
19
|
+
*/
|
|
20
|
+
export declare function buildToolbarTooltipHtml<T>(item: NormalizedToolbarItem<T>, shortcutKey?: string): string;
|
|
15
21
|
/**
|
|
16
22
|
* Render toolbar HTML for a specific row
|
|
23
|
+
* @param reverseRows - If true, reverse row order so Row 1 ends up at top visually
|
|
24
|
+
* (CSS column-reverse makes last HTML row appear at top)
|
|
17
25
|
*/
|
|
18
|
-
export declare function renderToolbarHTML<T>(items: NormalizedToolbarItem<T>[], row: T, rowIndex: number): string;
|
|
26
|
+
export declare function renderToolbarHTML<T>(items: NormalizedToolbarItem<T>[], row: T, rowIndex: number, reverseRows?: boolean): string;
|
|
19
27
|
/**
|
|
20
28
|
* Open toolbar for a specific row
|
|
21
29
|
*/
|
|
@@ -53,4 +61,4 @@ export declare function updateConnector<T>(ctx: GridContext<T>, displayItems: T[
|
|
|
53
61
|
/**
|
|
54
62
|
* Render the toolbar trigger button HTML
|
|
55
63
|
*/
|
|
56
|
-
export declare function renderTriggerButton(rowIndex: number, isActive: boolean): string;
|
|
64
|
+
export declare function renderTriggerButton(rowIndex: number, isActive: boolean, title?: string): string;
|
package/dist/types.d.ts
CHANGED
|
@@ -38,6 +38,8 @@ export type EditorOptions<T = unknown> = {
|
|
|
38
38
|
onselect?: (option: EditorOption, row: T) => void;
|
|
39
39
|
allowEmpty?: boolean;
|
|
40
40
|
emptyLabel?: string;
|
|
41
|
+
noOptionsText?: string;
|
|
42
|
+
searchingText?: string;
|
|
41
43
|
maxLength?: number;
|
|
42
44
|
placeholder?: string;
|
|
43
45
|
pattern?: string;
|
|
@@ -138,6 +140,11 @@ export type RowChangeDetail<T> = {
|
|
|
138
140
|
validationError?: string | null;
|
|
139
141
|
};
|
|
140
142
|
export type PredefinedToolbarItemType = 'add' | 'delete' | 'duplicate' | 'moveUp' | 'moveDown';
|
|
143
|
+
export type ToolbarPosition = 'auto' | 'left' | 'right' | 'top' | 'inline';
|
|
144
|
+
export type ToolbarTooltip = {
|
|
145
|
+
description?: string;
|
|
146
|
+
shortcut?: string;
|
|
147
|
+
};
|
|
141
148
|
export type RowToolbarItem<T> = {
|
|
142
149
|
id: string;
|
|
143
150
|
icon: string;
|
|
@@ -148,13 +155,19 @@ export type RowToolbarItem<T> = {
|
|
|
148
155
|
type?: PredefinedToolbarItemType;
|
|
149
156
|
danger?: boolean;
|
|
150
157
|
disabled?: boolean | ((row: T, rowIndex: number) => boolean);
|
|
158
|
+
hidden?: boolean | ((row: T, rowIndex: number) => boolean);
|
|
159
|
+
tooltip?: ToolbarTooltip;
|
|
160
|
+
tooltipCallback?: (row: T, rowIndex: number) => string;
|
|
151
161
|
onclick?: (detail: {
|
|
152
162
|
row: T;
|
|
153
163
|
rowIndex: number;
|
|
154
164
|
}) => void | Promise<void>;
|
|
155
165
|
};
|
|
156
166
|
export type RowToolbarConfig<T> = PredefinedToolbarItemType | RowToolbarItem<T>;
|
|
157
|
-
export type NormalizedToolbarItem<T> = Required<Pick<RowToolbarItem<T>, 'id' | 'icon' | 'title' | 'row' | 'group'>> & Omit<RowToolbarItem<T>, 'id' | 'icon' | 'title' | 'row' | 'group'
|
|
167
|
+
export type NormalizedToolbarItem<T> = Required<Pick<RowToolbarItem<T>, 'id' | 'icon' | 'title' | 'row' | 'group'>> & Omit<RowToolbarItem<T>, 'id' | 'icon' | 'title' | 'row' | 'group'> & {
|
|
168
|
+
tooltip?: ToolbarTooltip;
|
|
169
|
+
tooltipCallback?: (row: T, rowIndex: number) => string;
|
|
170
|
+
};
|
|
158
171
|
export type ToolbarClickDetail<T> = {
|
|
159
172
|
item: NormalizedToolbarItem<T>;
|
|
160
173
|
rowIndex: number;
|
|
@@ -177,17 +190,37 @@ export type ContextMenuItem<T> = {
|
|
|
177
190
|
id: string;
|
|
178
191
|
label: string | ((context: ContextMenuContext<T>) => string);
|
|
179
192
|
icon?: string | ((context: ContextMenuContext<T>) => string);
|
|
193
|
+
shortcut?: string;
|
|
180
194
|
disabled?: boolean | ((context: ContextMenuContext<T>) => boolean);
|
|
181
195
|
visible?: boolean | ((context: ContextMenuContext<T>) => boolean);
|
|
182
196
|
danger?: boolean;
|
|
183
197
|
dividerBefore?: boolean;
|
|
184
198
|
onclick?: (context: ContextMenuContext<T>) => void | Promise<void>;
|
|
185
199
|
};
|
|
200
|
+
export type ShortcutContext<T> = {
|
|
201
|
+
row: T;
|
|
202
|
+
rowIndex: number;
|
|
203
|
+
colIndex: number;
|
|
204
|
+
column: Column<T>;
|
|
205
|
+
cellValue: unknown;
|
|
206
|
+
};
|
|
207
|
+
export type RowShortcut<T> = {
|
|
208
|
+
key: string;
|
|
209
|
+
id: string;
|
|
210
|
+
label: string;
|
|
211
|
+
action: (ctx: ShortcutContext<T>) => void | Promise<void>;
|
|
212
|
+
disabled?: boolean | ((ctx: ShortcutContext<T>) => boolean);
|
|
213
|
+
};
|
|
214
|
+
export type ParsedKeyCombo = {
|
|
215
|
+
key: string;
|
|
216
|
+
ctrl: boolean;
|
|
217
|
+
shift: boolean;
|
|
218
|
+
alt: boolean;
|
|
219
|
+
meta: boolean;
|
|
220
|
+
};
|
|
186
221
|
export type QuickGridProps<T> = {
|
|
187
222
|
items: T[];
|
|
188
223
|
columns: Column<T>[];
|
|
189
|
-
/** @deprecated Use sortMode instead */
|
|
190
|
-
sortable?: boolean;
|
|
191
224
|
filterable?: boolean;
|
|
192
225
|
pageable?: boolean;
|
|
193
226
|
pageSize?: number;
|
|
@@ -221,14 +254,23 @@ export type QuickGridProps<T> = {
|
|
|
221
254
|
invalidCells?: CellValidationState[];
|
|
222
255
|
showRowToolbar?: boolean;
|
|
223
256
|
rowToolbar?: RowToolbarConfig<T>[];
|
|
224
|
-
|
|
225
|
-
|
|
257
|
+
toolbarVerticalAlign?: 'top' | 'center' | 'bottom';
|
|
258
|
+
toolbarHorizontalAlign?: 'start' | 'center' | 'end' | 'cursor';
|
|
226
259
|
toolbarTrigger?: 'hover' | 'click' | 'button';
|
|
227
|
-
toolbarPosition?:
|
|
260
|
+
toolbarPosition?: ToolbarPosition;
|
|
261
|
+
inlineActionsTitle?: string;
|
|
228
262
|
showRowActions?: boolean;
|
|
229
263
|
rowActions?: RowToolbarConfig<T>[];
|
|
264
|
+
toolbarAlign?: 'top' | 'center' | 'bottom';
|
|
265
|
+
toolbarTopPosition?: 'start' | 'center' | 'end' | 'cursor';
|
|
230
266
|
contextMenu?: ContextMenuItem<T>[];
|
|
267
|
+
contextMenuXOffset?: number;
|
|
268
|
+
contextMenuYOffset?: number;
|
|
231
269
|
oncontextmenuopen?: (context: ContextMenuContext<T>) => void;
|
|
270
|
+
rowShortcuts?: RowShortcut<T>[];
|
|
271
|
+
showShortcutsHelp?: boolean;
|
|
272
|
+
shortcutsHelpPosition?: 'top-right' | 'top-left';
|
|
273
|
+
shortcutsHelpContentCallback?: () => string;
|
|
232
274
|
virtualScroll?: boolean;
|
|
233
275
|
virtualScrollThreshold?: number;
|
|
234
276
|
virtualScrollRowHeight?: number;
|
|
@@ -314,6 +356,20 @@ export type PaginationLabelsContext = {
|
|
|
314
356
|
pageSize: number;
|
|
315
357
|
};
|
|
316
358
|
export type PaginationLabelsCallback = (context: PaginationLabelsContext) => Partial<PaginationLabels>;
|
|
359
|
+
export type GridLabels = {
|
|
360
|
+
rowActions: string;
|
|
361
|
+
inlineActionsHeader: string;
|
|
362
|
+
keyboardShortcuts: string;
|
|
363
|
+
paginationFirst: string;
|
|
364
|
+
paginationPrevious: string;
|
|
365
|
+
paginationNext: string;
|
|
366
|
+
paginationLast: string;
|
|
367
|
+
paginationPageInfo: string;
|
|
368
|
+
paginationItemCount: string;
|
|
369
|
+
paginationPerPage: string;
|
|
370
|
+
dropdownNoOptions: string;
|
|
371
|
+
dropdownSearching: string;
|
|
372
|
+
};
|
|
317
373
|
export type SummaryContext<T> = {
|
|
318
374
|
items: T[];
|
|
319
375
|
allItems: T[];
|
|
@@ -323,3 +379,27 @@ export type SummaryContext<T> = {
|
|
|
323
379
|
metadata: unknown;
|
|
324
380
|
};
|
|
325
381
|
export type SummaryContentCallback<T> = (context: SummaryContext<T>) => string;
|
|
382
|
+
export type RowLockInfo = {
|
|
383
|
+
isLocked: boolean;
|
|
384
|
+
lockedBy?: string;
|
|
385
|
+
lockedAt?: Date | string;
|
|
386
|
+
reason?: string;
|
|
387
|
+
[key: string]: unknown;
|
|
388
|
+
};
|
|
389
|
+
export type LockedRowEditBehavior = 'block' | 'allow' | 'callback';
|
|
390
|
+
export type RowLockingOptions<T> = {
|
|
391
|
+
lockedMember?: keyof T;
|
|
392
|
+
lockInfoMember?: keyof T;
|
|
393
|
+
isLockedCallback?: (row: T, rowIndex: number) => boolean;
|
|
394
|
+
getLockInfoCallback?: (row: T, rowIndex: number) => RowLockInfo | null;
|
|
395
|
+
lockedEditBehavior?: LockedRowEditBehavior;
|
|
396
|
+
canEditLockedCallback?: (row: T, lockInfo: RowLockInfo) => boolean;
|
|
397
|
+
lockTooltipCallback?: (lockInfo: RowLockInfo, row: T) => string | null;
|
|
398
|
+
};
|
|
399
|
+
export type RowLockChangeDetail<T> = {
|
|
400
|
+
rowId: unknown;
|
|
401
|
+
row: T | null;
|
|
402
|
+
rowIndex: number;
|
|
403
|
+
lockInfo: RowLockInfo | null;
|
|
404
|
+
source: 'property' | 'callback' | 'external';
|
|
405
|
+
};
|
package/dist/web-component.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { WebGrid } from './grid.js';
|
|
2
|
-
import type { Column, CellValidationState, RowToolbarConfig, ContextMenuItem, RowChangeDetail, ToolbarClickDetail, RowActionClickDetail, ContextMenuContext, EditTrigger, EditStartSelection, EditorOption, EditorOptions, GridMode, ToggleVisibility, DataRequestDetail, SortState, SortMode, PaginationLabelsCallback, SummaryContentCallback, ValidationTooltipContext } from './types.js';
|
|
2
|
+
import type { Column, CellValidationState, RowToolbarConfig, ContextMenuItem, RowShortcut, RowChangeDetail, ToolbarClickDetail, RowActionClickDetail, ContextMenuContext, EditTrigger, EditStartSelection, EditorOption, EditorOptions, GridMode, ToggleVisibility, DataRequestDetail, SortState, SortMode, PaginationLabelsCallback, SummaryContentCallback, ValidationTooltipContext, ToolbarPosition, GridLabels, RowLockInfo, RowLockingOptions, RowLockChangeDetail } from './types.js';
|
|
3
3
|
import type { GridContext } from './modules/types.js';
|
|
4
4
|
/**
|
|
5
5
|
* GridElement - Custom HTML Element for WebGrid
|
|
@@ -31,6 +31,8 @@ export declare class GridElement<T = unknown> extends HTMLElement implements Gri
|
|
|
31
31
|
private toolbarMoveInProgress;
|
|
32
32
|
private toolbarHideTimeout;
|
|
33
33
|
private toolbarHovered;
|
|
34
|
+
private toolbarShortcutHandler;
|
|
35
|
+
private inlineShortcutHandler;
|
|
34
36
|
dropdownOpen: boolean;
|
|
35
37
|
dropdownOptions: EditorOption[];
|
|
36
38
|
highlightedIndex: number;
|
|
@@ -38,6 +40,7 @@ export declare class GridElement<T = unknown> extends HTMLElement implements Gri
|
|
|
38
40
|
isUserFiltering: boolean;
|
|
39
41
|
justSelected: boolean;
|
|
40
42
|
isOpeningDropdown: boolean;
|
|
43
|
+
private isProgrammaticScroll;
|
|
41
44
|
searchDebounceTimer: ReturnType<typeof setTimeout> | null;
|
|
42
45
|
searchAbortController: AbortController | null;
|
|
43
46
|
isSearching: boolean;
|
|
@@ -65,8 +68,6 @@ export declare class GridElement<T = unknown> extends HTMLElement implements Gri
|
|
|
65
68
|
set items(value: T[]);
|
|
66
69
|
get columns(): Column<T>[];
|
|
67
70
|
set columns(value: Column<T>[]);
|
|
68
|
-
get sortable(): boolean;
|
|
69
|
-
set sortable(value: boolean);
|
|
70
71
|
get filterable(): boolean;
|
|
71
72
|
set filterable(value: boolean);
|
|
72
73
|
get pageable(): boolean;
|
|
@@ -103,16 +104,34 @@ export declare class GridElement<T = unknown> extends HTMLElement implements Gri
|
|
|
103
104
|
set showRowToolbar(value: boolean);
|
|
104
105
|
get rowToolbar(): RowToolbarConfig<T>[];
|
|
105
106
|
set rowToolbar(value: RowToolbarConfig<T>[]);
|
|
106
|
-
get
|
|
107
|
-
set
|
|
107
|
+
get toolbarVerticalAlign(): 'top' | 'center' | 'bottom';
|
|
108
|
+
set toolbarVerticalAlign(value: 'top' | 'center' | 'bottom');
|
|
109
|
+
get toolbarHorizontalAlign(): 'start' | 'center' | 'end' | 'cursor';
|
|
110
|
+
set toolbarHorizontalAlign(value: 'start' | 'center' | 'end' | 'cursor');
|
|
111
|
+
get toolbarAlign(): 'top' | 'center' | 'bottom';
|
|
112
|
+
set toolbarAlign(value: 'top' | 'center' | 'bottom');
|
|
108
113
|
get toolbarTopPosition(): 'start' | 'center' | 'end' | 'cursor';
|
|
109
114
|
set toolbarTopPosition(value: 'start' | 'center' | 'end' | 'cursor');
|
|
110
115
|
get toolbarTrigger(): 'hover' | 'click' | 'button';
|
|
111
116
|
set toolbarTrigger(value: 'hover' | 'click' | 'button');
|
|
112
|
-
get toolbarPosition():
|
|
113
|
-
set toolbarPosition(value:
|
|
117
|
+
get toolbarPosition(): ToolbarPosition;
|
|
118
|
+
set toolbarPosition(value: ToolbarPosition);
|
|
119
|
+
get inlineActionsTitle(): string;
|
|
120
|
+
set inlineActionsTitle(value: string);
|
|
114
121
|
get contextMenu(): ContextMenuItem<T>[] | undefined;
|
|
115
122
|
set contextMenu(value: ContextMenuItem<T>[] | undefined);
|
|
123
|
+
get contextMenuXOffset(): number;
|
|
124
|
+
set contextMenuXOffset(value: number);
|
|
125
|
+
get contextMenuYOffset(): number;
|
|
126
|
+
set contextMenuYOffset(value: number);
|
|
127
|
+
get rowShortcuts(): RowShortcut<T>[] | undefined;
|
|
128
|
+
set rowShortcuts(value: RowShortcut<T>[] | undefined);
|
|
129
|
+
get showShortcutsHelp(): boolean;
|
|
130
|
+
set showShortcutsHelp(value: boolean);
|
|
131
|
+
get shortcutsHelpPosition(): 'top-right' | 'top-left';
|
|
132
|
+
set shortcutsHelpPosition(value: 'top-right' | 'top-left');
|
|
133
|
+
get shortcutsHelpContentCallback(): (() => string) | undefined;
|
|
134
|
+
set shortcutsHelpContentCallback(value: (() => string) | undefined);
|
|
116
135
|
get showRowActions(): boolean;
|
|
117
136
|
set showRowActions(value: boolean);
|
|
118
137
|
get rowActions(): RowToolbarConfig<T>[];
|
|
@@ -173,10 +192,20 @@ export declare class GridElement<T = unknown> extends HTMLElement implements Gri
|
|
|
173
192
|
set customStylesCallback(value: (() => string) | undefined);
|
|
174
193
|
get rowClassCallback(): ((row: T, rowIndex: number) => string | null) | undefined;
|
|
175
194
|
set rowClassCallback(value: ((row: T, rowIndex: number) => string | null) | undefined);
|
|
195
|
+
get labels(): GridLabels;
|
|
196
|
+
set labels(value: Partial<GridLabels>);
|
|
176
197
|
get summaryMetadata(): unknown;
|
|
177
198
|
set summaryMetadata(value: unknown);
|
|
178
199
|
get summaryInline(): boolean;
|
|
179
200
|
set summaryInline(value: boolean);
|
|
201
|
+
get idValueMember(): keyof T | undefined;
|
|
202
|
+
set idValueMember(value: keyof T | undefined);
|
|
203
|
+
get idValueCallback(): ((row: T) => unknown) | undefined;
|
|
204
|
+
set idValueCallback(value: ((row: T) => unknown) | undefined);
|
|
205
|
+
get rowLocking(): RowLockingOptions<T> | undefined;
|
|
206
|
+
set rowLocking(value: RowLockingOptions<T> | undefined);
|
|
207
|
+
get onrowlockchange(): ((detail: RowLockChangeDetail<T>) => void) | undefined;
|
|
208
|
+
set onrowlockchange(value: ((detail: RowLockChangeDetail<T>) => void) | undefined);
|
|
180
209
|
get virtualScroll(): boolean;
|
|
181
210
|
set virtualScroll(value: boolean);
|
|
182
211
|
get virtualScrollThreshold(): number;
|
|
@@ -201,6 +230,30 @@ export declare class GridElement<T = unknown> extends HTMLElement implements Gri
|
|
|
201
230
|
discardAllDrafts(): void;
|
|
202
231
|
isCellInvalid(rowIndex: number, field: string): boolean;
|
|
203
232
|
getCellValidationError(rowIndex: number, field: string): string | null;
|
|
233
|
+
getRowId(row: T): unknown | undefined;
|
|
234
|
+
findRowById(id: unknown): {
|
|
235
|
+
row: T;
|
|
236
|
+
index: number;
|
|
237
|
+
} | null;
|
|
238
|
+
isRowLocked(rowOrId: T | unknown): boolean;
|
|
239
|
+
getRowLockInfo(rowOrId: T | unknown): RowLockInfo | null;
|
|
240
|
+
lockRowById(id: unknown, lockerInfo?: Partial<RowLockInfo>): boolean;
|
|
241
|
+
unlockRowById(id: unknown): boolean;
|
|
242
|
+
getExternalLocks(): Map<unknown, RowLockInfo>;
|
|
243
|
+
clearExternalLocks(): void;
|
|
244
|
+
updateRowById(id: unknown, newData: Partial<T>): boolean;
|
|
245
|
+
replaceRowById(id: unknown, newRow: T): boolean;
|
|
246
|
+
canEditCell(rowIndex: number, field: string): boolean;
|
|
247
|
+
/**
|
|
248
|
+
* Programmatically focus a cell. Updates state and focuses the DOM element.
|
|
249
|
+
* State is updated immediately so pending renders use the correct position.
|
|
250
|
+
*/
|
|
251
|
+
focusCell(rowIndex: number, colIndex: number): void;
|
|
252
|
+
/**
|
|
253
|
+
* Programmatically start editing a cell.
|
|
254
|
+
* Uses surgical DOM update instead of full re-render.
|
|
255
|
+
*/
|
|
256
|
+
startEditing(rowIndex: number, colIndex: number): void;
|
|
204
257
|
escapeHtml(text: string): string;
|
|
205
258
|
getCurrentEditingColumn(): Column<T> | null;
|
|
206
259
|
getCurrentEditorOptions(): EditorOptions;
|
|
@@ -219,6 +272,12 @@ export declare class GridElement<T = unknown> extends HTMLElement implements Gri
|
|
|
219
272
|
*/
|
|
220
273
|
private handleEditorKeyDown;
|
|
221
274
|
private attachEventListeners;
|
|
275
|
+
/**
|
|
276
|
+
* Scroll to a row position programmatically (keyboard navigation).
|
|
277
|
+
* Pre-renders the target row range ONCE, then scrolls. Flag prevents
|
|
278
|
+
* the scroll event from redundantly calling handleVirtualScroll.
|
|
279
|
+
*/
|
|
280
|
+
private scrollToRowProgrammatically;
|
|
222
281
|
/**
|
|
223
282
|
* Handle virtual scroll - recalculate visible range and re-render if changed
|
|
224
283
|
*/
|
|
@@ -232,6 +291,10 @@ export declare class GridElement<T = unknown> extends HTMLElement implements Gri
|
|
|
232
291
|
* Handle infinite scroll - trigger load more when near bottom
|
|
233
292
|
*/
|
|
234
293
|
private handleInfiniteScroll;
|
|
294
|
+
/**
|
|
295
|
+
* Render the shortcuts help icon and overlay
|
|
296
|
+
*/
|
|
297
|
+
private renderShortcutsHelpIcon;
|
|
235
298
|
private render;
|
|
236
299
|
/**
|
|
237
300
|
* Render the SVG connector arrow for toolbar row tracking
|
|
@@ -265,6 +328,25 @@ export declare class GridElement<T = unknown> extends HTMLElement implements Gri
|
|
|
265
328
|
* Handle context menu (right-click) on cells
|
|
266
329
|
*/
|
|
267
330
|
private handleContextMenu;
|
|
331
|
+
/**
|
|
332
|
+
* Setup document-level keyboard shortcut listener for toolbar row
|
|
333
|
+
* Allows shortcuts to work on hovered row without cell focus
|
|
334
|
+
*/
|
|
335
|
+
private setupToolbarShortcuts;
|
|
336
|
+
/**
|
|
337
|
+
* Setup keyboard shortcuts for inline toolbar mode
|
|
338
|
+
* Uses hoveredRowIndex to determine which row to act on
|
|
339
|
+
*/
|
|
340
|
+
private setupInlineShortcuts;
|
|
341
|
+
/**
|
|
342
|
+
* Remove inline shortcuts listener
|
|
343
|
+
*/
|
|
344
|
+
private removeInlineShortcuts;
|
|
345
|
+
/**
|
|
346
|
+
* Setup rich tooltips for toolbar buttons
|
|
347
|
+
* Shows title, description, and keyboard shortcut on hover
|
|
348
|
+
*/
|
|
349
|
+
private setupToolbarTooltips;
|
|
268
350
|
/**
|
|
269
351
|
* Show toolbar for a specific row
|
|
270
352
|
*/
|
|
@@ -277,6 +359,10 @@ export declare class GridElement<T = unknown> extends HTMLElement implements Gri
|
|
|
277
359
|
* Handle toolbar item click
|
|
278
360
|
*/
|
|
279
361
|
private handleToolbarItemClick;
|
|
362
|
+
/**
|
|
363
|
+
* Handle inline action button click (toolbarPosition="inline")
|
|
364
|
+
*/
|
|
365
|
+
private handleInlineActionClick;
|
|
280
366
|
/**
|
|
281
367
|
* Handle paste event in navigate mode
|
|
282
368
|
*/
|