@lavalogic/scoria 0.37.44 → 0.37.46

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 (239) hide show
  1. package/README.md +58 -58
  2. package/dist/Components/AccordionGroup.svelte +46 -46
  3. package/dist/Components/AccordionGroupButton.svelte +76 -76
  4. package/dist/Components/Action.svelte +136 -136
  5. package/dist/Components/ActionProps.d.ts +2 -6
  6. package/dist/Components/AlertModal.svelte +195 -183
  7. package/dist/Components/AppointmentCalendar/AppointmentCalendar.svelte +702 -702
  8. package/dist/Components/Base/BaseModal.svelte +125 -125
  9. package/dist/Components/Base/ContextWrapper.svelte +72 -72
  10. package/dist/Components/Base/Pagination.svelte +198 -198
  11. package/dist/Components/Base/Snippets.svelte +36 -36
  12. package/dist/Components/BigRadioSet.svelte +38 -38
  13. package/dist/Components/Bubble.svelte +101 -101
  14. package/dist/Components/Button.svelte +209 -209
  15. package/dist/Components/ButtonProps.d.ts +2 -6
  16. package/dist/Components/Checkbox.svelte +86 -86
  17. package/dist/Components/CollapsibleCard.svelte +78 -78
  18. package/dist/Components/Contexts/ContextMenu.svelte +164 -164
  19. package/dist/Components/Contexts/ContextMenuDivider.svelte +15 -15
  20. package/dist/Components/Contexts/ContextMenuOption.svelte +60 -60
  21. package/dist/Components/Contexts/Toast.svelte +86 -83
  22. package/dist/Components/Contexts/Toast.svelte.d.ts +8 -5
  23. package/dist/Components/Contexts/ToastContainer.svelte +65 -65
  24. package/dist/Components/Contexts/Tooltip.svelte +37 -37
  25. package/dist/Components/DataMatrixIcon.svelte +112 -112
  26. package/dist/Components/DataMatrixIconProps.d.ts +3 -13
  27. package/dist/Components/DateInput.svelte +148 -148
  28. package/dist/Components/DatePicker.svelte +300 -300
  29. package/dist/Components/DesktopModal.svelte +90 -90
  30. package/dist/Components/Dial.svelte +204 -204
  31. package/dist/Components/DialProps.d.ts +1 -18
  32. package/dist/Components/DimensionInput.svelte +170 -170
  33. package/dist/Components/DragMenu/DragMenuHolder.svelte +119 -119
  34. package/dist/Components/DragMenu/DraggableCard.svelte +77 -77
  35. package/dist/Components/FileCard.svelte +24 -24
  36. package/dist/Components/FileUpload.svelte +236 -236
  37. package/dist/Components/GridInput.svelte +196 -200
  38. package/dist/Components/GridInputSet.svelte +29 -29
  39. package/dist/Components/HorizontalTabGroup.svelte +82 -82
  40. package/dist/Components/HorizontalTabGroupButton.svelte +44 -44
  41. package/dist/Components/Icon.svelte +128 -128
  42. package/dist/Components/IconProps.d.ts +2 -7
  43. package/dist/Components/Icons.js +357 -357
  44. package/dist/Components/LoadingAnimation.svelte +29 -29
  45. package/dist/Components/LoadingModal.svelte +45 -45
  46. package/dist/Components/LoadingOverlay.svelte +25 -25
  47. package/dist/Components/LoadingOverlayProps.d.ts +3 -7
  48. package/dist/Components/Modal.svelte +258 -258
  49. package/dist/Components/ModalProps.d.ts +0 -3
  50. package/dist/Components/MultiSelect.svelte +220 -220
  51. package/dist/Components/MultiSelectCommonProps.d.ts +6 -17
  52. package/dist/Components/Nav/Nav.svelte +110 -99
  53. package/dist/Components/Nav/NavProps.d.ts +4 -11
  54. package/dist/Components/Nav/NavServiceMenuList.svelte +43 -43
  55. package/dist/Components/Nav/NavTab.svelte +62 -62
  56. package/dist/Components/Nav/ServiceMenuItem.svelte +100 -100
  57. package/dist/Components/Nav/ServicesNav.svelte +80 -80
  58. package/dist/Components/NumberInput.svelte +157 -157
  59. package/dist/Components/PageHeading.svelte +25 -25
  60. package/dist/Components/PasswordInput.svelte +88 -88
  61. package/dist/Components/Portal.svelte +36 -36
  62. package/dist/Components/ProgressBubble.svelte +107 -108
  63. package/dist/Components/ProgressBubbleProps.d.ts +3 -3
  64. package/dist/Components/QuerySelect.svelte +366 -366
  65. package/dist/Components/QuerySelectProps.d.ts +4 -14
  66. package/dist/Components/SingleSelect.svelte +250 -250
  67. package/dist/Components/SingleSelectCommonProps.d.ts +3 -19
  68. package/dist/Components/StepButton.svelte +70 -70
  69. package/dist/Components/StepForm.svelte +140 -140
  70. package/dist/Components/Switch.svelte +69 -69
  71. package/dist/Components/Table/ARCHITECTURE.md +298 -0
  72. package/dist/Components/Table/Body/QuickSearchCell.svelte +683 -694
  73. package/dist/Components/Table/Body/Rows/ColumnHighlight.svelte +51 -51
  74. package/dist/Components/Table/Body/Rows/ColumnList.svelte +59 -59
  75. package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +456 -478
  76. package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +79 -79
  77. package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +185 -188
  78. package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +124 -124
  79. package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +120 -120
  80. package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte +230 -230
  81. package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +105 -105
  82. package/dist/Components/Table/Body/Rows/Columns/SelectColumn.d.ts +12 -9
  83. package/dist/Components/Table/Body/Rows/Columns/SelectTableCell.d.ts +5 -5
  84. package/dist/Components/Table/Body/Rows/Columns/TableAction.svelte +87 -87
  85. package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +126 -126
  86. package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +159 -159
  87. package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +246 -246
  88. package/dist/Components/Table/Body/Rows/Columns/TableDatePickerProps.d.ts +4 -4
  89. package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +216 -216
  90. package/dist/Components/Table/Body/Rows/Columns/TableQueryCell.d.ts +6 -5
  91. package/dist/Components/Table/Body/Rows/Columns/TableQueryColumn.d.ts +7 -6
  92. package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +252 -257
  93. package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +179 -179
  94. package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +221 -229
  95. package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte.d.ts +11 -11
  96. package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +197 -197
  97. package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +190 -190
  98. package/dist/Components/Table/Body/Rows/TableRow.svelte +290 -290
  99. package/dist/Components/Table/Body/TableBody.svelte +155 -155
  100. package/dist/Components/Table/ColumnDefinitions/ExampleItemColumnDefRepository.svelte.js +2 -3
  101. package/dist/Components/Table/ColumnFactory.svelte.d.ts +9 -11
  102. package/dist/Components/Table/ColumnFactory.svelte.js +110 -143
  103. package/dist/Components/Table/ColumnKindRegistry.d.ts +112 -0
  104. package/dist/Components/Table/ColumnKindRegistry.js +63 -0
  105. package/dist/Components/Table/Headers/HighlightAllHeader.svelte +41 -41
  106. package/dist/Components/Table/Headers/SelectAllHeader.svelte +30 -30
  107. package/dist/Components/Table/Headers/TableHead.svelte +415 -413
  108. package/dist/Components/Table/Misc/ColumnPanel.svelte +94 -94
  109. package/dist/Components/Table/Misc/ColumnPanelModal.svelte +112 -112
  110. package/dist/Components/Table/Misc/FilterInput.svelte +620 -644
  111. package/dist/Components/Table/Misc/FilterInput.svelte.d.ts +12 -12
  112. package/dist/Components/Table/Misc/FilterInputProps.d.ts +2 -2
  113. package/dist/Components/Table/Misc/FilterPanel.svelte +257 -257
  114. package/dist/Components/Table/Misc/FilterPanelModal.svelte +30 -30
  115. package/dist/Components/Table/Misc/SidePanel.svelte +35 -35
  116. package/dist/Components/Table/Misc/TableFooter.svelte +311 -311
  117. package/dist/Components/Table/Misc/TableHorizontalBar.svelte +125 -125
  118. package/dist/Components/Table/Misc/TableSidebar.svelte +157 -157
  119. package/dist/Components/Table/Misc/ToolboxPanel.svelte +100 -100
  120. package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +107 -107
  121. package/dist/Components/Table/NestedTable.svelte +130 -133
  122. package/dist/Components/Table/SubApis.svelte.d.ts +1 -5
  123. package/dist/Components/Table/SubApis.svelte.js +33 -32
  124. package/dist/Components/Table/Table.svelte +692 -745
  125. package/dist/Components/Table/TableHelpers.svelte.d.ts +6 -19
  126. package/dist/Components/Table/TableHelpers.svelte.js +6 -14
  127. package/dist/Components/Table/Types/Columns/Column.d.ts +2 -2
  128. package/dist/Components/Table/Types/Columns/DateColumn.d.ts +3 -3
  129. package/dist/Components/Table/Types/Columns/DateTableCell.d.ts +7 -7
  130. package/dist/Components/Table/Types/Columns/Definitions/Accessors/AccessorDef.svelte.d.ts +7 -8
  131. package/dist/Components/Table/Types/Columns/Definitions/Accessors/AccessorDef.svelte.js +4 -5
  132. package/dist/Components/Table/Types/Columns/Definitions/Accessors/CheckboxDef.svelte.d.ts +11 -14
  133. package/dist/Components/Table/Types/Columns/Definitions/Accessors/CheckboxDef.svelte.js +3 -4
  134. package/dist/Components/Table/Types/Columns/Definitions/Accessors/DateInputDef.svelte.d.ts +7 -11
  135. package/dist/Components/Table/Types/Columns/Definitions/Accessors/DateInputDef.svelte.js +3 -3
  136. package/dist/Components/Table/Types/Columns/Definitions/Accessors/NumberInputDef.svelte.d.ts +13 -18
  137. package/dist/Components/Table/Types/Columns/Definitions/Accessors/NumberInputDef.svelte.js +4 -5
  138. package/dist/Components/Table/Types/Columns/Definitions/Accessors/QueryDef.svelte.d.ts +5 -5
  139. package/dist/Components/Table/Types/Columns/Definitions/Accessors/QueryDef.svelte.js +2 -2
  140. package/dist/Components/Table/Types/Columns/Definitions/Accessors/SelectDef.svelte.d.ts +15 -12
  141. package/dist/Components/Table/Types/Columns/Definitions/Accessors/SelectDef.svelte.js +4 -5
  142. package/dist/Components/Table/Types/Columns/Definitions/Accessors/TextInputDef.svelte.d.ts +8 -12
  143. package/dist/Components/Table/Types/Columns/Definitions/Accessors/TextInputDef.svelte.js +3 -3
  144. package/dist/Components/Table/Types/Columns/Definitions/Actions/ActionsDef.svelte.d.ts +6 -6
  145. package/dist/Components/Table/Types/Columns/Definitions/Actions/ActionsDef.svelte.js +3 -3
  146. package/dist/Components/Table/Types/Columns/Definitions/ColumnDef.svelte.d.ts +49 -16
  147. package/dist/Components/Table/Types/Columns/Definitions/ColumnDef.svelte.js +27 -5
  148. package/dist/Components/Table/Types/Columns/Definitions/Display/AbstractDisplayDef.svelte.d.ts +7 -7
  149. package/dist/Components/Table/Types/Columns/Definitions/Display/AbstractDisplayDef.svelte.js +4 -4
  150. package/dist/Components/Table/Types/Columns/Definitions/Display/BubbleDef.svelte.d.ts +5 -5
  151. package/dist/Components/Table/Types/Columns/Definitions/Display/BubbleDef.svelte.js +2 -2
  152. package/dist/Components/Table/Types/Columns/Definitions/Display/DisplayDef.svelte.d.ts +5 -5
  153. package/dist/Components/Table/Types/Columns/Definitions/Display/DisplayDef.svelte.js +2 -2
  154. package/dist/Components/Table/Types/Columns/Definitions/Display/ProgressBarDef.svelte.d.ts +5 -5
  155. package/dist/Components/Table/Types/Columns/Definitions/Display/ProgressBarDef.svelte.js +2 -2
  156. package/dist/Components/Table/Types/Columns/Definitions/Display/ValidityDef.svelte.d.ts +5 -5
  157. package/dist/Components/Table/Types/Columns/Definitions/Display/ValidityDef.svelte.js +2 -2
  158. package/dist/Components/Table/Types/Columns/Definitions/Expand/ExpandDef.svelte.d.ts +11 -19
  159. package/dist/Components/Table/Types/Columns/Definitions/Expand/ExpandDef.svelte.js +4 -8
  160. package/dist/Components/Table/Types/Columns/Definitions/FilterOnly/FilterOnlyDef.svelte.d.ts +6 -7
  161. package/dist/Components/Table/Types/Columns/Definitions/FilterOnly/FilterOnlyDef.svelte.js +3 -4
  162. package/dist/Components/Table/Types/Columns/Definitions/RowSelection/RowSelectionDef.svelte.d.ts +9 -9
  163. package/dist/Components/Table/Types/Columns/Definitions/RowSelection/RowSelectionDef.svelte.js +4 -4
  164. package/dist/Components/Table/Types/Columns/ExpandTableCell.d.ts +5 -5
  165. package/dist/Components/Table/Types/Columns/ProgressBarTableCell.d.ts +6 -6
  166. package/dist/Components/Table/Types/Columns/TableCell.d.ts +7 -6
  167. package/dist/Components/Table/Types/Context/ClipboardState.svelte.d.ts +98 -0
  168. package/dist/Components/Table/Types/Context/ClipboardState.svelte.js +290 -0
  169. package/dist/Components/Table/Types/Context/ColumnLayoutState.svelte.d.ts +17 -45
  170. package/dist/Components/Table/Types/Context/ColumnLayoutState.svelte.js +17 -45
  171. package/dist/Components/Table/Types/Context/FilteringState.svelte.d.ts +9 -20
  172. package/dist/Components/Table/Types/Context/FilteringState.svelte.js +9 -20
  173. package/dist/Components/Table/Types/Context/FocusState.svelte.d.ts +23 -42
  174. package/dist/Components/Table/Types/Context/FocusState.svelte.js +32 -59
  175. package/dist/Components/Table/Types/Context/ITable.d.ts +5 -8
  176. package/dist/Components/Table/Types/Context/PreferencesState.svelte.d.ts +29 -56
  177. package/dist/Components/Table/Types/Context/PreferencesState.svelte.js +28 -55
  178. package/dist/Components/Table/Types/Context/QueryValuesState.svelte.d.ts +50 -0
  179. package/dist/Components/Table/Types/Context/QueryValuesState.svelte.js +62 -0
  180. package/dist/Components/Table/Types/Context/SelectionState.svelte.d.ts +17 -28
  181. package/dist/Components/Table/Types/Context/SelectionState.svelte.js +17 -28
  182. package/dist/Components/Table/Types/Context/SortingState.svelte.d.ts +15 -29
  183. package/dist/Components/Table/Types/Context/SortingState.svelte.js +17 -31
  184. package/dist/Components/Table/Types/Context/TableContext.svelte.d.ts +212 -325
  185. package/dist/Components/Table/Types/Context/TableContext.svelte.js +292 -706
  186. package/dist/Components/Table/Types/Context/VirtualisationState.svelte.d.ts +62 -79
  187. package/dist/Components/Table/Types/Context/VirtualisationState.svelte.js +54 -73
  188. package/dist/Components/Table/Types/DataRepository/BuiltInRemoteRepository.svelte.d.ts +16 -27
  189. package/dist/Components/Table/Types/DataRepository/BuiltInRemoteRepository.svelte.js +16 -27
  190. package/dist/Components/Table/Types/DataRepository/IDataRepository.d.ts +12 -15
  191. package/dist/Components/Table/Types/DataRepository/TableDataRepository.svelte.d.ts +15 -30
  192. package/dist/Components/Table/Types/DataRepository/TableDataRepository.svelte.js +16 -28
  193. package/dist/Components/Table/Types/Header.d.ts +4 -4
  194. package/dist/Components/Table/Types/HeaderGroup.d.ts +5 -5
  195. package/dist/Components/Table/Types/Public/index.d.ts +2 -4
  196. package/dist/Components/Table/Types/Public/index.js +2 -4
  197. package/dist/Components/Table/clipboardEscape.d.ts +32 -0
  198. package/dist/Components/Table/clipboardEscape.js +45 -0
  199. package/dist/Components/Table/createTable.svelte.d.ts +8 -18
  200. package/dist/Components/Table/createTable.svelte.js +19 -47
  201. package/dist/Components/Test/TestContextConsumer.svelte +13 -13
  202. package/dist/Components/TextArea.svelte +130 -130
  203. package/dist/Components/TextInput.svelte +176 -176
  204. package/dist/Components/ThreeStateRadio.svelte +131 -131
  205. package/dist/Components/Touch/BoolCard.svelte +45 -45
  206. package/dist/Components/Touch/DateModal.svelte +209 -209
  207. package/dist/Components/Touch/EditCard.svelte +59 -59
  208. package/dist/Components/Touch/InfoCard.svelte +31 -31
  209. package/dist/Components/Touch/InfoTextCard.svelte +28 -28
  210. package/dist/Components/Touch/ModalExplanation.svelte +17 -17
  211. package/dist/Components/Touch/NumberKeyboard.svelte +225 -225
  212. package/dist/Components/Touch/NumberModal.svelte +79 -79
  213. package/dist/Components/Touch/PlusMinusCard.svelte +46 -46
  214. package/dist/Components/Touch/SelectModal.svelte +123 -123
  215. package/dist/Components/Touch/SummaryCard.svelte +93 -93
  216. package/dist/Components/Touch/TextAreaModal.svelte +95 -95
  217. package/dist/Components/Touch/TextModal.svelte +106 -106
  218. package/dist/Components/Touch/TouchCard.svelte +33 -33
  219. package/dist/Components/Touch/TouchModal.svelte +274 -274
  220. package/dist/Components/Touch/UtilityButton.svelte +109 -109
  221. package/dist/Components/VerticalTabGroup.svelte +79 -79
  222. package/dist/Components/VerticalTabGroupButton.svelte +58 -58
  223. package/dist/Contexts/ToastContext.svelte.js +3 -4
  224. package/dist/Helpers/Datamatrix.d.ts +19 -19
  225. package/dist/Helpers/Datamatrix.js +291 -291
  226. package/dist/Helpers/Helpers.svelte.d.ts +47 -4
  227. package/dist/Helpers/Helpers.svelte.js +97 -4
  228. package/dist/Helpers/dropdownPortal.d.ts +26 -41
  229. package/dist/Helpers/dropdownPortal.js +62 -116
  230. package/dist/Types/Examples/ExampleModal.svelte +35 -35
  231. package/dist/index.d.ts +1 -2
  232. package/dist/index.js +1 -1
  233. package/dist/scss/_basics.scss +12 -12
  234. package/dist/scss/_colours.scss +134 -134
  235. package/dist/scss/_mixins.scss +3358 -3360
  236. package/dist/scss/_motion.scss +57 -57
  237. package/dist/scss/_sizing.scss +85 -85
  238. package/dist/scss/_transitions.scss +8 -8
  239. package/package.json +8 -6
@@ -12,19 +12,9 @@ interface QuerySelectCommonProps<V extends object, VP extends ValueProp<V>> {
12
12
  name?: string;
13
13
  /** Disable the input. */
14
14
  disabled?: boolean;
15
- /**
16
- * CSS width override. Interpolated into a CSS custom property.
17
- *
18
- * BREAKING (Phase 7.7): was `string`; now requires the `CssLength`
19
- * brand. Use the `cssLength('...')` helper.
20
- */
15
+ /** CSS width override. Use `cssLength('...')` to construct. */
21
16
  width?: CssLength;
22
- /**
23
- * CSS height override. Interpolated into a CSS custom property.
24
- *
25
- * BREAKING (Phase 7.7): was `string`; now requires the `CssLength`
26
- * brand. Use the `cssLength('...')` helper.
27
- */
17
+ /** CSS height override. Use `cssLength('...')` to construct. */
28
18
  height?: CssLength;
29
19
  /** Top label. */
30
20
  label?: string;
@@ -57,8 +47,8 @@ export interface QuerySelectPropsAsPrimitive<V extends object, VP extends ValueP
57
47
  value: V[VP] | null;
58
48
  /**
59
49
  * Called when the selection changes. Receives the primitive key value
60
- * (`V[VP]`) or null because `valueAsObject` is `false`. Do NOT read
61
- * `.value` off the argument -- it is already the primitive.
50
+ * (`V[VP]`) or null because `valueAsObject` is `false`. The argument
51
+ * is ALREADY the primitive do not read `.value` off it.
62
52
  */
63
53
  onchange: (newValue: V[VP] | null) => void | Promise<void>;
64
54
  }
@@ -1,252 +1,252 @@
1
- <svelte:options runes />
2
-
3
- <script
4
- lang="ts"
5
- generics="V extends object, VP extends ValueProp<V>"
6
- >
7
- import { devCatch, generateWeakId, vowels } from '../Helpers/Helpers.svelte.js';
8
- import { attachDropdownPortal } from '../Helpers/dropdownPortal.js';
9
- import { Colour, ColourSet } from '../scss/colours.js';
10
- import type { ValueProp } from '../Types/Internal/Misc.js';
11
- import { Size } from '../Types/Internal/Size.js';
12
- import Svelecte from 'svelecte';
13
- import { onMount, tick } from 'svelte';
14
- import Action from './Action.svelte';
15
- import type { SingleSelectProps } from './SingleSelectProps.js';
16
-
17
- const {
18
- label,
19
- options,
20
- labelProp,
21
- valueProp,
22
- focusOnLoad = false,
23
- searchable = true,
24
- creatable = false,
25
-
26
- createFilter,
27
- disabled,
28
- width,
29
- height,
30
- name = 'Item',
31
- valueAsObject,
32
- minHeight,
33
- clearable = false,
34
- required = false,
35
- invalid = false,
36
- borderless = false,
37
- lazyDropdown = false,
38
- forceUpwards = false,
39
- inputId = generateWeakId(),
40
- value: selectedValue,
41
- onchange,
42
- onfocus,
43
- onCreateOption,
44
- }: SingleSelectProps<V, VP> = $props();
45
-
46
- // Single source of truth for the current value. The previous code mixed
47
- // `$derived` and `$effect.pre`, which fired a redundant assignment on mount.
48
- const currentValue = $derived(selectedValue);
49
- let ref = $state<Svelecte | undefined>();
50
- let wrapperRef: HTMLDivElement | undefined = $state();
51
-
52
- const an = $derived(name && vowels.has(name.at(0)?.toLocaleLowerCase() ?? '') ? 'an' : 'a');
53
-
54
- const isInvalid = $derived((required && !currentValue) || invalid);
55
-
56
- let hasAutoFocused = $state(false);
57
-
58
- // ResizeObserver-driven height. Replaces the layout-forcing
59
- // `getBoundingClientRect()` call that used to run inside a `$derived`.
60
- let dropdownBottom = $state(0);
61
- $effect(() => {
62
- if (!wrapperRef) {
63
- return;
64
- }
65
- const ro = new ResizeObserver((entries) => {
66
- const entry = entries[0];
67
- dropdownBottom = entry.borderBoxSize[0].blockSize;
68
- });
69
- ro.observe(wrapperRef);
70
- return () => {
71
- ro.disconnect();
72
- };
73
- });
74
-
75
- function forceShowDropdown(input: HTMLInputElement) {
76
- if (focusOnLoad && !hasAutoFocused) {
77
- hasAutoFocused = true;
78
- input.click();
79
- }
80
- }
81
-
82
- let isExpanded = $state(false);
83
-
84
- onMount(() => {
85
- if (focusOnLoad) {
86
- tick()
87
- .then(() => {
88
- (ref as HTMLSelectElement | undefined)?.focus();
89
- })
90
- .catch(devCatch);
91
- }
92
-
93
- const input = document.getElementById(inputId);
94
- const svelecteRoot = input?.closest('div.svelecte') as HTMLElement | null;
95
- const dropdownRef =
96
- (svelecteRoot?.querySelector('.sv_dropdown') as HTMLElement | null) ?? undefined;
97
-
98
- // HACK callback for is-open on/off. Drives the chevron
99
- // rotation / clear icon visibility below.
100
- const observer = new MutationObserver((mutations: Array<MutationRecord>) => {
101
- for (let i = mutations.length - 1; i > -1; i--) {
102
- const mutation = mutations[i];
103
- if (mutation.attributeName === 'class') {
104
- isExpanded = dropdownRef?.classList.contains('is-open') ?? false;
105
- }
106
- }
107
- });
108
-
109
- if (dropdownRef) {
110
- observer.observe(dropdownRef, { attributes: true });
111
- }
112
-
113
- // Teleport the dropdown to `document.body` while open so it
114
- // escapes every ancestor `overflow` / `transform` / `z-index`
115
- // stacking context (filter-panel groups, sticky table strips,
116
- // modals, etc.). The portal helper also auto-flips upwards
117
- // when there is not enough space below the trigger and
118
- // repositions on scroll / resize. See
119
- // `Helpers/dropdownPortal.ts` for the full rationale.
120
- const detachPortal = attachDropdownPortal({
121
- getTrigger: () => svelecteRoot,
122
- getDropdown: () => dropdownRef,
123
- });
124
-
125
- return () => {
126
- observer.disconnect();
127
- detachPortal();
128
- };
129
- });
130
-
131
- function isObject(value: SingleSelectProps<V, VP>['value']): value is V {
132
- return value !== null && typeof value === 'object';
133
- }
134
- </script>
135
-
136
- <div
137
- class="select-wrapper"
138
- class:no-border={borderless}
139
- style={`${width ? `--input-width: ${width};` : ''}${height ? `--input-height: ${height};` : ''} --dropdown-bottom: calc(${dropdownBottom}px + 1px); --sv-min-height: ${minHeight ?? '2rem'};`}
140
- class:invalid={isInvalid}
141
- class:force-upwards={forceUpwards}
142
- bind:this={wrapperRef}
143
- >
144
- {#if label}
145
- <label for={inputId}>
146
- <span
147
- >{label}{#if !required}&nbsp;- <i>optional</i>{/if}</span
148
- >
149
- <span class="border"
150
- >{label}{#if !required}&nbsp;- <i>optional</i>{/if}</span
151
- >
152
- </label>
153
- {/if}
154
-
155
- <Svelecte
156
- {createFilter}
157
- {disabled}
158
- {name}
159
- onFocus={(target: HTMLInputElement) => {
160
- forceShowDropdown(target);
161
- onfocus?.(target);
162
- }}
163
- bind:this={ref}
164
- {valueAsObject}
165
- {inputId}
166
- {required}
167
- valueField={valueProp}
168
- labelField={labelProp}
169
- virtualList={false}
170
- {options}
171
- {creatable}
172
- searchProps={{ keepSelectionInList: true }}
173
- {onCreateOption}
174
- placeholder="Please Select {name ? `${an} ${name}` : ''}"
175
- {lazyDropdown}
176
- value={// eslint-disable-next-line @typescript-eslint/no-explicit-any
177
- currentValue as Array<any>}
178
- onChange={(newValue: V | null) => {
179
- // svelecte always emits the full option object regardless of
180
- // `valueAsObject`. Map to the shape the discriminated variant
181
- // promised: primitive for AsPrimitive, object for AsObject.
182
- if (valueAsObject) {
183
- void (onchange as (v: V | null) => void | Promise<void>)(newValue);
184
- } else {
185
- const primitive = newValue == null ? null : newValue[valueProp];
186
- // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
187
- void (onchange as (v: V[VP] | null) => void | Promise<void>)(primitive);
188
- }
189
- }}
190
- {searchable}
191
- selectOnTab
192
- keepSelectionInList
193
- deselectMode={clearable ? 'toggle' : 'none'}
194
- >
195
- {#snippet option(opt)}<span class="dropdown-item"> {(opt as V)[labelProp]}</span>{/snippet}
196
-
197
- {#snippet append()}
198
- <div class="icons">
199
- {#if clearable && currentValue}
200
- <Action
201
- noTabIndex
202
- onclick={(e: MouseEvent) => {
203
- if (isExpanded) {
204
- e.stopPropagation();
205
- }
206
-
207
- void onchange(null);
208
- }}
209
- {disabled}
210
- colourSet={ColourSet.Auxiliary}
211
- size={Size.Small}
212
- icon={{
213
- name: 'close-menu-cross',
214
- colour: Colour['$ui-blue-10'],
215
- }}
216
- />
217
- {/if}
218
-
219
- <Action
220
- noTabIndex
221
- colourSet={ColourSet.Auxiliary}
222
- size={Size.Small}
223
- {disabled}
224
- icon={{
225
- name: isExpanded ? 'chevron-up' : 'chevron-down',
226
- colour: Colour['$ui-blue-10'],
227
- }}
228
- />
229
- </div>
230
- {/snippet}
231
- {#snippet toggleIcon()}
232
- <div class="nothing"></div>
233
- {/snippet}
234
-
235
- {#snippet selection(/*_selectedOptions: Array<any>*/)}
236
- <span
237
- class="selection"
238
- class:invalid={isInvalid}
239
- >
240
- {#if isObject(selectedValue)}
241
- {selectedValue[labelProp]}
242
- {:else}
243
- {options.find((it) => it[valueProp] === selectedValue)?.[labelProp]}
244
- {/if}
245
- </span>
246
- {/snippet}
247
- </Svelecte>
248
- </div>
249
-
1
+ <svelte:options runes />
2
+
3
+ <script
4
+ lang="ts"
5
+ generics="V extends object, VP extends ValueProp<V>"
6
+ >
7
+ import { devCatch, generateWeakId, vowels } from '../Helpers/Helpers.svelte.js';
8
+ import { attachDropdownPortal } from '../Helpers/dropdownPortal.js';
9
+ import { Colour, ColourSet } from '../scss/colours.js';
10
+ import type { ValueProp } from '../Types/Internal/Misc.js';
11
+ import { Size } from '../Types/Internal/Size.js';
12
+ import Svelecte from 'svelecte';
13
+ import { onMount, tick } from 'svelte';
14
+ import Action from './Action.svelte';
15
+ import type { SingleSelectProps } from './SingleSelectProps.js';
16
+
17
+ const {
18
+ label,
19
+ options,
20
+ labelProp,
21
+ valueProp,
22
+ focusOnLoad = false,
23
+ searchable = true,
24
+ creatable = false,
25
+
26
+ createFilter,
27
+ disabled,
28
+ width,
29
+ height,
30
+ name = 'Item',
31
+ valueAsObject,
32
+ minHeight,
33
+ clearable = false,
34
+ required = false,
35
+ invalid = false,
36
+ borderless = false,
37
+ lazyDropdown = false,
38
+ forceUpwards = false,
39
+ inputId = generateWeakId(),
40
+ value: selectedValue,
41
+ onchange,
42
+ onfocus,
43
+ onCreateOption,
44
+ }: SingleSelectProps<V, VP> = $props();
45
+
46
+ // Single source of truth for the current value. The previous code mixed
47
+ // `$derived` and `$effect.pre`, which fired a redundant assignment on mount.
48
+ const currentValue = $derived(selectedValue);
49
+ let ref = $state<Svelecte | undefined>();
50
+ let wrapperRef: HTMLDivElement | undefined = $state();
51
+
52
+ const an = $derived(name && vowels.has(name.at(0)?.toLocaleLowerCase() ?? '') ? 'an' : 'a');
53
+
54
+ const isInvalid = $derived((required && !currentValue) || invalid);
55
+
56
+ let hasAutoFocused = $state(false);
57
+
58
+ // ResizeObserver-driven height. Replaces the layout-forcing
59
+ // `getBoundingClientRect()` call that used to run inside a `$derived`.
60
+ let dropdownBottom = $state(0);
61
+ $effect(() => {
62
+ if (!wrapperRef) {
63
+ return;
64
+ }
65
+ const ro = new ResizeObserver((entries) => {
66
+ const entry = entries[0];
67
+ dropdownBottom = entry.borderBoxSize[0].blockSize;
68
+ });
69
+ ro.observe(wrapperRef);
70
+ return () => {
71
+ ro.disconnect();
72
+ };
73
+ });
74
+
75
+ function forceShowDropdown(input: HTMLInputElement) {
76
+ if (focusOnLoad && !hasAutoFocused) {
77
+ hasAutoFocused = true;
78
+ input.click();
79
+ }
80
+ }
81
+
82
+ let isExpanded = $state(false);
83
+
84
+ onMount(() => {
85
+ if (focusOnLoad) {
86
+ tick()
87
+ .then(() => {
88
+ (ref as HTMLSelectElement | undefined)?.focus();
89
+ })
90
+ .catch(devCatch);
91
+ }
92
+
93
+ const input = document.getElementById(inputId);
94
+ const svelecteRoot = input?.closest('div.svelecte') as HTMLElement | null;
95
+ const dropdownRef =
96
+ (svelecteRoot?.querySelector('.sv_dropdown') as HTMLElement | null) ?? undefined;
97
+
98
+ // HACK callback for is-open on/off. Drives the chevron
99
+ // rotation / clear icon visibility below.
100
+ const observer = new MutationObserver((mutations: Array<MutationRecord>) => {
101
+ for (let i = mutations.length - 1; i > -1; i--) {
102
+ const mutation = mutations[i];
103
+ if (mutation.attributeName === 'class') {
104
+ isExpanded = dropdownRef?.classList.contains('is-open') ?? false;
105
+ }
106
+ }
107
+ });
108
+
109
+ if (dropdownRef) {
110
+ observer.observe(dropdownRef, { attributes: true });
111
+ }
112
+
113
+ // Teleport the dropdown to `document.body` while open so it
114
+ // escapes every ancestor `overflow` / `transform` / `z-index`
115
+ // stacking context (filter-panel groups, sticky table strips,
116
+ // modals, etc.). The portal helper also auto-flips upwards
117
+ // when there is not enough space below the trigger and
118
+ // repositions on scroll / resize. See
119
+ // `Helpers/dropdownPortal.ts` for the full rationale.
120
+ const detachPortal = attachDropdownPortal({
121
+ getTrigger: () => svelecteRoot,
122
+ getDropdown: () => dropdownRef,
123
+ });
124
+
125
+ return () => {
126
+ observer.disconnect();
127
+ detachPortal();
128
+ };
129
+ });
130
+
131
+ function isObject(value: SingleSelectProps<V, VP>['value']): value is V {
132
+ return value !== null && typeof value === 'object';
133
+ }
134
+ </script>
135
+
136
+ <div
137
+ class="select-wrapper"
138
+ class:no-border={borderless}
139
+ style={`${width ? `--input-width: ${width};` : ''}${height ? `--input-height: ${height};` : ''} --dropdown-bottom: calc(${dropdownBottom}px + 1px); --sv-min-height: ${minHeight ?? '2rem'};`}
140
+ class:invalid={isInvalid}
141
+ class:force-upwards={forceUpwards}
142
+ bind:this={wrapperRef}
143
+ >
144
+ {#if label}
145
+ <label for={inputId}>
146
+ <span
147
+ >{label}{#if !required}&nbsp;- <i>optional</i>{/if}</span
148
+ >
149
+ <span class="border"
150
+ >{label}{#if !required}&nbsp;- <i>optional</i>{/if}</span
151
+ >
152
+ </label>
153
+ {/if}
154
+
155
+ <Svelecte
156
+ {createFilter}
157
+ {disabled}
158
+ {name}
159
+ onFocus={(target: HTMLInputElement) => {
160
+ forceShowDropdown(target);
161
+ onfocus?.(target);
162
+ }}
163
+ bind:this={ref}
164
+ {valueAsObject}
165
+ {inputId}
166
+ {required}
167
+ valueField={valueProp}
168
+ labelField={labelProp}
169
+ virtualList={false}
170
+ {options}
171
+ {creatable}
172
+ searchProps={{ keepSelectionInList: true }}
173
+ {onCreateOption}
174
+ placeholder="Please Select {name ? `${an} ${name}` : ''}"
175
+ {lazyDropdown}
176
+ value={// eslint-disable-next-line @typescript-eslint/no-explicit-any
177
+ currentValue as Array<any>}
178
+ onChange={(newValue: V | null) => {
179
+ // svelecte always emits the full option object regardless of
180
+ // `valueAsObject`. Map to the shape the discriminated variant
181
+ // promised: primitive for AsPrimitive, object for AsObject.
182
+ if (valueAsObject) {
183
+ void (onchange as (v: V | null) => void | Promise<void>)(newValue);
184
+ } else {
185
+ const primitive = newValue == null ? null : newValue[valueProp];
186
+ // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
187
+ void (onchange as (v: V[VP] | null) => void | Promise<void>)(primitive);
188
+ }
189
+ }}
190
+ {searchable}
191
+ selectOnTab
192
+ keepSelectionInList
193
+ deselectMode={clearable ? 'toggle' : 'none'}
194
+ >
195
+ {#snippet option(opt)}<span class="dropdown-item"> {(opt as V)[labelProp]}</span>{/snippet}
196
+
197
+ {#snippet append()}
198
+ <div class="icons">
199
+ {#if clearable && currentValue}
200
+ <Action
201
+ noTabIndex
202
+ onclick={(e: MouseEvent) => {
203
+ if (isExpanded) {
204
+ e.stopPropagation();
205
+ }
206
+
207
+ void onchange(null);
208
+ }}
209
+ {disabled}
210
+ colourSet={ColourSet.Auxiliary}
211
+ size={Size.Small}
212
+ icon={{
213
+ name: 'close-menu-cross',
214
+ colour: Colour['$ui-blue-10'],
215
+ }}
216
+ />
217
+ {/if}
218
+
219
+ <Action
220
+ noTabIndex
221
+ colourSet={ColourSet.Auxiliary}
222
+ size={Size.Small}
223
+ {disabled}
224
+ icon={{
225
+ name: isExpanded ? 'chevron-up' : 'chevron-down',
226
+ colour: Colour['$ui-blue-10'],
227
+ }}
228
+ />
229
+ </div>
230
+ {/snippet}
231
+ {#snippet toggleIcon()}
232
+ <div class="nothing"></div>
233
+ {/snippet}
234
+
235
+ {#snippet selection(/*_selectedOptions: Array<any>*/)}
236
+ <span
237
+ class="selection"
238
+ class:invalid={isInvalid}
239
+ >
240
+ {#if isObject(selectedValue)}
241
+ {selectedValue[labelProp]}
242
+ {:else}
243
+ {options.find((it) => it[valueProp] === selectedValue)?.[labelProp]}
244
+ {/if}
245
+ </span>
246
+ {/snippet}
247
+ </Svelecte>
248
+ </div>
249
+
250
250
  <style>.select-wrapper {
251
251
  min-width: var(--input-min-width, 12rem);
252
252
  width: var(--input-width, 100%);
@@ -409,4 +409,4 @@ div.icons {
409
409
  }
410
410
  :global(.dropdown-item) .toggle-icon.yes {
411
411
  opacity: 1;
412
- }</style>
412
+ }</style>
@@ -8,29 +8,13 @@ export interface SingleSelectCommonProps<V extends object, VP extends ValueProp<
8
8
  valueProp: VP;
9
9
  /** Singular display name. */
10
10
  name?: string;
11
- /**
12
- * CSS width override. Interpolated into a CSS custom property.
13
- *
14
- * BREAKING (Phase 7.7): was `string`; now requires the `CssLength`
15
- * brand. Use the `cssLength('...')` helper.
16
- */
11
+ /** CSS width override. Use `cssLength('...')` to construct. */
17
12
  width?: CssLength;
18
- /**
19
- * CSS height override. Interpolated into a CSS custom property.
20
- *
21
- * BREAKING (Phase 7.7): was `string`; now requires the `CssLength`
22
- * brand. Use the `cssLength('...')` helper.
23
- */
13
+ /** CSS height override. Use `cssLength('...')` to construct. */
24
14
  height?: CssLength;
25
15
  /** Top label. */
26
16
  label?: string;
27
- /**
28
- * Minimum height for the wrapper.
29
- *
30
- * BREAKING (Phase 7.7): was `string`; now requires the `CssLength`
31
- * brand. Use the `cssLength('...')` helper. Defaults to `'2rem'`
32
- * inside the component when omitted.
33
- */
17
+ /** Minimum height for the wrapper. Defaults to `'2rem'`. */
34
18
  minHeight?: CssLength;
35
19
  /** Focus the input on mount. */
36
20
  focusOnLoad?: boolean;