@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.
Files changed (237) 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 +83 -83
  22. package/dist/Components/Contexts/ToastContainer.svelte +65 -65
  23. package/dist/Components/Contexts/Tooltip.svelte +37 -37
  24. package/dist/Components/DataMatrixIcon.svelte +112 -112
  25. package/dist/Components/DataMatrixIconProps.d.ts +3 -13
  26. package/dist/Components/DateInput.svelte +148 -148
  27. package/dist/Components/DatePicker.svelte +300 -300
  28. package/dist/Components/DesktopModal.svelte +90 -90
  29. package/dist/Components/Dial.svelte +204 -204
  30. package/dist/Components/DialProps.d.ts +1 -18
  31. package/dist/Components/DimensionInput.svelte +170 -170
  32. package/dist/Components/DragMenu/DragMenuHolder.svelte +119 -119
  33. package/dist/Components/DragMenu/DraggableCard.svelte +77 -77
  34. package/dist/Components/FileCard.svelte +24 -24
  35. package/dist/Components/FileUpload.svelte +236 -236
  36. package/dist/Components/GridInput.svelte +196 -200
  37. package/dist/Components/GridInputSet.svelte +29 -29
  38. package/dist/Components/HorizontalTabGroup.svelte +82 -82
  39. package/dist/Components/HorizontalTabGroupButton.svelte +44 -44
  40. package/dist/Components/Icon.svelte +128 -128
  41. package/dist/Components/IconProps.d.ts +2 -7
  42. package/dist/Components/Icons.js +357 -357
  43. package/dist/Components/LoadingAnimation.svelte +29 -29
  44. package/dist/Components/LoadingModal.svelte +45 -45
  45. package/dist/Components/LoadingOverlay.svelte +25 -25
  46. package/dist/Components/LoadingOverlayProps.d.ts +3 -7
  47. package/dist/Components/Modal.svelte +258 -258
  48. package/dist/Components/ModalProps.d.ts +0 -3
  49. package/dist/Components/MultiSelect.svelte +220 -220
  50. package/dist/Components/MultiSelectCommonProps.d.ts +6 -17
  51. package/dist/Components/Nav/Nav.svelte +99 -99
  52. package/dist/Components/Nav/NavProps.d.ts +4 -11
  53. package/dist/Components/Nav/NavServiceMenuList.svelte +43 -43
  54. package/dist/Components/Nav/NavTab.svelte +62 -62
  55. package/dist/Components/Nav/ServiceMenuItem.svelte +100 -100
  56. package/dist/Components/Nav/ServicesNav.svelte +80 -80
  57. package/dist/Components/NumberInput.svelte +157 -157
  58. package/dist/Components/PageHeading.svelte +25 -25
  59. package/dist/Components/PasswordInput.svelte +88 -88
  60. package/dist/Components/Portal.svelte +36 -36
  61. package/dist/Components/ProgressBubble.svelte +107 -108
  62. package/dist/Components/ProgressBubbleProps.d.ts +3 -3
  63. package/dist/Components/QuerySelect.svelte +366 -366
  64. package/dist/Components/QuerySelectProps.d.ts +4 -14
  65. package/dist/Components/SingleSelect.svelte +250 -250
  66. package/dist/Components/SingleSelectCommonProps.d.ts +3 -19
  67. package/dist/Components/StepButton.svelte +70 -70
  68. package/dist/Components/StepForm.svelte +140 -140
  69. package/dist/Components/Switch.svelte +69 -69
  70. package/dist/Components/Table/ARCHITECTURE.md +298 -0
  71. package/dist/Components/Table/Body/QuickSearchCell.svelte +679 -694
  72. package/dist/Components/Table/Body/Rows/ColumnHighlight.svelte +51 -51
  73. package/dist/Components/Table/Body/Rows/ColumnList.svelte +59 -59
  74. package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +456 -478
  75. package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +79 -79
  76. package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +185 -188
  77. package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +124 -124
  78. package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +120 -120
  79. package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte +230 -230
  80. package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +105 -105
  81. package/dist/Components/Table/Body/Rows/Columns/SelectColumn.d.ts +12 -9
  82. package/dist/Components/Table/Body/Rows/Columns/SelectTableCell.d.ts +5 -5
  83. package/dist/Components/Table/Body/Rows/Columns/TableAction.svelte +87 -87
  84. package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +126 -126
  85. package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +159 -159
  86. package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +246 -246
  87. package/dist/Components/Table/Body/Rows/Columns/TableDatePickerProps.d.ts +4 -4
  88. package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +216 -216
  89. package/dist/Components/Table/Body/Rows/Columns/TableQueryCell.d.ts +6 -5
  90. package/dist/Components/Table/Body/Rows/Columns/TableQueryColumn.d.ts +7 -6
  91. package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +252 -257
  92. package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +179 -179
  93. package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +221 -229
  94. package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte.d.ts +11 -11
  95. package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +197 -197
  96. package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +190 -190
  97. package/dist/Components/Table/Body/Rows/TableRow.svelte +290 -290
  98. package/dist/Components/Table/Body/TableBody.svelte +155 -155
  99. package/dist/Components/Table/ColumnDefinitions/ExampleItemColumnDefRepository.svelte.js +2 -3
  100. package/dist/Components/Table/ColumnFactory.svelte.d.ts +9 -11
  101. package/dist/Components/Table/ColumnFactory.svelte.js +101 -118
  102. package/dist/Components/Table/ColumnKindRegistry.d.ts +112 -0
  103. package/dist/Components/Table/ColumnKindRegistry.js +63 -0
  104. package/dist/Components/Table/Headers/HighlightAllHeader.svelte +41 -41
  105. package/dist/Components/Table/Headers/SelectAllHeader.svelte +30 -30
  106. package/dist/Components/Table/Headers/TableHead.svelte +415 -413
  107. package/dist/Components/Table/Misc/ColumnPanel.svelte +94 -94
  108. package/dist/Components/Table/Misc/ColumnPanelModal.svelte +112 -112
  109. package/dist/Components/Table/Misc/FilterInput.svelte +620 -644
  110. package/dist/Components/Table/Misc/FilterInput.svelte.d.ts +12 -12
  111. package/dist/Components/Table/Misc/FilterInputProps.d.ts +2 -2
  112. package/dist/Components/Table/Misc/FilterPanel.svelte +257 -257
  113. package/dist/Components/Table/Misc/FilterPanelModal.svelte +30 -30
  114. package/dist/Components/Table/Misc/SidePanel.svelte +35 -35
  115. package/dist/Components/Table/Misc/TableFooter.svelte +311 -311
  116. package/dist/Components/Table/Misc/TableHorizontalBar.svelte +125 -125
  117. package/dist/Components/Table/Misc/TableSidebar.svelte +157 -157
  118. package/dist/Components/Table/Misc/ToolboxPanel.svelte +100 -100
  119. package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +107 -107
  120. package/dist/Components/Table/NestedTable.svelte +130 -133
  121. package/dist/Components/Table/SubApis.svelte.d.ts +1 -5
  122. package/dist/Components/Table/SubApis.svelte.js +33 -32
  123. package/dist/Components/Table/Table.svelte +692 -745
  124. package/dist/Components/Table/TableHelpers.svelte.d.ts +6 -19
  125. package/dist/Components/Table/TableHelpers.svelte.js +6 -14
  126. package/dist/Components/Table/Types/Columns/Column.d.ts +2 -2
  127. package/dist/Components/Table/Types/Columns/DateColumn.d.ts +3 -3
  128. package/dist/Components/Table/Types/Columns/DateTableCell.d.ts +7 -7
  129. package/dist/Components/Table/Types/Columns/Definitions/Accessors/AccessorDef.svelte.d.ts +7 -8
  130. package/dist/Components/Table/Types/Columns/Definitions/Accessors/AccessorDef.svelte.js +4 -5
  131. package/dist/Components/Table/Types/Columns/Definitions/Accessors/CheckboxDef.svelte.d.ts +11 -14
  132. package/dist/Components/Table/Types/Columns/Definitions/Accessors/CheckboxDef.svelte.js +3 -4
  133. package/dist/Components/Table/Types/Columns/Definitions/Accessors/DateInputDef.svelte.d.ts +7 -11
  134. package/dist/Components/Table/Types/Columns/Definitions/Accessors/DateInputDef.svelte.js +3 -3
  135. package/dist/Components/Table/Types/Columns/Definitions/Accessors/NumberInputDef.svelte.d.ts +13 -18
  136. package/dist/Components/Table/Types/Columns/Definitions/Accessors/NumberInputDef.svelte.js +4 -5
  137. package/dist/Components/Table/Types/Columns/Definitions/Accessors/QueryDef.svelte.d.ts +5 -5
  138. package/dist/Components/Table/Types/Columns/Definitions/Accessors/QueryDef.svelte.js +2 -2
  139. package/dist/Components/Table/Types/Columns/Definitions/Accessors/SelectDef.svelte.d.ts +15 -12
  140. package/dist/Components/Table/Types/Columns/Definitions/Accessors/SelectDef.svelte.js +4 -5
  141. package/dist/Components/Table/Types/Columns/Definitions/Accessors/TextInputDef.svelte.d.ts +8 -12
  142. package/dist/Components/Table/Types/Columns/Definitions/Accessors/TextInputDef.svelte.js +3 -3
  143. package/dist/Components/Table/Types/Columns/Definitions/Actions/ActionsDef.svelte.d.ts +6 -6
  144. package/dist/Components/Table/Types/Columns/Definitions/Actions/ActionsDef.svelte.js +3 -3
  145. package/dist/Components/Table/Types/Columns/Definitions/ColumnDef.svelte.d.ts +49 -16
  146. package/dist/Components/Table/Types/Columns/Definitions/ColumnDef.svelte.js +27 -5
  147. package/dist/Components/Table/Types/Columns/Definitions/Display/AbstractDisplayDef.svelte.d.ts +7 -7
  148. package/dist/Components/Table/Types/Columns/Definitions/Display/AbstractDisplayDef.svelte.js +4 -4
  149. package/dist/Components/Table/Types/Columns/Definitions/Display/BubbleDef.svelte.d.ts +5 -5
  150. package/dist/Components/Table/Types/Columns/Definitions/Display/BubbleDef.svelte.js +2 -2
  151. package/dist/Components/Table/Types/Columns/Definitions/Display/DisplayDef.svelte.d.ts +5 -5
  152. package/dist/Components/Table/Types/Columns/Definitions/Display/DisplayDef.svelte.js +2 -2
  153. package/dist/Components/Table/Types/Columns/Definitions/Display/ProgressBarDef.svelte.d.ts +5 -5
  154. package/dist/Components/Table/Types/Columns/Definitions/Display/ProgressBarDef.svelte.js +2 -2
  155. package/dist/Components/Table/Types/Columns/Definitions/Display/ValidityDef.svelte.d.ts +5 -5
  156. package/dist/Components/Table/Types/Columns/Definitions/Display/ValidityDef.svelte.js +2 -2
  157. package/dist/Components/Table/Types/Columns/Definitions/Expand/ExpandDef.svelte.d.ts +11 -19
  158. package/dist/Components/Table/Types/Columns/Definitions/Expand/ExpandDef.svelte.js +4 -8
  159. package/dist/Components/Table/Types/Columns/Definitions/FilterOnly/FilterOnlyDef.svelte.d.ts +6 -7
  160. package/dist/Components/Table/Types/Columns/Definitions/FilterOnly/FilterOnlyDef.svelte.js +3 -4
  161. package/dist/Components/Table/Types/Columns/Definitions/RowSelection/RowSelectionDef.svelte.d.ts +9 -9
  162. package/dist/Components/Table/Types/Columns/Definitions/RowSelection/RowSelectionDef.svelte.js +4 -4
  163. package/dist/Components/Table/Types/Columns/ExpandTableCell.d.ts +5 -5
  164. package/dist/Components/Table/Types/Columns/ProgressBarTableCell.d.ts +6 -6
  165. package/dist/Components/Table/Types/Columns/TableCell.d.ts +7 -6
  166. package/dist/Components/Table/Types/Context/ClipboardState.svelte.d.ts +98 -0
  167. package/dist/Components/Table/Types/Context/ClipboardState.svelte.js +290 -0
  168. package/dist/Components/Table/Types/Context/ColumnLayoutState.svelte.d.ts +17 -45
  169. package/dist/Components/Table/Types/Context/ColumnLayoutState.svelte.js +17 -45
  170. package/dist/Components/Table/Types/Context/FilteringState.svelte.d.ts +9 -20
  171. package/dist/Components/Table/Types/Context/FilteringState.svelte.js +9 -20
  172. package/dist/Components/Table/Types/Context/FocusState.svelte.d.ts +23 -42
  173. package/dist/Components/Table/Types/Context/FocusState.svelte.js +32 -59
  174. package/dist/Components/Table/Types/Context/ITable.d.ts +5 -8
  175. package/dist/Components/Table/Types/Context/PreferencesState.svelte.d.ts +29 -56
  176. package/dist/Components/Table/Types/Context/PreferencesState.svelte.js +28 -55
  177. package/dist/Components/Table/Types/Context/QueryValuesState.svelte.d.ts +50 -0
  178. package/dist/Components/Table/Types/Context/QueryValuesState.svelte.js +62 -0
  179. package/dist/Components/Table/Types/Context/SelectionState.svelte.d.ts +17 -28
  180. package/dist/Components/Table/Types/Context/SelectionState.svelte.js +17 -28
  181. package/dist/Components/Table/Types/Context/SortingState.svelte.d.ts +15 -29
  182. package/dist/Components/Table/Types/Context/SortingState.svelte.js +17 -31
  183. package/dist/Components/Table/Types/Context/TableContext.svelte.d.ts +212 -325
  184. package/dist/Components/Table/Types/Context/TableContext.svelte.js +292 -706
  185. package/dist/Components/Table/Types/Context/VirtualisationState.svelte.d.ts +62 -79
  186. package/dist/Components/Table/Types/Context/VirtualisationState.svelte.js +54 -73
  187. package/dist/Components/Table/Types/DataRepository/BuiltInRemoteRepository.svelte.d.ts +16 -27
  188. package/dist/Components/Table/Types/DataRepository/BuiltInRemoteRepository.svelte.js +16 -27
  189. package/dist/Components/Table/Types/DataRepository/IDataRepository.d.ts +12 -15
  190. package/dist/Components/Table/Types/DataRepository/TableDataRepository.svelte.d.ts +15 -30
  191. package/dist/Components/Table/Types/DataRepository/TableDataRepository.svelte.js +16 -28
  192. package/dist/Components/Table/Types/Header.d.ts +4 -4
  193. package/dist/Components/Table/Types/HeaderGroup.d.ts +5 -5
  194. package/dist/Components/Table/Types/Public/index.d.ts +2 -4
  195. package/dist/Components/Table/Types/Public/index.js +2 -4
  196. package/dist/Components/Table/clipboardEscape.d.ts +32 -0
  197. package/dist/Components/Table/clipboardEscape.js +45 -0
  198. package/dist/Components/Table/createTable.svelte.d.ts +8 -18
  199. package/dist/Components/Table/createTable.svelte.js +19 -47
  200. package/dist/Components/Test/TestContextConsumer.svelte +13 -13
  201. package/dist/Components/TextArea.svelte +130 -130
  202. package/dist/Components/TextInput.svelte +176 -176
  203. package/dist/Components/ThreeStateRadio.svelte +131 -131
  204. package/dist/Components/Touch/BoolCard.svelte +45 -45
  205. package/dist/Components/Touch/DateModal.svelte +209 -209
  206. package/dist/Components/Touch/EditCard.svelte +59 -59
  207. package/dist/Components/Touch/InfoCard.svelte +31 -31
  208. package/dist/Components/Touch/InfoTextCard.svelte +28 -28
  209. package/dist/Components/Touch/ModalExplanation.svelte +17 -17
  210. package/dist/Components/Touch/NumberKeyboard.svelte +225 -225
  211. package/dist/Components/Touch/NumberModal.svelte +79 -79
  212. package/dist/Components/Touch/PlusMinusCard.svelte +46 -46
  213. package/dist/Components/Touch/SelectModal.svelte +123 -123
  214. package/dist/Components/Touch/SummaryCard.svelte +93 -93
  215. package/dist/Components/Touch/TextAreaModal.svelte +95 -95
  216. package/dist/Components/Touch/TextModal.svelte +106 -106
  217. package/dist/Components/Touch/TouchCard.svelte +33 -33
  218. package/dist/Components/Touch/TouchModal.svelte +274 -274
  219. package/dist/Components/Touch/UtilityButton.svelte +109 -109
  220. package/dist/Components/VerticalTabGroup.svelte +79 -79
  221. package/dist/Components/VerticalTabGroupButton.svelte +58 -58
  222. package/dist/Contexts/ToastContext.svelte.js +3 -4
  223. package/dist/Helpers/Datamatrix.d.ts +19 -19
  224. package/dist/Helpers/Datamatrix.js +291 -291
  225. package/dist/Helpers/Helpers.svelte.d.ts +2 -4
  226. package/dist/Helpers/Helpers.svelte.js +2 -4
  227. package/dist/Helpers/dropdownPortal.d.ts +26 -41
  228. package/dist/Helpers/dropdownPortal.js +62 -116
  229. package/dist/Types/Examples/ExampleModal.svelte +35 -35
  230. package/dist/index.d.ts +0 -1
  231. package/dist/scss/_basics.scss +12 -12
  232. package/dist/scss/_colours.scss +134 -134
  233. package/dist/scss/_mixins.scss +3348 -3360
  234. package/dist/scss/_motion.scss +57 -57
  235. package/dist/scss/_sizing.scss +85 -85
  236. package/dist/scss/_transitions.scss +8 -8
  237. package/package.json +2 -1
@@ -1,238 +1,238 @@
1
- <svelte:options runes />
2
-
3
- <script lang="ts">
4
- import { cssLength } from '../Helpers/Helpers.svelte.js';
5
- import { Colour, ColourSet } from '../scss/colours.js';
6
- import { InputVariant } from '../Types/Internal/InputVariant.js';
7
- import { Size } from '../Types/Internal/Size.js';
8
- import Action from './Action.svelte';
9
- import FileCard from './FileCard.svelte';
10
- import type { FileRejection, FileUploadProps } from './FileUploadProps.js';
11
- import Icon from './Icon.svelte';
12
-
13
- let {
14
- accept,
15
- files = $bindable([]),
16
- multiple = false,
17
- labelTop,
18
- labelRight,
19
- placeholder,
20
- required = false,
21
- variant = InputVariant.Default,
22
- disabled,
23
- optional = false,
24
- leftIcon,
25
- rightIcon,
26
- onLeftIconClick,
27
- onRightIconClick,
28
-
29
- inputRef = $bindable(),
30
- onblur,
31
- onfocus,
32
- onchange,
33
- onreject,
34
- maxSize,
35
- allowedMimeTypes,
36
- allowedExtensions,
37
- }: FileUploadProps = $props();
38
-
39
- function reasonToReject(file: File): FileRejection['reason'] | null {
40
- if (maxSize != undefined && file.size > maxSize) {
41
- return 'size';
42
- }
43
- if (allowedMimeTypes && allowedMimeTypes.length > 0) {
44
- if (!allowedMimeTypes.includes(file.type)) {
45
- return 'mime';
46
- }
47
- }
48
- if (allowedExtensions && allowedExtensions.length > 0) {
49
- const lower = file.name.toLocaleLowerCase();
50
- const matched = allowedExtensions.some((ext) => lower.endsWith(ext.toLocaleLowerCase()));
51
- if (!matched) {
52
- return 'extension';
53
- }
54
- }
55
- return null;
56
- }
57
-
58
- function partition(candidates: ArrayLike<File>): {
59
- accepted: ReadonlyArray<File>;
60
- rejected: ReadonlyArray<FileRejection>;
61
- } {
62
- const accepted: Array<File> = [];
63
- const rejected: Array<FileRejection> = [];
64
- for (let i = 0; i < candidates.length; i++) {
65
- const file = candidates[i];
66
- const reason = reasonToReject(file);
67
- if (reason == null) {
68
- accepted.push(file);
69
- } else {
70
- rejected.push({ file, reason });
71
- }
72
- }
73
- return { accepted, rejected };
74
- }
75
-
76
- function commit(accepted: ReadonlyArray<File>) {
77
- if (accepted.length === 0) {
78
- return;
79
- }
80
- files = [...files, ...accepted];
81
- onchange?.(files);
82
- }
83
-
84
- function onPickerChange(e: Event & { currentTarget: EventTarget & HTMLInputElement }) {
85
- const markedFiles = e.currentTarget.files ?? [];
86
- const { accepted, rejected } = partition(markedFiles);
87
- if (rejected.length > 0) {
88
- onreject?.(rejected);
89
- }
90
- commit(accepted);
91
- }
92
-
93
- function openPicker() {
94
- inputRef?.showPicker();
95
- }
96
-
97
- let dragover = $state(false);
98
-
99
- function ondrop(e: DragEvent) {
100
- e.stopPropagation();
101
- e.preventDefault();
102
- dragover = false;
103
-
104
- if (!e.dataTransfer?.files) {
105
- return;
106
- }
107
-
108
- const { accepted, rejected } = partition(e.dataTransfer.files);
109
- if (rejected.length > 0) {
110
- onreject?.(rejected);
111
- }
112
- commit(accepted);
113
- }
114
-
115
- function ondragover(e: DragEvent) {
116
- e.preventDefault();
117
- dragover = true;
118
- }
119
-
120
- function ondragleave(e: DragEvent) {
121
- e.preventDefault();
122
- dragover = false;
123
- }
124
- </script>
125
-
126
- <label
127
- class:dragover
128
- class:for-modal={variant === InputVariant.Modal}
129
- {ondrop}
130
- {ondragover}
131
- {ondragleave}
132
- >
133
- {#if labelTop && variant !== InputVariant.Modal}
134
- <span
135
- class="top-label"
136
- class:for-default={variant === InputVariant.Default}
137
- >{labelTop}{#if optional}<i>&nbsp;- optional</i>{/if}</span
138
- >
139
- {#if variant === InputVariant.Default}
140
- <span class="border"
141
- >{labelTop}{#if optional}<i>&nbsp;- optional</i>{/if}</span
142
- >
143
- {/if}
144
- {/if}
145
- <div
146
- class="icon-container"
147
- class:for-modal={variant == InputVariant.Modal}
148
- >
149
- {#if leftIcon}
150
- <Icon
151
- name={leftIcon.name}
152
- size={leftIcon.size ?? Size.Medium}
153
- colour={leftIcon.colour}
154
- float
155
- left={cssLength('0.75rem')}
156
- top={cssLength('50%')}
157
- anchorX={cssLength('0')}
158
- anchorY={cssLength('-50%')}
159
- clickable={!!onLeftIconClick}
160
- onclick={onLeftIconClick}
161
- />
162
- {/if}
163
- <input
164
- hidden
165
- class:left-pad={leftIcon != undefined}
166
- class:right-pad={rightIcon != undefined}
167
- class:for-modal={variant == InputVariant.Modal}
168
- {onblur}
169
- {accept}
170
- {onfocus}
171
- type="file"
172
- bind:this={inputRef}
173
- {placeholder}
174
- {required}
175
- {disabled}
176
- {multiple}
177
- onchange={onPickerChange}
178
- />
179
-
180
- <div
181
- class="file-list"
182
- role="list"
183
- aria-label="Selected files"
184
- >
185
- {#if files.length}
186
- {#each files as file, index (file)}
187
- <FileCard
188
- {file}
189
- ondelete={() => {
190
- files = files.toSpliced(index, 1);
191
- onchange?.(files);
192
- }}
193
- />
194
- {/each}
195
- {:else}
196
- <p>
197
- Drag and Drop or Click to Upload {#if multiple}multiple documents{:else}a document{/if}
198
- </p>
199
- {/if}
200
- </div>
201
- <div class="side">
202
- <Action
203
- colourSet={ColourSet.Secondary}
204
- backgroundColour={Colour['$transparent-0']}
205
- icon={{ name: 'upload' }}
206
- label="Upload"
207
- size={Size.Medium}
208
- onclick={() => {
209
- openPicker();
210
- }}
211
- />
212
- </div>
213
- {#if rightIcon}
214
- <Icon
215
- name={rightIcon.name}
216
- size={rightIcon.size ?? Size.Medium}
217
- colour={rightIcon.colour}
218
- float
219
- right={cssLength(variant == InputVariant.Modal ? '1rem' : '0.5rem')}
220
- top={cssLength('50%')}
221
- anchorX={cssLength('0')}
222
- anchorY={cssLength('-50%')}
223
- clickable={!!onRightIconClick}
224
- onclick={onRightIconClick}
225
- />
226
- {/if}
227
- {#if labelRight}
228
- <span
229
- class="right-label"
230
- class:for-modal={variant == InputVariant.Modal}>{labelRight}</span
231
- >
232
- {/if}
233
- </div>
234
- </label>
235
-
1
+ <svelte:options runes />
2
+
3
+ <script lang="ts">
4
+ import { cssLength } from '../Helpers/Helpers.svelte.js';
5
+ import { Colour, ColourSet } from '../scss/colours.js';
6
+ import { InputVariant } from '../Types/Internal/InputVariant.js';
7
+ import { Size } from '../Types/Internal/Size.js';
8
+ import Action from './Action.svelte';
9
+ import FileCard from './FileCard.svelte';
10
+ import type { FileRejection, FileUploadProps } from './FileUploadProps.js';
11
+ import Icon from './Icon.svelte';
12
+
13
+ let {
14
+ accept,
15
+ files = $bindable([]),
16
+ multiple = false,
17
+ labelTop,
18
+ labelRight,
19
+ placeholder,
20
+ required = false,
21
+ variant = InputVariant.Default,
22
+ disabled,
23
+ optional = false,
24
+ leftIcon,
25
+ rightIcon,
26
+ onLeftIconClick,
27
+ onRightIconClick,
28
+
29
+ inputRef = $bindable(),
30
+ onblur,
31
+ onfocus,
32
+ onchange,
33
+ onreject,
34
+ maxSize,
35
+ allowedMimeTypes,
36
+ allowedExtensions,
37
+ }: FileUploadProps = $props();
38
+
39
+ function reasonToReject(file: File): FileRejection['reason'] | null {
40
+ if (maxSize != undefined && file.size > maxSize) {
41
+ return 'size';
42
+ }
43
+ if (allowedMimeTypes && allowedMimeTypes.length > 0) {
44
+ if (!allowedMimeTypes.includes(file.type)) {
45
+ return 'mime';
46
+ }
47
+ }
48
+ if (allowedExtensions && allowedExtensions.length > 0) {
49
+ const lower = file.name.toLocaleLowerCase();
50
+ const matched = allowedExtensions.some((ext) => lower.endsWith(ext.toLocaleLowerCase()));
51
+ if (!matched) {
52
+ return 'extension';
53
+ }
54
+ }
55
+ return null;
56
+ }
57
+
58
+ function partition(candidates: ArrayLike<File>): {
59
+ accepted: ReadonlyArray<File>;
60
+ rejected: ReadonlyArray<FileRejection>;
61
+ } {
62
+ const accepted: Array<File> = [];
63
+ const rejected: Array<FileRejection> = [];
64
+ for (let i = 0; i < candidates.length; i++) {
65
+ const file = candidates[i];
66
+ const reason = reasonToReject(file);
67
+ if (reason == null) {
68
+ accepted.push(file);
69
+ } else {
70
+ rejected.push({ file, reason });
71
+ }
72
+ }
73
+ return { accepted, rejected };
74
+ }
75
+
76
+ function commit(accepted: ReadonlyArray<File>) {
77
+ if (accepted.length === 0) {
78
+ return;
79
+ }
80
+ files = [...files, ...accepted];
81
+ onchange?.(files);
82
+ }
83
+
84
+ function onPickerChange(e: Event & { currentTarget: EventTarget & HTMLInputElement }) {
85
+ const markedFiles = e.currentTarget.files ?? [];
86
+ const { accepted, rejected } = partition(markedFiles);
87
+ if (rejected.length > 0) {
88
+ onreject?.(rejected);
89
+ }
90
+ commit(accepted);
91
+ }
92
+
93
+ function openPicker() {
94
+ inputRef?.showPicker();
95
+ }
96
+
97
+ let dragover = $state(false);
98
+
99
+ function ondrop(e: DragEvent) {
100
+ e.stopPropagation();
101
+ e.preventDefault();
102
+ dragover = false;
103
+
104
+ if (!e.dataTransfer?.files) {
105
+ return;
106
+ }
107
+
108
+ const { accepted, rejected } = partition(e.dataTransfer.files);
109
+ if (rejected.length > 0) {
110
+ onreject?.(rejected);
111
+ }
112
+ commit(accepted);
113
+ }
114
+
115
+ function ondragover(e: DragEvent) {
116
+ e.preventDefault();
117
+ dragover = true;
118
+ }
119
+
120
+ function ondragleave(e: DragEvent) {
121
+ e.preventDefault();
122
+ dragover = false;
123
+ }
124
+ </script>
125
+
126
+ <label
127
+ class:dragover
128
+ class:for-modal={variant === InputVariant.Modal}
129
+ {ondrop}
130
+ {ondragover}
131
+ {ondragleave}
132
+ >
133
+ {#if labelTop && variant !== InputVariant.Modal}
134
+ <span
135
+ class="top-label"
136
+ class:for-default={variant === InputVariant.Default}
137
+ >{labelTop}{#if optional}<i>&nbsp;- optional</i>{/if}</span
138
+ >
139
+ {#if variant === InputVariant.Default}
140
+ <span class="border"
141
+ >{labelTop}{#if optional}<i>&nbsp;- optional</i>{/if}</span
142
+ >
143
+ {/if}
144
+ {/if}
145
+ <div
146
+ class="icon-container"
147
+ class:for-modal={variant == InputVariant.Modal}
148
+ >
149
+ {#if leftIcon}
150
+ <Icon
151
+ name={leftIcon.name}
152
+ size={leftIcon.size ?? Size.Medium}
153
+ colour={leftIcon.colour}
154
+ float
155
+ left={cssLength('0.75rem')}
156
+ top={cssLength('50%')}
157
+ anchorX={cssLength('0')}
158
+ anchorY={cssLength('-50%')}
159
+ clickable={!!onLeftIconClick}
160
+ onclick={onLeftIconClick}
161
+ />
162
+ {/if}
163
+ <input
164
+ hidden
165
+ class:left-pad={leftIcon != undefined}
166
+ class:right-pad={rightIcon != undefined}
167
+ class:for-modal={variant == InputVariant.Modal}
168
+ {onblur}
169
+ {accept}
170
+ {onfocus}
171
+ type="file"
172
+ bind:this={inputRef}
173
+ {placeholder}
174
+ {required}
175
+ {disabled}
176
+ {multiple}
177
+ onchange={onPickerChange}
178
+ />
179
+
180
+ <div
181
+ class="file-list"
182
+ role="list"
183
+ aria-label="Selected files"
184
+ >
185
+ {#if files.length}
186
+ {#each files as file, index (file)}
187
+ <FileCard
188
+ {file}
189
+ ondelete={() => {
190
+ files = files.toSpliced(index, 1);
191
+ onchange?.(files);
192
+ }}
193
+ />
194
+ {/each}
195
+ {:else}
196
+ <p>
197
+ Drag and Drop or Click to Upload {#if multiple}multiple documents{:else}a document{/if}
198
+ </p>
199
+ {/if}
200
+ </div>
201
+ <div class="side">
202
+ <Action
203
+ colourSet={ColourSet.Secondary}
204
+ backgroundColour={Colour['$transparent-0']}
205
+ icon={{ name: 'upload' }}
206
+ label="Upload"
207
+ size={Size.Medium}
208
+ onclick={() => {
209
+ openPicker();
210
+ }}
211
+ />
212
+ </div>
213
+ {#if rightIcon}
214
+ <Icon
215
+ name={rightIcon.name}
216
+ size={rightIcon.size ?? Size.Medium}
217
+ colour={rightIcon.colour}
218
+ float
219
+ right={cssLength(variant == InputVariant.Modal ? '1rem' : '0.5rem')}
220
+ top={cssLength('50%')}
221
+ anchorX={cssLength('0')}
222
+ anchorY={cssLength('-50%')}
223
+ clickable={!!onRightIconClick}
224
+ onclick={onRightIconClick}
225
+ />
226
+ {/if}
227
+ {#if labelRight}
228
+ <span
229
+ class="right-label"
230
+ class:for-modal={variant == InputVariant.Modal}>{labelRight}</span
231
+ >
232
+ {/if}
233
+ </div>
234
+ </label>
235
+
236
236
  <style>input {
237
237
  box-sizing: border-box;
238
238
  height: 100%;
@@ -438,4 +438,4 @@ label {
438
438
 
439
439
  .dragover {
440
440
  background-color: rgba(31, 129, 160, 0.4);
441
- }</style>
441
+ }</style>