@lavalogic/scoria 0.37.44 → 0.37.45
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 +58 -58
- package/dist/Components/AccordionGroup.svelte +46 -46
- package/dist/Components/AccordionGroupButton.svelte +76 -76
- package/dist/Components/Action.svelte +136 -136
- package/dist/Components/ActionProps.d.ts +2 -6
- package/dist/Components/AlertModal.svelte +195 -183
- package/dist/Components/AppointmentCalendar/AppointmentCalendar.svelte +702 -702
- package/dist/Components/Base/BaseModal.svelte +125 -125
- package/dist/Components/Base/ContextWrapper.svelte +72 -72
- package/dist/Components/Base/Pagination.svelte +198 -198
- package/dist/Components/Base/Snippets.svelte +36 -36
- package/dist/Components/BigRadioSet.svelte +38 -38
- package/dist/Components/Bubble.svelte +101 -101
- package/dist/Components/Button.svelte +209 -209
- package/dist/Components/ButtonProps.d.ts +2 -6
- package/dist/Components/Checkbox.svelte +86 -86
- package/dist/Components/CollapsibleCard.svelte +78 -78
- package/dist/Components/Contexts/ContextMenu.svelte +164 -164
- package/dist/Components/Contexts/ContextMenuDivider.svelte +15 -15
- package/dist/Components/Contexts/ContextMenuOption.svelte +60 -60
- package/dist/Components/Contexts/Toast.svelte +83 -83
- package/dist/Components/Contexts/ToastContainer.svelte +65 -65
- package/dist/Components/Contexts/Tooltip.svelte +37 -37
- package/dist/Components/DataMatrixIcon.svelte +112 -112
- package/dist/Components/DataMatrixIconProps.d.ts +3 -13
- package/dist/Components/DateInput.svelte +148 -148
- package/dist/Components/DatePicker.svelte +300 -300
- package/dist/Components/DesktopModal.svelte +90 -90
- package/dist/Components/Dial.svelte +204 -204
- package/dist/Components/DialProps.d.ts +1 -18
- package/dist/Components/DimensionInput.svelte +170 -170
- package/dist/Components/DragMenu/DragMenuHolder.svelte +119 -119
- package/dist/Components/DragMenu/DraggableCard.svelte +77 -77
- package/dist/Components/FileCard.svelte +24 -24
- package/dist/Components/FileUpload.svelte +236 -236
- package/dist/Components/GridInput.svelte +196 -200
- package/dist/Components/GridInputSet.svelte +29 -29
- package/dist/Components/HorizontalTabGroup.svelte +82 -82
- package/dist/Components/HorizontalTabGroupButton.svelte +44 -44
- package/dist/Components/Icon.svelte +128 -128
- package/dist/Components/IconProps.d.ts +2 -7
- package/dist/Components/Icons.js +357 -357
- package/dist/Components/LoadingAnimation.svelte +29 -29
- package/dist/Components/LoadingModal.svelte +45 -45
- package/dist/Components/LoadingOverlay.svelte +25 -25
- package/dist/Components/LoadingOverlayProps.d.ts +3 -7
- package/dist/Components/Modal.svelte +258 -258
- package/dist/Components/ModalProps.d.ts +0 -3
- package/dist/Components/MultiSelect.svelte +220 -220
- package/dist/Components/MultiSelectCommonProps.d.ts +6 -17
- package/dist/Components/Nav/Nav.svelte +99 -99
- package/dist/Components/Nav/NavProps.d.ts +4 -11
- package/dist/Components/Nav/NavServiceMenuList.svelte +43 -43
- package/dist/Components/Nav/NavTab.svelte +62 -62
- package/dist/Components/Nav/ServiceMenuItem.svelte +100 -100
- package/dist/Components/Nav/ServicesNav.svelte +80 -80
- package/dist/Components/NumberInput.svelte +157 -157
- package/dist/Components/PageHeading.svelte +25 -25
- package/dist/Components/PasswordInput.svelte +88 -88
- package/dist/Components/Portal.svelte +36 -36
- package/dist/Components/ProgressBubble.svelte +107 -108
- package/dist/Components/ProgressBubbleProps.d.ts +3 -3
- package/dist/Components/QuerySelect.svelte +366 -366
- package/dist/Components/QuerySelectProps.d.ts +4 -14
- package/dist/Components/SingleSelect.svelte +250 -250
- package/dist/Components/SingleSelectCommonProps.d.ts +3 -19
- package/dist/Components/StepButton.svelte +70 -70
- package/dist/Components/StepForm.svelte +140 -140
- package/dist/Components/Switch.svelte +69 -69
- package/dist/Components/Table/ARCHITECTURE.md +298 -0
- package/dist/Components/Table/Body/QuickSearchCell.svelte +679 -694
- package/dist/Components/Table/Body/Rows/ColumnHighlight.svelte +51 -51
- package/dist/Components/Table/Body/Rows/ColumnList.svelte +59 -59
- package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +456 -478
- package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +79 -79
- package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +185 -188
- package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +124 -124
- package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +120 -120
- package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte +230 -230
- package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +105 -105
- package/dist/Components/Table/Body/Rows/Columns/SelectColumn.d.ts +12 -9
- package/dist/Components/Table/Body/Rows/Columns/SelectTableCell.d.ts +5 -5
- package/dist/Components/Table/Body/Rows/Columns/TableAction.svelte +87 -87
- package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +126 -126
- package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +159 -159
- package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +246 -246
- package/dist/Components/Table/Body/Rows/Columns/TableDatePickerProps.d.ts +4 -4
- package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +216 -216
- package/dist/Components/Table/Body/Rows/Columns/TableQueryCell.d.ts +6 -5
- package/dist/Components/Table/Body/Rows/Columns/TableQueryColumn.d.ts +7 -6
- package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +252 -257
- package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +179 -179
- package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +221 -229
- package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte.d.ts +11 -11
- package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +197 -197
- package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +190 -190
- package/dist/Components/Table/Body/Rows/TableRow.svelte +290 -290
- package/dist/Components/Table/Body/TableBody.svelte +155 -155
- package/dist/Components/Table/ColumnDefinitions/ExampleItemColumnDefRepository.svelte.js +2 -3
- package/dist/Components/Table/ColumnFactory.svelte.d.ts +9 -11
- package/dist/Components/Table/ColumnFactory.svelte.js +101 -118
- package/dist/Components/Table/ColumnKindRegistry.d.ts +112 -0
- package/dist/Components/Table/ColumnKindRegistry.js +63 -0
- package/dist/Components/Table/Headers/HighlightAllHeader.svelte +41 -41
- package/dist/Components/Table/Headers/SelectAllHeader.svelte +30 -30
- package/dist/Components/Table/Headers/TableHead.svelte +415 -413
- package/dist/Components/Table/Misc/ColumnPanel.svelte +94 -94
- package/dist/Components/Table/Misc/ColumnPanelModal.svelte +112 -112
- package/dist/Components/Table/Misc/FilterInput.svelte +620 -644
- package/dist/Components/Table/Misc/FilterInput.svelte.d.ts +12 -12
- package/dist/Components/Table/Misc/FilterInputProps.d.ts +2 -2
- package/dist/Components/Table/Misc/FilterPanel.svelte +257 -257
- package/dist/Components/Table/Misc/FilterPanelModal.svelte +30 -30
- package/dist/Components/Table/Misc/SidePanel.svelte +35 -35
- package/dist/Components/Table/Misc/TableFooter.svelte +311 -311
- package/dist/Components/Table/Misc/TableHorizontalBar.svelte +125 -125
- package/dist/Components/Table/Misc/TableSidebar.svelte +157 -157
- package/dist/Components/Table/Misc/ToolboxPanel.svelte +100 -100
- package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +107 -107
- package/dist/Components/Table/NestedTable.svelte +130 -133
- package/dist/Components/Table/SubApis.svelte.d.ts +1 -5
- package/dist/Components/Table/SubApis.svelte.js +33 -32
- package/dist/Components/Table/Table.svelte +692 -745
- package/dist/Components/Table/TableHelpers.svelte.d.ts +6 -19
- package/dist/Components/Table/TableHelpers.svelte.js +6 -14
- package/dist/Components/Table/Types/Columns/Column.d.ts +2 -2
- package/dist/Components/Table/Types/Columns/DateColumn.d.ts +3 -3
- package/dist/Components/Table/Types/Columns/DateTableCell.d.ts +7 -7
- package/dist/Components/Table/Types/Columns/Definitions/Accessors/AccessorDef.svelte.d.ts +7 -8
- package/dist/Components/Table/Types/Columns/Definitions/Accessors/AccessorDef.svelte.js +4 -5
- package/dist/Components/Table/Types/Columns/Definitions/Accessors/CheckboxDef.svelte.d.ts +11 -14
- package/dist/Components/Table/Types/Columns/Definitions/Accessors/CheckboxDef.svelte.js +3 -4
- package/dist/Components/Table/Types/Columns/Definitions/Accessors/DateInputDef.svelte.d.ts +7 -11
- package/dist/Components/Table/Types/Columns/Definitions/Accessors/DateInputDef.svelte.js +3 -3
- package/dist/Components/Table/Types/Columns/Definitions/Accessors/NumberInputDef.svelte.d.ts +13 -18
- package/dist/Components/Table/Types/Columns/Definitions/Accessors/NumberInputDef.svelte.js +4 -5
- package/dist/Components/Table/Types/Columns/Definitions/Accessors/QueryDef.svelte.d.ts +5 -5
- package/dist/Components/Table/Types/Columns/Definitions/Accessors/QueryDef.svelte.js +2 -2
- package/dist/Components/Table/Types/Columns/Definitions/Accessors/SelectDef.svelte.d.ts +15 -12
- package/dist/Components/Table/Types/Columns/Definitions/Accessors/SelectDef.svelte.js +4 -5
- package/dist/Components/Table/Types/Columns/Definitions/Accessors/TextInputDef.svelte.d.ts +8 -12
- package/dist/Components/Table/Types/Columns/Definitions/Accessors/TextInputDef.svelte.js +3 -3
- package/dist/Components/Table/Types/Columns/Definitions/Actions/ActionsDef.svelte.d.ts +6 -6
- package/dist/Components/Table/Types/Columns/Definitions/Actions/ActionsDef.svelte.js +3 -3
- package/dist/Components/Table/Types/Columns/Definitions/ColumnDef.svelte.d.ts +49 -16
- package/dist/Components/Table/Types/Columns/Definitions/ColumnDef.svelte.js +27 -5
- package/dist/Components/Table/Types/Columns/Definitions/Display/AbstractDisplayDef.svelte.d.ts +7 -7
- package/dist/Components/Table/Types/Columns/Definitions/Display/AbstractDisplayDef.svelte.js +4 -4
- package/dist/Components/Table/Types/Columns/Definitions/Display/BubbleDef.svelte.d.ts +5 -5
- package/dist/Components/Table/Types/Columns/Definitions/Display/BubbleDef.svelte.js +2 -2
- package/dist/Components/Table/Types/Columns/Definitions/Display/DisplayDef.svelte.d.ts +5 -5
- package/dist/Components/Table/Types/Columns/Definitions/Display/DisplayDef.svelte.js +2 -2
- package/dist/Components/Table/Types/Columns/Definitions/Display/ProgressBarDef.svelte.d.ts +5 -5
- package/dist/Components/Table/Types/Columns/Definitions/Display/ProgressBarDef.svelte.js +2 -2
- package/dist/Components/Table/Types/Columns/Definitions/Display/ValidityDef.svelte.d.ts +5 -5
- package/dist/Components/Table/Types/Columns/Definitions/Display/ValidityDef.svelte.js +2 -2
- package/dist/Components/Table/Types/Columns/Definitions/Expand/ExpandDef.svelte.d.ts +11 -19
- package/dist/Components/Table/Types/Columns/Definitions/Expand/ExpandDef.svelte.js +4 -8
- package/dist/Components/Table/Types/Columns/Definitions/FilterOnly/FilterOnlyDef.svelte.d.ts +6 -7
- package/dist/Components/Table/Types/Columns/Definitions/FilterOnly/FilterOnlyDef.svelte.js +3 -4
- package/dist/Components/Table/Types/Columns/Definitions/RowSelection/RowSelectionDef.svelte.d.ts +9 -9
- package/dist/Components/Table/Types/Columns/Definitions/RowSelection/RowSelectionDef.svelte.js +4 -4
- package/dist/Components/Table/Types/Columns/ExpandTableCell.d.ts +5 -5
- package/dist/Components/Table/Types/Columns/ProgressBarTableCell.d.ts +6 -6
- package/dist/Components/Table/Types/Columns/TableCell.d.ts +7 -6
- package/dist/Components/Table/Types/Context/ClipboardState.svelte.d.ts +98 -0
- package/dist/Components/Table/Types/Context/ClipboardState.svelte.js +290 -0
- package/dist/Components/Table/Types/Context/ColumnLayoutState.svelte.d.ts +17 -45
- package/dist/Components/Table/Types/Context/ColumnLayoutState.svelte.js +17 -45
- package/dist/Components/Table/Types/Context/FilteringState.svelte.d.ts +9 -20
- package/dist/Components/Table/Types/Context/FilteringState.svelte.js +9 -20
- package/dist/Components/Table/Types/Context/FocusState.svelte.d.ts +23 -42
- package/dist/Components/Table/Types/Context/FocusState.svelte.js +32 -59
- package/dist/Components/Table/Types/Context/ITable.d.ts +5 -8
- package/dist/Components/Table/Types/Context/PreferencesState.svelte.d.ts +29 -56
- package/dist/Components/Table/Types/Context/PreferencesState.svelte.js +28 -55
- package/dist/Components/Table/Types/Context/QueryValuesState.svelte.d.ts +50 -0
- package/dist/Components/Table/Types/Context/QueryValuesState.svelte.js +62 -0
- package/dist/Components/Table/Types/Context/SelectionState.svelte.d.ts +17 -28
- package/dist/Components/Table/Types/Context/SelectionState.svelte.js +17 -28
- package/dist/Components/Table/Types/Context/SortingState.svelte.d.ts +15 -29
- package/dist/Components/Table/Types/Context/SortingState.svelte.js +17 -31
- package/dist/Components/Table/Types/Context/TableContext.svelte.d.ts +212 -325
- package/dist/Components/Table/Types/Context/TableContext.svelte.js +292 -706
- package/dist/Components/Table/Types/Context/VirtualisationState.svelte.d.ts +62 -79
- package/dist/Components/Table/Types/Context/VirtualisationState.svelte.js +54 -73
- package/dist/Components/Table/Types/DataRepository/BuiltInRemoteRepository.svelte.d.ts +16 -27
- package/dist/Components/Table/Types/DataRepository/BuiltInRemoteRepository.svelte.js +16 -27
- package/dist/Components/Table/Types/DataRepository/IDataRepository.d.ts +12 -15
- package/dist/Components/Table/Types/DataRepository/TableDataRepository.svelte.d.ts +15 -30
- package/dist/Components/Table/Types/DataRepository/TableDataRepository.svelte.js +16 -28
- package/dist/Components/Table/Types/Header.d.ts +4 -4
- package/dist/Components/Table/Types/HeaderGroup.d.ts +5 -5
- package/dist/Components/Table/Types/Public/index.d.ts +2 -4
- package/dist/Components/Table/Types/Public/index.js +2 -4
- package/dist/Components/Table/clipboardEscape.d.ts +32 -0
- package/dist/Components/Table/clipboardEscape.js +45 -0
- package/dist/Components/Table/createTable.svelte.d.ts +8 -18
- package/dist/Components/Table/createTable.svelte.js +19 -47
- package/dist/Components/Test/TestContextConsumer.svelte +13 -13
- package/dist/Components/TextArea.svelte +130 -130
- package/dist/Components/TextInput.svelte +176 -176
- package/dist/Components/ThreeStateRadio.svelte +131 -131
- package/dist/Components/Touch/BoolCard.svelte +45 -45
- package/dist/Components/Touch/DateModal.svelte +209 -209
- package/dist/Components/Touch/EditCard.svelte +59 -59
- package/dist/Components/Touch/InfoCard.svelte +31 -31
- package/dist/Components/Touch/InfoTextCard.svelte +28 -28
- package/dist/Components/Touch/ModalExplanation.svelte +17 -17
- package/dist/Components/Touch/NumberKeyboard.svelte +225 -225
- package/dist/Components/Touch/NumberModal.svelte +79 -79
- package/dist/Components/Touch/PlusMinusCard.svelte +46 -46
- package/dist/Components/Touch/SelectModal.svelte +123 -123
- package/dist/Components/Touch/SummaryCard.svelte +93 -93
- package/dist/Components/Touch/TextAreaModal.svelte +95 -95
- package/dist/Components/Touch/TextModal.svelte +106 -106
- package/dist/Components/Touch/TouchCard.svelte +33 -33
- package/dist/Components/Touch/TouchModal.svelte +274 -274
- package/dist/Components/Touch/UtilityButton.svelte +109 -109
- package/dist/Components/VerticalTabGroup.svelte +79 -79
- package/dist/Components/VerticalTabGroupButton.svelte +58 -58
- package/dist/Contexts/ToastContext.svelte.js +3 -4
- package/dist/Helpers/Datamatrix.d.ts +19 -19
- package/dist/Helpers/Datamatrix.js +291 -291
- package/dist/Helpers/Helpers.svelte.d.ts +2 -4
- package/dist/Helpers/Helpers.svelte.js +2 -4
- package/dist/Helpers/dropdownPortal.d.ts +26 -41
- package/dist/Helpers/dropdownPortal.js +62 -116
- package/dist/Types/Examples/ExampleModal.svelte +35 -35
- package/dist/index.d.ts +0 -1
- package/dist/scss/_basics.scss +12 -12
- package/dist/scss/_colours.scss +134 -134
- package/dist/scss/_mixins.scss +3348 -3360
- package/dist/scss/_motion.scss +57 -57
- package/dist/scss/_sizing.scss +85 -85
- package/dist/scss/_transitions.scss +8 -8
- package/package.json +2 -1
|
@@ -1,19 +1,10 @@
|
|
|
1
1
|
import { PaginationType } from '../Pagination/PaginationType.js';
|
|
2
2
|
import { SvelteMap } from 'svelte/reactivity';
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* slot, and the `updateFilters` `OnChangeFn` slot.
|
|
9
|
-
*
|
|
10
|
-
* `TableContext` retains delegating getters / setters for every legacy
|
|
11
|
-
* surface (`filteredIndices`, `filteredData`, `showQuickFiltering`,
|
|
12
|
-
* `showSelectedOnly`, `remoteFilters`, `dateFilter`, `numberFilter`,
|
|
13
|
-
* `selectFilter`, `boolFilter`, `stringFilter`, `updateFilters`); future
|
|
14
|
-
* consumers can read `tableContext._filtering` directly once the
|
|
15
|
-
* migration completes (see
|
|
16
|
-
* `src/stories/Concepts/TableContext-decomposition.mdx`).
|
|
4
|
+
* Sub-context owning filtering-related state: relayed per-type
|
|
5
|
+
* `FilterFn` derived values, the `filteredData` `$derived` chain, the
|
|
6
|
+
* user-facing toggle flags (`showQuickFiltering`, `showSelectedOnly`),
|
|
7
|
+
* the remote-filter slot, and the `updateFilters` `OnChangeFn` slot.
|
|
17
8
|
*/
|
|
18
9
|
export class FilteringState {
|
|
19
10
|
_deps;
|
|
@@ -54,10 +45,9 @@ export class FilteringState {
|
|
|
54
45
|
}
|
|
55
46
|
/**
|
|
56
47
|
* Whether the quick-filter row is currently visible. The setter
|
|
57
|
-
* enforces the `allowQuickFiltering` gate
|
|
58
|
-
*
|
|
59
|
-
* a
|
|
60
|
-
* `TableContext.showQuickFiltering` setter verbatim.
|
|
48
|
+
* enforces the `allowQuickFiltering` master gate: when quick
|
|
49
|
+
* filtering is disabled at the table level, the setter is a no-op
|
|
50
|
+
* (with a debug log).
|
|
61
51
|
*/
|
|
62
52
|
get showQuickFiltering() {
|
|
63
53
|
return this._showQuickFiltering;
|
|
@@ -152,9 +142,8 @@ export class FilteringState {
|
|
|
152
142
|
*
|
|
153
143
|
* Reactivity note: `selectedItems` is intentionally NOT touched
|
|
154
144
|
* outside the `showSelectedOnly` branches. Reading it unconditionally
|
|
155
|
-
* would invalidate `filteredData`
|
|
156
|
-
*
|
|
157
|
-
* during Phase-5 Group 2).
|
|
145
|
+
* would invalidate `filteredData` -> `sortedData` ->
|
|
146
|
+
* `currentPageData` -> the entire row model on every single toggle.
|
|
158
147
|
*/
|
|
159
148
|
filteredData = $derived.by(() => {
|
|
160
149
|
const repoData = this._deps.getRepoData();
|
|
@@ -74,71 +74,52 @@ export interface FocusStateDeps<T extends object> {
|
|
|
74
74
|
tabBackward: () => void;
|
|
75
75
|
/** Logger gate; mirrors the parent `TableContext.debug` field. */
|
|
76
76
|
getDebug: () => boolean;
|
|
77
|
-
/** Returns the parent `TableContext`. Used by
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* closes over the parent at construction time. */
|
|
77
|
+
/** Returns the parent `TableContext`. Used by `getFocusDetailsFor`
|
|
78
|
+
* to construct `TableFocusDetails` lazily on cache miss. The thunk
|
|
79
|
+
* is used instead of a direct ref so the sub-context never closes
|
|
80
|
+
* over the parent at construction time. */
|
|
82
81
|
getTableContextRef: () => unknown;
|
|
83
82
|
}
|
|
84
83
|
/**
|
|
85
|
-
*
|
|
86
|
-
* focus + keyboard-navigation concern previously held directly on
|
|
87
|
-
* `TableContext`:
|
|
84
|
+
* Sub-context owning every focus + keyboard-navigation concern:
|
|
88
85
|
*
|
|
89
86
|
* - `focusStart` / `focusEnd` (the two `CellCoordinates` slots that
|
|
90
87
|
* define the focused cell-range);
|
|
91
|
-
* - `focusStartIsBeingEdited` (
|
|
88
|
+
* - `focusStartIsBeingEdited` (editing-mode flag);
|
|
92
89
|
* - `isMousingDown` (drag-select sentinel for mouse-driven multi-cell
|
|
93
90
|
* selection);
|
|
94
|
-
* -
|
|
95
|
-
*
|
|
91
|
+
* - `focusedRowIndices` / `focusedColumnIds` derived sets that power
|
|
92
|
+
* the per-cell `TableFocusDetails` outline computation;
|
|
96
93
|
* - `startFocus` / `moveFocus` / `unfocus` / `endFocus` / `setFocusEnd`
|
|
97
|
-
* (consumer-facing writers
|
|
94
|
+
* (consumer-facing writers, mouse-driven and direct);
|
|
98
95
|
* - `focusToTop` / `focusToBottom` / `moveToTop` / `moveToBottom` /
|
|
99
96
|
* `focusToStart` / `focusToEnd` / `moveToStart` / `moveToEnd`
|
|
100
97
|
* (range jumps);
|
|
101
98
|
* - `moveFocusUp` / `setFocusUp` / `moveFocusDown` / `setFocusDown` /
|
|
102
99
|
* `moveFocusLeft` / `setFocusLeft` / `moveFocusRight` / `setFocusRight`
|
|
103
100
|
* (single-cell vs. range arrow moves);
|
|
104
|
-
* - `handleTdKeydown` (
|
|
105
|
-
* - `handleKeystroke` (
|
|
106
|
-
* Ctrl+C paths);
|
|
101
|
+
* - `handleTdKeydown` (table-container `onkeydown` router);
|
|
102
|
+
* - `handleKeystroke` (arrow / Home / End / Ctrl+A / Ctrl+C dispatch);
|
|
107
103
|
* - `focusStartVisualColumn` / `focusEndVisualColumn` (visual-column
|
|
108
104
|
* getters powered by `getVisualColumnIndexById`).
|
|
109
105
|
*
|
|
110
106
|
* Effect lifecycle: the parent owns the `$effect` that publishes
|
|
111
|
-
* `_focusedRowIndices` / `_focusedColumnIds`. That effect
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
* `
|
|
116
|
-
*
|
|
117
|
-
* `TableContext` retains delegating getters / setters / methods for
|
|
118
|
-
* every legacy surface (`focusStart`, `focusEnd`, `focusStartIsBeingEdited`,
|
|
119
|
-
* `isMousingDown`, `focusedRowIndices`, `focusedColumnIds`,
|
|
120
|
-
* `focusStartVisualColumn`, `focusEndVisualColumn`, `startFocus`,
|
|
121
|
-
* `moveFocus`, `unfocus`, `endFocus`, `setFocusEnd`, `setFocusUp`,
|
|
122
|
-
* `setFocusDown`, `setFocusLeft`, `setFocusRight`, `moveFocusUp`,
|
|
123
|
-
* `moveFocusDown`, `moveFocusLeft`, `moveFocusRight`, `moveToTop`,
|
|
124
|
-
* `moveToBottom`, `moveToStart`, `moveToEnd`, `focusToTop`,
|
|
125
|
-
* `focusToBottom`, `focusToStart`, `focusToEnd`, `handleTdKeydown`)
|
|
126
|
-
* so existing consumers need no migration.
|
|
107
|
+
* `_focusedRowIndices` / `_focusedColumnIds`. That effect calls into
|
|
108
|
+
* this sub-context through `setFocusedDerived(rows, cols)` rather
|
|
109
|
+
* than mutating state slots directly. The effect lives on
|
|
110
|
+
* `TableContext` because it reads `paginationRowModel` and
|
|
111
|
+
* `_visualColumns`.
|
|
127
112
|
*
|
|
128
113
|
* @remarks
|
|
129
|
-
*
|
|
130
|
-
*
|
|
131
|
-
* `
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
* (a `WeakMap<TableCell<T>, TableFocusDetails<T, RowIdType>>`),
|
|
137
|
-
* which side-steps the async key entirely, or
|
|
114
|
+
* Per-cell `TableFocusDetails` reuse is deferred. A cache would need a
|
|
115
|
+
* `${rowKey}:${columnId}` key, but `selectionExtractor` can be async
|
|
116
|
+
* (`cachedKey` returns `RowIdType | Promise<RowIdType>`), so a sync
|
|
117
|
+
* lookup at cell-render time is impossible. A follow-up either:
|
|
118
|
+
* a) memoises `TableFocusDetails` on the row reference itself
|
|
119
|
+
* (`WeakMap<TableCell<T>, TableFocusDetails<T, RowIdType>>`,
|
|
120
|
+
* which side-steps the async key entirely), or
|
|
138
121
|
* b) hoists the key resolution into a `$state` slot populated by
|
|
139
122
|
* `updateSelectedItems` so the lookup is sync at render time.
|
|
140
|
-
* Both are larger surface changes than the FocusState extraction;
|
|
141
|
-
* tracked under Phase 6.7 BREAKING-CHANGES.md.
|
|
142
123
|
*/
|
|
143
124
|
export declare class FocusState<T extends object> {
|
|
144
125
|
private readonly _deps;
|
|
@@ -2,63 +2,45 @@ import { tick } from 'svelte';
|
|
|
2
2
|
import { devCatch } from '../../../../Helpers/Helpers.svelte.js';
|
|
3
3
|
import { TableFocusDetails } from '../Focus/TableFocusDetails.svelte.js';
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
* focus + keyboard-navigation concern previously held directly on
|
|
7
|
-
* `TableContext`:
|
|
5
|
+
* Sub-context owning every focus + keyboard-navigation concern:
|
|
8
6
|
*
|
|
9
7
|
* - `focusStart` / `focusEnd` (the two `CellCoordinates` slots that
|
|
10
8
|
* define the focused cell-range);
|
|
11
|
-
* - `focusStartIsBeingEdited` (
|
|
9
|
+
* - `focusStartIsBeingEdited` (editing-mode flag);
|
|
12
10
|
* - `isMousingDown` (drag-select sentinel for mouse-driven multi-cell
|
|
13
11
|
* selection);
|
|
14
|
-
* -
|
|
15
|
-
*
|
|
12
|
+
* - `focusedRowIndices` / `focusedColumnIds` derived sets that power
|
|
13
|
+
* the per-cell `TableFocusDetails` outline computation;
|
|
16
14
|
* - `startFocus` / `moveFocus` / `unfocus` / `endFocus` / `setFocusEnd`
|
|
17
|
-
* (consumer-facing writers
|
|
15
|
+
* (consumer-facing writers, mouse-driven and direct);
|
|
18
16
|
* - `focusToTop` / `focusToBottom` / `moveToTop` / `moveToBottom` /
|
|
19
17
|
* `focusToStart` / `focusToEnd` / `moveToStart` / `moveToEnd`
|
|
20
18
|
* (range jumps);
|
|
21
19
|
* - `moveFocusUp` / `setFocusUp` / `moveFocusDown` / `setFocusDown` /
|
|
22
20
|
* `moveFocusLeft` / `setFocusLeft` / `moveFocusRight` / `setFocusRight`
|
|
23
21
|
* (single-cell vs. range arrow moves);
|
|
24
|
-
* - `handleTdKeydown` (
|
|
25
|
-
* - `handleKeystroke` (
|
|
26
|
-
* Ctrl+C paths);
|
|
22
|
+
* - `handleTdKeydown` (table-container `onkeydown` router);
|
|
23
|
+
* - `handleKeystroke` (arrow / Home / End / Ctrl+A / Ctrl+C dispatch);
|
|
27
24
|
* - `focusStartVisualColumn` / `focusEndVisualColumn` (visual-column
|
|
28
25
|
* getters powered by `getVisualColumnIndexById`).
|
|
29
26
|
*
|
|
30
27
|
* Effect lifecycle: the parent owns the `$effect` that publishes
|
|
31
|
-
* `_focusedRowIndices` / `_focusedColumnIds`. That effect
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* `
|
|
36
|
-
*
|
|
37
|
-
* `TableContext` retains delegating getters / setters / methods for
|
|
38
|
-
* every legacy surface (`focusStart`, `focusEnd`, `focusStartIsBeingEdited`,
|
|
39
|
-
* `isMousingDown`, `focusedRowIndices`, `focusedColumnIds`,
|
|
40
|
-
* `focusStartVisualColumn`, `focusEndVisualColumn`, `startFocus`,
|
|
41
|
-
* `moveFocus`, `unfocus`, `endFocus`, `setFocusEnd`, `setFocusUp`,
|
|
42
|
-
* `setFocusDown`, `setFocusLeft`, `setFocusRight`, `moveFocusUp`,
|
|
43
|
-
* `moveFocusDown`, `moveFocusLeft`, `moveFocusRight`, `moveToTop`,
|
|
44
|
-
* `moveToBottom`, `moveToStart`, `moveToEnd`, `focusToTop`,
|
|
45
|
-
* `focusToBottom`, `focusToStart`, `focusToEnd`, `handleTdKeydown`)
|
|
46
|
-
* so existing consumers need no migration.
|
|
28
|
+
* `_focusedRowIndices` / `_focusedColumnIds`. That effect calls into
|
|
29
|
+
* this sub-context through `setFocusedDerived(rows, cols)` rather
|
|
30
|
+
* than mutating state slots directly. The effect lives on
|
|
31
|
+
* `TableContext` because it reads `paginationRowModel` and
|
|
32
|
+
* `_visualColumns`.
|
|
47
33
|
*
|
|
48
34
|
* @remarks
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* `
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* (a `WeakMap<TableCell<T>, TableFocusDetails<T, RowIdType>>`),
|
|
57
|
-
* which side-steps the async key entirely, or
|
|
35
|
+
* Per-cell `TableFocusDetails` reuse is deferred. A cache would need a
|
|
36
|
+
* `${rowKey}:${columnId}` key, but `selectionExtractor` can be async
|
|
37
|
+
* (`cachedKey` returns `RowIdType | Promise<RowIdType>`), so a sync
|
|
38
|
+
* lookup at cell-render time is impossible. A follow-up either:
|
|
39
|
+
* a) memoises `TableFocusDetails` on the row reference itself
|
|
40
|
+
* (`WeakMap<TableCell<T>, TableFocusDetails<T, RowIdType>>`,
|
|
41
|
+
* which side-steps the async key entirely), or
|
|
58
42
|
* b) hoists the key resolution into a `$state` slot populated by
|
|
59
43
|
* `updateSelectedItems` so the lookup is sync at render time.
|
|
60
|
-
* Both are larger surface changes than the FocusState extraction;
|
|
61
|
-
* tracked under Phase 6.7 BREAKING-CHANGES.md.
|
|
62
44
|
*/
|
|
63
45
|
export class FocusState {
|
|
64
46
|
_deps;
|
|
@@ -702,27 +684,20 @@ export class FocusState {
|
|
|
702
684
|
this.moveFocus({ ...this._focusStart, row: newEndRowIndex });
|
|
703
685
|
}
|
|
704
686
|
// -----------------------------------------------------------------
|
|
705
|
-
// Per-cell TableFocusDetails reuse
|
|
706
|
-
//
|
|
707
|
-
// Prior to Phase 7.1, every cell component (TableTextInput,
|
|
708
|
-
// FocusableImmutableCell, TableNumberInput, etc.) wrote
|
|
709
|
-
// `$derived(new TableFocusDetails(cell, tableContext))`. The
|
|
710
|
-
// `$derived` re-runs on each reactive dep change, so a freshly
|
|
711
|
-
// constructed `TableFocusDetails` was the dominant per-cell cost.
|
|
712
|
-
//
|
|
713
|
-
// Phase 6.6 deferred this because the natural cache key
|
|
714
|
-
// `${rowKey}:${columnId}` cannot be computed synchronously inside
|
|
715
|
-
// a cell render (SelectionState.cachedKey can return a Promise).
|
|
687
|
+
// Per-cell TableFocusDetails reuse.
|
|
716
688
|
//
|
|
717
|
-
//
|
|
718
|
-
//
|
|
719
|
-
//
|
|
720
|
-
// each cell component, so the cache hits across the $derived
|
|
721
|
-
// re-evaluations that fire while the cell is mounted. When Item G
|
|
722
|
-
// stabilises Row references across pagination changes, cell refs
|
|
723
|
-
// also become stable and the cache hits across page flips too.
|
|
689
|
+
// Cell components run `$derived(new TableFocusDetails(cell, ctx))`
|
|
690
|
+
// which re-evaluates on every reactive dep change, making the
|
|
691
|
+
// `TableFocusDetails` construction the dominant per-cell cost.
|
|
724
692
|
//
|
|
725
|
-
//
|
|
693
|
+
// The cache is keyed on the cell REFERENCE itself (a WeakMap)
|
|
694
|
+
// because a `${rowKey}:${columnId}` string key cannot be computed
|
|
695
|
+
// synchronously inside a cell render (`SelectionState.cachedKey`
|
|
696
|
+
// can return a Promise). Cell objects are constructed by
|
|
697
|
+
// `createRow` / `rowsPromise`; within a single render pass the same
|
|
698
|
+
// cell instance is passed to every component, so the cache hits
|
|
699
|
+
// across the `$derived` re-evaluations that fire while the cell is
|
|
700
|
+
// mounted. `WeakMap` ensures cells do not pin `TableFocusDetails`
|
|
726
701
|
// after the row is dropped; GC reclaims both together.
|
|
727
702
|
// -----------------------------------------------------------------
|
|
728
703
|
_focusDetailsCache = new WeakMap();
|
|
@@ -739,9 +714,7 @@ export class FocusState {
|
|
|
739
714
|
let details = this._focusDetailsCache.get(cell);
|
|
740
715
|
if (!details) {
|
|
741
716
|
// The TableContext ref is supplied via a thunk to keep this
|
|
742
|
-
// sub-context decoupled from the parent.
|
|
743
|
-
// expected to return the *current* parent reference; in
|
|
744
|
-
// practice the parent never recycles its TableContext.
|
|
717
|
+
// sub-context decoupled from the parent.
|
|
745
718
|
const parent = this._deps.getTableContextRef();
|
|
746
719
|
details = new TableFocusDetails(cell, parent);
|
|
747
720
|
this._focusDetailsCache.set(cell, details);
|
|
@@ -9,14 +9,11 @@ import type { HeaderGroup } from '../HeaderGroup.js';
|
|
|
9
9
|
import type { OnChangeFn } from '../OnChangeFn.js';
|
|
10
10
|
import type { PaginationState } from '../Pagination/PaginationState.js';
|
|
11
11
|
/**
|
|
12
|
-
* Surface returned by `TableContext.table`. Mirrors the tanstack-table
|
|
13
|
-
* scoria's table API
|
|
14
|
-
* scoria Table actually exposes.
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* mixins that have not yet been implemented; they are retained as a backlog
|
|
18
|
-
* marker. Deleting them is deferred (workorder Types-Context-supporting
|
|
19
|
-
* finding 1) until a decision is made on which mixins to port.
|
|
12
|
+
* Surface returned by `TableContext.table`. Mirrors the tanstack-table
|
|
13
|
+
* shape scoria's table API derives from, narrowed to the methods the
|
|
14
|
+
* scoria Table actually exposes. The commented-out `extends X, Y, Z`
|
|
15
|
+
* lines mark tanstack-derived mixins not yet implemented; retained as
|
|
16
|
+
* a backlog marker pending a decision on which to port.
|
|
20
17
|
*/
|
|
21
18
|
export interface ITable<T extends object> {
|
|
22
19
|
data: Array<T>;
|
|
@@ -7,28 +7,21 @@ import type { SortingState as SortingStateArray } from '../DataRepository/Sortin
|
|
|
7
7
|
import type { SavedTableSettings, TableSettings } from './TableSettings.js';
|
|
8
8
|
/**
|
|
9
9
|
* Conservative typeguard for the persisted preset list. Storage is
|
|
10
|
-
* same-origin-writable so the
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* Lifted from `TableContext.svelte.ts` during Phase 6.4 god-object
|
|
16
|
-
* decomposition; semantics unchanged.
|
|
10
|
+
* same-origin-writable so only the array shape can be trusted;
|
|
11
|
+
* downstream `reassignDefsToPresets` performs deeper checks and drops
|
|
12
|
+
* presets that fail. Asserts the outer envelope plus the bare minimum
|
|
13
|
+
* per entry: a string `name` and an array `columnDefs`.
|
|
17
14
|
*/
|
|
18
15
|
export declare function isJSONColumnDefSetArray(raw: unknown): raw is Array<JSONColumnDefSet>;
|
|
19
16
|
/**
|
|
20
17
|
* Typeguard for the persisted user-level table settings blob. Every
|
|
21
|
-
* field is optional, but every present field must be boolean
|
|
18
|
+
* field is optional, but every present field must be boolean; anything
|
|
22
19
|
* else is a sign of schema drift or a tampered slot.
|
|
23
|
-
*
|
|
24
|
-
* Lifted from `TableContext.svelte.ts` during Phase 6.4.
|
|
25
20
|
*/
|
|
26
21
|
export declare function isSavedTableSettings(raw: unknown): raw is SavedTableSettings;
|
|
27
22
|
/**
|
|
28
23
|
* Typeguard for a non-empty string. Used for the persisted selected
|
|
29
24
|
* preset name slot.
|
|
30
|
-
*
|
|
31
|
-
* Lifted from `TableContext.svelte.ts` during Phase 6.4.
|
|
32
25
|
*/
|
|
33
26
|
export declare function isNonEmptyString(raw: unknown): raw is string;
|
|
34
27
|
/**
|
|
@@ -64,44 +57,34 @@ export interface PreferencesStateDeps<T extends object> {
|
|
|
64
57
|
setColumnVisibility: (state: VisibilityState) => void;
|
|
65
58
|
/** Apply the column-pinning map when a preset is restored. */
|
|
66
59
|
setColumnPinning: (state: ColumnPinningState) => void;
|
|
67
|
-
/** Apply the sort instruction list when a preset is restored.
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* `paginationRepo?.updateSorting?.()` call). */
|
|
60
|
+
/** Apply the sort instruction list when a preset is restored. The
|
|
61
|
+
* writer is a best-effort hook (`paginationRepo?.updateSorting?.()`
|
|
62
|
+
* no-ops when no pagination repository is attached yet). */
|
|
71
63
|
applySortingState: (state: SortingStateArray) => void;
|
|
72
64
|
/** Logger gate; mirrors the parent `TableContext.debug` field. */
|
|
73
65
|
getDebug: () => boolean;
|
|
74
66
|
}
|
|
75
67
|
/**
|
|
76
|
-
*
|
|
77
|
-
* persistence / preferences concern previously held directly on
|
|
78
|
-
* `TableContext`:
|
|
68
|
+
* Sub-context owning every persistence / preferences concern:
|
|
79
69
|
*
|
|
80
|
-
* - `_columnPresets` (
|
|
81
|
-
* - `_selectedPreset` (
|
|
82
|
-
* - `userIdSegment` (
|
|
83
|
-
*
|
|
70
|
+
* - `_columnPresets` (persisted preset list `$state`);
|
|
71
|
+
* - `_selectedPreset` (currently-active preset `$state`);
|
|
72
|
+
* - `userIdSegment` (sanitised user-id segment used in storage keys;
|
|
73
|
+
* `$derived` over `getUserId()`);
|
|
84
74
|
* - `saveColumnPreset(name)` (snapshot the live layout, persist the
|
|
85
|
-
* list, mark the new preset as selected)
|
|
75
|
+
* list, mark the new preset as selected);
|
|
86
76
|
* - `setSelectedPreset(preset)` (apply the preset to the live layout
|
|
87
|
-
* and persist the selected name)
|
|
77
|
+
* and persist the selected name);
|
|
88
78
|
* - `loadPresets()` / `loadSelectedPresetName()` /
|
|
89
79
|
* `loadSavedSettings()` (boot-time hydration helpers; the parent
|
|
90
|
-
* owns the orchestration because it depends on
|
|
91
|
-
* running first)
|
|
92
|
-
* - `clearPresetsAndSelection()` (drop both persisted slots)
|
|
80
|
+
* owns the orchestration because it depends on
|
|
81
|
+
* `setupDefaultColumnDefs` running first);
|
|
82
|
+
* - `clearPresetsAndSelection()` (drop both persisted slots);
|
|
93
83
|
* - `persistSettings(settings)` (write the per-table TableSettings
|
|
94
|
-
* blob)
|
|
95
|
-
* -
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
* `TableContext` retains delegating getters / setters / methods for
|
|
100
|
-
* every legacy surface (`columnPresets`, `selectedPreset`,
|
|
101
|
-
* `saveColumnPreset`, `setSelectedPreset`, `_updateLocalStorageSettings`)
|
|
102
|
-
* so existing consumers need no migration. Future consumers can read
|
|
103
|
-
* `tableContext._preferences` directly once the migration is complete
|
|
104
|
-
* (see `src/stories/Concepts/TableContext-decomposition.mdx`).
|
|
84
|
+
* blob);
|
|
85
|
+
* - schema-validation typeguards (`isJSONColumnDefSetArray`,
|
|
86
|
+
* `isSavedTableSettings`, `isNonEmptyString`) - exported alongside
|
|
87
|
+
* the class.
|
|
105
88
|
*
|
|
106
89
|
* Every `localStorage` access is funnelled through this sub-context so
|
|
107
90
|
* the `scoria-table:<user>:<tableName>:<suffix>` namespace convention
|
|
@@ -172,11 +155,8 @@ export declare class PreferencesState<T extends object> {
|
|
|
172
155
|
/**
|
|
173
156
|
* Boot-time hydration helper. Reads the persisted selected-preset
|
|
174
157
|
* name. Returns `null` for missing / empty / storage-error slots
|
|
175
|
-
* so the parent can fall back to the first preset (or the
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
* Mirrors the pre-extraction try/catch around `getItem` verbatim:
|
|
179
|
-
* the same dev-only warning is emitted on read failure.
|
|
158
|
+
* so the parent can fall back to the first preset (or the default).
|
|
159
|
+
* Emits a dev-only warning on `getItem` failure.
|
|
180
160
|
*/
|
|
181
161
|
loadSelectedPresetName(): string | null;
|
|
182
162
|
/**
|
|
@@ -199,8 +179,7 @@ export declare class PreferencesState<T extends object> {
|
|
|
199
179
|
persistSelectedPresetName(name: string): void;
|
|
200
180
|
/**
|
|
201
181
|
* Persist the per-table settings blob (`isCompact`,
|
|
202
|
-
* `singleClickEditing`, etc.) as JSON.
|
|
203
|
-
* exactly as before the extraction.
|
|
182
|
+
* `singleClickEditing`, etc.) as JSON.
|
|
204
183
|
*/
|
|
205
184
|
persistSettings(settings: TableSettings): void;
|
|
206
185
|
/**
|
|
@@ -209,15 +188,11 @@ export declare class PreferencesState<T extends object> {
|
|
|
209
188
|
* because Map does not survive `JSON.stringify`; the reader (via
|
|
210
189
|
* `loadPresets` -> `reassignDefsToPresets`) rehydrates it through
|
|
211
190
|
* `adaptJSONPinningState`.
|
|
212
|
-
*
|
|
213
|
-
* Pulled out of `saveColumnPreset` so the per-preset
|
|
214
|
-
* `toJSON()` walk is unit-testable in isolation.
|
|
215
191
|
*/
|
|
216
192
|
persistPresets(presets: ReadonlyArray<ColumnDefSet<T>>): void;
|
|
217
193
|
/**
|
|
218
|
-
* Apply a saved column preset to the live table layout and
|
|
219
|
-
*
|
|
220
|
-
* `TableContext.setSelectedPreset` verbatim:
|
|
194
|
+
* Apply a saved column preset to the live table layout and persist
|
|
195
|
+
* the selection by name:
|
|
221
196
|
*
|
|
222
197
|
* 1. Replace `columnDefs`, `columnVisibility`, `columnPinning`.
|
|
223
198
|
* 2. Forward the preset's `sortingState` to the data-repository
|
|
@@ -233,10 +208,8 @@ export declare class PreferencesState<T extends object> {
|
|
|
233
208
|
* Snapshot the current column layout into a new preset, replacing
|
|
234
209
|
* any existing preset whose name matches case-insensitively, and
|
|
235
210
|
* persist the full preset list to `localStorage`. Marks the new
|
|
236
|
-
* preset as selected (which also persists its name).
|
|
237
|
-
*
|
|
238
|
-
* Mirrors the pre-extraction `TableContext.saveColumnPreset`
|
|
239
|
-
* verbatim. No-op when `name` is empty.
|
|
211
|
+
* preset as selected (which also persists its name). No-op when
|
|
212
|
+
* `name` is empty.
|
|
240
213
|
*/
|
|
241
214
|
readonly saveColumnPreset: (name: string) => void;
|
|
242
215
|
}
|
|
@@ -2,13 +2,10 @@ import { dev } from '$app/environment';
|
|
|
2
2
|
import { readJSON } from '../../../../Helpers/Storage.js';
|
|
3
3
|
/**
|
|
4
4
|
* Conservative typeguard for the persisted preset list. Storage is
|
|
5
|
-
* same-origin-writable so the
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* Lifted from `TableContext.svelte.ts` during Phase 6.4 god-object
|
|
11
|
-
* decomposition; semantics unchanged.
|
|
5
|
+
* same-origin-writable so only the array shape can be trusted;
|
|
6
|
+
* downstream `reassignDefsToPresets` performs deeper checks and drops
|
|
7
|
+
* presets that fail. Asserts the outer envelope plus the bare minimum
|
|
8
|
+
* per entry: a string `name` and an array `columnDefs`.
|
|
12
9
|
*/
|
|
13
10
|
export function isJSONColumnDefSetArray(raw) {
|
|
14
11
|
if (!Array.isArray(raw)) {
|
|
@@ -24,10 +21,8 @@ export function isJSONColumnDefSetArray(raw) {
|
|
|
24
21
|
}
|
|
25
22
|
/**
|
|
26
23
|
* Typeguard for the persisted user-level table settings blob. Every
|
|
27
|
-
* field is optional, but every present field must be boolean
|
|
24
|
+
* field is optional, but every present field must be boolean; anything
|
|
28
25
|
* else is a sign of schema drift or a tampered slot.
|
|
29
|
-
*
|
|
30
|
-
* Lifted from `TableContext.svelte.ts` during Phase 6.4.
|
|
31
26
|
*/
|
|
32
27
|
export function isSavedTableSettings(raw) {
|
|
33
28
|
if (typeof raw !== 'object' || raw === null) {
|
|
@@ -45,42 +40,31 @@ export function isSavedTableSettings(raw) {
|
|
|
45
40
|
/**
|
|
46
41
|
* Typeguard for a non-empty string. Used for the persisted selected
|
|
47
42
|
* preset name slot.
|
|
48
|
-
*
|
|
49
|
-
* Lifted from `TableContext.svelte.ts` during Phase 6.4.
|
|
50
43
|
*/
|
|
51
44
|
export function isNonEmptyString(raw) {
|
|
52
45
|
return typeof raw === 'string' && raw.length > 0;
|
|
53
46
|
}
|
|
54
47
|
/**
|
|
55
|
-
*
|
|
56
|
-
* persistence / preferences concern previously held directly on
|
|
57
|
-
* `TableContext`:
|
|
48
|
+
* Sub-context owning every persistence / preferences concern:
|
|
58
49
|
*
|
|
59
|
-
* - `_columnPresets` (
|
|
60
|
-
* - `_selectedPreset` (
|
|
61
|
-
* - `userIdSegment` (
|
|
62
|
-
*
|
|
50
|
+
* - `_columnPresets` (persisted preset list `$state`);
|
|
51
|
+
* - `_selectedPreset` (currently-active preset `$state`);
|
|
52
|
+
* - `userIdSegment` (sanitised user-id segment used in storage keys;
|
|
53
|
+
* `$derived` over `getUserId()`);
|
|
63
54
|
* - `saveColumnPreset(name)` (snapshot the live layout, persist the
|
|
64
|
-
* list, mark the new preset as selected)
|
|
55
|
+
* list, mark the new preset as selected);
|
|
65
56
|
* - `setSelectedPreset(preset)` (apply the preset to the live layout
|
|
66
|
-
* and persist the selected name)
|
|
57
|
+
* and persist the selected name);
|
|
67
58
|
* - `loadPresets()` / `loadSelectedPresetName()` /
|
|
68
59
|
* `loadSavedSettings()` (boot-time hydration helpers; the parent
|
|
69
|
-
* owns the orchestration because it depends on
|
|
70
|
-
* running first)
|
|
71
|
-
* - `clearPresetsAndSelection()` (drop both persisted slots)
|
|
60
|
+
* owns the orchestration because it depends on
|
|
61
|
+
* `setupDefaultColumnDefs` running first);
|
|
62
|
+
* - `clearPresetsAndSelection()` (drop both persisted slots);
|
|
72
63
|
* - `persistSettings(settings)` (write the per-table TableSettings
|
|
73
|
-
* blob)
|
|
74
|
-
* -
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
* `TableContext` retains delegating getters / setters / methods for
|
|
79
|
-
* every legacy surface (`columnPresets`, `selectedPreset`,
|
|
80
|
-
* `saveColumnPreset`, `setSelectedPreset`, `_updateLocalStorageSettings`)
|
|
81
|
-
* so existing consumers need no migration. Future consumers can read
|
|
82
|
-
* `tableContext._preferences` directly once the migration is complete
|
|
83
|
-
* (see `src/stories/Concepts/TableContext-decomposition.mdx`).
|
|
64
|
+
* blob);
|
|
65
|
+
* - schema-validation typeguards (`isJSONColumnDefSetArray`,
|
|
66
|
+
* `isSavedTableSettings`, `isNonEmptyString`) - exported alongside
|
|
67
|
+
* the class.
|
|
84
68
|
*
|
|
85
69
|
* Every `localStorage` access is funnelled through this sub-context so
|
|
86
70
|
* the `scoria-table:<user>:<tableName>:<suffix>` namespace convention
|
|
@@ -89,9 +73,8 @@ export function isNonEmptyString(raw) {
|
|
|
89
73
|
export class PreferencesState {
|
|
90
74
|
_deps;
|
|
91
75
|
_columnPresets = $state([]);
|
|
92
|
-
//FIXME why
|
|
93
|
-
// `
|
|
94
|
-
// for source compatibility.
|
|
76
|
+
//FIXME why is this allowed to be undefined? Retained as
|
|
77
|
+
// `undefined`-capable for backwards source compatibility.
|
|
95
78
|
_selectedPreset = $state();
|
|
96
79
|
/**
|
|
97
80
|
* Sanitised segment of the persisted-storage key path. Resolves to
|
|
@@ -168,11 +151,8 @@ export class PreferencesState {
|
|
|
168
151
|
/**
|
|
169
152
|
* Boot-time hydration helper. Reads the persisted selected-preset
|
|
170
153
|
* name. Returns `null` for missing / empty / storage-error slots
|
|
171
|
-
* so the parent can fall back to the first preset (or the
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
* Mirrors the pre-extraction try/catch around `getItem` verbatim:
|
|
175
|
-
* the same dev-only warning is emitted on read failure.
|
|
154
|
+
* so the parent can fall back to the first preset (or the default).
|
|
155
|
+
* Emits a dev-only warning on `getItem` failure.
|
|
176
156
|
*/
|
|
177
157
|
loadSelectedPresetName() {
|
|
178
158
|
let savedPresetName = null;
|
|
@@ -221,8 +201,7 @@ export class PreferencesState {
|
|
|
221
201
|
}
|
|
222
202
|
/**
|
|
223
203
|
* Persist the per-table settings blob (`isCompact`,
|
|
224
|
-
* `singleClickEditing`, etc.) as JSON.
|
|
225
|
-
* exactly as before the extraction.
|
|
204
|
+
* `singleClickEditing`, etc.) as JSON.
|
|
226
205
|
*/
|
|
227
206
|
persistSettings(settings) {
|
|
228
207
|
localStorage.setItem(this.storageKey('settings'), JSON.stringify(settings));
|
|
@@ -233,9 +212,6 @@ export class PreferencesState {
|
|
|
233
212
|
* because Map does not survive `JSON.stringify`; the reader (via
|
|
234
213
|
* `loadPresets` -> `reassignDefsToPresets`) rehydrates it through
|
|
235
214
|
* `adaptJSONPinningState`.
|
|
236
|
-
*
|
|
237
|
-
* Pulled out of `saveColumnPreset` so the per-preset
|
|
238
|
-
* `toJSON()` walk is unit-testable in isolation.
|
|
239
215
|
*/
|
|
240
216
|
persistPresets(presets) {
|
|
241
217
|
const jsonFriendly = presets.map((preset) => {
|
|
@@ -253,9 +229,8 @@ export class PreferencesState {
|
|
|
253
229
|
localStorage.setItem(this.storageKey('presets'), JSON.stringify(jsonFriendly));
|
|
254
230
|
}
|
|
255
231
|
/**
|
|
256
|
-
* Apply a saved column preset to the live table layout and
|
|
257
|
-
*
|
|
258
|
-
* `TableContext.setSelectedPreset` verbatim:
|
|
232
|
+
* Apply a saved column preset to the live table layout and persist
|
|
233
|
+
* the selection by name:
|
|
259
234
|
*
|
|
260
235
|
* 1. Replace `columnDefs`, `columnVisibility`, `columnPinning`.
|
|
261
236
|
* 2. Forward the preset's `sortingState` to the data-repository
|
|
@@ -281,10 +256,8 @@ export class PreferencesState {
|
|
|
281
256
|
* Snapshot the current column layout into a new preset, replacing
|
|
282
257
|
* any existing preset whose name matches case-insensitively, and
|
|
283
258
|
* persist the full preset list to `localStorage`. Marks the new
|
|
284
|
-
* preset as selected (which also persists its name).
|
|
285
|
-
*
|
|
286
|
-
* Mirrors the pre-extraction `TableContext.saveColumnPreset`
|
|
287
|
-
* verbatim. No-op when `name` is empty.
|
|
259
|
+
* preset as selected (which also persists its name). No-op when
|
|
260
|
+
* `name` is empty.
|
|
288
261
|
*/
|
|
289
262
|
saveColumnPreset = (name) => {
|
|
290
263
|
if (!name) {
|