@keenmate/web-grid 1.0.0 → 1.0.3

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 CHANGED
@@ -2,6 +2,22 @@
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.3
6
+
7
+ - **`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.
8
+ - **Cell selection visual fix**: Focused cell outline no longer persists during cell range drag.
9
+ - **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).
10
+ - **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.
11
+ - **Logging system**: loglevel-based logging with 4 categories (`GRID:INIT`, `GRID:DATA`, `GRID:UI`, `GRID:INTERACTION`). Enable via `window.components['web-grid'].logging.enableLogging()`.
12
+ - **Runtime API**: `window.components['web-grid']` with `version()`, `config`, and `logging` — matching web-multiselect and web-daterangepicker.
13
+
14
+ ### v1.0.2
15
+
16
+ - **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.
17
+ - **HTML tooltips**: New `isTooltipHtml` column option for rich tooltip content.
18
+ - **`ontoolbarclick` detail**: Now includes `event` (MouseEvent) and `triggerElement` (HTMLElement) for anchoring popovers to toolbar buttons inside shadow DOM.
19
+ - **Tooltip show delay**: Reduced default from 400ms to 200ms.
20
+
5
21
  ## Installation
6
22
 
7
23
  ```bash
@@ -251,7 +267,7 @@ This architecture separates mode detection (the adapter decides *what* action a
251
267
 
252
268
  | Property | Type | Default | Description |
253
269
  |----------|------|---------|-------------|
254
- | `tooltipShowDelay` | `number` | `400` | Delay in ms before showing tooltip |
270
+ | `tooltipShowDelay` | `number` | `200` | Delay in ms before showing tooltip |
255
271
  | `tooltipHideDelay` | `number` | `100` | Delay in ms before hiding tooltip |
256
272
 
257
273
  ### Summary
@@ -613,7 +629,7 @@ These are **callback properties** set on the grid element, not DOM events. Use t
613
629
  | `onroweditstart` | `(detail: { row, rowIndex, field }) => void` | Editing started on a cell |
614
630
  | `onroweditcancel` | `(detail: { row, rowIndex, field }) => void` | Edit was cancelled (Escape) |
615
631
  | `onvalidationerror` | `(detail: { row, rowIndex, field, error }) => void` | Validation failed on commit |
616
- | `ontoolbarclick` | `(detail: ToolbarClickDetail<T>) => void` | Toolbar button clicked. Detail: `{ item, rowIndex, row }` |
632
+ | `ontoolbarclick` | `(detail: ToolbarClickDetail<T>) => void` | Toolbar button clicked. Detail: `{ item, rowIndex, row, event, triggerElement }` |
617
633
  | `onrowaction` | `(detail: { action, rowIndex, row }) => void` | *Legacy* — use `ontoolbarclick` |
618
634
  | `oncontextmenuopen` | `(context: ContextMenuContext<T>) => void` | Cell context menu opened |
619
635
  | `onheadercontextmenuopen` | `(context: HeaderMenuContext<T>) => void` | Header context menu opened |
@@ -779,9 +795,18 @@ The manifest follows the [component-variables schema](https://raw.githubusercont
779
795
 
780
796
  Dark mode is triggered automatically by:
781
797
  - OS preference: `@media (prefers-color-scheme: dark)`
782
- - Attribute: `data-theme="dark"` on ancestor
783
- - Bootstrap: `data-bs-theme="dark"` on ancestor
784
- - Class: `.dark` on ancestor (Tailwind CSS)
798
+ - Attribute: `data-theme="dark"` on any ancestor or host element
799
+ - Bootstrap: `data-bs-theme="dark"` on any ancestor or host element
800
+ - Class: `.dark` on any ancestor (Tailwind CSS)
801
+
802
+ To **force light mode** when the OS is in dark mode, set one of:
803
+ - Attribute: `data-theme="light"` on any ancestor or host element
804
+ - Bootstrap: `data-bs-theme="light"` on any ancestor or host element
805
+ - Class: `.light` on any ancestor (Tailwind CSS)
806
+
807
+ This is useful when your app manages its own theme (e.g. via a toggle) and needs to override the OS preference. The light mode selectors restore the `--base-*` fallback chain so theme-designer values are respected.
808
+
809
+ Ancestor detection uses `:host-context()` to cross shadow DOM boundaries (Chrome 88+, Firefox 128+, Safari 15.4+).
785
810
 
786
811
  ### Dynamic Cell & Row Styling
787
812
 
@@ -833,6 +858,25 @@ grid.labels = {
833
858
  }
834
859
  ```
835
860
 
861
+ ## Runtime API
862
+
863
+ The component registers itself at `window.components['web-grid']` for runtime introspection:
864
+
865
+ ```javascript
866
+ // Check version
867
+ window.components['web-grid'].version() // "1.0.3"
868
+
869
+ // Package info
870
+ window.components['web-grid'].config // { name, version, author, license, repository, homepage }
871
+
872
+ // Logging (silent by default)
873
+ window.components['web-grid'].logging.enableLogging() // Enable all at debug level
874
+ window.components['web-grid'].logging.setLogLevel('info') // Set level: trace|debug|info|warn|error|silent
875
+ window.components['web-grid'].logging.disableLogging() // Back to silent
876
+ window.components['web-grid'].logging.setCategoryLevel('GRID:UI', 'debug') // Per-category
877
+ window.components['web-grid'].logging.getCategories() // ['GRID:INIT', 'GRID:DATA', 'GRID:UI', 'GRID:INTERACTION']
878
+ ```
879
+
836
880
  ## Browser Support
837
881
 
838
882
  - Chrome/Edge 88+
@@ -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: 400ms)
304
+ tooltipShowDelay (default: 200ms)
305
305
  tooltipHideDelay (default: 100ms)
306
306
 
307
307
 
package/ai/selection.txt CHANGED
@@ -222,8 +222,10 @@ Master/detail pattern:
222
222
  }
223
223
 
224
224
  Behavior:
225
- - Click on data cell -> sets focusedRowIndex, fires onrowfocus
226
- - Click on row number -> selects row but does NOT change focus
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)
@@ -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
@@ -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
@@ -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
@@ -33,7 +33,7 @@ export declare function renderToolbarHTML<T>(items: NormalizedToolbarItem<T>[],
33
33
  /**
34
34
  * Open toolbar for a specific row
35
35
  */
36
- export declare function openToolbar<T>(ctx: GridContext<T>, rowElement: HTMLElement, rowIndex: number, items: NormalizedToolbarItem<T>[], row: T, onItemClick: (item: NormalizedToolbarItem<T>) => void, cursorX?: number): void;
36
+ export declare function openToolbar<T>(ctx: GridContext<T>, rowElement: HTMLElement, rowIndex: number, items: NormalizedToolbarItem<T>[], row: T, onItemClick: (item: NormalizedToolbarItem<T>, event: MouseEvent, triggerElement: HTMLElement) => void, cursorX?: number): void;
37
37
  /**
38
38
  * Close the active toolbar
39
39
  */
package/dist/types.d.ts CHANGED
@@ -125,6 +125,7 @@ export type Column<T> = {
125
125
  isEditButtonVisible?: boolean;
126
126
  tooltipMember?: string;
127
127
  tooltipCallback?: (value: unknown, row: T) => string | null;
128
+ isTooltipHtml?: boolean;
128
129
  beforeCopyCallback?: (value: unknown, row: T) => string;
129
130
  beforePasteCallback?: (value: string, row: T) => unknown;
130
131
  validationTooltipCallback?: (context: ValidationTooltipContext<T>) => string | null;
@@ -196,6 +197,8 @@ export type ToolbarClickDetail<T> = {
196
197
  item: NormalizedToolbarItem<T>;
197
198
  rowIndex: number;
198
199
  row: T;
200
+ event: MouseEvent;
201
+ triggerElement: HTMLElement;
199
202
  };
200
203
  export type RowActionType = PredefinedToolbarItemType;
201
204
  export type RowActionClickDetail<T> = {
@@ -367,6 +367,8 @@ export declare class GridElement<T = unknown> extends HTMLElement implements Gri
367
367
  * Handle keydown in editor inputs
368
368
  */
369
369
  private handleEditorKeyDown;
370
+ /** Tracks whether a mouse button is currently pressed on the table (mousedown→mouseup) */
371
+ private _isMouseDown;
370
372
  private attachEventListeners;
371
373
  /**
372
374
  * Scroll to a row position programmatically (keyboard navigation).