@reforgium/data-grid 2.1.1 → 2.2.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/README.md CHANGED
@@ -18,7 +18,7 @@ Designed for **real-world datasets**, not demo tables.
18
18
  - Virtual row rendering (smooth, no jumps)
19
19
  - Infinity scroll (loads data when reaching the bottom)
20
20
  - Jitter-free fixed (sticky) columns
21
- - Two-line headers max, with ellipsis and tooltip
21
+ - Two-line text clamp (header + body) with ellipsis
22
22
  - Declarative column DSL (`<re-dg-column>`) *[NEW in 2.0.0]*
23
23
  - Column expanders (hidden columns via toggler)
24
24
  - Scrollable overlay scrollbar
@@ -61,12 +61,6 @@ export class SomeComponent {
61
61
  ```
62
62
  ---
63
63
 
64
- ## Migration notes (1.1.0 -> 2.0.0)
65
-
66
- - **Column tooltips are now explicit.** Use `tooltip` on a column (string / function / `TemplateRef`) to show a popover on hover.
67
- - **New column manager entrypoint.** Import it from `@reforgium/data-grid/column-manager` and wire `columns` + `columnsChange`.
68
- - **Sticky columns use sides.** Prefer `sticky="left"` / `sticky="right"`; legacy `true` still maps to left.
69
-
70
64
  ## Configuration
71
65
 
72
66
  ### Global defaults provider
@@ -115,8 +109,9 @@ Supported default fields:
115
109
  | headerGroups | `GridHeaderGroup<T>[]` | `[]` | Optional top header row groups (`from`..`to`) for 2-level headers | *[NEW in 2.0.0]* |
116
110
  | pinnedRows | `GridPinnedRow<T>[]` | `[]` | Top / bottom pinned rows | |
117
111
  | isRowSticky | `(row: T, index: number) => boolean` | `undefined` | Predicate that marks rows as sticky at the top | |
112
+ | isRowDisabled | `(row: T, index: number) => boolean` | `undefined` | Predicate that marks rows as disabled (no select/click/context/double-click interactions) | |
118
113
  | getRowTemplate | `(row: T, index: number) => TemplateRef \| null` | `undefined` | Optional resolver for custom row template | |
119
- | mode | `'none' \| 'pagination' \| 'infinity'` | `'pagination'` | Grid operation mode | |
114
+ | sortMode | 'single' \| 'multi' | 'single' | Sorting mode for header clicks | |
120
115
  | pageSize | `number` | `20` | Number of items per page (pagination/infinity modes) | |
121
116
  | pageStartFromZero | `boolean` | `true` | If true, page indexing starts from 0, otherwise from 1 | |
122
117
  | hasIndexColumn | `boolean` | `false` | If true, an index column will be shown | |
@@ -135,6 +130,13 @@ Supported default fields:
135
130
 
136
131
  When selection mode is `'single'` or `'multi'`, provide a `key` (data property) and optionally `defaultSelected`.
137
132
 
133
+ Feature lazy-loading behavior (runtime `import()`):
134
+
135
+ - Selection feature is loaded when `selection.mode !== 'none'`.
136
+ - Sticky feature is loaded when `isRowSticky` is provided.
137
+ - Tooltip feature is loaded when at least one column has `tooltip`.
138
+ - Overlay-scroll feature is loaded on first scroll lifecycle usage.
139
+
138
140
  Loading behavior:
139
141
 
140
142
  - `loadingMode="spinner"`: shows centered spinner over grid content.
@@ -179,7 +181,8 @@ Row templates:
179
181
  | rowClick | `GridRowClickEvent<T>` | Emitted when a row is clicked (includes native event) | *[UPD in 2.0.0]* |
180
182
  | rowContext | `GridRowContextEvent<T>` | Emitted on row context menu | *[NEW in 2.0.0]* |
181
183
  | rowDoubleClick | `GridRowDoubleClickEvent<T>` | Emitted when a row is double-clicked | *[NEW in 2.0.0]* |
182
- | sortChange | `GridSortEvent<T>` | Emitted when sort order changes | |
184
+ | sortChange | `GridSortEvent<T>` | Emitted when single-sort order changes | |
185
+ | multiSortChange | `GridMultiSortEvent<T>` | Emitted when multi-sort order changes | *[NEW in 2.2.0]* |
183
186
  | pageChange | `GridPageChangeEvent` | Emitted when requesting data for a new page | |
184
187
  | selectChange | `GridSelectEvent<T>` | Emitted when selected rows change | |
185
188
 
@@ -187,6 +190,16 @@ Notes:
187
190
 
188
191
  - A cell click also triggers the row click event (bubbling), so listen to one or stop propagation if needed.
189
192
 
193
+ ### Public API methods
194
+
195
+ `DataGrid` exposes imperative helpers via component instance (e.g. `@ViewChild(DataGrid)`):
196
+
197
+ - `clearSelection()` - clears current selection and emits `selectChange`
198
+ - `selectAllLoaded()` - selects currently loaded rows (multi mode) and emits `selectChange`
199
+ - `resetSort()` - resets sort state and emits sort events
200
+ - `setSort(event)` - applies single-sort state and emits sort events
201
+ - `setMultiSort(items)` - applies multi-sort state and emits sort events
202
+
190
203
  ### GridColumn<T> reference
191
204
 
192
205
  `columns` accepts `GridColumn<T>[]`, where `GridColumn<T>` is a union of three column variants:
@@ -197,15 +210,15 @@ Notes:
197
210
 
198
211
  Common (base) fields:
199
212
 
200
- | Field | Type | Description |
201
- |-------------------------|---------------------------------------------------------------------|---------------------------------------------------------------------------------|
202
- | `sortKey` | `string` | Alternative key used for sorting when display `key` differs from sortable data. |
203
- | `sticky` | `'left' \| 'right' \| true` | Keeps the column fixed while horizontally scrolling. `true` pins to the left. |
204
- | `expandBy` | `DataKey<T>` | Data key that controls expand/collapse behavior for the column. |
205
- | `flex` | `number` | Flex grow factor for width distribution in flexible layouts. |
206
- | `minWidth` / `maxWidth` | `number` | Column width limits in pixels. |
207
- | `cellClass` | `string \| ((row: T) => string)` | Static CSS class or resolver per row. |
208
- | `tooltip` | `string \| ((row: T) => string) \| TemplateRef<GridTooltipContext>` | Popover tooltip content shown on cell hover. |
213
+ | Field | Type | Description | |
214
+ |-------------------------|-----------------------------------------------------------------------------|----------------------------------------------------------------------------------------|------------------|
215
+ | `sortKey` | `string` | Alternative key used for sorting when display `key` differs from sortable data. | |
216
+ | `sticky` | `'left' \| 'right' \| true` | Keeps the column fixed while horizontally scrolling. `true` pins to the left. | |
217
+ | `expandBy` | `DataKey<T>` | Data key that controls expand/collapse behavior for the column. | |
218
+ | `flex` | `number` | Flex grow factor for width distribution in flexible layouts. | |
219
+ | `minWidth` / `maxWidth` | `number` | Column width limits in pixels. | |
220
+ | `cellClass` | `string \| ((row: T) => string)` | Static CSS class or resolver per row. | |
221
+ | `tooltip` | `true \| string \| ((row: T) => string) \| TemplateRef<GridTooltipContext>` | Popover tooltip content shown on cell hover. `true` uses the cell value automatically. | *[NEW in 2.2.0]* |
209
222
 
210
223
  Renderer-specific fields:
211
224
 
@@ -215,6 +228,11 @@ Renderer-specific fields:
215
228
  | Value renderer | `value: (row: T) => string \| number`, `track: (row: T) => string` | `track` is required for stable row identity and efficient updates. |
216
229
  | Template renderer | `renderTemplate: TemplateRef<...>`, `track: (row: T) => string` | `track` is required when rendering through Angular templates. |
217
230
 
231
+ Cell text wrapping/clamp behavior:
232
+
233
+ - Default header text and default body renderers (`plain`, `date`, `number`, `index`) are limited to 2 lines with ellipsis.
234
+ - Template-based renderers (`renderTemplate`, `reDataGridCell`, `reDataGridTypeCell`, etc.) are not clamped by default and are fully controlled by your template styles.
235
+
218
236
  ### Declarative columns *[NEW in 2.0.0]*
219
237
 
220
238
  You can define columns directly in markup via `<re-dg-column>`, then the grid will normalize them to `GridColumn<T>` internally.
@@ -254,6 +272,7 @@ Notes:
254
272
 
255
273
  ```ts
256
274
  columns = [
275
+ { key: 'name', header: 'Name', tooltip: true }, // auto tooltip from cell value
257
276
  { key: 'email', header: 'Email', tooltip: (row) => row.email },
258
277
  { key: 'status', header: 'Status', tooltip: 'User status' },
259
278
  ];
@@ -362,14 +381,14 @@ Scrollbar:
362
381
 
363
382
  Header:
364
383
 
365
- - `--re-data-grid-header-rounded` - header corner radius (`var(--re-data-grid-rounded)`)
366
- - `--re-data-grid-header-surface` - header area background (`#fff`)
367
- - `--re-data-grid-header-body-gap` - gap between header and body (`0px`)
368
- - `--re-data-grid-header-row-height` - main header row height (`40px`)
369
- - `--re-data-grid-header-row-separator-color` - main header separator color (`#ccc`)
370
- - `--re-data-grid-header-row-separator` - main header separator (`1px solid var(--re-data-grid-header-row-separator-color)`)
371
- - `--re-data-grid-header-group-row-height` - group header row height (`var(--re-data-grid-header-row-height)`)
372
- - `--re-data-grid-header-group-row-separator-color` - group header separator color (`var(--re-data-grid-header-row-separator-color)`)
384
+ - `--re-data-grid-header-rounded` - header corner radius (`var(--re-data-grid-rounded)`)
385
+ - `--re-data-grid-header-surface` - header area background (`#fff`)
386
+ - `--re-data-grid-header-body-gap` - gap between header and body (`0px`)
387
+ - `--re-data-grid-header-row-height` - main header row height (`40px`)
388
+ - `--re-data-grid-header-row-separator-color` - main header separator color (`#ccc`)
389
+ - `--re-data-grid-header-row-separator` - main header separator (`1px solid var(--re-data-grid-header-row-separator-color)`)
390
+ - `--re-data-grid-header-group-row-height` - group header row height (`var(--re-data-grid-header-row-height)`)
391
+ - `--re-data-grid-header-group-row-separator-color` - group header separator color (`var(--re-data-grid-header-row-separator-color)`)
373
392
  - `--re-data-grid-header-group-row-separator` - group header separator (`1px solid var(--re-data-grid-header-group-row-separator-color)`)
374
393
 
375
394
  Header Cells:
@@ -378,6 +397,8 @@ Header Cells:
378
397
  - `--re-data-grid-header-cell-font-size` - font size (`0.8rem`)
379
398
  - `--re-data-grid-header-cell-color` - text color (`#000`)
380
399
  - `--re-data-grid-header-cell-surface` - cell background (`#fafafa`)
400
+ - `--re-data-grid-header-cell-line-height` - header text line-height for clamp (`1.2`)
401
+ - `--re-data-grid-header-cell-max-lines` - header max text lines (`2`)
381
402
  - `--re-data-grid-header-group-cell-font-weight` - group font weight (`var(--re-data-grid-header-cell-font-weight)`)
382
403
  - `--re-data-grid-header-group-cell-font-size` - group font size (`var(--re-data-grid-header-cell-font-size)`)
383
404
  - `--re-data-grid-header-group-cell-color` - group text color (`var(--re-data-grid-header-cell-color)`)
@@ -391,12 +412,12 @@ Footer:
391
412
 
392
413
  Rows:
393
414
 
394
- - `--re-data-grid-row-separator-color` - row separator color (`#bbb`)
395
- - `--re-data-grid-row-separator` - separator line (`1px solid var(--re-data-grid-row-separator-color)`)
396
- - `--re-data-grid-row-odd-surface` - odd rows background (`var(--re-data-grid-cell-surface)`)
397
- - `--re-data-grid-row-hover-surface` - hover rows background (`var(--re-data-grid-cell-surface)`)
398
- - `--re-data-grid-row-hover-color` - hover rows text color (`var(--re-data-grid-cell-color)`)
399
- - `--re-data-grid-row-hover-rounded` - hover row corner radius (`0px`)
415
+ - `--re-data-grid-row-separator-color` - row separator color (`#bbb`)
416
+ - `--re-data-grid-row-separator` - separator line (`1px solid var(--re-data-grid-row-separator-color)`)
417
+ - `--re-data-grid-row-odd-surface` - odd rows background (`var(--re-data-grid-cell-surface)`)
418
+ - `--re-data-grid-row-hover-surface` - hover rows background (`var(--re-data-grid-cell-surface)`)
419
+ - `--re-data-grid-row-hover-color` - hover rows text color (`var(--re-data-grid-cell-color)`)
420
+ - `--re-data-grid-row-hover-rounded` - hover row corner radius (`0px`)
400
421
 
401
422
  Columns:
402
423
 
@@ -411,6 +432,8 @@ Cells:
411
432
  - `--re-data-grid-cell-font-size` - font size (`0.75rem`)
412
433
  - `--re-data-grid-cell-color` - text color (`#000`)
413
434
  - `--re-data-grid-cell-surface` - cell background (`#fff`)
435
+ - `--re-data-grid-cell-line-height` - body text line-height for clamp (`1.2`)
436
+ - `--re-data-grid-cell-max-lines` - body max text lines (`2`)
414
437
 
415
438
  Checkbox:
416
439
 
@@ -421,6 +444,12 @@ Checkbox:
421
444
  - `--re-data-grid-checkbox-surface` - checkbox background (`var(--surface-neutral, #fff)`)
422
445
  - `--re-data-grid-checkbox-active-color` - checkbox active color (`var(--primary-color, #2563eb)`)
423
446
 
447
+ Focus Ring:
448
+
449
+ - `--re-data-grid-focus-ring-color` - keyboard focus outline color (`color-mix(in srgb, var(--primary-color, #2a90f4) 55%, transparent)`)
450
+ - `--re-data-grid-focus-ring-width` - keyboard focus outline width (`2px`)
451
+ - `--re-data-grid-focus-ring-offset` - keyboard focus outline offset (`-2px`)
452
+
424
453
  Sticky Cells:
425
454
 
426
455
  - `--re-data-grid-sticky-header-cell-surface` - sticky header cell background (`#fff`)
@@ -0,0 +1,79 @@
1
+ import { c as computeScrollbarState, a as clampThumbTop, m as mapThumbTopToScrollTop } from './reforgium-data-grid-reforgium-data-grid-Dn9s4YO5.mjs';
2
+
3
+ function createGridOverlayScrollFeature(ctx) {
4
+ const showScrollbar = () => {
5
+ ctx.setScrollbarVisible(true);
6
+ clearTimeout(ctx.getHideTimeout());
7
+ };
8
+ const hideScrollbarSoon = (delay = 1200) => {
9
+ if (ctx.isDragging()) {
10
+ return;
11
+ }
12
+ clearTimeout(ctx.getHideTimeout());
13
+ ctx.setHideTimeout(setTimeout(() => ctx.setScrollbarVisible(false), delay));
14
+ };
15
+ const onThumbDown = (event) => {
16
+ event.preventDefault();
17
+ event.stopPropagation();
18
+ const scrollEl = ctx.getScrollElement();
19
+ if (!scrollEl) {
20
+ return;
21
+ }
22
+ ctx.setDragging(true);
23
+ showScrollbar();
24
+ const startY = event.clientY;
25
+ const startTop = ctx.getThumbTop();
26
+ const state = computeScrollbarState(scrollEl.scrollHeight || 1, scrollEl.clientHeight || 1, scrollEl.scrollTop || 0);
27
+ const maxThumbTop = state.maxThumbTop || 1;
28
+ const maxScrollTop = state.maxScrollTop || 1;
29
+ const onMove = (moveEvent) => {
30
+ const delta = moveEvent.clientY - startY;
31
+ const newTop = clampThumbTop(startTop + delta, maxThumbTop);
32
+ ctx.setThumbTop(newTop);
33
+ scrollEl.scrollTop = mapThumbTopToScrollTop(newTop, maxThumbTop, maxScrollTop);
34
+ ctx.calcScrollbar();
35
+ showScrollbar();
36
+ };
37
+ const onUp = () => {
38
+ window.removeEventListener('mousemove', onMove);
39
+ window.removeEventListener('mouseup', onUp);
40
+ ctx.setDragging(false);
41
+ hideScrollbarSoon();
42
+ };
43
+ window.addEventListener('mousemove', onMove);
44
+ window.addEventListener('mouseup', onUp);
45
+ };
46
+ const scheduleScrollbarUpdate = () => {
47
+ if (ctx.getScrollbarRafId() !== null) {
48
+ return;
49
+ }
50
+ ctx.setScrollbarRafId(requestAnimationFrame(() => {
51
+ ctx.setScrollbarRafId(null);
52
+ ctx.calcScrollbar();
53
+ }));
54
+ };
55
+ const clearScrollbarRaf = () => {
56
+ const rafId = ctx.getScrollbarRafId();
57
+ if (rafId === null) {
58
+ return;
59
+ }
60
+ cancelAnimationFrame(rafId);
61
+ ctx.setScrollbarRafId(null);
62
+ };
63
+ const finalizeScroll = () => {
64
+ scheduleScrollbarUpdate();
65
+ showScrollbar();
66
+ hideScrollbarSoon();
67
+ };
68
+ return {
69
+ onThumbDown,
70
+ showScrollbar,
71
+ hideScrollbarSoon,
72
+ scheduleScrollbarUpdate,
73
+ clearScrollbarRaf,
74
+ finalizeScroll,
75
+ };
76
+ }
77
+
78
+ export { createGridOverlayScrollFeature };
79
+ //# sourceMappingURL=reforgium-data-grid-grid-overlay-scroll.feature-DRUc6eDp.mjs.map
@@ -0,0 +1,54 @@
1
+ // noinspection ES6PreferShortImport
2
+ function createGridSelectionFeature(ctx) {
3
+ const clearSelection = () => {
4
+ ctx.clearSelectedKeys();
5
+ ctx.emitSelectChange([]);
6
+ };
7
+ const selectAllLoaded = () => {
8
+ if (ctx.getSelectionMode() !== 'multi') {
9
+ return;
10
+ }
11
+ ctx.emitSelectChange(ctx.selectAll());
12
+ };
13
+ const onSelectAll = (event) => {
14
+ event?.preventDefault();
15
+ event?.stopPropagation();
16
+ selectAllLoaded();
17
+ };
18
+ const onCheckboxToggle = (row, index, event) => {
19
+ event?.preventDefault();
20
+ event?.stopPropagation();
21
+ if (ctx.isRowDisabled(row, index)) {
22
+ return;
23
+ }
24
+ if (ctx.getSelectionMode() === 'none') {
25
+ return;
26
+ }
27
+ ctx.emitSelectChange(ctx.selectRow(row));
28
+ };
29
+ const onSelectAllKeydown = (event) => {
30
+ const key = event.key;
31
+ if (key !== 'Enter' && key !== ' ') {
32
+ return;
33
+ }
34
+ onSelectAll(event);
35
+ };
36
+ const onCheckboxKeydown = (row, index, event) => {
37
+ const key = event.key;
38
+ if (key !== 'Enter' && key !== ' ') {
39
+ return;
40
+ }
41
+ onCheckboxToggle(row, index, event);
42
+ };
43
+ return {
44
+ clearSelection,
45
+ selectAllLoaded,
46
+ onSelectAll,
47
+ onCheckboxToggle,
48
+ onSelectAllKeydown,
49
+ onCheckboxKeydown,
50
+ };
51
+ }
52
+
53
+ export { createGridSelectionFeature };
54
+ //# sourceMappingURL=reforgium-data-grid-grid-selection.feature-CGRNpMeD.mjs.map
@@ -0,0 +1,86 @@
1
+ function createGridStickyFeature(ctx) {
2
+ const isStickyRowIndex = (index) => {
3
+ return ctx.getStickyRowIndex() === index;
4
+ };
5
+ const findStickyIndexBefore = (indexes, index) => {
6
+ let low = 0;
7
+ let high = indexes.length - 1;
8
+ let result = -1;
9
+ while (low <= high) {
10
+ const mid = (low + high) >>> 1;
11
+ const value = indexes[mid];
12
+ if (value <= index) {
13
+ result = value;
14
+ low = mid + 1;
15
+ }
16
+ else {
17
+ high = mid - 1;
18
+ }
19
+ }
20
+ return result === -1 ? null : result;
21
+ };
22
+ const updateStickyRow = (scrollTop, rowHeight, pinnedTopH) => {
23
+ const indexes = ctx.getStickyIndexes();
24
+ if (!indexes.length) {
25
+ ctx.setStickyRowIndex(null);
26
+ return;
27
+ }
28
+ const scrollRowIndex = Math.max(0, Math.floor(scrollTop / rowHeight));
29
+ const currentIndex = findStickyIndexBefore(indexes, scrollRowIndex);
30
+ if (currentIndex === null) {
31
+ ctx.setStickyRowIndex(null);
32
+ return;
33
+ }
34
+ let activeIndex = currentIndex;
35
+ const prevIndex = ctx.getStickyRowIndex();
36
+ const hysteresisPx = Math.max(1, rowHeight * 0.5);
37
+ if (prevIndex !== null && prevIndex !== currentIndex) {
38
+ const boundaryPx = currentIndex * rowHeight;
39
+ const delta = Math.abs(scrollTop - boundaryPx);
40
+ if (delta < hysteresisPx) {
41
+ activeIndex = prevIndex;
42
+ }
43
+ }
44
+ const stickyTop = ctx.getHeaderHeight() + pinnedTopH;
45
+ const topPx = scrollTop + stickyTop;
46
+ ctx.setStickyRowIndex(activeIndex);
47
+ ctx.setStickyRowTopPx(topPx);
48
+ };
49
+ const updateStickyFromScroll = () => {
50
+ const el = ctx.getScrollElement();
51
+ if (!el) {
52
+ return;
53
+ }
54
+ const scrollTop = el.scrollTop ?? 0;
55
+ const rowHeight = Math.max(1, ctx.getRowHeight());
56
+ const pinnedTopH = ctx.getPinnedTopCount() * rowHeight;
57
+ updateStickyRow(scrollTop, rowHeight, pinnedTopH);
58
+ };
59
+ const scheduleStickyUpdate = () => {
60
+ if (ctx.getStickyRafId() !== null) {
61
+ return;
62
+ }
63
+ ctx.setStickyRafId(requestAnimationFrame(() => {
64
+ ctx.setStickyRafId(null);
65
+ ctx.runInAngular(() => updateStickyFromScroll());
66
+ }));
67
+ };
68
+ const clearStickyRaf = () => {
69
+ const rafId = ctx.getStickyRafId();
70
+ if (rafId === null) {
71
+ return;
72
+ }
73
+ cancelAnimationFrame(rafId);
74
+ ctx.setStickyRafId(null);
75
+ };
76
+ return {
77
+ isStickyRowIndex,
78
+ updateStickyRow,
79
+ updateStickyFromScroll,
80
+ scheduleStickyUpdate,
81
+ clearStickyRaf,
82
+ };
83
+ }
84
+
85
+ export { createGridStickyFeature };
86
+ //# sourceMappingURL=reforgium-data-grid-grid-sticky.feature-DBpn_6R8.mjs.map
@@ -0,0 +1,89 @@
1
+ function createGridTooltipFeature(ctx) {
2
+ const resolveCellValue = (row, col) => {
3
+ return 'value' in col ? col.value(row) : row[col.key];
4
+ };
5
+ const resolveTooltip = (row, col) => {
6
+ const tooltip = col.tooltip;
7
+ if (!tooltip) {
8
+ return null;
9
+ }
10
+ if (tooltip === true) {
11
+ const baseValue = resolveCellValue(row, col);
12
+ if (baseValue === null || baseValue === undefined || baseValue === '') {
13
+ return null;
14
+ }
15
+ return String(baseValue);
16
+ }
17
+ if (typeof tooltip === 'function') {
18
+ const value = tooltip(row);
19
+ if (value === null || value === undefined || value === '') {
20
+ return null;
21
+ }
22
+ return String(value);
23
+ }
24
+ if (typeof tooltip === 'string') {
25
+ return tooltip === '' ? null : tooltip;
26
+ }
27
+ return tooltip;
28
+ };
29
+ const showTooltip = (event, row, col, index) => {
30
+ const resolved = resolveTooltip(row, col);
31
+ if (!resolved) {
32
+ return;
33
+ }
34
+ const baseValue = resolveCellValue(row, col);
35
+ const context = {
36
+ $implicit: row,
37
+ row,
38
+ col: col,
39
+ index,
40
+ value: baseValue,
41
+ };
42
+ const offset = 12;
43
+ const x = event.clientX + offset;
44
+ const y = event.clientY + offset;
45
+ if (typeof resolved === 'string') {
46
+ ctx.setTooltipState({ text: resolved, x, y, visible: true });
47
+ }
48
+ else {
49
+ ctx.setTooltipState({ tpl: resolved, ctx: context, x, y, visible: true });
50
+ }
51
+ ctx.requestPositioning();
52
+ };
53
+ const hideTooltip = () => {
54
+ if (!ctx.getTooltipState().visible) {
55
+ return;
56
+ }
57
+ ctx.patchTooltipState({ visible: false });
58
+ };
59
+ const positionTooltip = (tooltipEl) => {
60
+ const state = ctx.getTooltipState();
61
+ if (!tooltipEl || !state.visible) {
62
+ return;
63
+ }
64
+ const rect = tooltipEl.getBoundingClientRect();
65
+ const padding = 8;
66
+ const vw = window.innerWidth;
67
+ const vh = window.innerHeight;
68
+ let x = state.x;
69
+ let y = state.y;
70
+ if (x + rect.width + padding > vw) {
71
+ x = Math.max(padding, vw - rect.width - padding);
72
+ }
73
+ if (y + rect.height + padding > vh) {
74
+ y = Math.max(padding, vh - rect.height - padding);
75
+ }
76
+ if (x !== state.x || y !== state.y) {
77
+ ctx.patchTooltipState({ x, y });
78
+ }
79
+ };
80
+ return {
81
+ resolveTooltip,
82
+ showTooltip,
83
+ hideTooltip,
84
+ positionTooltip,
85
+ };
86
+ }
87
+
88
+ export { createGridTooltipFeature };
89
+ //# sourceMappingURL=reforgium-data-grid-grid-tooltip.feature-CMo88m8o.mjs.map