@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/README.md
CHANGED
|
@@ -118,9 +118,16 @@ Compatibility aliases are provided for the framework-neutral names: `createGrid`
|
|
|
118
118
|
|
|
119
119
|
SvGrid publishes an [MCP server](https://www.npmjs.com/package/@svgrid/mcp) and `llms.txt` / `llms-full.txt`, so Claude, Cursor, and Zed answer with accurate, version-pinned APIs and all 280+ demo sources as context - not hallucinated methods.
|
|
120
120
|
|
|
121
|
-
## Enterprise
|
|
121
|
+
## Enterprise features
|
|
122
122
|
|
|
123
|
-
The MIT core is free for any use, including commercial. The optional [`@svgrid/enterprise`](https://www.npmjs.com/package/@svgrid/enterprise) pack
|
|
123
|
+
The MIT core is free for any use, including commercial, with **no feature gating** - sorting, filtering, editing, virtualization, and the **server-side row model** (sort / filter / group pushdown) all ship in the free package. The optional [`@svgrid/enterprise`](https://www.npmjs.com/package/@svgrid/enterprise) pack layers on the export- and analytics-heavy features teams tend to need last:
|
|
124
|
+
|
|
125
|
+
- **Excel / PDF / CSV / TSV / HTML export** plus paginated print.
|
|
126
|
+
- **Pivot tables** with a drag-and-drop pivot Designer.
|
|
127
|
+
- **Scheduler / calendar view** and Kanban roll-ups for larger deployments.
|
|
128
|
+
- **AI helpers** and SvGrid Studio for data-app scaffolding.
|
|
129
|
+
|
|
130
|
+
OSS projects receive an Enterprise key free. See the [Enterprise docs](https://svgrid.com/docs) and [Pricing](https://svgrid.com/pricing).
|
|
124
131
|
|
|
125
132
|
## Documentation
|
|
126
133
|
|
|
@@ -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>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DockPopoutHost - the tiny root mounted into a popped-out browser window. It
|
|
3
|
+
* just renders the manager's `pane` snippet for the popped pane, so a pop-out
|
|
4
|
+
* shows the exact same content as the docked view.
|
|
5
|
+
*/
|
|
6
|
+
import type { Snippet } from 'svelte';
|
|
7
|
+
import type { DockPane } from './dock-model';
|
|
8
|
+
type $$ComponentProps = {
|
|
9
|
+
pane: Snippet<[DockPane]>;
|
|
10
|
+
paneData: DockPane;
|
|
11
|
+
};
|
|
12
|
+
declare const DockPopoutHost: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
13
|
+
type DockPopoutHost = ReturnType<typeof DockPopoutHost>;
|
|
14
|
+
export default DockPopoutHost;
|
package/dist/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}
|