@keenmate/web-grid 1.0.1 → 1.0.4
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/README.md +40 -2
- package/ai/basic-setup.txt +1 -0
- package/ai/callbacks-events.txt +2 -1
- package/ai/columns.txt +1 -1
- package/ai/editing.txt +21 -0
- package/ai/public-methods.txt +6 -0
- package/ai/selection.txt +4 -2
- package/ai/styling-theming.txt +3 -0
- package/ai/toolbar-actions.txt +2 -0
- package/ai/typescript-types.txt +1 -1
- package/dist/grid.d.ts +11 -0
- package/dist/logger.d.ts +54 -0
- package/dist/modules/actions/adapter.d.ts +4 -0
- package/dist/types.d.ts +1 -0
- package/dist/web-component.d.ts +6 -0
- package/dist/web-grid.js +1789 -1453
- package/dist/web-grid.umd.js +72 -72
- package/package.json +1 -1
- package/src/css/_cell-selection.css +4 -4
- package/src/css/_cells.css +1 -1
- package/src/css/_dark-mode.css +5 -0
- package/src/css/_dirty-indicator.css +37 -0
- package/src/css/_fill-handle.css +2 -2
- package/src/css/_freeze.css +4 -3
- package/src/css/_header.css +1 -1
- package/src/css/_reorder.css +2 -2
- package/src/css/_resize.css +1 -1
- package/src/css/_shortcuts.css +1 -1
- package/src/css/_table.css +2 -2
- package/src/css/_variables.css +25 -3
- package/src/css/main.css +9 -8
package/README.md
CHANGED
|
@@ -2,6 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
A feature-rich, framework-agnostic data grid web component built with TypeScript. Sorting, filtering, pagination, inline editing (8 editor types), cell range selection, clipboard support, row toolbar, context menus, frozen columns, column reorder/resize, fill handle, virtual scroll, dark mode, and full CSS variable theming — all in a Shadow DOM encapsulated `<web-grid>` element.
|
|
4
4
|
|
|
5
|
+
## What's New in v1.0.4
|
|
6
|
+
|
|
7
|
+
- **Dirty cell/row indicator**: New `isDirtyIndicatorVisible` property (default: `true`). Edited cells show a subtle orange tint + corner triangle; row numbers get an orange left border. Themable via `--wg-dirty-*` variables. Public methods: `isCellDirty()`, `isRowDirty()`.
|
|
8
|
+
- **Dropdown positioning fix**: Fixed dropdown editors appearing offset in shadow DOM by switching from `position: fixed` to `position: absolute`.
|
|
9
|
+
|
|
10
|
+
### v1.0.3
|
|
11
|
+
|
|
12
|
+
- **`onrowfocus` fixes**: No longer fires during cell range selection (drag/shift+click). Mouse-triggered row focus now defers to click (mouseup) instead of mousedown; keyboard navigation still fires immediately.
|
|
13
|
+
- **Cell selection visual fix**: Focused cell outline no longer persists during cell range drag.
|
|
14
|
+
- **Toolbar fixes**: Tooltip hides when toolbar moves/closes. Selections cleared on toolbar action click. `triggerElement` in `ontoolbarclick` detail stays alive (no longer detached by synchronous re-render).
|
|
15
|
+
- **Z-index layer system**: All z-index values now use CSS custom properties (`--wg-z-header`, `--wg-z-frozen`, etc.). Fixes cell selection bleeding through sticky header and frozen header stacking.
|
|
16
|
+
|
|
17
|
+
### v1.0.2
|
|
18
|
+
|
|
19
|
+
- **Tooltip positioning in transformed containers**: Fixed tooltips appearing at grid's top-left when ancestor has CSS `transform`. Switched to `position: absolute` with `:host` as positioning context.
|
|
20
|
+
- **HTML tooltips**: New `isTooltipHtml` column option for rich tooltip content.
|
|
21
|
+
- **`ontoolbarclick` detail**: Now includes `event` (MouseEvent) and `triggerElement` (HTMLElement) for anchoring popovers to toolbar buttons inside shadow DOM.
|
|
22
|
+
- **Tooltip show delay**: Reduced default from 400ms to 200ms.
|
|
23
|
+
|
|
5
24
|
## Installation
|
|
6
25
|
|
|
7
26
|
```bash
|
|
@@ -251,7 +270,7 @@ This architecture separates mode detection (the adapter decides *what* action a
|
|
|
251
270
|
|
|
252
271
|
| Property | Type | Default | Description |
|
|
253
272
|
|----------|------|---------|-------------|
|
|
254
|
-
| `tooltipShowDelay` | `number` | `
|
|
273
|
+
| `tooltipShowDelay` | `number` | `200` | Delay in ms before showing tooltip |
|
|
255
274
|
| `tooltipHideDelay` | `number` | `100` | Delay in ms before hiding tooltip |
|
|
256
275
|
|
|
257
276
|
### Summary
|
|
@@ -613,7 +632,7 @@ These are **callback properties** set on the grid element, not DOM events. Use t
|
|
|
613
632
|
| `onroweditstart` | `(detail: { row, rowIndex, field }) => void` | Editing started on a cell |
|
|
614
633
|
| `onroweditcancel` | `(detail: { row, rowIndex, field }) => void` | Edit was cancelled (Escape) |
|
|
615
634
|
| `onvalidationerror` | `(detail: { row, rowIndex, field, error }) => void` | Validation failed on commit |
|
|
616
|
-
| `ontoolbarclick` | `(detail: ToolbarClickDetail<T>) => void` | Toolbar button clicked. Detail: `{ item, rowIndex, row }` |
|
|
635
|
+
| `ontoolbarclick` | `(detail: ToolbarClickDetail<T>) => void` | Toolbar button clicked. Detail: `{ item, rowIndex, row, event, triggerElement }` |
|
|
617
636
|
| `onrowaction` | `(detail: { action, rowIndex, row }) => void` | *Legacy* — use `ontoolbarclick` |
|
|
618
637
|
| `oncontextmenuopen` | `(context: ContextMenuContext<T>) => void` | Cell context menu opened |
|
|
619
638
|
| `onheadercontextmenuopen` | `(context: HeaderMenuContext<T>) => void` | Header context menu opened |
|
|
@@ -842,6 +861,25 @@ grid.labels = {
|
|
|
842
861
|
}
|
|
843
862
|
```
|
|
844
863
|
|
|
864
|
+
## Runtime API
|
|
865
|
+
|
|
866
|
+
The component registers itself at `window.components['web-grid']` for runtime introspection:
|
|
867
|
+
|
|
868
|
+
```javascript
|
|
869
|
+
// Check version
|
|
870
|
+
window.components['web-grid'].version() // "1.0.3"
|
|
871
|
+
|
|
872
|
+
// Package info
|
|
873
|
+
window.components['web-grid'].config // { name, version, author, license, repository, homepage }
|
|
874
|
+
|
|
875
|
+
// Logging (silent by default)
|
|
876
|
+
window.components['web-grid'].logging.enableLogging() // Enable all at debug level
|
|
877
|
+
window.components['web-grid'].logging.setLogLevel('info') // Set level: trace|debug|info|warn|error|silent
|
|
878
|
+
window.components['web-grid'].logging.disableLogging() // Back to silent
|
|
879
|
+
window.components['web-grid'].logging.setCategoryLevel('GRID:UI', 'debug') // Per-category
|
|
880
|
+
window.components['web-grid'].logging.getCategories() // ['GRID:INIT', 'GRID:DATA', 'GRID:UI', 'GRID:INTERACTION']
|
|
881
|
+
```
|
|
882
|
+
|
|
845
883
|
## Browser Support
|
|
846
884
|
|
|
847
885
|
- Chrome/Edge 88+
|
package/ai/basic-setup.txt
CHANGED
|
@@ -89,6 +89,7 @@ page-size pageSize number 10 Rows per pa
|
|
|
89
89
|
is-editable isEditable boolean false Enable cell editing
|
|
90
90
|
edit-trigger editTrigger string 'dblclick' How editing starts (see below)
|
|
91
91
|
is-row-numbers-visible isRowNumbersVisible boolean false Show row number column
|
|
92
|
+
isDirtyIndicatorVisible boolean true Show dirty indicator on edited cells
|
|
92
93
|
mode mode string (none) Grid mode (see below)
|
|
93
94
|
is-scrollable isScrollable boolean false Enable scroll container
|
|
94
95
|
freeze-columns freezeColumns number 0 Freeze first N columns
|
package/ai/callbacks-events.txt
CHANGED
|
@@ -39,7 +39,8 @@ onvalidationerror
|
|
|
39
39
|
ontoolbarclick
|
|
40
40
|
Signature: (detail: ToolbarClickDetail<T>) => void
|
|
41
41
|
Fires when a toolbar button is clicked.
|
|
42
|
-
Detail: { item: NormalizedToolbarItem<T>, rowIndex: number, row: T }
|
|
42
|
+
Detail: { item: NormalizedToolbarItem<T>, rowIndex: number, row: T, event: MouseEvent, triggerElement: HTMLElement }
|
|
43
|
+
The triggerElement is the clicked button inside the shadow DOM — usable as a Floating UI anchor for popovers.
|
|
43
44
|
|
|
44
45
|
onrowaction
|
|
45
46
|
Signature: (detail: { action: string, rowIndex: number, row: T }) => void
|
package/ai/columns.txt
CHANGED
|
@@ -301,7 +301,7 @@ tooltipCallback ((value: unknown, row: T) => string | null)
|
|
|
301
301
|
row.description ? row.description : null
|
|
302
302
|
|
|
303
303
|
Tooltip show/hide delays are controlled by grid-level properties:
|
|
304
|
-
tooltipShowDelay (default:
|
|
304
|
+
tooltipShowDelay (default: 200ms)
|
|
305
305
|
tooltipHideDelay (default: 100ms)
|
|
306
306
|
|
|
307
307
|
|
package/ai/editing.txt
CHANGED
|
@@ -427,6 +427,27 @@ Draft behavior:
|
|
|
427
427
|
- The onrowchange callback includes both row (original) and draftRow (with
|
|
428
428
|
changes) so the consumer can compare.
|
|
429
429
|
|
|
430
|
+
Dirty indicator:
|
|
431
|
+
grid.isDirtyIndicatorVisible (boolean, default: true)
|
|
432
|
+
When enabled, edited cells show a subtle orange background tint and a small
|
|
433
|
+
corner triangle. Row numbers show an orange left border when any cell in
|
|
434
|
+
the row has been modified.
|
|
435
|
+
|
|
436
|
+
grid.isCellDirty(rowIndex, field) -- Returns true if the cell's draft value
|
|
437
|
+
differs from the original.
|
|
438
|
+
grid.isRowDirty(rowIndex) -- Returns true if any cell in the row
|
|
439
|
+
has been modified (draft exists).
|
|
440
|
+
|
|
441
|
+
CSS variables for theming:
|
|
442
|
+
--wg-dirty-indicator-color (default: #ed8b00)
|
|
443
|
+
--wg-dirty-indicator-size (default: 6px)
|
|
444
|
+
--wg-dirty-cell-bg (default: rgba(237, 139, 0, 0.08))
|
|
445
|
+
--wg-dirty-row-number-border-color (default: #ed8b00)
|
|
446
|
+
|
|
447
|
+
CSS classes applied:
|
|
448
|
+
.wg__cell--dirty -- on dirty data cells
|
|
449
|
+
.wg__row-number--dirty -- on row number cells of dirty rows
|
|
450
|
+
|
|
430
451
|
|
|
431
452
|
EVENTS (CALLBACKS)
|
|
432
453
|
------------------
|
package/ai/public-methods.txt
CHANGED
|
@@ -53,6 +53,12 @@ discardAllDrafts(): void
|
|
|
53
53
|
Discard all draft changes across all rows. Reverts every edited cell
|
|
54
54
|
to its original value.
|
|
55
55
|
|
|
56
|
+
isCellDirty(rowIndex: number, field: string): boolean
|
|
57
|
+
Check if a specific cell has been modified (draft value differs from original).
|
|
58
|
+
|
|
59
|
+
isRowDirty(rowIndex: number): boolean
|
|
60
|
+
Check if any cell in a row has been modified (draft exists for that row).
|
|
61
|
+
|
|
56
62
|
|
|
57
63
|
----------------------------------------------------------------------
|
|
58
64
|
VALIDATION
|
package/ai/selection.txt
CHANGED
|
@@ -222,8 +222,10 @@ Master/detail pattern:
|
|
|
222
222
|
}
|
|
223
223
|
|
|
224
224
|
Behavior:
|
|
225
|
-
- Click on data cell ->
|
|
226
|
-
-
|
|
225
|
+
- Click on data cell -> fires onrowfocus on mouseup (click), NOT on mousedown
|
|
226
|
+
- Keyboard navigation (Tab, arrows) -> fires onrowfocus immediately on focus
|
|
227
|
+
- Click on row number -> selects row but does NOT change focus or fire onrowfocus
|
|
228
|
+
- Cell range selection (drag/shift+click) -> does NOT fire onrowfocus
|
|
227
229
|
- Click outside grid -> clears focus (focusedRowIndex becomes null)
|
|
228
230
|
- Starting cell range drag -> clears focus
|
|
229
231
|
- Programmatic: grid.focusedRowIndex = 3 (focuses row 3, fires onrowfocus)
|
package/ai/styling-theming.txt
CHANGED
|
@@ -115,6 +115,9 @@ All four methods apply the same dark palette overrides:
|
|
|
115
115
|
--wg-hover-bg: #3a3a3a
|
|
116
116
|
--wg-danger-color: #f87c86
|
|
117
117
|
--wg-danger-bg-light: #442726
|
|
118
|
+
--wg-dirty-indicator-color: #ffa940
|
|
119
|
+
--wg-dirty-cell-bg: rgba(255, 169, 64, 0.12)
|
|
120
|
+
--wg-dirty-row-number-border-color: #ffa940
|
|
118
121
|
|
|
119
122
|
The attribute can be on the <web-grid> element itself or any ancestor:
|
|
120
123
|
|
package/ai/toolbar-actions.txt
CHANGED
|
@@ -383,6 +383,8 @@ ontoolbarclick:
|
|
|
383
383
|
item: NormalizedToolbarItem<T>
|
|
384
384
|
rowIndex: number
|
|
385
385
|
row: T
|
|
386
|
+
event: MouseEvent // Original click event
|
|
387
|
+
triggerElement: HTMLElement // The clicked button element (usable as Floating UI anchor)
|
|
386
388
|
}
|
|
387
389
|
|
|
388
390
|
This fires AFTER the item's own onclick handler. For predefined
|
package/ai/typescript-types.txt
CHANGED
|
@@ -477,7 +477,7 @@ ADDITIONAL EXPORTED TYPES
|
|
|
477
477
|
type ColumnOrderState = { field: string, order: number }
|
|
478
478
|
type ColumnResizeDetail = { field: string, oldWidth: string, newWidth: string, allWidths: ColumnWidthState[] }
|
|
479
479
|
type ColumnReorderDetail = { field: string, fromIndex: number, toIndex: number, allOrder: ColumnOrderState[] }
|
|
480
|
-
type ToolbarClickDetail<T> = { item: NormalizedToolbarItem<T>, rowIndex: number, row: T }
|
|
480
|
+
type ToolbarClickDetail<T> = { item: NormalizedToolbarItem<T>, rowIndex: number, row: T, event: MouseEvent, triggerElement: HTMLElement }
|
|
481
481
|
type ToolbarTooltip = { description?: string, shortcut?: string }
|
|
482
482
|
type SummaryContext<T> = { items: T[], allItems: T[], totalItems: number, currentPage: number, pageSize: number, metadata: unknown }
|
|
483
483
|
type SummaryContentCallback<T> = (context: SummaryContext<T>) => string
|
package/dist/grid.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ export declare class WebGrid<T = unknown> {
|
|
|
28
28
|
protected _isStickyRowNumbers: boolean;
|
|
29
29
|
protected _freezeColumns: number;
|
|
30
30
|
protected _invalidCells: CellValidationState[];
|
|
31
|
+
protected _isDirtyIndicatorVisible: boolean;
|
|
31
32
|
protected _isRowToolbarVisible: boolean;
|
|
32
33
|
protected _rowToolbar: RowToolbarConfig<T>[];
|
|
33
34
|
protected _toolbarVerticalAlign: 'top' | 'center' | 'bottom';
|
|
@@ -200,6 +201,8 @@ export declare class WebGrid<T = unknown> {
|
|
|
200
201
|
set isCheckboxAlwaysEditable(value: boolean);
|
|
201
202
|
get isRowNumbersVisible(): boolean;
|
|
202
203
|
set isRowNumbersVisible(value: boolean);
|
|
204
|
+
get isDirtyIndicatorVisible(): boolean;
|
|
205
|
+
set isDirtyIndicatorVisible(value: boolean);
|
|
203
206
|
get isStickyRowNumbers(): boolean;
|
|
204
207
|
set isStickyRowNumbers(value: boolean);
|
|
205
208
|
get freezeColumns(): number;
|
|
@@ -544,6 +547,14 @@ export declare class WebGrid<T = unknown> {
|
|
|
544
547
|
protected requestUpdate(): void;
|
|
545
548
|
getRowDraft(rowIndex: number): T | undefined;
|
|
546
549
|
hasRowDraft(rowIndex: number): boolean;
|
|
550
|
+
/**
|
|
551
|
+
* Check if a specific cell has been modified (draft value differs from original)
|
|
552
|
+
*/
|
|
553
|
+
isCellDirty(rowIndex: number, field: string): boolean;
|
|
554
|
+
/**
|
|
555
|
+
* Check if any cell in a row has been modified
|
|
556
|
+
*/
|
|
557
|
+
isRowDirty(rowIndex: number): boolean;
|
|
547
558
|
discardRowDraft(rowIndex: number): void;
|
|
548
559
|
/**
|
|
549
560
|
* Discard draft value for a single cell (field)
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logging configuration using loglevel with categorized loggers
|
|
3
|
+
*
|
|
4
|
+
* Categories:
|
|
5
|
+
* - GRID:INIT: Component initialization and configuration
|
|
6
|
+
* - GRID:DATA: Data loading, sorting, filtering, pagination
|
|
7
|
+
* - GRID:UI: UI updates, rendering, scroll, resize operations
|
|
8
|
+
* - GRID:INTERACTION: User interactions, clicks, selections, keyboard events
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* - By default, all logging is disabled (silent mode) for production
|
|
12
|
+
* - Enable logging in browser console:
|
|
13
|
+
* ```javascript
|
|
14
|
+
* // Enable all logging at debug level
|
|
15
|
+
* window.components['web-grid'].logging.enableLogging();
|
|
16
|
+
*
|
|
17
|
+
* // Or set a specific log level for all categories
|
|
18
|
+
* window.components['web-grid'].logging.setLogLevel('info');
|
|
19
|
+
*
|
|
20
|
+
* // Or enable/disable specific categories
|
|
21
|
+
* window.components['web-grid'].logging.disableLogging(); // First disable all
|
|
22
|
+
* window.components['web-grid'].logging.setCategoryLevel('GRID:UI', 'debug');
|
|
23
|
+
* window.components['web-grid'].logging.setCategoryLevel('GRID:DATA', 'info');
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
import log from './vendor/loglevel/index.js';
|
|
27
|
+
export declare const initLogger: any;
|
|
28
|
+
export declare const dataLogger: any;
|
|
29
|
+
export declare const uiLogger: any;
|
|
30
|
+
export declare const interactionLogger: any;
|
|
31
|
+
export default log;
|
|
32
|
+
/**
|
|
33
|
+
* List of all logging categories for introspection
|
|
34
|
+
*/
|
|
35
|
+
export declare const LOGGING_CATEGORIES: string[];
|
|
36
|
+
/**
|
|
37
|
+
* Enable all logging (set to debug level)
|
|
38
|
+
*/
|
|
39
|
+
export declare function enableLogging(): void;
|
|
40
|
+
/**
|
|
41
|
+
* Disable all logging (set to silent level)
|
|
42
|
+
*/
|
|
43
|
+
export declare function disableLogging(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Set log level for all loggers
|
|
46
|
+
* @param level Log level to set ('trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent')
|
|
47
|
+
*/
|
|
48
|
+
export declare function setLogLevel(level: string): void;
|
|
49
|
+
/**
|
|
50
|
+
* Set log level for a specific category
|
|
51
|
+
* @param category Category logger to configure (e.g., 'GRID:UI')
|
|
52
|
+
* @param level Log level to set ('trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent')
|
|
53
|
+
*/
|
|
54
|
+
export declare function setCategoryLevel(category: string, level: string): void;
|
|
@@ -73,6 +73,10 @@ export declare class ActionPipelineAdapter<T = unknown> {
|
|
|
73
73
|
* Note: This checks the original context, not the Object.create'd executor context
|
|
74
74
|
*/
|
|
75
75
|
isDatepickerOpen(): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Clear all selections (row, cell range, column) through the pipeline
|
|
78
|
+
*/
|
|
79
|
+
clearSelection(): void;
|
|
76
80
|
}
|
|
77
81
|
/**
|
|
78
82
|
* Create an action pipeline adapter for a grid context
|
package/dist/types.d.ts
CHANGED
package/dist/web-component.d.ts
CHANGED
|
@@ -113,6 +113,10 @@ export declare class GridElement<T = unknown> extends HTMLElement implements Gri
|
|
|
113
113
|
set isCheckboxAlwaysEditable(value: boolean);
|
|
114
114
|
get isRowNumbersVisible(): boolean;
|
|
115
115
|
set isRowNumbersVisible(value: boolean);
|
|
116
|
+
get isDirtyIndicatorVisible(): boolean;
|
|
117
|
+
set isDirtyIndicatorVisible(value: boolean);
|
|
118
|
+
isCellDirty(rowIndex: number, field: string): boolean;
|
|
119
|
+
isRowDirty(rowIndex: number): boolean;
|
|
116
120
|
get isStickyRowNumbers(): boolean;
|
|
117
121
|
set isStickyRowNumbers(value: boolean);
|
|
118
122
|
get freezeColumns(): number;
|
|
@@ -367,6 +371,8 @@ export declare class GridElement<T = unknown> extends HTMLElement implements Gri
|
|
|
367
371
|
* Handle keydown in editor inputs
|
|
368
372
|
*/
|
|
369
373
|
private handleEditorKeyDown;
|
|
374
|
+
/** Tracks whether a mouse button is currently pressed on the table (mousedown→mouseup) */
|
|
375
|
+
private _isMouseDown;
|
|
370
376
|
private attachEventListeners;
|
|
371
377
|
/**
|
|
372
378
|
* Scroll to a row position programmatically (keyboard navigation).
|