@lavalogic/scoria 0.40.13 → 0.40.15

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.
Files changed (143) hide show
  1. package/README.md +58 -58
  2. package/dist/Components/AccordionGroup.svelte +35 -46
  3. package/dist/Components/AccordionGroupButton.svelte +68 -76
  4. package/dist/Components/Action.svelte +103 -135
  5. package/dist/Components/AlertModal.svelte +171 -190
  6. package/dist/Components/AppointmentCalendar/AppointmentCalendar.svelte +614 -697
  7. package/dist/Components/Base/BaseModal.svelte +90 -116
  8. package/dist/Components/Base/ContextWrapper.svelte +67 -72
  9. package/dist/Components/Base/Pagination.svelte +173 -196
  10. package/dist/Components/Base/Snippets.svelte +34 -36
  11. package/dist/Components/BigRadioSet.svelte +36 -38
  12. package/dist/Components/Bubble.svelte +78 -101
  13. package/dist/Components/Button.svelte +175 -208
  14. package/dist/Components/Checkbox.svelte +75 -86
  15. package/dist/Components/CollapsibleCard.svelte +72 -87
  16. package/dist/Components/CollapsibleMenuGroup.svelte +53 -57
  17. package/dist/Components/ConditionBuilder/ConditionBuilder.svelte +39 -64
  18. package/dist/Components/Contexts/ContextMenu.svelte +141 -156
  19. package/dist/Components/Contexts/ContextMenuDivider.svelte +15 -15
  20. package/dist/Components/Contexts/ContextMenuOption.svelte +53 -60
  21. package/dist/Components/Contexts/Toast.svelte +81 -86
  22. package/dist/Components/Contexts/ToastContainer.svelte +58 -62
  23. package/dist/Components/Contexts/Tooltip.svelte +36 -37
  24. package/dist/Components/DataMatrixIcon.svelte +95 -108
  25. package/dist/Components/DateInput.svelte +118 -146
  26. package/dist/Components/DatePicker.svelte +255 -294
  27. package/dist/Components/DesktopModal.svelte +70 -90
  28. package/dist/Components/Dial.svelte +167 -197
  29. package/dist/Components/DimensionInput.svelte +124 -169
  30. package/dist/Components/DragMenu/DragMenuHolder.svelte +98 -114
  31. package/dist/Components/DragMenu/DraggableCard.svelte +64 -76
  32. package/dist/Components/FileCard.svelte +21 -24
  33. package/dist/Components/FileUpload.svelte +190 -225
  34. package/dist/Components/GridInput.svelte +159 -196
  35. package/dist/Components/GridInputSet.svelte +24 -29
  36. package/dist/Components/HorizontalTabGroup.svelte +73 -89
  37. package/dist/Components/HorizontalTabGroupButton.svelte +40 -44
  38. package/dist/Components/Icon.svelte +99 -128
  39. package/dist/Components/Icons.js +357 -357
  40. package/dist/Components/InfoAlert.svelte +35 -38
  41. package/dist/Components/LoadingAnimation.svelte +691 -755
  42. package/dist/Components/LoadingModal.svelte +36 -44
  43. package/dist/Components/LoadingOverlay.svelte +22 -26
  44. package/dist/Components/Modal.svelte +204 -254
  45. package/dist/Components/MultiSelect.svelte +186 -216
  46. package/dist/Components/Nav/Nav.svelte +94 -110
  47. package/dist/Components/Nav/NavServiceMenuList.svelte +57 -61
  48. package/dist/Components/Nav/NavTab.svelte +58 -62
  49. package/dist/Components/Nav/ServiceMenuItem.svelte +103 -111
  50. package/dist/Components/Nav/ServicesNav.svelte +72 -79
  51. package/dist/Components/NumberInput.svelte +121 -155
  52. package/dist/Components/OptionCards.svelte +62 -73
  53. package/dist/Components/PageHeading.svelte +23 -25
  54. package/dist/Components/PasswordInput.svelte +69 -88
  55. package/dist/Components/PopoverButton.svelte +151 -0
  56. package/dist/Components/PopoverButton.svelte.d.ts +9 -0
  57. package/dist/Components/PopoverButtonProps.d.ts +21 -0
  58. package/dist/Components/PopoverButtonProps.js +1 -0
  59. package/dist/Components/Portal.svelte +29 -35
  60. package/dist/Components/ProgressBubble.svelte +91 -106
  61. package/dist/Components/QuerySelect.svelte +260 -346
  62. package/dist/Components/SidebarPanel.svelte +34 -36
  63. package/dist/Components/SingleSelect.svelte +196 -244
  64. package/dist/Components/StepButton.svelte +65 -70
  65. package/dist/Components/StepForm.svelte +115 -135
  66. package/dist/Components/Switch.svelte +57 -69
  67. package/dist/Components/Table/ARCHITECTURE.md +298 -298
  68. package/dist/Components/Table/Body/QuickSearchCell.svelte +578 -655
  69. package/dist/Components/Table/Body/Rows/ColumnHighlight.svelte +42 -51
  70. package/dist/Components/Table/Body/Rows/ColumnList.svelte +42 -58
  71. package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +403 -442
  72. package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +51 -78
  73. package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +165 -184
  74. package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +110 -123
  75. package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +134 -160
  76. package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte +190 -231
  77. package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +82 -104
  78. package/dist/Components/Table/Body/Rows/Columns/TableAction.svelte +52 -87
  79. package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +122 -150
  80. package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +132 -159
  81. package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +190 -236
  82. package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +173 -211
  83. package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +204 -244
  84. package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +140 -177
  85. package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +188 -217
  86. package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +173 -193
  87. package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +166 -187
  88. package/dist/Components/Table/Body/Rows/TableRow.svelte +245 -288
  89. package/dist/Components/Table/Body/TableBody.svelte +141 -154
  90. package/dist/Components/Table/Headers/HighlightAllHeader.svelte +35 -41
  91. package/dist/Components/Table/Headers/SelectAllHeader.svelte +24 -30
  92. package/dist/Components/Table/Headers/TableHead.svelte +348 -402
  93. package/dist/Components/Table/Misc/ColumnPanel.svelte +37 -39
  94. package/dist/Components/Table/Misc/ColumnPanelModal.svelte +35 -39
  95. package/dist/Components/Table/Misc/FilterInput.svelte +556 -619
  96. package/dist/Components/Table/Misc/FilterPanel.svelte +170 -183
  97. package/dist/Components/Table/Misc/FilterPanelModal.svelte +25 -31
  98. package/dist/Components/Table/Misc/ShareViewModal.svelte +252 -281
  99. package/dist/Components/Table/Misc/SidePanel.svelte +32 -35
  100. package/dist/Components/Table/Misc/TableConfigurationModal.svelte +574 -629
  101. package/dist/Components/Table/Misc/TableFooter.svelte +326 -332
  102. package/dist/Components/Table/Misc/TableHorizontalBar.svelte +134 -140
  103. package/dist/Components/Table/Misc/TableSidebar.svelte +183 -198
  104. package/dist/Components/Table/Misc/TableViewDropdown.svelte +83 -103
  105. package/dist/Components/Table/Misc/ToolboxPanel.svelte +83 -100
  106. package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +88 -107
  107. package/dist/Components/Table/Misc/UpdateViewOptionsModal.svelte +163 -190
  108. package/dist/Components/Table/NestedTable.svelte +102 -128
  109. package/dist/Components/Table/Table.svelte +531 -663
  110. package/dist/Components/Test/TestContextConsumer.svelte +11 -13
  111. package/dist/Components/TextArea.svelte +95 -130
  112. package/dist/Components/TextInput.svelte +125 -176
  113. package/dist/Components/ThreeStateRadio.svelte +111 -130
  114. package/dist/Components/Touch/BoolCard.svelte +33 -45
  115. package/dist/Components/Touch/DateModal.svelte +164 -204
  116. package/dist/Components/Touch/EditCard.svelte +48 -59
  117. package/dist/Components/Touch/InfoCard.svelte +28 -31
  118. package/dist/Components/Touch/InfoTextCard.svelte +26 -28
  119. package/dist/Components/Touch/ModalExplanation.svelte +15 -17
  120. package/dist/Components/Touch/NumberKeyboard.svelte +181 -218
  121. package/dist/Components/Touch/NumberModal.svelte +59 -79
  122. package/dist/Components/Touch/PlusMinusCard.svelte +43 -46
  123. package/dist/Components/Touch/SelectModal.svelte +111 -126
  124. package/dist/Components/Touch/SummaryCard.svelte +80 -93
  125. package/dist/Components/Touch/TextAreaModal.svelte +72 -94
  126. package/dist/Components/Touch/TextModal.svelte +77 -105
  127. package/dist/Components/Touch/TouchCard.svelte +31 -33
  128. package/dist/Components/Touch/TouchModal.svelte +214 -270
  129. package/dist/Components/Touch/UtilityButton.svelte +88 -109
  130. package/dist/Components/VerticalTabGroup.svelte +60 -78
  131. package/dist/Components/VerticalTabGroupButton.svelte +54 -58
  132. package/dist/Helpers/Datamatrix.d.ts +19 -19
  133. package/dist/Helpers/Datamatrix.js +291 -291
  134. package/dist/Types/Examples/ExampleModal.svelte +31 -35
  135. package/dist/index.d.ts +2 -0
  136. package/dist/index.js +1 -0
  137. package/dist/scss/_basics.scss +12 -12
  138. package/dist/scss/_colours.scss +134 -134
  139. package/dist/scss/_mixins.scss +3392 -3392
  140. package/dist/scss/_motion.scss +57 -57
  141. package/dist/scss/_sizing.scss +85 -85
  142. package/dist/scss/_transitions.scss +8 -8
  143. package/package.json +1 -1
@@ -1,202 +1,187 @@
1
- <svelte:options runes />
2
-
3
- <script
4
- lang="ts"
5
- generics="T extends object, IdType extends Primitive"
6
- >
7
- import Button from '../../Button.svelte';
8
- import { devCatch } from '../../../Helpers/Helpers.svelte.js';
9
- import { Side } from '../../../Types/Internal/Side.js';
10
- import { Size } from '../../../Types/Internal/Size.js';
11
- import { Variant } from '../../../Types/Internal/Variant.js';
12
- import { getContext } from 'svelte';
13
- import { TableContext } from '../Types/Context/TableContext.svelte.js';
14
- import type { Primitive } from '../Types/Context/TableInitOptions.js';
15
- import { ExpandedPanel } from '../Types/ExpandedPanel.js';
16
- import { ToolbarPosition } from '../Types/Toolbar/ToolbarPosition.js';
17
- import ColumnPanel from './ColumnPanel.svelte';
18
- import FilterPanel from './FilterPanel.svelte';
19
- import SidePanel from './SidePanel.svelte';
20
- import TableConfigurationModal from './TableConfigurationModal.svelte';
21
- import ToolboxPanel from './ToolboxPanel.svelte';
22
-
23
- const tableContext = getContext<TableContext<T, IdType>>(TableContext.identifier);
24
-
25
- // `TableConfigurationModal` is a full `DesktopModal` rather than a
26
- // side-panel body, so it is registered here but rendered standalone
27
- // (outside `SidePanel`) below - `panels` only maps the side-panel
28
- // kinds. Keeping the Configuration key in the map documents the
29
- // relationship and mirrors `TableHorizontalBar`'s registration.
30
- const panels = {
31
- [ExpandedPanel.Column]: ColumnPanel,
32
- [ExpandedPanel.Filter]: FilterPanel,
33
- [ExpandedPanel.Toolbox]: ToolboxPanel,
34
- [ExpandedPanel.Configuration]: TableConfigurationModal,
35
- } as const;
36
-
37
- let expandedPanel = $state<ExpandedPanel | null>(null);
38
-
39
- $effect(() => {
40
- // The Configuration modal owns its own overlay and must not shrink
41
- // the table footer the way an inline side panel does.
42
- tableContext.limitFooter = !!expandedPanel && expandedPanel !== ExpandedPanel.Configuration;
43
- });
44
-
45
- // Side-panel body for the inline panel kinds only; the Configuration
46
- // kind is excluded and handled by the standalone modal block below.
47
- let ExpandedPanelElement = $derived(
48
- expandedPanel &&
49
- expandedPanel !== ExpandedPanel.None &&
50
- expandedPanel !== ExpandedPanel.Configuration
51
- ? panels[expandedPanel]
52
- : null
53
- );
54
-
55
- function handleClickOutside(e: MouseEvent) {
56
- const target = e.target as HTMLElement;
57
- if (!target.isConnected) {
58
- return;
59
- }
60
- // A click landing inside the side-panel or the toolbar
61
- // sidebar should keep the panel open.
62
- if (target.closest('.side-content') != null) {
63
- return;
64
- }
65
- if (target.closest('.sidebar') != null) {
66
- return;
67
- }
68
- // A click landing inside a teleported select dropdown (see
69
- // `Helpers/dropdownPortal.ts`) is a logical extension of the
70
- // trigger that lives inside the side-panel, so it must not
71
- // close the panel. The marker attribute is set by the portal
72
- // helper while the dropdown is teleported to `document.body`.
73
- if (target.closest('[data-scoria-portal-dropdown]') != null) {
74
- return;
75
- }
76
- // The Table Configuration modal owns its own backdrop + close
77
- // affordances; a click inside its `.modal-root` must not be
78
- // treated as a click-outside that dismisses the panel.
79
- if (target.closest('.modal-root') != null) {
80
- return;
81
- }
82
- expandedPanel = null;
1
+ <svelte:options runes />
2
+
3
+ <script
4
+ lang="ts"
5
+ generics="T extends object, IdType extends Primitive"
6
+ >import Button from "../../Button.svelte";
7
+ import { devCatch } from "../../../Helpers/Helpers.svelte.js";
8
+ import { Side } from "../../../Types/Internal/Side.js";
9
+ import { Size } from "../../../Types/Internal/Size.js";
10
+ import { Variant } from "../../../Types/Internal/Variant.js";
11
+ import { getContext } from "svelte";
12
+ import { TableContext } from "../Types/Context/TableContext.svelte.js";
13
+ import { ExpandedPanel } from "../Types/ExpandedPanel.js";
14
+ import { ToolbarPosition } from "../Types/Toolbar/ToolbarPosition.js";
15
+ import ColumnPanel from "./ColumnPanel.svelte";
16
+ import FilterPanel from "./FilterPanel.svelte";
17
+ import SidePanel from "./SidePanel.svelte";
18
+ import TableConfigurationModal from "./TableConfigurationModal.svelte";
19
+ import ToolboxPanel from "./ToolboxPanel.svelte";
20
+ const tableContext = getContext(TableContext.identifier);
21
+ // `TableConfigurationModal` is a full `DesktopModal` rather than a
22
+ // side-panel body, so it is registered here but rendered standalone
23
+ // (outside `SidePanel`) below - `panels` only maps the side-panel
24
+ // kinds. Keeping the Configuration key in the map documents the
25
+ // relationship and mirrors `TableHorizontalBar`'s registration.
26
+ const panels = {
27
+ [ExpandedPanel.Column]: ColumnPanel,
28
+ [ExpandedPanel.Filter]: FilterPanel,
29
+ [ExpandedPanel.Toolbox]: ToolboxPanel,
30
+ [ExpandedPanel.Configuration]: TableConfigurationModal
31
+ };
32
+ let expandedPanel = $state(null);
33
+ $effect(() => {
34
+ // The Configuration modal owns its own overlay and must not shrink
35
+ // the table footer the way an inline side panel does.
36
+ tableContext.limitFooter = !!expandedPanel && expandedPanel !== ExpandedPanel.Configuration;
37
+ });
38
+ // Side-panel body for the inline panel kinds only; the Configuration
39
+ // kind is excluded and handled by the standalone modal block below.
40
+ let ExpandedPanelElement = $derived(expandedPanel && expandedPanel !== ExpandedPanel.None && expandedPanel !== ExpandedPanel.Configuration ? panels[expandedPanel] : null);
41
+ function handleClickOutside(e) {
42
+ const target = e.target;
43
+ if (!target.isConnected) {
44
+ return;
45
+ }
46
+ // A click landing inside the side-panel or the toolbar
47
+ // sidebar should keep the panel open.
48
+ if (target.closest(".side-content") != null) {
49
+ return;
50
+ }
51
+ if (target.closest(".sidebar") != null) {
52
+ return;
53
+ }
54
+ // A click landing inside a teleported select dropdown (see
55
+ // `Helpers/dropdownPortal.ts`) is a logical extension of the
56
+ // trigger that lives inside the side-panel, so it must not
57
+ // close the panel. The marker attribute is set by the portal
58
+ // helper while the dropdown is teleported to `document.body`.
59
+ if (target.closest("[data-scoria-portal-dropdown]") != null) {
60
+ return;
83
61
  }
84
-
85
- function handleEscKey(e: KeyboardEvent) {
86
- if (e.key === 'Escape') {
87
- expandedPanel = null;
88
- }
62
+ // The Table Configuration modal owns its own backdrop + close
63
+ // affordances; a click inside its `.modal-root` must not be
64
+ // treated as a click-outside that dismisses the panel.
65
+ if (target.closest(".modal-root") != null) {
66
+ return;
89
67
  }
90
- </script>
91
-
92
- <svelte:window
93
- onclick={handleClickOutside}
94
- onkeydown={handleEscKey}
95
- />
96
-
97
- {#if ExpandedPanelElement != null}
98
- <SidePanel toolbarPosition={tableContext.toolbarPosition}>
99
- <ExpandedPanelElement />
100
- </SidePanel>
101
- {/if}
102
-
103
- {#if expandedPanel === ExpandedPanel.Configuration}
104
- <TableConfigurationModal
105
- onclose={() => {
106
- expandedPanel = null;
107
- }}
108
- />
109
- {/if}
110
- <div class="sidebar">
111
- <Button
112
- side={tableContext.toolbarPosition === ToolbarPosition.Left ? Side.Left : Side.Right}
113
- onclick={() => {
114
- tableContext.toggleQuickFiltering();
115
- }}
116
- toggled={tableContext.showQuickFiltering}
117
- disabled={!tableContext.allowQuickFiltering}
118
- variant={Variant.Toolbar}
119
- iconTop={{
120
- name: 'assessment',
121
- size: Size.Medium,
122
- }}
123
- label="Quick Filter"
124
- />
125
- <Button
126
- side={tableContext.toolbarPosition === ToolbarPosition.Left ? Side.Left : Side.Right}
127
- disabled={!tableContext.allowAdvancedFiltering}
128
- toggled={expandedPanel === ExpandedPanel.Filter}
129
- onclick={() => {
130
- expandedPanel = expandedPanel === ExpandedPanel.Filter ? null : ExpandedPanel.Filter;
131
- }}
132
- variant={Variant.Toolbar}
133
- iconTop={{
134
- name: 'filter-bars',
135
- size: Size.Medium,
136
- }}
137
- label="Advanced Filter"
138
- />
139
- <Button
140
- side={tableContext.toolbarPosition === ToolbarPosition.Left ? Side.Left : Side.Right}
141
- onclick={() => {
142
- expandedPanel = expandedPanel === ExpandedPanel.Column ? null : ExpandedPanel.Column;
143
- }}
144
- variant={Variant.Toolbar}
145
- toggled={expandedPanel === ExpandedPanel.Column}
146
- iconTop={{
147
- name: 'columns',
148
- size: Size.Medium,
149
- }}
150
- label="Modify Columns"
151
- />
152
- <Button
153
- side={tableContext.toolbarPosition === ToolbarPosition.Left ? Side.Left : Side.Right}
154
- toggled={expandedPanel === ExpandedPanel.Toolbox}
155
- onclick={() => {
156
- expandedPanel = expandedPanel === ExpandedPanel.Toolbox ? null : ExpandedPanel.Toolbox;
157
- }}
158
- variant={Variant.Toolbar}
159
- iconTop={{
160
- name: 'category',
161
- size: Size.Medium,
162
- }}
163
- label="My Tool Box"
164
- />
165
- <Button
166
- side={tableContext.toolbarPosition === ToolbarPosition.Left ? Side.Left : Side.Right}
167
- toggled={expandedPanel === ExpandedPanel.Configuration}
168
- onclick={() => {
169
- expandedPanel =
170
- expandedPanel === ExpandedPanel.Configuration ? null : ExpandedPanel.Configuration;
171
- }}
172
- variant={Variant.Toolbar}
173
- iconTop={{
174
- name: 'setting-cog',
175
- size: Size.Medium,
176
- }}
177
- label="Table Configuration"
178
- />
179
-
180
- {#if tableContext.paginationRepo?.reload}
181
- <Button
182
- side={tableContext.toolbarPosition === ToolbarPosition.Left ? Side.Left : Side.Right}
183
- onclick={() => {
184
- tableContext.paginationRepo?.reload?.().catch(devCatch);
185
- }}
186
- disabled={!tableContext.allowQuickFiltering}
187
- variant={Variant.Toolbar}
188
- toggled={tableContext.dataRepo.isLoading}
189
- iconTop={{
190
- name: 'refresh',
191
- size: Size.Medium,
192
- }}
193
- label="Refresh"
194
- />
195
- {/if}
196
-
197
- <div class="filler"></div>
198
- </div>
199
-
68
+ expandedPanel = null;
69
+ }
70
+ function handleEscKey(e) {
71
+ if (e.key === "Escape") {
72
+ expandedPanel = null;
73
+ }
74
+ }
75
+ </script>
76
+
77
+ <svelte:window
78
+ onclick={handleClickOutside}
79
+ onkeydown={handleEscKey}
80
+ />
81
+
82
+ {#if ExpandedPanelElement != null}
83
+ <SidePanel toolbarPosition={tableContext.toolbarPosition}>
84
+ <ExpandedPanelElement />
85
+ </SidePanel>
86
+ {/if}
87
+
88
+ {#if expandedPanel === ExpandedPanel.Configuration}
89
+ <TableConfigurationModal
90
+ onclose={() => {
91
+ expandedPanel = null;
92
+ }}
93
+ />
94
+ {/if}
95
+ <div class="sidebar">
96
+ <Button
97
+ side={tableContext.toolbarPosition === ToolbarPosition.Left ? Side.Left : Side.Right}
98
+ onclick={() => {
99
+ tableContext.toggleQuickFiltering();
100
+ }}
101
+ toggled={tableContext.showQuickFiltering}
102
+ disabled={!tableContext.allowQuickFiltering}
103
+ variant={Variant.Toolbar}
104
+ iconTop={{
105
+ name: 'assessment',
106
+ size: Size.Medium,
107
+ }}
108
+ label="Quick Filter"
109
+ />
110
+ <Button
111
+ side={tableContext.toolbarPosition === ToolbarPosition.Left ? Side.Left : Side.Right}
112
+ disabled={!tableContext.allowAdvancedFiltering}
113
+ toggled={expandedPanel === ExpandedPanel.Filter}
114
+ onclick={() => {
115
+ expandedPanel = expandedPanel === ExpandedPanel.Filter ? null : ExpandedPanel.Filter;
116
+ }}
117
+ variant={Variant.Toolbar}
118
+ iconTop={{
119
+ name: 'filter-bars',
120
+ size: Size.Medium,
121
+ }}
122
+ label="Advanced Filter"
123
+ />
124
+ <Button
125
+ side={tableContext.toolbarPosition === ToolbarPosition.Left ? Side.Left : Side.Right}
126
+ onclick={() => {
127
+ expandedPanel = expandedPanel === ExpandedPanel.Column ? null : ExpandedPanel.Column;
128
+ }}
129
+ variant={Variant.Toolbar}
130
+ toggled={expandedPanel === ExpandedPanel.Column}
131
+ iconTop={{
132
+ name: 'columns',
133
+ size: Size.Medium,
134
+ }}
135
+ label="Modify Columns"
136
+ />
137
+ <Button
138
+ side={tableContext.toolbarPosition === ToolbarPosition.Left ? Side.Left : Side.Right}
139
+ toggled={expandedPanel === ExpandedPanel.Toolbox}
140
+ onclick={() => {
141
+ expandedPanel = expandedPanel === ExpandedPanel.Toolbox ? null : ExpandedPanel.Toolbox;
142
+ }}
143
+ variant={Variant.Toolbar}
144
+ iconTop={{
145
+ name: 'category',
146
+ size: Size.Medium,
147
+ }}
148
+ label="My Tool Box"
149
+ />
150
+ <Button
151
+ side={tableContext.toolbarPosition === ToolbarPosition.Left ? Side.Left : Side.Right}
152
+ toggled={expandedPanel === ExpandedPanel.Configuration}
153
+ onclick={() => {
154
+ expandedPanel =
155
+ expandedPanel === ExpandedPanel.Configuration ? null : ExpandedPanel.Configuration;
156
+ }}
157
+ variant={Variant.Toolbar}
158
+ iconTop={{
159
+ name: 'setting-cog',
160
+ size: Size.Medium,
161
+ }}
162
+ label="Table Configuration"
163
+ />
164
+
165
+ {#if tableContext.paginationRepo?.reload}
166
+ <Button
167
+ side={tableContext.toolbarPosition === ToolbarPosition.Left ? Side.Left : Side.Right}
168
+ onclick={() => {
169
+ tableContext.paginationRepo?.reload?.().catch(devCatch);
170
+ }}
171
+ disabled={!tableContext.allowQuickFiltering}
172
+ variant={Variant.Toolbar}
173
+ toggled={tableContext.dataRepo.isLoading}
174
+ iconTop={{
175
+ name: 'refresh',
176
+ size: Size.Medium,
177
+ }}
178
+ label="Refresh"
179
+ />
180
+ {/if}
181
+
182
+ <div class="filler"></div>
183
+ </div>
184
+
200
185
  <style>.sidebar {
201
186
  flex-flow: column nowrap;
202
187
  text-orientation: sideways;
@@ -215,4 +200,4 @@
215
200
  .sidebar .filler {
216
201
  flex-grow: 2;
217
202
  background-color: #ffffff;
218
- }</style>
203
+ }</style>
@@ -1,109 +1,89 @@
1
- <svelte:options runes />
2
-
3
- <script
4
- lang="ts"
5
- generics="T extends object, IdType extends Primitive"
6
- >
7
- import SingleSelect from '../../SingleSelect.svelte';
8
- import type { SelectOption } from '../../../Types/Internal/SelectOption.js';
9
- import { getContext } from 'svelte';
10
- import { TableContext } from '../Types/Context/TableContext.svelte.js';
11
- import type { Primitive } from '../Types/Context/TableInitOptions.js';
12
- import type { DatatableViewKind } from '../Types/Persistence/DatatableViewKind.js';
13
-
14
- interface Props {
15
- /**
16
- * Which view-state slice this dropdown switches between. `'layout'`
17
- * lists saved column layouts; `'filter'` lists saved filter sets.
18
- * Drives every `_viewState` read (label / active view / saved
19
- * views) and which kind `resetToDefault` is called with.
20
- */
21
- kind: DatatableViewKind;
1
+ <svelte:options runes />
2
+
3
+ <script
4
+ lang="ts"
5
+ generics="T extends object, IdType extends Primitive"
6
+ >import SingleSelect from "../../SingleSelect.svelte";
7
+ import { getContext } from "svelte";
8
+ import { TableContext } from "../Types/Context/TableContext.svelte.js";
9
+ const { kind } = $props();
10
+ const tableContext = getContext(TableContext.identifier);
11
+ // Sentinel value for the "Default" option. Must be NON-EMPTY: svelecte
12
+ // treats an empty-string value as "no selection" and shows the
13
+ // placeholder instead of the selected option. The leading space keeps
14
+ // it distinct from every server-assigned saved-view id (numeric
15
+ // strings) and from `UNSAVED_OPTION`.
16
+ const DEFAULT_OPTION = " default";
17
+ // The view-state slice for `kind`, read live from the context.
18
+ const activeView = $derived(tableContext._viewState.activeView(kind));
19
+ const savedViews = $derived(tableContext._viewState.savedViews(kind));
20
+ // Dropdown label: 'Default' / 'Custom (unsaved)' / '<name>' / '<name>
21
+ // (unsaved)'. Used as the displayed value of the select so it reflects
22
+ // the dirty state exactly. When dirty this is a *transient* string
23
+ // ("Custom (unsaved)" / "<name> (unsaved)") that is deliberately NOT
24
+ // one of the selectable options below.
25
+ const dropdownLabel = $derived(tableContext._viewState.dropdownLabel(kind));
26
+ // The value of the currently-active option: the sentinel for Default,
27
+ // otherwise the saved view's id.
28
+ const activeValue = $derived(activeView.kind === "saved" ? activeView.id : DEFAULT_OPTION);
29
+ // The selectable options. ALWAYS "Default" first (with its plain
30
+ // label, so the user can always pick it to revert) followed by every
31
+ // saved view of this kind with its plain name. The transient
32
+ // "…(unsaved)" label is never substituted in here - keeping it out
33
+ // means "Default" and the saved views stay selectable even while the
34
+ // table state is dirty. "Default" is present even when remote saved
35
+ // views are disabled and `savedViews` is empty.
36
+ const options = $derived([{
37
+ label: "Default",
38
+ value: DEFAULT_OPTION
39
+ }, ...savedViews.map((view) => ({
40
+ label: view.name,
41
+ value: view.id
42
+ }))]);
43
+ // The value handed to `SingleSelect`. The `value` is always the active
44
+ // option's real value (the Default sentinel or a saved-view id), so it
45
+ // matches an entry in `options` and `SingleSelect` keeps the selection
46
+ // rendered. The `label` is `dropdownLabel`, which already encodes the
47
+ // dirty state ("…(unsaved)"); `SingleSelect` shows it verbatim via its
48
+ // `selection` snippet. An earlier approach fed a transient value that
49
+ // was absent from `options`, which made svelecte drop the selection
50
+ // and fall back to its placeholder.
51
+ const selectedOption = $derived({
52
+ label: dropdownLabel,
53
+ value: activeValue
54
+ });
55
+ /** Apply the option the user picked from the dropdown. */
56
+ function selectOption(option) {
57
+ if (!option) {
58
+ return;
22
59
  }
23
-
24
- const { kind }: Props = $props();
25
-
26
- const tableContext = getContext<TableContext<T, IdType>>(TableContext.identifier);
27
-
28
- // Sentinel value for the "Default" option. Must be NON-EMPTY: svelecte
29
- // treats an empty-string value as "no selection" and shows the
30
- // placeholder instead of the selected option. The leading space keeps
31
- // it distinct from every server-assigned saved-view id (numeric
32
- // strings) and from `UNSAVED_OPTION`.
33
- const DEFAULT_OPTION = ' default';
34
-
35
- // The view-state slice for `kind`, read live from the context.
36
- const activeView = $derived(tableContext._viewState.activeView(kind));
37
- const savedViews = $derived(tableContext._viewState.savedViews(kind));
38
-
39
- // Dropdown label: 'Default' / 'Custom (unsaved)' / '<name>' / '<name>
40
- // (unsaved)'. Used as the displayed value of the select so it reflects
41
- // the dirty state exactly. When dirty this is a *transient* string
42
- // ("Custom (unsaved)" / "<name> (unsaved)") that is deliberately NOT
43
- // one of the selectable options below.
44
- const dropdownLabel = $derived(tableContext._viewState.dropdownLabel(kind));
45
-
46
- // The value of the currently-active option: the sentinel for Default,
47
- // otherwise the saved view's id.
48
- const activeValue = $derived(activeView.kind === 'saved' ? activeView.id : DEFAULT_OPTION);
49
-
50
- // The selectable options. ALWAYS "Default" first (with its plain
51
- // label, so the user can always pick it to revert) followed by every
52
- // saved view of this kind with its plain name. The transient
53
- // "…(unsaved)" label is never substituted in here - keeping it out
54
- // means "Default" and the saved views stay selectable even while the
55
- // table state is dirty. "Default" is present even when remote saved
56
- // views are disabled and `savedViews` is empty.
57
- const options: Array<SelectOption<string>> = $derived([
58
- { label: 'Default', value: DEFAULT_OPTION },
59
- ...savedViews.map((view) => ({ label: view.name, value: view.id })),
60
- ]);
61
-
62
- // The value handed to `SingleSelect`. The `value` is always the active
63
- // option's real value (the Default sentinel or a saved-view id), so it
64
- // matches an entry in `options` and `SingleSelect` keeps the selection
65
- // rendered. The `label` is `dropdownLabel`, which already encodes the
66
- // dirty state ("…(unsaved)"); `SingleSelect` shows it verbatim via its
67
- // `selection` snippet. An earlier approach fed a transient value that
68
- // was absent from `options`, which made svelecte drop the selection
69
- // and fall back to its placeholder.
70
- const selectedOption: SelectOption<string> = $derived({
71
- label: dropdownLabel,
72
- value: activeValue,
73
- });
74
-
75
- /** Apply the option the user picked from the dropdown. */
76
- function selectOption(option: SelectOption<string> | null): void {
77
- if (!option) {
78
- return;
79
- }
80
- if (option.value === DEFAULT_OPTION) {
81
- tableContext.resetToDefault(kind);
82
- return;
83
- }
84
- const view = savedViews.find((v) => v.id === option.value);
85
- if (view) {
86
- tableContext.applyDatatableView(view);
87
- }
60
+ if (option.value === DEFAULT_OPTION) {
61
+ tableContext.resetToDefault(kind);
62
+ return;
88
63
  }
89
- </script>
90
-
91
- <div class="view-dropdown">
92
- <SingleSelect
93
- label={kind === 'filter' ? 'Filter' : 'Layout'}
94
- name={kind === 'filter' ? 'Filter' : 'Layout'}
95
- {options}
96
- labelProp="label"
97
- valueProp="value"
98
- value={selectedOption}
99
- valueAsObject
100
- searchable={false}
101
- onchange={selectOption}
102
- />
103
- </div>
104
-
64
+ const view = savedViews.find((v) => v.id === option.value);
65
+ if (view) {
66
+ tableContext.applyDatatableView(view);
67
+ }
68
+ }
69
+ </script>
70
+
71
+ <div class="view-dropdown">
72
+ <SingleSelect
73
+ label={kind === 'filter' ? 'Filter' : 'Layout'}
74
+ name={kind === 'filter' ? 'Filter' : 'Layout'}
75
+ {options}
76
+ labelProp="label"
77
+ valueProp="value"
78
+ value={selectedOption}
79
+ valueAsObject
80
+ searchable={false}
81
+ onchange={selectOption}
82
+ />
83
+ </div>
84
+
105
85
  <style>.view-dropdown {
106
86
  display: flex;
107
87
  flex-flow: column nowrap;
108
88
  width: 100%;
109
- }</style>
89
+ }</style>