@svgrid/grid 2.2.16 → 2.2.17
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 +1 -1
- package/dist/GridFooter.svelte +12 -11
- package/dist/SvAnchor.svelte +65 -0
- package/dist/SvAnchor.svelte.d.ts +24 -0
- package/dist/SvAspectRatio.svelte +38 -0
- package/dist/SvAspectRatio.svelte.d.ts +16 -0
- package/dist/SvAutoComplete.svelte +52 -7
- package/dist/SvAutoComplete.svelte.d.ts +4 -1
- package/dist/SvBlockquote.svelte +43 -0
- package/dist/SvBlockquote.svelte.d.ts +16 -0
- package/dist/SvCalendar.svelte +33 -2
- package/dist/SvCalendar.svelte.d.ts +8 -1
- package/dist/SvCheckBox.svelte +6 -2
- package/dist/SvCode.svelte +52 -0
- package/dist/SvCode.svelte.d.ts +19 -0
- package/dist/SvCollapsible.svelte +75 -0
- package/dist/SvCollapsible.svelte.d.ts +27 -0
- package/dist/SvColorInput.svelte +11 -17
- package/dist/SvColorInput.svelte.d.ts +2 -0
- package/dist/SvComboBox.svelte +85 -8
- package/dist/SvComboBox.svelte.d.ts +14 -0
- package/dist/SvCountryInput.svelte +2 -2
- package/dist/SvCountryInput.svelte.d.ts +1 -1
- package/dist/SvDropDownList.svelte +154 -51
- package/dist/SvDropDownList.svelte.d.ts +17 -3
- package/dist/SvDurationInput.svelte +59 -41
- package/dist/SvDurationInput.svelte.d.ts +18 -0
- package/dist/SvField.svelte +203 -12
- package/dist/SvField.svelte.d.ts +45 -8
- package/dist/SvForm.svelte +195 -21
- package/dist/SvForm.svelte.d.ts +23 -0
- package/dist/SvGrid.controller.svelte.d.ts +12 -1
- package/dist/SvGrid.controller.svelte.js +87 -7
- package/dist/SvGrid.svelte +383 -181
- package/dist/SvGrid.types.d.ts +123 -2
- package/dist/SvGridChartView.svelte +70 -0
- package/dist/SvGridChartView.svelte.d.ts +11 -0
- package/dist/SvGridDropdown.svelte +9 -2
- package/dist/SvGridSelect.svelte +5 -2
- package/dist/SvGridSelect.svelte.d.ts +1 -1
- package/dist/SvGroup.svelte +41 -0
- package/dist/SvGroup.svelte.d.ts +27 -0
- package/dist/SvHoverCard.svelte +70 -0
- package/dist/SvHoverCard.svelte.d.ts +41 -0
- package/dist/SvKbd.svelte +51 -0
- package/dist/SvKbd.svelte.d.ts +18 -0
- package/dist/SvList.svelte +55 -0
- package/dist/SvList.svelte.d.ts +23 -0
- package/dist/SvListBox.svelte +166 -77
- package/dist/SvListBox.svelte.d.ts +17 -4
- package/dist/SvLoadingOverlay.svelte +53 -0
- package/dist/SvLoadingOverlay.svelte.d.ts +28 -0
- package/dist/SvMark.svelte +36 -0
- package/dist/SvMark.svelte.d.ts +14 -0
- package/dist/SvMaskedInput.svelte +50 -35
- package/dist/SvMaskedInput.svelte.d.ts +17 -2
- package/dist/SvMenuList.svelte +32 -3
- package/dist/SvMenubar.svelte +200 -0
- package/dist/SvMenubar.svelte.d.ts +18 -0
- package/dist/SvMultiSelect.svelte +7 -4
- package/dist/SvMultiSelect.svelte.d.ts +1 -1
- package/dist/SvNumberInput.svelte +79 -42
- package/dist/SvNumberInput.svelte.d.ts +25 -0
- package/dist/SvOtpInput.svelte +2 -2
- package/dist/SvPasswordInput.svelte +51 -31
- package/dist/SvPasswordInput.svelte.d.ts +17 -0
- package/dist/SvPhoneInput.svelte +39 -28
- package/dist/SvPhoneInput.svelte.d.ts +4 -0
- package/dist/SvPopconfirm.svelte +79 -0
- package/dist/SvPopconfirm.svelte.d.ts +42 -0
- package/dist/SvPopover.svelte +87 -29
- package/dist/SvPopover.svelte.d.ts +18 -4
- package/dist/SvRadioGroup.svelte +5 -1
- package/dist/SvResult.svelte +73 -0
- package/dist/SvResult.svelte.d.ts +28 -0
- package/dist/SvSegmented.svelte +114 -0
- package/dist/SvSegmented.svelte.d.ts +29 -0
- package/dist/SvSimpleGrid.svelte +41 -0
- package/dist/SvSimpleGrid.svelte.d.ts +25 -0
- package/dist/SvSlider.svelte +23 -10
- package/dist/SvSpinner.svelte +43 -0
- package/dist/SvSpinner.svelte.d.ts +20 -0
- package/dist/SvStack.svelte +37 -0
- package/dist/SvStack.svelte.d.ts +24 -0
- package/dist/SvSwitchButton.svelte +6 -1
- package/dist/SvTagsInput.svelte +9 -5
- package/dist/SvText.svelte +76 -0
- package/dist/SvText.svelte.d.ts +31 -0
- package/dist/SvTextInput.svelte +75 -43
- package/dist/SvTextInput.svelte.d.ts +28 -1
- package/dist/SvTimePicker.svelte +32 -2
- package/dist/SvTimePicker.svelte.d.ts +8 -9
- package/dist/SvTitle.svelte +57 -0
- package/dist/SvTitle.svelte.d.ts +24 -0
- package/dist/SvToaster.svelte +41 -6
- package/dist/SvToggleButton.svelte +4 -1
- package/dist/SvTooltip.svelte +68 -34
- package/dist/SvTooltip.svelte.d.ts +14 -2
- package/dist/SvTree.svelte +81 -21
- package/dist/SvTree.svelte.d.ts +3 -2
- package/dist/SvTreeSelect.svelte +5 -2
- package/dist/SvTreeSelect.svelte.d.ts +1 -1
- package/dist/SvVisuallyHidden.svelte +49 -0
- package/dist/SvVisuallyHidden.svelte.d.ts +19 -0
- package/dist/ai.d.ts +289 -0
- package/dist/ai.js +1013 -0
- package/dist/board-view.svelte.d.ts +22 -0
- package/dist/board-view.svelte.js +13 -0
- package/dist/build-api.js +36 -6
- package/dist/cdn/GridMenus-0AK9O7qG.js +420 -0
- package/dist/cdn/GridMenus-BjUoCXoD.js +416 -0
- package/dist/cdn/SvDateTimePicker-CYC7gRER.js +2176 -0
- package/dist/cdn/SvDateTimePicker-DtQKd4Ns.js +2198 -0
- package/dist/cdn/SvGridChart-BcLCYvw9.js +1195 -0
- package/dist/cdn/SvGridChart-BhnFdLd0.js +1203 -0
- package/dist/cdn/SvGridChartPanel-Cmx9DHAS.js +561 -0
- package/dist/cdn/SvGridChartPanel-DvjwxLvK.js +577 -0
- package/dist/cdn/SvGridChartView-B40DTJSX.js +54 -0
- package/dist/cdn/SvGridChartView-PwqI4s02.js +53 -0
- package/dist/cdn/SvGridDropdown-DjALc_4f.js +255 -0
- package/dist/cdn/SvGridDropdown-hpnHvOGt.js +254 -0
- package/dist/cdn/chart-T1usDN0o.js +1212 -0
- package/dist/cdn/disclose-version-DoD9AFD_.js +2958 -0
- package/dist/cdn/export-format-JT5pWVT8.js +561 -0
- package/dist/cdn/popover-P-9P2YYn.js +69 -0
- package/dist/cdn/rolldown-runtime-Dy4uBu1J.js +11 -0
- package/dist/cdn/src-BLhdLmoN.js +25707 -0
- package/dist/cdn/src-BwnUVj3T.js +25623 -0
- package/dist/cdn/svgrid.js +9 -32897
- package/dist/cdn/svgrid.svelte-external.js +9 -30052
- package/dist/cell-formatting.d.ts +2 -2
- package/dist/cell-render.js +4 -4
- package/dist/chart-view.svelte.d.ts +25 -0
- package/dist/chart-view.svelte.js +14 -0
- package/dist/createCombobox.svelte.d.ts +5 -0
- package/dist/createCombobox.svelte.js +21 -5
- package/dist/createDropdownList.svelte.d.ts +3 -0
- package/dist/createDropdownList.svelte.js +8 -2
- package/dist/createForm.svelte.d.ts +18 -0
- package/dist/createForm.svelte.js +51 -6
- package/dist/createMenu.svelte.js +27 -0
- package/dist/createPopoverSelect.svelte.d.ts +3 -0
- package/dist/createPopoverSelect.svelte.js +9 -1
- package/dist/createSlider.svelte.d.ts +8 -21
- package/dist/createSlider.svelte.js +34 -0
- package/dist/createTooltip.svelte.d.ts +12 -0
- package/dist/createTooltip.svelte.js +72 -9
- package/dist/editor-contract.d.ts +15 -0
- package/dist/export-provider.d.ts +27 -0
- package/dist/export-provider.js +9 -0
- package/dist/filter-operators.d.ts +6 -0
- package/dist/filter-operators.js +33 -0
- package/dist/form-field.d.ts +45 -2
- package/dist/grid-messages.d.ts +61 -0
- package/dist/grid-messages.js +72 -0
- package/dist/group-display.d.ts +62 -0
- package/dist/group-display.js +78 -0
- package/dist/index.d.ts +36 -4
- package/dist/index.js +43 -2
- package/dist/js-scroller.svelte.d.ts +35 -0
- package/dist/js-scroller.svelte.js +154 -0
- package/dist/list-option.d.ts +46 -0
- package/dist/list-option.js +53 -0
- package/dist/menus.js +25 -11
- package/dist/pivot-view.svelte.d.ts +72 -0
- package/dist/pivot-view.svelte.js +13 -0
- package/dist/positioning.d.ts +111 -0
- package/dist/positioning.js +191 -0
- package/dist/scheduler-model.d.ts +3 -0
- package/dist/scheduler-model.js +22 -5
- package/dist/svgrid-wrapper.types.d.ts +18 -0
- package/dist/toast-store.svelte.d.ts +54 -0
- package/dist/toast-store.svelte.js +65 -15
- package/package.json +9 -1
- package/src/GridFooter.svelte +12 -11
- package/src/SvAnchor.svelte +65 -0
- package/src/SvAspectRatio.svelte +38 -0
- package/src/SvAutoComplete.svelte +52 -7
- package/src/SvBlockquote.svelte +43 -0
- package/src/SvCalendar.svelte +33 -2
- package/src/SvCalendar.test.ts +15 -0
- package/src/SvCheckBox.svelte +6 -2
- package/src/SvCode.svelte +52 -0
- package/src/SvCollapsible.svelte +75 -0
- package/src/SvColorInput.svelte +11 -17
- package/src/SvComboBox.svelte +85 -8
- package/src/SvCountryInput.svelte +2 -2
- package/src/SvDropDownList.svelte +154 -51
- package/src/SvDurationInput.svelte +59 -41
- package/src/SvField.svelte +203 -12
- package/src/SvForm.svelte +195 -21
- package/src/SvForm.test.ts +112 -0
- package/src/SvGrid.controller.svelte.ts +88 -7
- package/src/SvGrid.svelte +383 -181
- package/src/SvGrid.types.ts +125 -1
- package/src/SvGridChartView.svelte +70 -0
- package/src/SvGridDropdown.svelte +9 -2
- package/src/SvGridSelect.svelte +5 -2
- package/src/SvGroup.svelte +41 -0
- package/src/SvHoverCard.svelte +70 -0
- package/src/SvKbd.svelte +51 -0
- package/src/SvList.svelte +55 -0
- package/src/SvListBox.svelte +166 -77
- package/src/SvLoadingOverlay.svelte +53 -0
- package/src/SvMark.svelte +36 -0
- package/src/SvMaskedInput.svelte +50 -35
- package/src/SvMenuList.svelte +32 -3
- package/src/SvMenubar.svelte +200 -0
- package/src/SvMultiSelect.svelte +7 -4
- package/src/SvNumberInput.svelte +79 -42
- package/src/SvOtpInput.svelte +2 -2
- package/src/SvPasswordInput.svelte +51 -31
- package/src/SvPhoneInput.svelte +39 -28
- package/src/SvPopconfirm.svelte +79 -0
- package/src/SvPopover.svelte +87 -29
- package/src/SvRadioGroup.svelte +5 -1
- package/src/SvResult.svelte +73 -0
- package/src/SvSegmented.svelte +114 -0
- package/src/SvSimpleGrid.svelte +41 -0
- package/src/SvSlider.svelte +23 -10
- package/src/SvSpinner.svelte +43 -0
- package/src/SvStack.svelte +37 -0
- package/src/SvSwitchButton.svelte +6 -1
- package/src/SvTagsInput.svelte +9 -5
- package/src/SvText.svelte +76 -0
- package/src/SvTextInput.svelte +75 -43
- package/src/SvTimePicker.svelte +32 -2
- package/src/SvTitle.svelte +57 -0
- package/src/SvToaster.svelte +41 -6
- package/src/SvToaster.test.ts +32 -0
- package/src/SvToggleButton.svelte +4 -1
- package/src/SvTooltip.svelte +68 -34
- package/src/SvTree.svelte +81 -21
- package/src/SvTreeSelect.svelte +5 -2
- package/src/SvVisuallyHidden.svelte +49 -0
- package/src/ai.test.ts +502 -0
- package/src/ai.ts +1391 -0
- package/src/board-view.svelte.ts +33 -0
- package/src/build-api.coverage.test.ts +101 -0
- package/src/build-api.ts +43 -18
- package/src/builtin-editors.grid.test.ts +1 -1
- package/src/cell-formatting.ts +5 -5
- package/src/cell-render.ts +4 -4
- package/src/chart-view.svelte.ts +36 -0
- package/src/createCombobox.svelte.ts +17 -5
- package/src/createDropdownList.svelte.ts +8 -2
- package/src/createForm.svelte.ts +59 -6
- package/src/createMenu.svelte.ts +23 -0
- package/src/createPopoverSelect.svelte.ts +8 -1
- package/src/createSlider.svelte.ts +20 -0
- package/src/createTooltip.svelte.ts +67 -9
- package/src/editor-contract.ts +16 -0
- package/src/export-provider.ts +40 -0
- package/src/filter-operators.ts +37 -0
- package/src/form-field.ts +42 -2
- package/src/grid-messages.test.ts +24 -0
- package/src/grid-messages.ts +137 -0
- package/src/group-display.test.ts +77 -0
- package/src/group-display.ts +117 -0
- package/src/i18n.grid.test.ts +73 -0
- package/src/index.ts +91 -2
- package/src/js-scroller.svelte.ts +173 -0
- package/src/list-option.test.ts +56 -0
- package/src/list-option.ts +81 -0
- package/src/menus.test.ts +32 -0
- package/src/menus.ts +25 -12
- package/src/pivot-view.svelte.ts +90 -0
- package/src/pivot-view.test.ts +38 -0
- package/src/pivot.grid.test.ts +102 -0
- package/src/positioning.test.ts +141 -0
- package/src/positioning.ts +266 -0
- package/src/scheduler-model.test.ts +16 -0
- package/src/scheduler-model.ts +24 -5
- package/src/svgrid-wrapper.types.ts +23 -0
- package/src/svgrid.charting.test.ts +8 -1
- package/src/svgrid.comments-autocomplete.test.ts +7 -2
- package/src/svgrid.context-menu.test.ts +8 -3
- package/src/toast-store.svelte.ts +98 -0
- package/src/toast-store.test.ts +62 -1
- package/src/ui-breadth.test.ts +138 -0
- package/src/ui-buttons.test.ts +39 -0
- package/src/ui-inputs.test.ts +2 -2
- package/src/ui-range.test.ts +9 -0
- package/src/ui-selection.test.ts +36 -0
- package/src/ui-tier1.test.ts +1 -1
- package/src/virtual.test.ts +20 -6
- package/dist/SvGridBoard.svelte +0 -2339
- package/dist/SvGridBoard.svelte.d.ts +0 -31
- package/src/SvGridBoard.svelte +0 -2339
- package/src/board.test.ts +0 -927
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* positioning - a small, dependency-free anchor-positioning engine for the
|
|
3
|
+
* overlay layer (popover, tooltip, menu, dropdowns). It replaces the vertical-
|
|
4
|
+
* flip-only `anchoredRect` for components that need the full placement matrix.
|
|
5
|
+
*
|
|
6
|
+
* Two halves:
|
|
7
|
+
*
|
|
8
|
+
* 1. `computePosition(reference, floating, options)` - PURE geometry. Given the
|
|
9
|
+
* reference rect and the floating size (plus a viewport), it returns the
|
|
10
|
+
* floating `x`/`y`, the resolved `placement` (after flip), the arrow offset,
|
|
11
|
+
* and the available `maxWidth`/`maxHeight` on the chosen side. No DOM, so it
|
|
12
|
+
* is fully unit-tested by feeding rects and asserting placement.
|
|
13
|
+
*
|
|
14
|
+
* 2. `autoUpdate(referenceEl, floatingEl, update)` - the browser half. Re-runs
|
|
15
|
+
* `update` whenever the reference/floating resize, an ancestor scrolls, or the
|
|
16
|
+
* window resizes (via `ResizeObserver` + scroll/resize listeners). SSR-safe
|
|
17
|
+
* (a no-op without `window`).
|
|
18
|
+
*
|
|
19
|
+
* The middleware (flip / shift / size / arrow) is implemented inline - no
|
|
20
|
+
* Floating-UI dependency - matching the kit's zero-runtime-dep posture.
|
|
21
|
+
*/
|
|
22
|
+
/** A physical side the floating element is placed on, relative to the reference. */
|
|
23
|
+
export type Side = 'top' | 'bottom' | 'left' | 'right';
|
|
24
|
+
/** Cross-axis alignment. `center` is the bare side (e.g. `'bottom'`). */
|
|
25
|
+
export type Align = 'start' | 'center' | 'end';
|
|
26
|
+
/** `'bottom'` = bottom-center; `'bottom-start'` / `'bottom-end'` align the edges. */
|
|
27
|
+
export type Placement = Side | `${Side}-start` | `${Side}-end`;
|
|
28
|
+
/** A viewport-relative rectangle (CSS `getBoundingClientRect` shape suffices). */
|
|
29
|
+
export type Rect = {
|
|
30
|
+
x: number;
|
|
31
|
+
y: number;
|
|
32
|
+
width: number;
|
|
33
|
+
height: number;
|
|
34
|
+
};
|
|
35
|
+
/** The available viewport (defaults to `window` in the browser). */
|
|
36
|
+
export type Viewport = {
|
|
37
|
+
width: number;
|
|
38
|
+
height: number;
|
|
39
|
+
};
|
|
40
|
+
export type ComputePositionOptions = {
|
|
41
|
+
/** Preferred placement. Default `'bottom-start'`. */
|
|
42
|
+
placement?: Placement;
|
|
43
|
+
/** Main-axis gap between reference and floating. Default 6. */
|
|
44
|
+
offset?: number;
|
|
45
|
+
/** Viewport edge kept clear on every side. Default 8. */
|
|
46
|
+
padding?: number;
|
|
47
|
+
/** Flip to the opposite side when the preferred side overflows. Default true. */
|
|
48
|
+
flip?: boolean;
|
|
49
|
+
/** Shift along the cross axis to stay in view (without flipping). Default true. */
|
|
50
|
+
shift?: boolean;
|
|
51
|
+
/** Compute `maxWidth`/`maxHeight` for the chosen side. Default true. */
|
|
52
|
+
size?: boolean;
|
|
53
|
+
/** When set, compute the arrow offset for an arrow element of this size (px). */
|
|
54
|
+
arrow?: {
|
|
55
|
+
size: number;
|
|
56
|
+
};
|
|
57
|
+
/** Extra placements to try (after the automatic opposite) before giving up. */
|
|
58
|
+
fallbackPlacements?: Placement[];
|
|
59
|
+
/** Viewport to fit within. Defaults to the window; pure callers pass it. */
|
|
60
|
+
viewport?: Viewport;
|
|
61
|
+
/** Floor for the available main-axis size returned by `size`. Default 0. */
|
|
62
|
+
minMainAxis?: number;
|
|
63
|
+
};
|
|
64
|
+
export type ComputePositionResult = {
|
|
65
|
+
/** Floating left, in viewport (fixed-position) coordinates. */
|
|
66
|
+
x: number;
|
|
67
|
+
/** Floating top, in viewport (fixed-position) coordinates. */
|
|
68
|
+
y: number;
|
|
69
|
+
/** The resolved placement after flip. */
|
|
70
|
+
placement: Placement;
|
|
71
|
+
/** The resolved side after flip. */
|
|
72
|
+
side: Side;
|
|
73
|
+
/** The resolved cross-axis alignment. */
|
|
74
|
+
align: Align;
|
|
75
|
+
/** Space available for the floating on the chosen side's main axis (+cross). */
|
|
76
|
+
maxWidth: number;
|
|
77
|
+
maxHeight: number;
|
|
78
|
+
/**
|
|
79
|
+
* Arrow offset within the floating box: `x` for top/bottom placements, `y` for
|
|
80
|
+
* left/right. Only present when `options.arrow` is set. Clamped so the arrow
|
|
81
|
+
* stays inside the floating (minus padding).
|
|
82
|
+
*/
|
|
83
|
+
arrow?: {
|
|
84
|
+
x?: number;
|
|
85
|
+
y?: number;
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
/** Split a placement into its side + alignment (`center` when no suffix). */
|
|
89
|
+
export declare function parsePlacement(p: Placement): {
|
|
90
|
+
side: Side;
|
|
91
|
+
align: Align;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Compute the floating position anchored to `reference`, applying flip (opposite
|
|
95
|
+
* side when the preferred side overflows), shift (cross-axis clamp to stay in
|
|
96
|
+
* view), size (available max width/height on the chosen side) and an optional
|
|
97
|
+
* arrow offset. Pure - pass an explicit `viewport` in tests.
|
|
98
|
+
*/
|
|
99
|
+
export declare function computePosition(reference: Rect, floating: Viewport, options?: ComputePositionOptions): ComputePositionResult;
|
|
100
|
+
/**
|
|
101
|
+
* Re-run `update` whenever the anchored position could change: the reference or
|
|
102
|
+
* floating element resizes, an ancestor scrolls, or the window scrolls/resizes.
|
|
103
|
+
* Returns a cleanup function. SSR-safe (a no-op without `window`).
|
|
104
|
+
*
|
|
105
|
+
* ```ts
|
|
106
|
+
* const stop = autoUpdate(triggerEl, panelEl, () => reposition())
|
|
107
|
+
* // ...later
|
|
108
|
+
* stop()
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
export declare function autoUpdate(reference: Element, floating: HTMLElement, update: () => void): () => void;
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* positioning - a small, dependency-free anchor-positioning engine for the
|
|
3
|
+
* overlay layer (popover, tooltip, menu, dropdowns). It replaces the vertical-
|
|
4
|
+
* flip-only `anchoredRect` for components that need the full placement matrix.
|
|
5
|
+
*
|
|
6
|
+
* Two halves:
|
|
7
|
+
*
|
|
8
|
+
* 1. `computePosition(reference, floating, options)` - PURE geometry. Given the
|
|
9
|
+
* reference rect and the floating size (plus a viewport), it returns the
|
|
10
|
+
* floating `x`/`y`, the resolved `placement` (after flip), the arrow offset,
|
|
11
|
+
* and the available `maxWidth`/`maxHeight` on the chosen side. No DOM, so it
|
|
12
|
+
* is fully unit-tested by feeding rects and asserting placement.
|
|
13
|
+
*
|
|
14
|
+
* 2. `autoUpdate(referenceEl, floatingEl, update)` - the browser half. Re-runs
|
|
15
|
+
* `update` whenever the reference/floating resize, an ancestor scrolls, or the
|
|
16
|
+
* window resizes (via `ResizeObserver` + scroll/resize listeners). SSR-safe
|
|
17
|
+
* (a no-op without `window`).
|
|
18
|
+
*
|
|
19
|
+
* The middleware (flip / shift / size / arrow) is implemented inline - no
|
|
20
|
+
* Floating-UI dependency - matching the kit's zero-runtime-dep posture.
|
|
21
|
+
*/
|
|
22
|
+
const SIDES = { top: 'bottom', bottom: 'top', left: 'right', right: 'left' };
|
|
23
|
+
/** Split a placement into its side + alignment (`center` when no suffix). */
|
|
24
|
+
export function parsePlacement(p) {
|
|
25
|
+
const [side, align] = p.split('-');
|
|
26
|
+
return { side, align: align ?? 'center' };
|
|
27
|
+
}
|
|
28
|
+
function opposite(p) {
|
|
29
|
+
const { side, align } = parsePlacement(p);
|
|
30
|
+
return (align === 'center' ? SIDES[side] : `${SIDES[side]}-${align}`);
|
|
31
|
+
}
|
|
32
|
+
function clamp(v, min, max) {
|
|
33
|
+
if (max < min)
|
|
34
|
+
return min;
|
|
35
|
+
return v < min ? min : v > max ? max : v;
|
|
36
|
+
}
|
|
37
|
+
/** Floating x/y for a given side+align (before flip/shift). */
|
|
38
|
+
function coordsFor(side, align, r, f, offset) {
|
|
39
|
+
if (side === 'top' || side === 'bottom') {
|
|
40
|
+
const y = side === 'top' ? r.y - f.height - offset : r.y + r.height + offset;
|
|
41
|
+
const x = align === 'start' ? r.x : align === 'end' ? r.x + r.width - f.width : r.x + r.width / 2 - f.width / 2;
|
|
42
|
+
return { x, y };
|
|
43
|
+
}
|
|
44
|
+
const x = side === 'left' ? r.x - f.width - offset : r.x + r.width + offset;
|
|
45
|
+
const y = align === 'start' ? r.y : align === 'end' ? r.y + r.height - f.height : r.y + r.height / 2 - f.height / 2;
|
|
46
|
+
return { x, y };
|
|
47
|
+
}
|
|
48
|
+
/** How far the floating exceeds the viewport on the placement's MAIN axis. >0 = overflow. */
|
|
49
|
+
function mainAxisOverflow(side, x, y, f, v, pad) {
|
|
50
|
+
switch (side) {
|
|
51
|
+
case 'top':
|
|
52
|
+
return pad - y;
|
|
53
|
+
case 'bottom':
|
|
54
|
+
return y + f.height - (v.height - pad);
|
|
55
|
+
case 'left':
|
|
56
|
+
return pad - x;
|
|
57
|
+
default:
|
|
58
|
+
return x + f.width - (v.width - pad);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function resolveViewport(v) {
|
|
62
|
+
if (v)
|
|
63
|
+
return v;
|
|
64
|
+
if (typeof window !== 'undefined')
|
|
65
|
+
return { width: window.innerWidth, height: window.innerHeight };
|
|
66
|
+
return { width: 0, height: 0 };
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Compute the floating position anchored to `reference`, applying flip (opposite
|
|
70
|
+
* side when the preferred side overflows), shift (cross-axis clamp to stay in
|
|
71
|
+
* view), size (available max width/height on the chosen side) and an optional
|
|
72
|
+
* arrow offset. Pure - pass an explicit `viewport` in tests.
|
|
73
|
+
*/
|
|
74
|
+
export function computePosition(reference, floating, options = {}) {
|
|
75
|
+
const offset = options.offset ?? 6;
|
|
76
|
+
const pad = options.padding ?? 8;
|
|
77
|
+
const doFlip = options.flip !== false;
|
|
78
|
+
const doShift = options.shift !== false;
|
|
79
|
+
const v = resolveViewport(options.viewport);
|
|
80
|
+
const preferred = options.placement ?? 'bottom-start';
|
|
81
|
+
// ---- flip: pick the placement whose main-axis overflow is smallest ----
|
|
82
|
+
const candidates = [preferred];
|
|
83
|
+
if (doFlip) {
|
|
84
|
+
candidates.push(opposite(preferred));
|
|
85
|
+
for (const fb of options.fallbackPlacements ?? [])
|
|
86
|
+
candidates.push(fb);
|
|
87
|
+
}
|
|
88
|
+
let chosen = preferred;
|
|
89
|
+
let best = Infinity;
|
|
90
|
+
for (const cand of candidates) {
|
|
91
|
+
const { side, align } = parsePlacement(cand);
|
|
92
|
+
const { x, y } = coordsFor(side, align, reference, floating, offset);
|
|
93
|
+
const overflow = mainAxisOverflow(side, x, y, floating, v, pad);
|
|
94
|
+
if (overflow <= 0) {
|
|
95
|
+
chosen = cand;
|
|
96
|
+
best = overflow;
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
if (overflow < best) {
|
|
100
|
+
best = overflow;
|
|
101
|
+
chosen = cand;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const { side, align } = parsePlacement(chosen);
|
|
105
|
+
let { x, y } = coordsFor(side, align, reference, floating, offset);
|
|
106
|
+
// ---- shift: clamp along the CROSS axis so the floating stays in view ----
|
|
107
|
+
if (doShift) {
|
|
108
|
+
if (side === 'top' || side === 'bottom') {
|
|
109
|
+
x = clamp(x, pad, v.width - pad - floating.width);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
y = clamp(y, pad, v.height - pad - floating.height);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// ---- size: available room on the chosen side ----
|
|
116
|
+
const minMain = options.minMainAxis ?? 0;
|
|
117
|
+
let maxWidth;
|
|
118
|
+
let maxHeight;
|
|
119
|
+
if (side === 'top' || side === 'bottom') {
|
|
120
|
+
const avail = side === 'top' ? reference.y - offset - pad : v.height - pad - (reference.y + reference.height + offset);
|
|
121
|
+
maxHeight = Math.max(minMain, Math.floor(avail));
|
|
122
|
+
maxWidth = Math.max(0, v.width - 2 * pad);
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
const avail = side === 'left' ? reference.x - offset - pad : v.width - pad - (reference.x + reference.width + offset);
|
|
126
|
+
maxWidth = Math.max(minMain, Math.floor(avail));
|
|
127
|
+
maxHeight = Math.max(0, v.height - 2 * pad);
|
|
128
|
+
}
|
|
129
|
+
const result = { x, y, placement: chosen, side, align, maxWidth, maxHeight };
|
|
130
|
+
// ---- arrow: point at the reference center, clamped inside the floating ----
|
|
131
|
+
if (options.arrow) {
|
|
132
|
+
const a = options.arrow.size;
|
|
133
|
+
if (side === 'top' || side === 'bottom') {
|
|
134
|
+
const center = reference.x + reference.width / 2;
|
|
135
|
+
const ax = clamp(center - x - a / 2, pad, floating.width - a - pad);
|
|
136
|
+
result.arrow = { x: ax };
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
const center = reference.y + reference.height / 2;
|
|
140
|
+
const ay = clamp(center - y - a / 2, pad, floating.height - a - pad);
|
|
141
|
+
result.arrow = { y: ay };
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
146
|
+
/** Collect scrollable ancestors so `autoUpdate` can listen to their scroll. */
|
|
147
|
+
function scrollParents(node) {
|
|
148
|
+
const out = [];
|
|
149
|
+
let el = node.parentElement;
|
|
150
|
+
while (el) {
|
|
151
|
+
const style = getComputedStyle(el);
|
|
152
|
+
if (/(auto|scroll|overlay|hidden)/.test(style.overflow + style.overflowY + style.overflowX))
|
|
153
|
+
out.push(el);
|
|
154
|
+
el = el.parentElement;
|
|
155
|
+
}
|
|
156
|
+
return out;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Re-run `update` whenever the anchored position could change: the reference or
|
|
160
|
+
* floating element resizes, an ancestor scrolls, or the window scrolls/resizes.
|
|
161
|
+
* Returns a cleanup function. SSR-safe (a no-op without `window`).
|
|
162
|
+
*
|
|
163
|
+
* ```ts
|
|
164
|
+
* const stop = autoUpdate(triggerEl, panelEl, () => reposition())
|
|
165
|
+
* // ...later
|
|
166
|
+
* stop()
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
export function autoUpdate(reference, floating, update) {
|
|
170
|
+
if (typeof window === 'undefined')
|
|
171
|
+
return () => { };
|
|
172
|
+
const ancestors = scrollParents(reference);
|
|
173
|
+
for (const a of ancestors)
|
|
174
|
+
a.addEventListener('scroll', update, { passive: true });
|
|
175
|
+
window.addEventListener('scroll', update, { passive: true });
|
|
176
|
+
window.addEventListener('resize', update);
|
|
177
|
+
let ro;
|
|
178
|
+
if (typeof ResizeObserver === 'function') {
|
|
179
|
+
ro = new ResizeObserver(update);
|
|
180
|
+
ro.observe(reference);
|
|
181
|
+
ro.observe(floating);
|
|
182
|
+
}
|
|
183
|
+
update();
|
|
184
|
+
return () => {
|
|
185
|
+
for (const a of ancestors)
|
|
186
|
+
a.removeEventListener('scroll', update);
|
|
187
|
+
window.removeEventListener('scroll', update);
|
|
188
|
+
window.removeEventListener('resize', update);
|
|
189
|
+
ro?.disconnect();
|
|
190
|
+
};
|
|
191
|
+
}
|
|
@@ -52,6 +52,9 @@ export type RecurrenceException = {
|
|
|
52
52
|
end?: DateLike | null;
|
|
53
53
|
title?: string;
|
|
54
54
|
allDay?: boolean;
|
|
55
|
+
/** Per-occurrence overrides for any other field, merged over the row for just
|
|
56
|
+
* this occurrence (attendees, calendar, color, resource, ...). */
|
|
57
|
+
fields?: Record<string, unknown>;
|
|
55
58
|
};
|
|
56
59
|
/** Field accessors the model uses to read an event off a row. The component
|
|
57
60
|
* builds this from `SchedulerConfig`, applying its move/edit overlay first so
|
package/dist/scheduler-model.js
CHANGED
|
@@ -140,6 +140,14 @@ export function resolveEvents(rows, spec, rangeStart, rangeEnd) {
|
|
|
140
140
|
let iEnd = new Date(occStart.getTime() + durationMs);
|
|
141
141
|
let iTitle = title;
|
|
142
142
|
let iAllDay = allDay;
|
|
143
|
+
// Per-occurrence overrides of ANY other field: merge onto a copy of the
|
|
144
|
+
// row for this instance, then re-derive the surfaced props from it so a
|
|
145
|
+
// "This event" change to attendees / calendar / color / resource shows.
|
|
146
|
+
let iRow = row;
|
|
147
|
+
let iColor = color;
|
|
148
|
+
let iColor2 = color2;
|
|
149
|
+
let iStatus = status;
|
|
150
|
+
let iResource = resourceId;
|
|
143
151
|
if (ex) {
|
|
144
152
|
const exS = toDate(ex.start);
|
|
145
153
|
const exE = toDate(ex.end);
|
|
@@ -154,6 +162,15 @@ export function resolveEvents(rows, spec, rangeStart, rangeEnd) {
|
|
|
154
162
|
iTitle = ex.title;
|
|
155
163
|
if (ex.allDay != null)
|
|
156
164
|
iAllDay = ex.allDay;
|
|
165
|
+
if (ex.fields) {
|
|
166
|
+
iRow = { ...row, ...ex.fields };
|
|
167
|
+
iColor = spec.getColor?.(iRow) ?? color;
|
|
168
|
+
iColor2 = spec.getSecondaryColor?.(iRow) ?? color2;
|
|
169
|
+
iStatus = spec.getStatus?.(iRow) ?? status;
|
|
170
|
+
iResource = spec.getResource?.(iRow) ?? resourceId;
|
|
171
|
+
if (ex.title == null)
|
|
172
|
+
iTitle = spec.getTitle?.(iRow) ?? iTitle;
|
|
173
|
+
}
|
|
157
174
|
}
|
|
158
175
|
if (!rangesOverlap(iStart, iEnd, rangeStart, rangeEnd))
|
|
159
176
|
continue;
|
|
@@ -161,15 +178,15 @@ export function resolveEvents(rows, spec, rangeStart, rangeEnd) {
|
|
|
161
178
|
// Key on the CANONICAL occurrence start so a moved occurrence keeps its identity.
|
|
162
179
|
key: `${rowKey}#${occStart.getFullYear()}-${occStart.getMonth() + 1}-${occStart.getDate()}T${occStart.getHours()}:${occStart.getMinutes()}`,
|
|
163
180
|
rowKey,
|
|
164
|
-
row,
|
|
181
|
+
row: iRow,
|
|
165
182
|
title: iTitle,
|
|
166
183
|
start: iStart,
|
|
167
184
|
end: iEnd,
|
|
168
185
|
allDay: iAllDay,
|
|
169
|
-
color,
|
|
170
|
-
color2,
|
|
171
|
-
status,
|
|
172
|
-
resourceId,
|
|
186
|
+
color: iColor,
|
|
187
|
+
color2: iColor2,
|
|
188
|
+
status: iStatus,
|
|
189
|
+
resourceId: iResource,
|
|
173
190
|
recurring: true,
|
|
174
191
|
occurrenceStart: occStart,
|
|
175
192
|
isException: !!ex,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CellFormatConfig, ColumnDef, RowData, SvGridOptions, TableFeatures } from './core';
|
|
2
|
+
import type { Props } from './SvGrid.types';
|
|
2
3
|
import type { GridExportOptions, GridClipboardOptions } from './export-format';
|
|
3
4
|
import type { ChartSpec, ChartType } from './chart';
|
|
4
5
|
export type SvGridFilterOperator = 'contains' | 'equals' | 'startsWith' | 'greaterThan' | 'lessThan' | 'between' | 'isBlank';
|
|
@@ -168,6 +169,23 @@ export type SvGridApi<TFeatures extends TableFeatures, TData extends RowData> =
|
|
|
168
169
|
setSort(columnId: string, direction: 'asc' | 'desc' | null): void;
|
|
169
170
|
clearSort(): void;
|
|
170
171
|
setGroupBy(columnIds: ReadonlyArray<string>): void;
|
|
172
|
+
/**
|
|
173
|
+
* Change a grid prop at runtime, e.g. `api.setOption('sortable', true)`. The
|
|
174
|
+
* override is merged over the incoming prop and the grid re-renders reactively -
|
|
175
|
+
* identical to the parent passing a new prop value. Pass `undefined` to clear the
|
|
176
|
+
* override and fall back to the prop.
|
|
177
|
+
*
|
|
178
|
+
* Note: seed-once props are NOT retroactive - `initialSorting`,
|
|
179
|
+
* `initialColumnPinning`, `initialHiddenColumns`, `columnOrder`, the initial
|
|
180
|
+
* `pageSize`, and the one-shot `externalSort` / `externalFilter` are read at mount,
|
|
181
|
+
* so overriding them later has no effect. Prefer the dedicated data path for
|
|
182
|
+
* `data` / `columns` (this works, but the sync effects are the idiomatic route).
|
|
183
|
+
*/
|
|
184
|
+
setOption<K extends keyof Props<TFeatures, TData>>(key: K, value: Props<TFeatures, TData>[K] | undefined): void;
|
|
185
|
+
/** Read a prop's effective value: the runtime override if set, else the incoming prop. */
|
|
186
|
+
getOption<K extends keyof Props<TFeatures, TData>>(key: K): Props<TFeatures, TData>[K];
|
|
187
|
+
/** Clear every runtime override set via `setOption`, reverting to the incoming props. */
|
|
188
|
+
resetOptions(): void;
|
|
171
189
|
/** Set the operator filter for a column. Pass `null` to clear. */
|
|
172
190
|
setFilter(columnId: string, filter: {
|
|
173
191
|
operator: SvGridFilterOperator;
|
|
@@ -1,4 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* toast-store - the headless model behind <SvToaster>: a singleton reactive
|
|
3
|
+
* queue of transient notifications with auto-dismiss timers, plus the `toast()`
|
|
4
|
+
* API you call from anywhere. Every toast is also pushed to the shared ARIA
|
|
5
|
+
* live region via `announce()`, so screen-reader users hear it even though the
|
|
6
|
+
* visual toast is off to the side.
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { toast } from '@svgrid/grid'
|
|
10
|
+
* toast.success('Saved')
|
|
11
|
+
* toast.error('Could not save', { duration: 0 }) // sticky
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* Mount a single <SvToaster /> once near the app root to render the queue.
|
|
15
|
+
*/
|
|
16
|
+
import type { Snippet } from 'svelte';
|
|
1
17
|
export type ToastVariant = 'info' | 'success' | 'warning' | 'error';
|
|
18
|
+
/** A button rendered inside a toast (a primary `action` or a secondary `cancel`). */
|
|
19
|
+
export type ToastAction = {
|
|
20
|
+
label: string;
|
|
21
|
+
/** Invoked with the toast id when pressed. */
|
|
22
|
+
onClick?: (id: number) => void;
|
|
23
|
+
/** Keep the toast open after the click (default: dismiss it). */
|
|
24
|
+
keepOpen?: boolean;
|
|
25
|
+
};
|
|
2
26
|
export type ToastOptions = {
|
|
3
27
|
variant?: ToastVariant;
|
|
4
28
|
/** Auto-dismiss after N ms. `0` = sticky (dismiss manually). Default 4000. */
|
|
@@ -7,6 +31,12 @@ export type ToastOptions = {
|
|
|
7
31
|
dismissible?: boolean;
|
|
8
32
|
/** Optional bold title above the message. */
|
|
9
33
|
title?: string;
|
|
34
|
+
/** Primary action button. */
|
|
35
|
+
action?: ToastAction;
|
|
36
|
+
/** Secondary (cancel) action button. */
|
|
37
|
+
cancel?: ToastAction;
|
|
38
|
+
/** Render a fully custom toast body instead of the icon + title + message. */
|
|
39
|
+
render?: Snippet<[Toast]>;
|
|
10
40
|
};
|
|
11
41
|
export type Toast = {
|
|
12
42
|
id: number;
|
|
@@ -15,6 +45,17 @@ export type Toast = {
|
|
|
15
45
|
duration: number;
|
|
16
46
|
dismissible: boolean;
|
|
17
47
|
title?: string;
|
|
48
|
+
action?: ToastAction;
|
|
49
|
+
cancel?: ToastAction;
|
|
50
|
+
render?: Snippet<[Toast]>;
|
|
51
|
+
};
|
|
52
|
+
/** Patch applied by `toast.update(id, patch)`; every field is optional. */
|
|
53
|
+
export type UpdateToast = Partial<Omit<Toast, 'id'>>;
|
|
54
|
+
/** Messages for `toast.promise`; success/error may derive from the value/error. */
|
|
55
|
+
export type PromiseMessages<T> = {
|
|
56
|
+
loading: string;
|
|
57
|
+
success: string | ((value: T) => string);
|
|
58
|
+
error: string | ((error: unknown) => string);
|
|
18
59
|
};
|
|
19
60
|
type VariantOptions = Omit<ToastOptions, 'variant'>;
|
|
20
61
|
export type ToastFn = {
|
|
@@ -23,6 +64,17 @@ export type ToastFn = {
|
|
|
23
64
|
success: (message: string, options?: VariantOptions) => number;
|
|
24
65
|
warning: (message: string, options?: VariantOptions) => number;
|
|
25
66
|
error: (message: string, options?: VariantOptions) => number;
|
|
67
|
+
/**
|
|
68
|
+
* Show a sticky loading toast, then update it IN PLACE to success/error when
|
|
69
|
+
* the promise settles. Returns the original promise so callers can await it.
|
|
70
|
+
*/
|
|
71
|
+
promise: <T>(promise: Promise<T>, messages: PromiseMessages<T>, options?: ToastOptions) => Promise<T>;
|
|
72
|
+
/** Patch an existing toast (message/variant/title/action/duration/render). */
|
|
73
|
+
update: (id: number, patch: UpdateToast) => void;
|
|
74
|
+
/** Push a toast with a fully custom body snippet. Returns its id. */
|
|
75
|
+
custom: (render: Snippet<[Toast]>, options?: ToastOptions) => number;
|
|
76
|
+
/** Dismiss a toast by id. */
|
|
77
|
+
dismiss: (id: number) => void;
|
|
26
78
|
};
|
|
27
79
|
/** Live reactive list of active toasts (read inside a component/effect). */
|
|
28
80
|
export declare const toastStore: {
|
|
@@ -32,6 +84,8 @@ export declare const toastStore: {
|
|
|
32
84
|
export declare const toast: ToastFn;
|
|
33
85
|
/** Dismiss a toast by id. */
|
|
34
86
|
export declare const dismissToast: (id: number) => void;
|
|
87
|
+
/** Patch an existing toast in place (message/variant/title/action/duration/render). */
|
|
88
|
+
export declare const updateToast: (id: number, patch: UpdateToast) => void;
|
|
35
89
|
/** Remove every toast (and cancel their timers). */
|
|
36
90
|
export declare const clearToasts: () => void;
|
|
37
91
|
/** Pause a toast's auto-dismiss countdown (e.g. while hovered). */
|
|
@@ -1,18 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* toast-store - the headless model behind <SvToaster>: a singleton reactive
|
|
3
|
-
* queue of transient notifications with auto-dismiss timers, plus the `toast()`
|
|
4
|
-
* API you call from anywhere. Every toast is also pushed to the shared ARIA
|
|
5
|
-
* live region via `announce()`, so screen-reader users hear it even though the
|
|
6
|
-
* visual toast is off to the side.
|
|
7
|
-
*
|
|
8
|
-
* ```ts
|
|
9
|
-
* import { toast } from '@svgrid/grid'
|
|
10
|
-
* toast.success('Saved')
|
|
11
|
-
* toast.error('Could not save', { duration: 0 }) // sticky
|
|
12
|
-
* ```
|
|
13
|
-
*
|
|
14
|
-
* Mount a single <SvToaster /> once near the app root to render the queue.
|
|
15
|
-
*/
|
|
16
1
|
import { announce } from './a11y/live-region';
|
|
17
2
|
function createToastStore() {
|
|
18
3
|
const toasts = $state([]);
|
|
@@ -72,6 +57,9 @@ function createToastStore() {
|
|
|
72
57
|
duration,
|
|
73
58
|
dismissible: options.dismissible ?? true,
|
|
74
59
|
title: options.title,
|
|
60
|
+
action: options.action,
|
|
61
|
+
cancel: options.cancel,
|
|
62
|
+
render: options.render,
|
|
75
63
|
};
|
|
76
64
|
toasts.push(entry);
|
|
77
65
|
// Errors/warnings interrupt (assertive); info/success are polite.
|
|
@@ -82,16 +70,76 @@ function createToastStore() {
|
|
|
82
70
|
schedule(id, duration);
|
|
83
71
|
return id;
|
|
84
72
|
}
|
|
73
|
+
/** Patch an existing toast in place (used by `promise`, and callable directly). */
|
|
74
|
+
function update(id, patch) {
|
|
75
|
+
const t = toasts.find((x) => x.id === id);
|
|
76
|
+
if (!t)
|
|
77
|
+
return;
|
|
78
|
+
if (patch.message != null)
|
|
79
|
+
t.message = patch.message;
|
|
80
|
+
if (patch.title !== undefined)
|
|
81
|
+
t.title = patch.title;
|
|
82
|
+
if (patch.variant)
|
|
83
|
+
t.variant = patch.variant;
|
|
84
|
+
if (patch.dismissible !== undefined)
|
|
85
|
+
t.dismissible = patch.dismissible;
|
|
86
|
+
if (patch.action !== undefined)
|
|
87
|
+
t.action = patch.action;
|
|
88
|
+
if (patch.cancel !== undefined)
|
|
89
|
+
t.cancel = patch.cancel;
|
|
90
|
+
if (patch.render !== undefined)
|
|
91
|
+
t.render = patch.render;
|
|
92
|
+
// A new duration restarts the auto-dismiss timer (0 = make it sticky again).
|
|
93
|
+
if (patch.duration !== undefined) {
|
|
94
|
+
const timer = timers.get(id);
|
|
95
|
+
if (timer) {
|
|
96
|
+
clearTimeout(timer);
|
|
97
|
+
timers.delete(id);
|
|
98
|
+
}
|
|
99
|
+
meta.delete(id);
|
|
100
|
+
t.duration = patch.duration;
|
|
101
|
+
if (patch.duration > 0)
|
|
102
|
+
schedule(id, patch.duration);
|
|
103
|
+
}
|
|
104
|
+
announce(t.title ? `${t.title}: ${t.message}` : t.message, {
|
|
105
|
+
assertive: t.variant === 'error' || t.variant === 'warning',
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
function promise(p, messages, options = {}) {
|
|
109
|
+
const id = push(messages.loading, {
|
|
110
|
+
...options,
|
|
111
|
+
variant: 'info',
|
|
112
|
+
duration: 0,
|
|
113
|
+
dismissible: options.dismissible ?? false,
|
|
114
|
+
});
|
|
115
|
+
p.then((value) => update(id, {
|
|
116
|
+
message: typeof messages.success === 'function' ? messages.success(value) : messages.success,
|
|
117
|
+
variant: 'success',
|
|
118
|
+
duration: options.duration ?? 4000,
|
|
119
|
+
dismissible: true,
|
|
120
|
+
}), (error) => update(id, {
|
|
121
|
+
message: typeof messages.error === 'function' ? messages.error(error) : messages.error,
|
|
122
|
+
variant: 'error',
|
|
123
|
+
duration: options.duration ?? 6000,
|
|
124
|
+
dismissible: true,
|
|
125
|
+
}));
|
|
126
|
+
return p;
|
|
127
|
+
}
|
|
85
128
|
const toast = push;
|
|
86
129
|
toast.info = (m, o = {}) => push(m, { ...o, variant: 'info' });
|
|
87
130
|
toast.success = (m, o = {}) => push(m, { ...o, variant: 'success' });
|
|
88
131
|
toast.warning = (m, o = {}) => push(m, { ...o, variant: 'warning' });
|
|
89
132
|
toast.error = (m, o = {}) => push(m, { ...o, variant: 'error' });
|
|
133
|
+
toast.promise = promise;
|
|
134
|
+
toast.update = update;
|
|
135
|
+
toast.custom = (render, o = {}) => push('', { ...o, render });
|
|
136
|
+
toast.dismiss = dismiss;
|
|
90
137
|
return {
|
|
91
138
|
get toasts() {
|
|
92
139
|
return toasts;
|
|
93
140
|
},
|
|
94
141
|
toast,
|
|
142
|
+
update,
|
|
95
143
|
dismiss,
|
|
96
144
|
clear,
|
|
97
145
|
pause,
|
|
@@ -105,6 +153,8 @@ export const toastStore = { get toasts() { return store.toasts; } };
|
|
|
105
153
|
export const toast = store.toast;
|
|
106
154
|
/** Dismiss a toast by id. */
|
|
107
155
|
export const dismissToast = (id) => store.dismiss(id);
|
|
156
|
+
/** Patch an existing toast in place (message/variant/title/action/duration/render). */
|
|
157
|
+
export const updateToast = (id, patch) => store.update(id, patch);
|
|
108
158
|
/** Remove every toast (and cancel their timers). */
|
|
109
159
|
export const clearToasts = () => store.clear();
|
|
110
160
|
/** Pause a toast's auto-dismiss countdown (e.g. while hovered). */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@svgrid/grid",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.17",
|
|
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",
|
|
@@ -22,6 +22,9 @@
|
|
|
22
22
|
"datagrid"
|
|
23
23
|
],
|
|
24
24
|
"type": "module",
|
|
25
|
+
"sideEffects": [
|
|
26
|
+
"**/*.css"
|
|
27
|
+
],
|
|
25
28
|
"types": "dist/index.d.ts",
|
|
26
29
|
"module": "dist/index.js",
|
|
27
30
|
"svelte": "./dist/index.js",
|
|
@@ -51,6 +54,11 @@
|
|
|
51
54
|
"svelte": "./dist/export-format.js",
|
|
52
55
|
"import": "./dist/export-format.js"
|
|
53
56
|
},
|
|
57
|
+
"./filtering": {
|
|
58
|
+
"types": "./dist/filtering/excel-filters.d.ts",
|
|
59
|
+
"svelte": "./dist/filtering/excel-filters.js",
|
|
60
|
+
"import": "./dist/filtering/excel-filters.js"
|
|
61
|
+
},
|
|
54
62
|
"./flex-render": {
|
|
55
63
|
"types": "./dist/flex-render.d.ts",
|
|
56
64
|
"svelte": "./dist/flex-render.js",
|