@svgrid/grid 2.1.22 → 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 +9 -2
- package/dist/DockNodeView.svelte +306 -0
- package/dist/DockNodeView.svelte.d.ts +7 -0
- package/dist/DockPopoutHost.svelte +17 -0
- package/dist/DockPopoutHost.svelte.d.ts +14 -0
- package/dist/FlexRender.svelte +96 -96
- package/dist/GridFooter.svelte +178 -178
- package/dist/GridMenus.svelte +83 -3
- package/dist/SvAutoComplete.svelte +5 -3
- package/dist/SvCarousel.svelte +141 -163
- package/dist/SvColorInput.svelte +187 -186
- package/dist/SvColorInput.svelte.d.ts +1 -1
- package/dist/SvComboBox.svelte +7 -3
- package/dist/SvCommand.svelte +28 -85
- package/dist/SvContextMenu.svelte +116 -116
- package/dist/SvCountryInput.svelte +1 -1
- package/dist/SvDateRangeInput.svelte +1 -1
- package/dist/SvDateTimePicker.svelte +9 -3
- package/dist/SvDateTimePicker.svelte.d.ts +3 -0
- package/dist/SvDockLayout.svelte +244 -0
- package/dist/SvDockLayout.svelte.d.ts +77 -0
- package/dist/SvDockManager.svelte +922 -0
- package/dist/SvDockManager.svelte.d.ts +106 -0
- package/dist/SvDrawer.svelte +250 -228
- package/dist/SvDrawer.svelte.d.ts +4 -0
- package/dist/SvDropDownList.svelte +85 -13
- package/dist/SvDropDownList.svelte.d.ts +3 -0
- package/dist/SvField.svelte +21 -4
- package/dist/SvField.svelte.d.ts +1 -0
- package/dist/SvForm.svelte +201 -91
- package/dist/SvForm.svelte.d.ts +15 -22
- package/dist/SvGrid.controller.svelte.d.ts +32 -1
- package/dist/SvGrid.controller.svelte.js +156 -27
- package/dist/SvGrid.css +193 -5
- package/dist/SvGrid.svelte +3131 -2786
- package/dist/SvGrid.types.d.ts +452 -1
- package/dist/SvGridBoard.svelte +2339 -2339
- package/dist/SvGridChart.svelte +1724 -1724
- package/dist/SvGridChartPanel.svelte +485 -485
- package/dist/SvGridDropdown.svelte +689 -682
- package/dist/SvGridSelect.svelte +1 -0
- package/dist/SvGroupCell.svelte +109 -109
- package/dist/SvListBox.svelte +36 -14
- package/dist/SvMaskedInput.svelte +4 -3
- package/dist/SvMaskedInput.svelte.d.ts +1 -1
- package/dist/SvMenu.svelte +124 -124
- package/dist/SvMenuList.svelte +117 -165
- package/dist/SvMenuList.svelte.d.ts +2 -13
- package/dist/SvModal.svelte +12 -29
- package/dist/SvMultiSelect.svelte +1 -0
- package/dist/SvNumberInput.svelte +131 -130
- package/dist/SvNumberInput.svelte.d.ts +1 -1
- package/dist/SvOtpInput.svelte +158 -158
- package/dist/SvPagination.svelte +18 -18
- package/dist/SvPasswordInput.svelte +3 -2
- package/dist/SvPasswordInput.svelte.d.ts +1 -1
- package/dist/SvPhoneInput.svelte +3 -2
- package/dist/SvPhoneInput.svelte.d.ts +1 -1
- package/dist/SvPopover.svelte +139 -139
- package/dist/SvRowGroupPanel.svelte +170 -170
- package/dist/SvScrollArea.svelte +61 -61
- package/dist/SvStepper.svelte +6 -9
- package/dist/SvTagsInput.svelte +3 -2
- package/dist/SvTagsInput.svelte.d.ts +1 -1
- package/dist/SvTooltip.svelte +127 -138
- package/dist/SvTour.svelte +204 -176
- package/dist/SvTree.svelte +377 -377
- package/dist/SvTreeSelect.svelte +230 -229
- package/dist/build-api.js +76 -54
- package/dist/cdn/svgrid.js +10913 -6450
- package/dist/cdn/svgrid.svelte-external.js +9628 -5481
- package/dist/chart-export.js +8 -8
- package/dist/columns.js +6 -0
- package/dist/conditional-formatting.d.ts +67 -3
- package/dist/conditional-formatting.js +124 -17
- package/dist/createCarousel.svelte.d.ts +72 -0
- package/dist/createCarousel.svelte.js +80 -0
- package/dist/createCommand.svelte.d.ts +62 -0
- package/dist/createCommand.svelte.js +109 -0
- package/dist/createForm.svelte.d.ts +62 -0
- package/dist/createForm.svelte.js +374 -0
- package/dist/createMenu.svelte.d.ts +88 -0
- package/dist/createMenu.svelte.js +153 -0
- package/dist/createOverlay.svelte.d.ts +38 -0
- package/dist/createOverlay.svelte.js +68 -0
- package/dist/createPagination.d.ts +74 -0
- package/dist/createPagination.js +71 -0
- package/dist/createPopoverSelect.svelte.js +6 -12
- package/dist/createStepper.d.ts +44 -0
- package/dist/createStepper.js +26 -0
- package/dist/createTooltip.svelte.d.ts +32 -0
- package/dist/createTooltip.svelte.js +61 -0
- package/dist/datetime/timezone.d.ts +36 -0
- package/dist/datetime/timezone.js +110 -0
- package/dist/dock-context.d.ts +52 -0
- package/dist/dock-context.js +1 -0
- package/dist/dock-manager-model.d.ts +136 -0
- package/dist/dock-manager-model.js +514 -0
- package/dist/dock-model.d.ts +105 -0
- package/dist/dock-model.js +288 -0
- package/dist/dock-popout.d.ts +30 -0
- package/dist/dock-popout.js +81 -0
- package/dist/editor-contract.d.ts +2 -0
- package/dist/filter-operators.d.ts +6 -0
- package/dist/filter-operators.js +35 -2
- package/dist/filtering/excel-filters.d.ts +18 -1
- package/dist/filtering/excel-filters.js +56 -0
- package/dist/form-field.d.ts +73 -0
- package/dist/form-field.js +15 -0
- package/dist/index.d.ts +25 -5
- package/dist/index.js +40 -4
- package/dist/list-nav.d.ts +18 -0
- package/dist/list-nav.js +30 -0
- package/dist/list-option.d.ts +2 -0
- package/dist/menu-item.d.ts +20 -0
- package/dist/menu-item.js +1 -0
- package/dist/menus.d.ts +5 -0
- package/dist/menus.js +68 -16
- package/dist/panel-resize.d.ts +25 -0
- package/dist/panel-resize.js +40 -0
- package/dist/popover.d.ts +29 -3
- package/dist/popover.js +22 -6
- package/dist/recurrence.d.ts +33 -7
- package/dist/recurrence.js +151 -13
- package/dist/row-drag.d.ts +8 -0
- package/dist/row-drag.js +11 -0
- package/dist/scheduler-ical.d.ts +30 -0
- package/dist/scheduler-ical.js +180 -0
- package/dist/scheduler-model.d.ts +269 -0
- package/dist/scheduler-model.js +602 -0
- package/dist/scheduler-view.svelte.d.ts +22 -0
- package/dist/scheduler-view.svelte.js +13 -0
- package/dist/spreadsheet.js +20 -12
- package/dist/ui-app.types.d.ts +3 -0
- package/package.json +14 -10
- package/src/DockNodeView.svelte +306 -0
- package/src/DockPopoutHost.svelte +17 -0
- package/src/FlexRender.svelte +96 -96
- package/src/GridFooter.svelte +178 -178
- package/src/GridMenus.svelte +83 -3
- package/src/SvAutoComplete.svelte +5 -3
- package/src/SvCarousel.svelte +141 -163
- package/src/SvCarousel.test.ts +68 -0
- package/src/SvColorInput.svelte +187 -186
- package/src/SvComboBox.svelte +7 -3
- package/src/SvCommand.svelte +28 -85
- package/src/SvCommand.test.ts +78 -0
- package/src/SvContextMenu.svelte +116 -116
- package/src/SvCountryInput.svelte +1 -1
- package/src/SvDateRangeInput.svelte +1 -1
- package/src/SvDateTimePicker.svelte +9 -3
- package/src/SvDockLayout.svelte +244 -0
- package/src/SvDockManager.svelte +922 -0
- package/src/SvDrawer.svelte +250 -228
- package/src/SvDropDownList.svelte +85 -13
- package/src/SvField.svelte +21 -4
- package/src/SvForm.svelte +201 -91
- package/src/SvForm.test.ts +299 -0
- package/src/SvGrid.controller.svelte.ts +3158 -3034
- package/src/SvGrid.css +193 -5
- package/src/SvGrid.svelte +3131 -2786
- package/src/SvGrid.types.ts +1489 -1027
- package/src/SvGridBoard.svelte +2339 -2339
- package/src/SvGridChart.svelte +1724 -1724
- package/src/SvGridChartPanel.svelte +485 -485
- package/src/SvGridDropdown.svelte +689 -682
- package/src/SvGridSelect.svelte +1 -0
- package/src/SvGroupCell.svelte +109 -109
- package/src/SvListBox.svelte +36 -14
- package/src/SvMaskedInput.svelte +4 -3
- package/src/SvMenu.svelte +124 -124
- package/src/SvMenu.test.ts +97 -73
- package/src/SvMenuList.svelte +117 -165
- package/src/SvModal.svelte +12 -29
- package/src/SvModal.test.ts +82 -0
- package/src/SvMultiSelect.svelte +1 -0
- package/src/SvNumberInput.svelte +131 -130
- package/src/SvOtpInput.svelte +158 -158
- package/src/SvPagination.svelte +18 -18
- package/src/SvPasswordInput.svelte +3 -2
- package/src/SvPhoneInput.svelte +3 -2
- package/src/SvPopover.svelte +139 -139
- package/src/SvRowGroupPanel.svelte +170 -170
- package/src/SvScrollArea.svelte +61 -61
- package/src/SvStepper.svelte +6 -9
- package/src/SvTagsInput.svelte +3 -2
- package/src/SvTooltip.svelte +127 -138
- package/src/SvTooltip.test.ts +73 -0
- package/src/SvTour.svelte +204 -176
- package/src/SvTree.svelte +377 -377
- package/src/SvTreeSelect.svelte +230 -229
- package/src/a11y.contract.test.ts +49 -49
- package/src/a11y.test.ts +59 -59
- package/src/a11y.ts +61 -61
- package/src/build-api.ts +870 -847
- package/src/cell-formatting.ts +169 -169
- package/src/cell-render.ts +469 -469
- package/src/chart-export.ts +201 -201
- package/src/chart.ts +2296 -2296
- package/src/collaboration.test.ts +104 -104
- package/src/collaboration.ts +167 -167
- package/src/columns.ts +5 -0
- package/src/conditional-formatting.test.ts +104 -0
- package/src/conditional-formatting.ts +176 -19
- package/src/core.performance.test.ts +30 -30
- package/src/core.ts +1111 -1111
- package/src/createAutocomplete.svelte.ts +132 -132
- package/src/createCarousel.svelte.ts +104 -0
- package/src/createCombobox.svelte.ts +179 -179
- package/src/createCommand.svelte.ts +125 -0
- package/src/createCountryInput.svelte.ts +157 -157
- package/src/createDropdownList.svelte.ts +162 -162
- package/src/createForm.svelte.ts +333 -0
- package/src/createGrid.svelte.ts +42 -42
- package/src/createGrid.test.ts +10 -10
- package/src/createGridState.svelte.ts +17 -17
- package/src/createMenu.svelte.ts +202 -0
- package/src/createOverlay.svelte.ts +101 -0
- package/src/createPagination.test.ts +65 -0
- package/src/createPagination.ts +84 -0
- package/src/createPopoverSelect.svelte.ts +206 -210
- package/src/createStepper.test.ts +62 -0
- package/src/createStepper.ts +61 -0
- package/src/createTooltip.svelte.ts +86 -0
- package/src/createTree.svelte.ts +319 -319
- package/src/datetime/timezone.test.ts +69 -0
- package/src/datetime/timezone.ts +134 -0
- package/src/dock-context.ts +47 -0
- package/src/dock-manager-model.test.ts +275 -0
- package/src/dock-manager-model.ts +593 -0
- package/src/dock-model.test.ts +163 -0
- package/src/dock-model.ts +368 -0
- package/src/dock-popout.ts +94 -0
- package/src/editing.test.ts +859 -859
- package/src/editing.ts +675 -675
- package/src/editor-contract.ts +2 -0
- package/src/export-data-api.test.ts +126 -126
- package/src/export-format.test.ts +107 -107
- package/src/export-format.ts +598 -598
- package/src/filter-operators.test.ts +59 -0
- package/src/filter-operators.ts +35 -2
- package/src/filtering/excel-filters.test.ts +86 -1
- package/src/filtering/excel-filters.ts +65 -0
- package/src/flex-render.ts +3 -3
- package/src/form-field.ts +87 -0
- package/src/index.ts +623 -469
- package/src/keyboard.test.ts +59 -59
- package/src/keyboard.ts +97 -97
- package/src/list-nav.test.ts +49 -0
- package/src/list-nav.ts +29 -0
- package/src/list-option.ts +2 -0
- package/src/menu-item.ts +21 -0
- package/src/menus.test.ts +48 -0
- package/src/menus.ts +639 -582
- package/src/merge-objects.ts +48 -48
- package/src/overlays.test.ts +90 -90
- package/src/panel-resize.ts +52 -0
- package/src/popover.bounds.test.ts +93 -0
- package/src/popover.ts +51 -7
- package/src/recurrence.test.ts +88 -1
- package/src/recurrence.ts +166 -15
- package/src/render-component.ts +28 -28
- package/src/row-drag.ts +10 -0
- package/src/scheduler-ical.test.ts +68 -0
- package/src/scheduler-ical.ts +180 -0
- package/src/scheduler-model.test.ts +546 -0
- package/src/scheduler-model.ts +853 -0
- package/src/scheduler-view.svelte.ts +33 -0
- package/src/selection.test.ts +754 -754
- package/src/selection.ts +600 -600
- package/src/server-data-source.test.ts +289 -289
- package/src/server-data-source.ts +413 -413
- package/src/sparkline.test.ts +68 -68
- package/src/sparkline.ts +169 -169
- package/src/spreadsheet.test.ts +489 -489
- package/src/spreadsheet.ts +312 -304
- package/src/static-functions.ts +11 -11
- package/src/subscribe.ts +38 -38
- package/src/svgrid-wrapper.types.ts +501 -501
- package/src/svgrid.behavior.test.ts +706 -706
- package/src/svgrid.charting.test.ts +527 -527
- package/src/svgrid.effect-driven-filter.svelte.test.ts +116 -0
- package/src/svgrid.features.test.ts +157 -157
- package/src/svgrid.new-features.wrapper.test.ts +251 -251
- package/src/svgrid.wrapper.test.ts +40 -40
- package/src/test-setup.ts +62 -62
- package/src/themes/index.ts +159 -159
- package/src/ui-app.types.ts +3 -0
- package/src/virtual.test.ts +6 -4
- 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/ui-app.types.d.ts
CHANGED
|
@@ -65,6 +65,9 @@ export type TourStep = {
|
|
|
65
65
|
target?: string | HTMLElement;
|
|
66
66
|
title?: string;
|
|
67
67
|
content: string;
|
|
68
|
+
/** Optional illustration shown as a banner above the title. A URL / data-URI
|
|
69
|
+
* (rendered as an `<img>`) or inline SVG/HTML markup (author-controlled). */
|
|
70
|
+
image?: string;
|
|
68
71
|
};
|
|
69
72
|
/** One entry in a timeline. */
|
|
70
73
|
export type TimelineItem = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@svgrid/grid",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
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",
|
|
@@ -10,6 +10,10 @@
|
|
|
10
10
|
"directory": "packages/grid"
|
|
11
11
|
},
|
|
12
12
|
"homepage": "https://svgrid.com",
|
|
13
|
+
"funding": {
|
|
14
|
+
"type": "commercial",
|
|
15
|
+
"url": "https://svgrid.com/pricing"
|
|
16
|
+
},
|
|
13
17
|
"keywords": [
|
|
14
18
|
"svelte",
|
|
15
19
|
"grid",
|
|
@@ -68,14 +72,6 @@
|
|
|
68
72
|
"src",
|
|
69
73
|
"themes"
|
|
70
74
|
],
|
|
71
|
-
"scripts": {
|
|
72
|
-
"clean": "rimraf ./build && rimraf ./dist",
|
|
73
|
-
"test:eslint": "eslint ./src",
|
|
74
|
-
"test:types": "svelte-check --tsconfig ./tsconfig.json",
|
|
75
|
-
"test:lib": "vitest run --coverage",
|
|
76
|
-
"test:build": "publint --strict",
|
|
77
|
-
"build": "svelte-package --input ./src --output ./dist && node ../../tools/strip-dist-tests.mjs ./dist && node ./scripts/build-cdn.mjs && node ./scripts/build-themes.mjs"
|
|
78
|
-
},
|
|
79
75
|
"devDependencies": {
|
|
80
76
|
"@sveltejs/package": "^2.5.7",
|
|
81
77
|
"@sveltejs/vite-plugin-svelte": "^7.0.0",
|
|
@@ -88,5 +84,13 @@
|
|
|
88
84
|
},
|
|
89
85
|
"peerDependencies": {
|
|
90
86
|
"svelte": "^5.0.0"
|
|
87
|
+
},
|
|
88
|
+
"scripts": {
|
|
89
|
+
"clean": "rimraf ./build && rimraf ./dist",
|
|
90
|
+
"test:eslint": "eslint ./src",
|
|
91
|
+
"test:types": "svelte-check --tsconfig ./tsconfig.json",
|
|
92
|
+
"test:lib": "vitest run --coverage",
|
|
93
|
+
"test:build": "publint --strict",
|
|
94
|
+
"build": "svelte-package --input ./src --output ./dist && node ../../tools/strip-dist-tests.mjs ./dist && node ./scripts/build-cdn.mjs && node ./scripts/build-themes.mjs"
|
|
91
95
|
}
|
|
92
|
-
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* DockNodeView - the recursive renderer for one node of a <SvDockLayout> tree.
|
|
4
|
+
* A `group` becomes a flex row/column of children with draggable splitters
|
|
5
|
+
* between them; a `tabs` leaf becomes a tab strip over the active pane's
|
|
6
|
+
* content. All tree edits go through the pure `dock-model`; this file only
|
|
7
|
+
* paints and wires gestures. It renders itself for nested groups.
|
|
8
|
+
*/
|
|
9
|
+
import { getContext } from 'svelte'
|
|
10
|
+
import Self from './DockNodeView.svelte'
|
|
11
|
+
import { DOCK_CONTEXT, type DockContext } from './dock-context'
|
|
12
|
+
import { leafMinSize, type DockNode, type DockGroup } from './dock-model'
|
|
13
|
+
|
|
14
|
+
let { node }: { node: DockNode } = $props()
|
|
15
|
+
|
|
16
|
+
const ctx = getContext<DockContext>(DOCK_CONTEXT)
|
|
17
|
+
|
|
18
|
+
// ---- splitter drag (group children resize) ----------------------------
|
|
19
|
+
let groupEl = $state<HTMLElement | null>(null)
|
|
20
|
+
|
|
21
|
+
/** A child's minimum size (px): a leaf's largest per-pane `minSize`, else 0. */
|
|
22
|
+
function nodeMin(n: DockNode | undefined): number {
|
|
23
|
+
return n && n.type === 'tabs' ? leafMinSize(n) : 0
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function onSplitterDown(e: PointerEvent, group: DockGroup, index: number) {
|
|
27
|
+
if (e.button !== 0 || !groupEl) return
|
|
28
|
+
e.preventDefault()
|
|
29
|
+
const vertical = group.direction === 'column'
|
|
30
|
+
const rect = groupEl.getBoundingClientRect()
|
|
31
|
+
const total = vertical ? rect.height : rect.width
|
|
32
|
+
if (total <= 0) return
|
|
33
|
+
const startSizes = group.sizes.slice()
|
|
34
|
+
const startPos = vertical ? e.clientY : e.clientX
|
|
35
|
+
// Only the two panes adjacent to this gutter move; the rest stay put. Each
|
|
36
|
+
// honors its own minimum (a leaf's largest per-pane `minSize`, else global).
|
|
37
|
+
const a = index
|
|
38
|
+
const b = index + 1
|
|
39
|
+
const minA = Math.max(ctx.minSize(), nodeMin(group.children[a])) / total
|
|
40
|
+
const minB = Math.max(ctx.minSize(), nodeMin(group.children[b])) / total
|
|
41
|
+
const pairTotal = startSizes[a]! + startSizes[b]!
|
|
42
|
+
|
|
43
|
+
const onMove = (ev: PointerEvent) => {
|
|
44
|
+
const delta = ((vertical ? ev.clientY : ev.clientX) - startPos) / total
|
|
45
|
+
let fa = Math.min(Math.max(startSizes[a]! + delta, minA), pairTotal - minB)
|
|
46
|
+
const next = startSizes.slice()
|
|
47
|
+
next[a] = fa
|
|
48
|
+
next[b] = pairTotal - fa
|
|
49
|
+
ctx.resize(group.id, next)
|
|
50
|
+
}
|
|
51
|
+
const onUp = () => {
|
|
52
|
+
window.removeEventListener('pointermove', onMove)
|
|
53
|
+
window.removeEventListener('pointerup', onUp)
|
|
54
|
+
document.body.style.userSelect = ''
|
|
55
|
+
document.body.style.cursor = ''
|
|
56
|
+
}
|
|
57
|
+
document.body.style.userSelect = 'none'
|
|
58
|
+
document.body.style.cursor = vertical ? 'row-resize' : 'col-resize'
|
|
59
|
+
window.addEventListener('pointermove', onMove)
|
|
60
|
+
window.addEventListener('pointerup', onUp)
|
|
61
|
+
}
|
|
62
|
+
</script>
|
|
63
|
+
|
|
64
|
+
{#if node.type === 'group'}
|
|
65
|
+
<div
|
|
66
|
+
class="sv-dock__group sv-dock__group--{node.direction}"
|
|
67
|
+
bind:this={groupEl}
|
|
68
|
+
role="group"
|
|
69
|
+
>
|
|
70
|
+
{#each node.children as child, i (child.id)}
|
|
71
|
+
<div class="sv-dock__cell" style:flex-grow={node.sizes[i] ?? 1} style:flex-basis="0">
|
|
72
|
+
<Self node={child} />
|
|
73
|
+
</div>
|
|
74
|
+
{#if i < node.children.length - 1}
|
|
75
|
+
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
76
|
+
<div
|
|
77
|
+
class="sv-dock__splitter sv-dock__splitter--{node.direction}"
|
|
78
|
+
role="separator"
|
|
79
|
+
aria-orientation={node.direction === 'column' ? 'horizontal' : 'vertical'}
|
|
80
|
+
onpointerdown={(e) => onSplitterDown(e, node as DockGroup, i)}
|
|
81
|
+
></div>
|
|
82
|
+
{/if}
|
|
83
|
+
{/each}
|
|
84
|
+
</div>
|
|
85
|
+
{:else}
|
|
86
|
+
{@const active = node.panes[node.active] ?? node.panes[0]}
|
|
87
|
+
{@const reorder = ctx.reorderTarget?.() ?? null}
|
|
88
|
+
{@const reorderHere = reorder && reorder.tabsId === node.id ? reorder.index : -1}
|
|
89
|
+
{@const hp = ctx.headerPosition?.() ?? 'top'}
|
|
90
|
+
<!-- A single-pane leaf in an auto-hide fly-out drops its (redundant with the edge strip)
|
|
91
|
+
tab button, leaving just the leaf actions (pin). -->
|
|
92
|
+
{@const bareSingle = !!ctx.hideSingleTab?.() && node.panes.length === 1}
|
|
93
|
+
<div class="sv-dock__leaf sv-dock__leaf--h-{hp}" class:is-focused={ctx.focusedLeaf?.() === node.id} data-dock-tabs={node.id}>
|
|
94
|
+
<div class="sv-dock__tabstrip" class:is-bare={bareSingle} role="tablist">
|
|
95
|
+
{#if !bareSingle}
|
|
96
|
+
{#each node.panes as p, i (p.id)}
|
|
97
|
+
{#if reorderHere === i}<div class="sv-dock__ins" aria-hidden="true"></div>{/if}
|
|
98
|
+
<div
|
|
99
|
+
class="sv-dock__tab"
|
|
100
|
+
class:is-active={i === node.active}
|
|
101
|
+
role="tab"
|
|
102
|
+
aria-selected={i === node.active}
|
|
103
|
+
tabindex={i === node.active ? 0 : -1}
|
|
104
|
+
data-dock-tab={p.id}
|
|
105
|
+
data-tab-index={i}
|
|
106
|
+
onpointerdown={(e) => {
|
|
107
|
+
if (e.button === 0) { ctx.activate(node.id, i); ctx.beginDrag(e, p.id, node.id) }
|
|
108
|
+
}}
|
|
109
|
+
onkeydown={(e) => {
|
|
110
|
+
if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); ctx.activate(node.id, i) }
|
|
111
|
+
}}
|
|
112
|
+
>
|
|
113
|
+
<span class="sv-dock__tab-label">{p.title}</span>
|
|
114
|
+
{#if p.closable !== false}
|
|
115
|
+
<button
|
|
116
|
+
type="button"
|
|
117
|
+
class="sv-dock__tab-close"
|
|
118
|
+
aria-label={`Close ${p.title}`}
|
|
119
|
+
title="Close"
|
|
120
|
+
onpointerdown={(e) => e.stopPropagation()}
|
|
121
|
+
onclick={(e) => { e.stopPropagation(); ctx.close(p.id) }}
|
|
122
|
+
>×</button>
|
|
123
|
+
{/if}
|
|
124
|
+
</div>
|
|
125
|
+
{/each}
|
|
126
|
+
{#if reorderHere === node.panes.length}<div class="sv-dock__ins" aria-hidden="true"></div>{/if}
|
|
127
|
+
{/if}
|
|
128
|
+
{#if ctx.leafActions}
|
|
129
|
+
<div class="sv-dock__leafctl">{@render ctx.leafActions(node)}</div>
|
|
130
|
+
{/if}
|
|
131
|
+
</div>
|
|
132
|
+
|
|
133
|
+
{#if ctx.keepAlive?.()}
|
|
134
|
+
<!-- Keep every tab mounted; hide the inactive ones so their state persists. -->
|
|
135
|
+
{#each node.panes as p (p.id)}
|
|
136
|
+
<div class="sv-dock__content" role="tabpanel" style:display={p.id === active?.id ? '' : 'none'}>
|
|
137
|
+
{@render ctx.pane(p)}
|
|
138
|
+
</div>
|
|
139
|
+
{/each}
|
|
140
|
+
{:else}
|
|
141
|
+
<!-- Only the active tab renders; `{#key}` remounts on switch so a pane's
|
|
142
|
+
content never bleeds into the next (use keepAlive to persist state). -->
|
|
143
|
+
{#if active}
|
|
144
|
+
{#key active.id}
|
|
145
|
+
<div class="sv-dock__content" role="tabpanel">{@render ctx.pane(active)}</div>
|
|
146
|
+
{/key}
|
|
147
|
+
{/if}
|
|
148
|
+
{/if}
|
|
149
|
+
|
|
150
|
+
{#if ctx.dropTarget()?.tabsId === node.id}
|
|
151
|
+
{@const dt = ctx.dropTarget()!}
|
|
152
|
+
{@const zone = dt.zone}
|
|
153
|
+
{@const centerOnly = dt.centerOnly === true}
|
|
154
|
+
<div class="sv-dock__dropzone" aria-hidden="true">
|
|
155
|
+
<!-- Preview: the region the panel will occupy (only when over a chip). -->
|
|
156
|
+
{#if zone}<div class="sv-dock__drop-hint sv-dock__drop-hint--{zone}"></div>{/if}
|
|
157
|
+
<!-- Guide: dock targets. Drop ON a chip to dock; off it, the tab floats. -->
|
|
158
|
+
<div class="sv-dock__guide" class:is-center-only={centerOnly}>
|
|
159
|
+
{#if !centerOnly}
|
|
160
|
+
<div class="sv-dock__guide-cell sv-dock__guide-cell--top" class:is-on={zone === 'top'}></div>
|
|
161
|
+
{/if}
|
|
162
|
+
<div class="sv-dock__guide-row">
|
|
163
|
+
{#if !centerOnly}
|
|
164
|
+
<div class="sv-dock__guide-cell sv-dock__guide-cell--left" class:is-on={zone === 'left'}></div>
|
|
165
|
+
{/if}
|
|
166
|
+
<div class="sv-dock__guide-cell sv-dock__guide-cell--center" class:is-on={zone === 'center'}></div>
|
|
167
|
+
{#if !centerOnly}
|
|
168
|
+
<div class="sv-dock__guide-cell sv-dock__guide-cell--right" class:is-on={zone === 'right'}></div>
|
|
169
|
+
{/if}
|
|
170
|
+
</div>
|
|
171
|
+
{#if !centerOnly}
|
|
172
|
+
<div class="sv-dock__guide-cell sv-dock__guide-cell--bottom" class:is-on={zone === 'bottom'}></div>
|
|
173
|
+
{/if}
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
{/if}
|
|
177
|
+
</div>
|
|
178
|
+
{/if}
|
|
179
|
+
|
|
180
|
+
<style>
|
|
181
|
+
.sv-dock__group { display: flex; width: 100%; height: 100%; min-width: 0; min-height: 0; }
|
|
182
|
+
.sv-dock__group--row { flex-direction: row; }
|
|
183
|
+
.sv-dock__group--column { flex-direction: column; }
|
|
184
|
+
.sv-dock__cell { min-width: 0; min-height: 0; overflow: hidden; display: flex; }
|
|
185
|
+
.sv-dock__cell > :global(*) { flex: 1; min-width: 0; min-height: 0; }
|
|
186
|
+
|
|
187
|
+
.sv-dock__splitter { flex: none; background: var(--sg-border, #e2e8f0); position: relative; touch-action: none; }
|
|
188
|
+
.sv-dock__splitter::after { content: ''; position: absolute; inset: -3px; }
|
|
189
|
+
.sv-dock__splitter--row { width: 4px; cursor: col-resize; }
|
|
190
|
+
.sv-dock__splitter--column { height: 4px; cursor: row-resize; }
|
|
191
|
+
.sv-dock__splitter:hover { background: var(--sg-accent, #2563eb); }
|
|
192
|
+
|
|
193
|
+
.sv-dock__leaf {
|
|
194
|
+
position: relative; display: flex; flex-direction: column; width: 100%; height: 100%;
|
|
195
|
+
min-width: 0; min-height: 0; background: var(--sg-bg, #fff);
|
|
196
|
+
border: 1px solid var(--sg-border, #e2e8f0); border-radius: 8px; overflow: hidden;
|
|
197
|
+
}
|
|
198
|
+
.sv-dock__tabstrip {
|
|
199
|
+
display: flex; flex: none; gap: 2px; padding: 4px 4px 0; overflow-x: auto;
|
|
200
|
+
background: var(--sg-header-bg, #f6f7f9); border-bottom: 1px solid var(--sg-border, #e2e8f0);
|
|
201
|
+
}
|
|
202
|
+
/* Focused leaf: accent-tinted header + active-tab underline. */
|
|
203
|
+
.sv-dock__leaf.is-focused > .sv-dock__tabstrip { background: color-mix(in srgb, var(--sg-accent, #2563eb) 8%, var(--sg-header-bg, #f6f7f9)); }
|
|
204
|
+
.sv-dock__leaf.is-focused .sv-dock__tab.is-active { box-shadow: inset 0 -2px 0 var(--sg-accent, #2563eb); }
|
|
205
|
+
/* Header on the bottom: content first, strip below with flipped chrome. */
|
|
206
|
+
.sv-dock__leaf--h-bottom { flex-direction: column-reverse; }
|
|
207
|
+
.sv-dock__leaf--h-bottom .sv-dock__tabstrip { padding: 0 4px 4px; border-bottom: none; border-top: 1px solid var(--sg-border, #e2e8f0); }
|
|
208
|
+
.sv-dock__leaf--h-bottom .sv-dock__tab { border-radius: 0 0 7px 7px; border-top: none; border-bottom: 1px solid transparent; }
|
|
209
|
+
.sv-dock__leaf--h-bottom .sv-dock__tab.is-active { border-color: var(--sg-border, #e2e8f0); border-top: none; }
|
|
210
|
+
|
|
211
|
+
/* Header on the left/right: a VERTICAL tab strip beside the content. */
|
|
212
|
+
.sv-dock__leaf--h-left { flex-direction: row; }
|
|
213
|
+
.sv-dock__leaf--h-right { flex-direction: row-reverse; }
|
|
214
|
+
.sv-dock__leaf--h-left .sv-dock__tabstrip,
|
|
215
|
+
.sv-dock__leaf--h-right .sv-dock__tabstrip {
|
|
216
|
+
flex-direction: column; overflow-x: hidden; overflow-y: auto; padding: 4px 0 4px 4px;
|
|
217
|
+
border-bottom: none;
|
|
218
|
+
}
|
|
219
|
+
.sv-dock__leaf--h-left .sv-dock__tabstrip { border-right: 1px solid var(--sg-border, #e2e8f0); }
|
|
220
|
+
.sv-dock__leaf--h-right .sv-dock__tabstrip { padding: 4px 4px 4px 0; border-left: 1px solid var(--sg-border, #e2e8f0); }
|
|
221
|
+
.sv-dock__leaf--h-left .sv-dock__tab,
|
|
222
|
+
.sv-dock__leaf--h-right .sv-dock__tab {
|
|
223
|
+
writing-mode: vertical-rl; padding: 10px 6px; border-radius: 7px 0 0 7px; border-bottom: 1px solid transparent;
|
|
224
|
+
max-height: 200px; overflow: hidden;
|
|
225
|
+
}
|
|
226
|
+
.sv-dock__leaf--h-right .sv-dock__tab { border-radius: 0 7px 7px 0; }
|
|
227
|
+
.sv-dock__leaf--h-left .sv-dock__tab.is-active,
|
|
228
|
+
.sv-dock__leaf--h-right .sv-dock__tab.is-active { border-color: var(--sg-border, #e2e8f0); }
|
|
229
|
+
/* Stack controls go to the bottom of a vertical strip. */
|
|
230
|
+
.sv-dock__leaf--h-left .sv-dock__leafctl,
|
|
231
|
+
.sv-dock__leaf--h-right .sv-dock__leafctl { flex-direction: column; margin-inline-start: 0; margin-top: auto; padding: 2px 0; align-self: center; }
|
|
232
|
+
/* Reorder insertion line runs horizontally between stacked tabs. */
|
|
233
|
+
.sv-dock__leaf--h-left .sv-dock__ins,
|
|
234
|
+
.sv-dock__leaf--h-right .sv-dock__ins { width: auto; height: 3px; align-self: stretch; margin: 0 3px; }
|
|
235
|
+
.sv-dock__tab {
|
|
236
|
+
display: inline-flex; align-items: center; gap: 6px; padding: 6px 10px; cursor: grab;
|
|
237
|
+
font-size: 12.5px; font-weight: 600; color: var(--sg-muted, #64748b); white-space: nowrap;
|
|
238
|
+
border: 1px solid transparent; border-bottom: none; border-radius: 7px 7px 0 0; user-select: none;
|
|
239
|
+
touch-action: none;
|
|
240
|
+
}
|
|
241
|
+
.sv-dock__tab:hover { color: var(--sg-fg, #0f172a); }
|
|
242
|
+
.sv-dock__tab.is-active {
|
|
243
|
+
color: var(--sg-fg, #0f172a); background: var(--sg-bg, #fff);
|
|
244
|
+
border-color: var(--sg-border, #e2e8f0);
|
|
245
|
+
}
|
|
246
|
+
.sv-dock__tab-close {
|
|
247
|
+
display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px;
|
|
248
|
+
padding: 0; font-size: 15px; line-height: 1; color: var(--sg-muted, #94a3b8); cursor: pointer;
|
|
249
|
+
background: none; border: none; border-radius: 4px;
|
|
250
|
+
}
|
|
251
|
+
.sv-dock__tab-close:hover { background: var(--sg-row-hover-bg, #f1f5f9); color: var(--sg-danger, #dc2626); }
|
|
252
|
+
/* Stack-header controls, pinned to the right of the tab strip. */
|
|
253
|
+
.sv-dock__leafctl { margin-inline-start: auto; align-self: center; display: flex; align-items: center; gap: 1px; padding: 0 2px 3px; }
|
|
254
|
+
.sv-dock__content { flex: 1; min-height: 0; overflow: auto; }
|
|
255
|
+
|
|
256
|
+
/* Tab-reorder insertion line. */
|
|
257
|
+
.sv-dock__ins {
|
|
258
|
+
flex: none; align-self: stretch; width: 3px; margin: 3px 0; border-radius: 2px;
|
|
259
|
+
background: var(--sg-accent, #2563eb); box-shadow: 0 0 0 1px color-mix(in srgb, var(--sg-accent, #2563eb) 40%, transparent);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/* Drop-zone indicators shown on the leaf under the pointer while dragging. */
|
|
263
|
+
.sv-dock__dropzone { position: absolute; inset: 0; pointer-events: none; z-index: 6; }
|
|
264
|
+
/* Ring around the whole targeted leaf, so which pane you're over is obvious. */
|
|
265
|
+
.sv-dock__dropzone::before {
|
|
266
|
+
content: ''; position: absolute; inset: 2px; border-radius: 7px;
|
|
267
|
+
box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--sg-accent, #2563eb) 32%, transparent);
|
|
268
|
+
}
|
|
269
|
+
.sv-dock__drop-hint {
|
|
270
|
+
position: absolute; background: color-mix(in srgb, var(--sg-accent, #2563eb) 22%, transparent);
|
|
271
|
+
border: 2px solid var(--sg-accent, #2563eb); border-radius: 6px; transition: inset 90ms ease;
|
|
272
|
+
}
|
|
273
|
+
.sv-dock__drop-hint--center { inset: 8px; }
|
|
274
|
+
.sv-dock__drop-hint--left { inset: 4px 50% 4px 4px; }
|
|
275
|
+
.sv-dock__drop-hint--right { inset: 4px 4px 4px 50%; }
|
|
276
|
+
.sv-dock__drop-hint--top { inset: 4px 4px 50% 4px; }
|
|
277
|
+
.sv-dock__drop-hint--bottom { inset: 50% 4px 4px 4px; }
|
|
278
|
+
|
|
279
|
+
/* The 5-direction dock guide (VS-style): a plus of targets, active one lit. */
|
|
280
|
+
.sv-dock__guide {
|
|
281
|
+
position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
|
|
282
|
+
display: flex; flex-direction: column; align-items: center; gap: 4px;
|
|
283
|
+
padding: 6px; border-radius: 10px;
|
|
284
|
+
background: color-mix(in srgb, var(--sg-bg, #fff) 82%, transparent);
|
|
285
|
+
box-shadow: 0 6px 20px -6px rgba(15,23,42,0.45); border: 1px solid var(--sg-border, #e2e8f0);
|
|
286
|
+
}
|
|
287
|
+
.sv-dock__guide-row { display: flex; gap: 4px; }
|
|
288
|
+
.sv-dock__guide-cell {
|
|
289
|
+
width: 26px; height: 26px; border-radius: 6px; position: relative;
|
|
290
|
+
background: var(--sg-header-bg, #f1f5f9); border: 1px solid var(--sg-border, #cbd5e1);
|
|
291
|
+
}
|
|
292
|
+
.sv-dock__guide-cell::after {
|
|
293
|
+
content: ''; position: absolute; border-radius: 3px;
|
|
294
|
+
background: color-mix(in srgb, var(--sg-accent, #2563eb) 55%, transparent);
|
|
295
|
+
}
|
|
296
|
+
.sv-dock__guide-cell--center::after { inset: 5px; }
|
|
297
|
+
.sv-dock__guide-cell--left::after { inset: 5px 13px 5px 5px; }
|
|
298
|
+
.sv-dock__guide-cell--right::after { inset: 5px 5px 5px 13px; }
|
|
299
|
+
.sv-dock__guide-cell--top::after { inset: 5px 5px 13px 5px; }
|
|
300
|
+
.sv-dock__guide-cell--bottom::after { inset: 13px 5px 5px 5px; }
|
|
301
|
+
.sv-dock__guide-cell.is-on {
|
|
302
|
+
background: color-mix(in srgb, var(--sg-accent, #2563eb) 18%, var(--sg-bg, #fff));
|
|
303
|
+
border-color: var(--sg-accent, #2563eb);
|
|
304
|
+
}
|
|
305
|
+
.sv-dock__guide-cell.is-on::after { background: var(--sg-accent, #2563eb); }
|
|
306
|
+
</style>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* DockPopoutHost - the tiny root mounted into a popped-out browser window. It
|
|
4
|
+
* just renders the manager's `pane` snippet for the popped pane, so a pop-out
|
|
5
|
+
* shows the exact same content as the docked view.
|
|
6
|
+
*/
|
|
7
|
+
import type { Snippet } from 'svelte'
|
|
8
|
+
import type { DockPane } from './dock-model'
|
|
9
|
+
|
|
10
|
+
let { pane, paneData }: { pane: Snippet<[DockPane]>; paneData: DockPane } = $props()
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<div class="sv-popout-host">{@render pane(paneData)}</div>
|
|
14
|
+
|
|
15
|
+
<style>
|
|
16
|
+
.sv-popout-host { width: 100%; height: 100vh; overflow: auto; box-sizing: border-box; }
|
|
17
|
+
</style>
|
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}
|