@svgrid/grid 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/FlexRender.svelte +96 -96
- package/dist/GridMenus.svelte +205 -127
- package/dist/SvGrid.controller.svelte.d.ts +44 -1
- package/dist/SvGrid.controller.svelte.js +240 -44
- package/dist/SvGrid.css +325 -22
- package/dist/SvGrid.helpers.test.d.ts +1 -0
- package/dist/SvGrid.helpers.test.js +298 -0
- package/dist/SvGrid.svelte +729 -203
- package/dist/SvGrid.types.d.ts +91 -4
- package/dist/aligned-grids.d.ts +6 -0
- package/dist/aligned-grids.js +84 -0
- package/dist/aligned-grids.test.d.ts +1 -0
- package/dist/aligned-grids.test.js +75 -0
- package/dist/build-api.coverage.test.d.ts +20 -0
- package/dist/build-api.coverage.test.js +505 -0
- package/dist/build-api.js +61 -31
- package/dist/cell-render.test.d.ts +1 -0
- package/dist/cell-render.test.js +338 -0
- package/dist/cell-values.d.ts +1 -1
- package/dist/cell-values.js +7 -7
- package/dist/chart-export.test.d.ts +1 -0
- package/dist/chart-export.test.js +302 -0
- package/dist/chart.coverage.test.d.ts +1 -0
- package/dist/chart.coverage.test.js +748 -0
- package/dist/clipboard.js +88 -24
- package/dist/clipboard.test.d.ts +1 -0
- package/dist/clipboard.test.js +700 -0
- package/dist/collaboration.coverage.test.d.ts +1 -0
- package/dist/collaboration.coverage.test.js +200 -0
- package/dist/column-groups.d.ts +19 -0
- package/dist/column-groups.js +62 -0
- package/dist/column-groups.test.d.ts +1 -0
- package/dist/column-groups.test.js +56 -0
- package/dist/column-types.d.ts +10 -0
- package/dist/column-types.js +63 -0
- package/dist/column-types.test.d.ts +1 -0
- package/dist/column-types.test.js +62 -0
- package/dist/columns.test.d.ts +1 -0
- package/dist/columns.test.js +625 -0
- package/dist/core.d.ts +86 -1
- package/dist/core.js +2 -2
- package/dist/editing.d.ts +7 -0
- package/dist/editing.js +191 -5
- package/dist/editing.test.d.ts +1 -0
- package/dist/editing.test.js +732 -0
- package/dist/editors/cell-editors.coverage.test.d.ts +1 -0
- package/dist/editors/cell-editors.coverage.test.js +139 -0
- package/dist/facet-buckets.test.d.ts +1 -0
- package/dist/facet-buckets.test.js +296 -0
- package/dist/filter-operators.test.d.ts +1 -0
- package/dist/filter-operators.test.js +135 -0
- package/dist/hyperformula-adapter.test.d.ts +1 -0
- package/dist/hyperformula-adapter.test.js +205 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +4 -1
- package/dist/keyboard-handlers.coverage.test.d.ts +1 -0
- package/dist/keyboard-handlers.coverage.test.js +495 -0
- package/dist/keyboard-handlers.js +7 -2
- package/dist/menus.js +1 -0
- package/dist/menus.test.d.ts +1 -0
- package/dist/menus.test.js +560 -0
- package/dist/named-views.coverage.test.d.ts +1 -0
- package/dist/named-views.coverage.test.js +180 -0
- package/dist/row-drag.d.ts +49 -0
- package/dist/row-drag.js +221 -0
- package/dist/row-drag.test.d.ts +1 -0
- package/dist/row-drag.test.js +142 -0
- package/dist/row-resize.test.d.ts +1 -0
- package/dist/row-resize.test.js +329 -0
- package/dist/scroll-sync.js +3 -0
- package/dist/scroll-sync.test.d.ts +1 -0
- package/dist/scroll-sync.test.js +290 -0
- package/dist/selection.d.ts +7 -1
- package/dist/selection.js +76 -36
- package/dist/selection.multi-range.test.d.ts +1 -0
- package/dist/selection.multi-range.test.js +55 -0
- package/dist/selection.test.d.ts +1 -0
- package/dist/selection.test.js +647 -0
- package/dist/server-data-source.coverage.test.d.ts +1 -0
- package/dist/server-data-source.coverage.test.js +154 -0
- package/dist/spreadsheet.d.ts +30 -0
- package/dist/spreadsheet.js +48 -0
- package/dist/spreadsheet.test.d.ts +1 -0
- package/dist/spreadsheet.test.js +446 -0
- package/dist/summaries.js +4 -4
- package/dist/sv-grid-scrollbar.js +13 -1
- package/dist/svgrid-wrapper.types.d.ts +19 -0
- package/dist/svgrid.behavior.test.js +20 -0
- package/dist/svgrid.interaction.test.js +31 -0
- package/dist/svgrid.new-features.wrapper.test.js +34 -2
- package/dist/test-setup.js +9 -3
- package/dist/virtualization/scroll-scaling.d.ts +17 -0
- package/dist/virtualization/scroll-scaling.js +35 -0
- package/dist/virtualization/scroll-scaling.test.js +42 -1
- package/package.json +2 -1
- package/src/FlexRender.svelte +96 -96
- package/src/GridMenus.svelte +205 -127
- package/src/SvGrid.controller.svelte.ts +204 -36
- package/src/SvGrid.css +277 -12
- package/src/SvGrid.svelte +727 -205
- package/src/SvGrid.types.ts +85 -4
- package/src/a11y.contract.test.ts +49 -49
- package/src/a11y.test.ts +59 -59
- package/src/a11y.ts +59 -59
- package/src/aligned-grids.test.ts +80 -0
- package/src/aligned-grids.ts +87 -0
- package/src/build-api.ts +43 -23
- package/src/cell-formatting.ts +169 -169
- package/src/cell-values.ts +4 -4
- package/src/clipboard.test.ts +49 -0
- package/src/clipboard.ts +51 -23
- package/src/column-groups.test.ts +59 -0
- package/src/column-groups.ts +80 -0
- package/src/column-types.test.ts +68 -0
- package/src/column-types.ts +82 -0
- package/src/core.performance.test.ts +30 -30
- package/src/core.ts +1077 -999
- package/src/createGrid.svelte.ts +42 -42
- package/src/createGrid.test.ts +10 -10
- package/src/createGridState.svelte.ts +17 -17
- package/src/editing.ts +161 -5
- package/src/flex-render.ts +3 -3
- package/src/index.ts +208 -196
- package/src/keyboard.test.ts +59 -59
- package/src/keyboard.ts +97 -97
- package/src/menus.ts +1 -0
- package/src/merge-objects.ts +48 -48
- package/src/render-component.ts +28 -28
- package/src/row-drag.test.ts +168 -0
- package/src/row-drag.ts +255 -0
- package/src/scroll-sync.ts +2 -0
- package/src/selection.multi-range.test.ts +61 -0
- package/src/selection.ts +71 -37
- package/src/spreadsheet.test.ts +46 -2
- package/src/spreadsheet.ts +58 -0
- package/src/static-functions.ts +11 -11
- package/src/subscribe.ts +38 -38
- package/src/summaries.ts +4 -4
- package/src/svgrid-wrapper.types.ts +412 -393
- package/src/svgrid.features.test.ts +157 -157
- package/src/svgrid.new-features.wrapper.test.ts +2 -2
- package/src/svgrid.wrapper.test.ts +40 -40
- package/src/virtualization/column-virtualizer.test.ts +27 -27
- package/src/virtualization/column-virtualizer.ts +30 -30
- package/src/virtualization/svelte-virtualizer.svelte.ts +26 -26
- package/src/virtualization/types.ts +30 -30
- package/src/virtualization/virtualizer.test.ts +47 -47
- package/src/virtualization/virtualizer.ts +296 -296
package/dist/test-setup.js
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
// Vitest setup. jsdom doesn't ship ResizeObserver, IntersectionObserver,
|
|
2
2
|
// or the layout APIs SvGrid touches inside its mount effects. Provide
|
|
3
3
|
// minimal no-op stubs so component mounting completes without crashing.
|
|
4
|
+
//
|
|
5
|
+
// These assign to globals/prototypes the jsdom env doesn't fully type, so
|
|
6
|
+
// the targets are cast to `any`. We deliberately avoid expect-error
|
|
7
|
+
// suppression directives: when a stub happens to line up with the lib types,
|
|
8
|
+
// such a directive becomes "unused" and svelte-check fails the build (an
|
|
9
|
+
// unused expect-error directive is itself an error).
|
|
4
10
|
if (typeof globalThis.ResizeObserver === 'undefined') {
|
|
5
|
-
|
|
11
|
+
;
|
|
6
12
|
globalThis.ResizeObserver = class {
|
|
7
13
|
observe() { }
|
|
8
14
|
unobserve() { }
|
|
@@ -10,7 +16,7 @@ if (typeof globalThis.ResizeObserver === 'undefined') {
|
|
|
10
16
|
};
|
|
11
17
|
}
|
|
12
18
|
if (typeof globalThis.IntersectionObserver === 'undefined') {
|
|
13
|
-
|
|
19
|
+
;
|
|
14
20
|
globalThis.IntersectionObserver = class {
|
|
15
21
|
observe() { }
|
|
16
22
|
unobserve() { }
|
|
@@ -23,7 +29,7 @@ if (typeof globalThis.IntersectionObserver === 'undefined') {
|
|
|
23
29
|
// jsdom's HTMLElement.scrollIntoView is a no-op; some grid code calls it
|
|
24
30
|
// during the first effect. Make sure the method exists on every element.
|
|
25
31
|
if (typeof Element !== 'undefined' && !Element.prototype.scrollIntoView) {
|
|
26
|
-
|
|
32
|
+
;
|
|
27
33
|
Element.prototype.scrollIntoView = function () { };
|
|
28
34
|
}
|
|
29
35
|
export {};
|
|
@@ -8,6 +8,23 @@ export type RowScrollScaling = {
|
|
|
8
8
|
/** Map a virtualizer logical offset back into a DOM scrollTop. */
|
|
9
9
|
logicalToDom(logical: number): number;
|
|
10
10
|
};
|
|
11
|
+
/**
|
|
12
|
+
* Resolve the usable max element height from the two raw DOM signals.
|
|
13
|
+
*
|
|
14
|
+
* `layoutCap` is a tall probe's clamped `offsetHeight` - the height layout
|
|
15
|
+
* assigns the element. `scrollCap` is the `scrollHeight` a real `overflow:auto`
|
|
16
|
+
* container exposes for that same probe - the height the user can actually
|
|
17
|
+
* scroll through. They differ on mobile / high-DPR engines, which report a
|
|
18
|
+
* generous `offsetHeight` but then expose a SMALLER scrollable range (the
|
|
19
|
+
* physical limit is in device px, so a 3x-DPR phone has ~1/3 the CSS-px scroll
|
|
20
|
+
* cap). Trusting `offsetHeight` alone is exactly what strands the last rows of
|
|
21
|
+
* a huge grid on a phone, so we take the smaller of the two.
|
|
22
|
+
*
|
|
23
|
+
* A junk reading (<= the sanity floor, or so large the browser clearly didn't
|
|
24
|
+
* clamp) is dropped; if neither signal survives, the caller's conservative
|
|
25
|
+
* `fallback` is returned unchanged.
|
|
26
|
+
*/
|
|
27
|
+
export declare function resolveMaxDomHeight(layoutCap: number, scrollCap: number, fallback: number): number;
|
|
11
28
|
/**
|
|
12
29
|
* Build the scaling mapping for one axis.
|
|
13
30
|
*
|
|
@@ -21,6 +21,41 @@ function clamp01(value) {
|
|
|
21
21
|
return 1;
|
|
22
22
|
return value;
|
|
23
23
|
}
|
|
24
|
+
/** Below this a reading is junk (0 from jsdom, a sub-cap layout quirk, etc). */
|
|
25
|
+
const MAX_DOM_HEIGHT_SANITY_FLOOR = 100000;
|
|
26
|
+
/** At/above this the browser didn't clamp (returned ~the 1e9 we asked for). */
|
|
27
|
+
const MAX_DOM_HEIGHT_SANITY_CEIL = 900000000;
|
|
28
|
+
/**
|
|
29
|
+
* Shave a hair off the detected cap so the spacer never sits at the exact
|
|
30
|
+
* physical edge, where sub-pixel rounding could leave the final row a touch
|
|
31
|
+
* out of reach. 0.5% is invisible at desktop caps (~33.5M -> ~33.3M) yet
|
|
32
|
+
* keeps a safety gap proportional to the cap.
|
|
33
|
+
*/
|
|
34
|
+
const MAX_DOM_HEIGHT_SAFETY = 0.995;
|
|
35
|
+
/**
|
|
36
|
+
* Resolve the usable max element height from the two raw DOM signals.
|
|
37
|
+
*
|
|
38
|
+
* `layoutCap` is a tall probe's clamped `offsetHeight` - the height layout
|
|
39
|
+
* assigns the element. `scrollCap` is the `scrollHeight` a real `overflow:auto`
|
|
40
|
+
* container exposes for that same probe - the height the user can actually
|
|
41
|
+
* scroll through. They differ on mobile / high-DPR engines, which report a
|
|
42
|
+
* generous `offsetHeight` but then expose a SMALLER scrollable range (the
|
|
43
|
+
* physical limit is in device px, so a 3x-DPR phone has ~1/3 the CSS-px scroll
|
|
44
|
+
* cap). Trusting `offsetHeight` alone is exactly what strands the last rows of
|
|
45
|
+
* a huge grid on a phone, so we take the smaller of the two.
|
|
46
|
+
*
|
|
47
|
+
* A junk reading (<= the sanity floor, or so large the browser clearly didn't
|
|
48
|
+
* clamp) is dropped; if neither signal survives, the caller's conservative
|
|
49
|
+
* `fallback` is returned unchanged.
|
|
50
|
+
*/
|
|
51
|
+
export function resolveMaxDomHeight(layoutCap, scrollCap, fallback) {
|
|
52
|
+
const usable = [layoutCap, scrollCap].filter((v) => Number.isFinite(v) &&
|
|
53
|
+
v > MAX_DOM_HEIGHT_SANITY_FLOOR &&
|
|
54
|
+
v < MAX_DOM_HEIGHT_SANITY_CEIL);
|
|
55
|
+
if (usable.length === 0)
|
|
56
|
+
return fallback;
|
|
57
|
+
return Math.floor(Math.min(...usable) * MAX_DOM_HEIGHT_SAFETY);
|
|
58
|
+
}
|
|
24
59
|
/**
|
|
25
60
|
* Build the scaling mapping for one axis.
|
|
26
61
|
*
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { createRowScrollScaling } from './scroll-scaling';
|
|
2
|
+
import { createRowScrollScaling, resolveMaxDomHeight } from './scroll-scaling';
|
|
3
3
|
const VIEWPORT = 600;
|
|
4
|
+
const FALLBACK = 8000000;
|
|
4
5
|
describe('createRowScrollScaling - inert (content fits under the cap)', () => {
|
|
5
6
|
// 1M rows * 18px = 18M, under a 33.5M (Chrome) cap -> no scaling.
|
|
6
7
|
const s = createRowScrollScaling(18000000, 33554400, VIEWPORT);
|
|
@@ -62,6 +63,46 @@ describe('createRowScrollScaling - active (content exceeds the cap)', () => {
|
|
|
62
63
|
}
|
|
63
64
|
});
|
|
64
65
|
});
|
|
66
|
+
describe('resolveMaxDomHeight - picks the smaller, real scrollable cap', () => {
|
|
67
|
+
it('keeps the desktop cap when both signals agree', () => {
|
|
68
|
+
// Chrome ~33.5M; offsetHeight and scrollHeight match. 0.5% safety shave.
|
|
69
|
+
const cap = resolveMaxDomHeight(33554400, 33554400, FALLBACK);
|
|
70
|
+
expect(cap).toBeLessThan(33554400);
|
|
71
|
+
expect(cap).toBeGreaterThan(33000000);
|
|
72
|
+
});
|
|
73
|
+
it('uses the SCROLL cap when a phone over-reports offsetHeight', () => {
|
|
74
|
+
// High-DPR mobile: layout says 24M, but the container only scrolls ~6M.
|
|
75
|
+
// Trusting offsetHeight is exactly what stranded the last rows.
|
|
76
|
+
const cap = resolveMaxDomHeight(24000000, 6000000, FALLBACK);
|
|
77
|
+
expect(cap).toBeLessThanOrEqual(6000000);
|
|
78
|
+
expect(cap).toBeGreaterThan(5900000);
|
|
79
|
+
});
|
|
80
|
+
it('shaves a safety margin so the spacer never sits at the exact edge', () => {
|
|
81
|
+
const cap = resolveMaxDomHeight(10000000, 10000000, FALLBACK);
|
|
82
|
+
expect(cap).toBeLessThan(10000000);
|
|
83
|
+
});
|
|
84
|
+
it('falls back when both readings are junk (jsdom returns 0)', () => {
|
|
85
|
+
expect(resolveMaxDomHeight(0, 0, FALLBACK)).toBe(FALLBACK);
|
|
86
|
+
});
|
|
87
|
+
it('falls back when the browser did not clamp (returned ~1e9)', () => {
|
|
88
|
+
expect(resolveMaxDomHeight(1000000000, 1000000000, FALLBACK)).toBe(FALLBACK);
|
|
89
|
+
});
|
|
90
|
+
it('ignores a junk signal but trusts the valid one', () => {
|
|
91
|
+
// offsetHeight unclamped/garbage, scrollHeight is the real cap.
|
|
92
|
+
const cap = resolveMaxDomHeight(1000000000, 5000000, FALLBACK);
|
|
93
|
+
expect(cap).toBeLessThanOrEqual(5000000);
|
|
94
|
+
expect(cap).toBeGreaterThan(4900000);
|
|
95
|
+
});
|
|
96
|
+
it('feeds straight into the scaler so the last row stays reachable', () => {
|
|
97
|
+
const maxDom = resolveMaxDomHeight(24000000, 6000000, FALLBACK);
|
|
98
|
+
const trueTotal = 500000 * 32; // 16M px of rows, over the phone cap
|
|
99
|
+
const s = createRowScrollScaling(trueTotal, maxDom, VIEWPORT);
|
|
100
|
+
expect(s.active).toBe(true);
|
|
101
|
+
expect(s.domTotal).toBeLessThanOrEqual(maxDom);
|
|
102
|
+
const domMax = s.domTotal - VIEWPORT;
|
|
103
|
+
expect(s.domToLogical(domMax)).toBeCloseTo(trueTotal - VIEWPORT, 0);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
65
106
|
describe('createRowScrollScaling - edge cases', () => {
|
|
66
107
|
it('handles an empty grid without dividing by zero', () => {
|
|
67
108
|
const s = createRowScrollScaling(0, 17895697, VIEWPORT);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@svgrid/grid",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "SvGrid - a headless-first, Svelte 5-native data grid engine and render component.",
|
|
5
5
|
"author": "jQWidgets <boikom@jqwidgets.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -60,6 +60,7 @@
|
|
|
60
60
|
"@vitest/coverage-v8": "^4.1.5",
|
|
61
61
|
"eslint-plugin-svelte": "^3.17.1",
|
|
62
62
|
"jsdom": "^29.1.1",
|
|
63
|
+
"publint": "^0.3.21",
|
|
63
64
|
"svelte": "^5.55.5",
|
|
64
65
|
"svelte-check": "^4.4.6"
|
|
65
66
|
},
|
package/src/FlexRender.svelte
CHANGED
|
@@ -1,96 +1,96 @@
|
|
|
1
|
-
<script
|
|
2
|
-
lang="ts"
|
|
3
|
-
generics="TData extends RowData"
|
|
4
|
-
>
|
|
5
|
-
import { isFunction } from './core'
|
|
6
|
-
import {
|
|
7
|
-
RenderComponentConfig,
|
|
8
|
-
RenderSnippetConfig,
|
|
9
|
-
} from './render-component'
|
|
10
|
-
import type {
|
|
11
|
-
Cell,
|
|
12
|
-
CellContext,
|
|
13
|
-
ColumnDefTemplate,
|
|
14
|
-
Header,
|
|
15
|
-
HeaderContext,
|
|
16
|
-
RowData,
|
|
17
|
-
} from './core'
|
|
18
|
-
|
|
19
|
-
type Props =
|
|
20
|
-
| {
|
|
21
|
-
content?: ColumnDefTemplate<
|
|
22
|
-
| HeaderContext<TData>
|
|
23
|
-
| CellContext<TData>
|
|
24
|
-
>
|
|
25
|
-
context:
|
|
26
|
-
| HeaderContext<TData>
|
|
27
|
-
| CellContext<TData>
|
|
28
|
-
cell?: never
|
|
29
|
-
header?: never
|
|
30
|
-
footer?: never
|
|
31
|
-
}
|
|
32
|
-
| {
|
|
33
|
-
cell: Cell<TData>
|
|
34
|
-
content?: never
|
|
35
|
-
context?: never
|
|
36
|
-
header?: never
|
|
37
|
-
footer?: never
|
|
38
|
-
}
|
|
39
|
-
| {
|
|
40
|
-
header: Header<TData>
|
|
41
|
-
content?: never
|
|
42
|
-
context?: never
|
|
43
|
-
cell?: never
|
|
44
|
-
footer?: never
|
|
45
|
-
}
|
|
46
|
-
| {
|
|
47
|
-
footer: Header<TData>
|
|
48
|
-
content?: never
|
|
49
|
-
context?: never
|
|
50
|
-
cell?: never
|
|
51
|
-
header?: never
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
let props: Props = $props()
|
|
55
|
-
|
|
56
|
-
const resolved = $derived.by(() => {
|
|
57
|
-
if ('cell' in props && props.cell) {
|
|
58
|
-
return {
|
|
59
|
-
content: props.cell.column.columnDef.cell,
|
|
60
|
-
context: props.cell.getContext(),
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
if ('header' in props && props.header) {
|
|
64
|
-
return {
|
|
65
|
-
content: props.header.column.columnDef.header,
|
|
66
|
-
context: props.header.getContext(),
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
if ('footer' in props && props.footer) {
|
|
70
|
-
return {
|
|
71
|
-
content: props.footer.column.columnDef.footer,
|
|
72
|
-
context: props.footer.getContext(),
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
return {
|
|
76
|
-
content: props.content,
|
|
77
|
-
context: props.context,
|
|
78
|
-
}
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
const result = $derived(
|
|
82
|
-
isFunction(resolved.content)
|
|
83
|
-
? resolved.content(resolved.context as any)
|
|
84
|
-
: undefined,
|
|
85
|
-
)
|
|
86
|
-
</script>
|
|
87
|
-
|
|
88
|
-
{#if typeof resolved.content === 'string'}
|
|
89
|
-
{resolved.content}
|
|
90
|
-
{:else if result instanceof RenderComponentConfig}
|
|
91
|
-
<result.component {...result.props} />
|
|
92
|
-
{:else if result instanceof RenderSnippetConfig}
|
|
93
|
-
{@render result.snippet(result.params)}
|
|
94
|
-
{:else if result !== undefined}
|
|
95
|
-
{result}
|
|
96
|
-
{/if}
|
|
1
|
+
<script
|
|
2
|
+
lang="ts"
|
|
3
|
+
generics="TData extends RowData"
|
|
4
|
+
>
|
|
5
|
+
import { isFunction } from './core'
|
|
6
|
+
import {
|
|
7
|
+
RenderComponentConfig,
|
|
8
|
+
RenderSnippetConfig,
|
|
9
|
+
} from './render-component'
|
|
10
|
+
import type {
|
|
11
|
+
Cell,
|
|
12
|
+
CellContext,
|
|
13
|
+
ColumnDefTemplate,
|
|
14
|
+
Header,
|
|
15
|
+
HeaderContext,
|
|
16
|
+
RowData,
|
|
17
|
+
} from './core'
|
|
18
|
+
|
|
19
|
+
type Props =
|
|
20
|
+
| {
|
|
21
|
+
content?: ColumnDefTemplate<
|
|
22
|
+
| HeaderContext<TData>
|
|
23
|
+
| CellContext<TData>
|
|
24
|
+
>
|
|
25
|
+
context:
|
|
26
|
+
| HeaderContext<TData>
|
|
27
|
+
| CellContext<TData>
|
|
28
|
+
cell?: never
|
|
29
|
+
header?: never
|
|
30
|
+
footer?: never
|
|
31
|
+
}
|
|
32
|
+
| {
|
|
33
|
+
cell: Cell<TData>
|
|
34
|
+
content?: never
|
|
35
|
+
context?: never
|
|
36
|
+
header?: never
|
|
37
|
+
footer?: never
|
|
38
|
+
}
|
|
39
|
+
| {
|
|
40
|
+
header: Header<TData>
|
|
41
|
+
content?: never
|
|
42
|
+
context?: never
|
|
43
|
+
cell?: never
|
|
44
|
+
footer?: never
|
|
45
|
+
}
|
|
46
|
+
| {
|
|
47
|
+
footer: Header<TData>
|
|
48
|
+
content?: never
|
|
49
|
+
context?: never
|
|
50
|
+
cell?: never
|
|
51
|
+
header?: never
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
let props: Props = $props()
|
|
55
|
+
|
|
56
|
+
const resolved = $derived.by(() => {
|
|
57
|
+
if ('cell' in props && props.cell) {
|
|
58
|
+
return {
|
|
59
|
+
content: props.cell.column.columnDef.cell,
|
|
60
|
+
context: props.cell.getContext(),
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if ('header' in props && props.header) {
|
|
64
|
+
return {
|
|
65
|
+
content: props.header.column.columnDef.header,
|
|
66
|
+
context: props.header.getContext(),
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if ('footer' in props && props.footer) {
|
|
70
|
+
return {
|
|
71
|
+
content: props.footer.column.columnDef.footer,
|
|
72
|
+
context: props.footer.getContext(),
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
content: props.content,
|
|
77
|
+
context: props.context,
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
const result = $derived(
|
|
82
|
+
isFunction(resolved.content)
|
|
83
|
+
? resolved.content(resolved.context as any)
|
|
84
|
+
: undefined,
|
|
85
|
+
)
|
|
86
|
+
</script>
|
|
87
|
+
|
|
88
|
+
{#if typeof resolved.content === 'string'}
|
|
89
|
+
{resolved.content}
|
|
90
|
+
{:else if result instanceof RenderComponentConfig}
|
|
91
|
+
<result.component {...result.props} />
|
|
92
|
+
{:else if result instanceof RenderSnippetConfig}
|
|
93
|
+
{@render result.snippet(result.params)}
|
|
94
|
+
{:else if result !== undefined}
|
|
95
|
+
{result}
|
|
96
|
+
{/if}
|