@lavalogic/scoria 0.40.32 → 0.40.33

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 (135) hide show
  1. package/README.md +58 -58
  2. package/dist/Components/AccordionGroup.svelte +28 -28
  3. package/dist/Components/AccordionGroupButton.svelte +60 -60
  4. package/dist/Components/Action.svelte +48 -48
  5. package/dist/Components/AlertModal.svelte +102 -102
  6. package/dist/Components/Base/ContextWrapper.svelte +45 -45
  7. package/dist/Components/Base/Pagination.svelte +135 -135
  8. package/dist/Components/Base/Snippets.svelte +25 -25
  9. package/dist/Components/BigRadioSet.svelte +34 -34
  10. package/dist/Components/Bubble.svelte +38 -38
  11. package/dist/Components/Button.svelte +83 -83
  12. package/dist/Components/Checkbox.svelte +71 -71
  13. package/dist/Components/CollapsibleCard.svelte +59 -59
  14. package/dist/Components/CollapsibleMenuGroup.svelte +43 -43
  15. package/dist/Components/ConditionBuilder/ConditionBuilder.svelte +101 -101
  16. package/dist/Components/Contexts/ContextMenu.svelte +76 -76
  17. package/dist/Components/Contexts/ContextMenuDivider.svelte +15 -15
  18. package/dist/Components/Contexts/ContextMenuOption.svelte +38 -38
  19. package/dist/Components/Contexts/Toast.svelte +71 -71
  20. package/dist/Components/Contexts/ToastContainer.svelte +34 -34
  21. package/dist/Components/Contexts/Tooltip.svelte +32 -32
  22. package/dist/Components/DataMatrixIcon.svelte +37 -37
  23. package/dist/Components/DateInput.svelte +80 -80
  24. package/dist/Components/DatePicker.svelte +86 -86
  25. package/dist/Components/DesktopModal.svelte +65 -65
  26. package/dist/Components/Dial.svelte +35 -35
  27. package/dist/Components/DimensionInput.svelte +95 -95
  28. package/dist/Components/DragMenu/DragMenuHolder.svelte +53 -53
  29. package/dist/Components/DragMenu/DraggableCard.svelte +49 -49
  30. package/dist/Components/FileCard.svelte +18 -18
  31. package/dist/Components/FileUpload.svelte +115 -115
  32. package/dist/Components/GridInput.svelte +123 -123
  33. package/dist/Components/GridInputSet.svelte +21 -21
  34. package/dist/Components/HorizontalTabGroup.svelte +54 -54
  35. package/dist/Components/HorizontalTabGroupButton.svelte +32 -32
  36. package/dist/Components/Icon.svelte +68 -68
  37. package/dist/Components/InfoAlert.svelte +32 -32
  38. package/dist/Components/LoadingAnimation.svelte +228 -227
  39. package/dist/Components/LoadingModal.svelte +19 -19
  40. package/dist/Components/LoadingOverlay.svelte +20 -20
  41. package/dist/Components/Modal.svelte +127 -127
  42. package/dist/Components/MultiSelect.svelte +126 -126
  43. package/dist/Components/Nav/Nav.svelte +71 -71
  44. package/dist/Components/Nav/NavServiceMenuList.svelte +37 -37
  45. package/dist/Components/Nav/NavTab.svelte +46 -46
  46. package/dist/Components/Nav/ServiceMenuItem.svelte +62 -62
  47. package/dist/Components/Nav/ServicesNav.svelte +50 -50
  48. package/dist/Components/NumberInput.svelte +98 -98
  49. package/dist/Components/OptionCards.svelte +58 -58
  50. package/dist/Components/PageHeading.svelte +21 -21
  51. package/dist/Components/PasswordInput.svelte +61 -61
  52. package/dist/Components/PopoverButton.svelte +53 -53
  53. package/dist/Components/Portal.svelte +7 -7
  54. package/dist/Components/ProgressBubble.svelte +42 -42
  55. package/dist/Components/QuerySelect.svelte +102 -102
  56. package/dist/Components/ResourceCalendar/ResourceCalendar.svelte +241 -241
  57. package/dist/Components/SidebarPanel.svelte +32 -32
  58. package/dist/Components/SingleSelect.svelte +122 -122
  59. package/dist/Components/StepButton.svelte +48 -48
  60. package/dist/Components/StepForm.svelte +58 -58
  61. package/dist/Components/Switch.svelte +43 -43
  62. package/dist/Components/Table/ARCHITECTURE.md +298 -298
  63. package/dist/Components/Table/Body/Rows/ColumnHighlight.svelte +30 -30
  64. package/dist/Components/Table/Body/Rows/ColumnList.svelte +24 -24
  65. package/dist/Components/Table/Body/Rows/ColumnListRow.svelte +165 -165
  66. package/dist/Components/Table/Body/Rows/Columns/AccessorComponent.svelte +13 -13
  67. package/dist/Components/Table/Body/Rows/Columns/ActionsCell.svelte +120 -120
  68. package/dist/Components/Table/Body/Rows/Columns/BubbleCell.svelte +81 -81
  69. package/dist/Components/Table/Body/Rows/Columns/ExpandCell.svelte +92 -92
  70. package/dist/Components/Table/Body/Rows/Columns/FocusableImmutableCell.svelte +110 -110
  71. package/dist/Components/Table/Body/Rows/Columns/ProgressCell.svelte +54 -54
  72. package/dist/Components/Table/Body/Rows/Columns/TableAction.svelte +35 -35
  73. package/dist/Components/Table/Body/Rows/Columns/TableCheckbox.svelte +64 -64
  74. package/dist/Components/Table/Body/Rows/Columns/TableColumn.svelte +82 -82
  75. package/dist/Components/Table/Body/Rows/Columns/TableDatePicker.svelte +88 -88
  76. package/dist/Components/Table/Body/Rows/Columns/TableNumberInput.svelte +90 -90
  77. package/dist/Components/Table/Body/Rows/Columns/TableQuerySelect.svelte +96 -96
  78. package/dist/Components/Table/Body/Rows/Columns/TableRowSelectionCheckbox.svelte +71 -71
  79. package/dist/Components/Table/Body/Rows/Columns/TableSelect.svelte +124 -124
  80. package/dist/Components/Table/Body/Rows/Columns/TableTextInput.svelte +91 -91
  81. package/dist/Components/Table/Body/Rows/Columns/ValidityCell.svelte +88 -88
  82. package/dist/Components/Table/Body/Rows/TableRow.svelte +127 -127
  83. package/dist/Components/Table/Body/TableBody.svelte +92 -92
  84. package/dist/Components/Table/Headers/HighlightAllHeader.svelte +25 -25
  85. package/dist/Components/Table/Headers/SelectAllHeader.svelte +20 -20
  86. package/dist/Components/Table/Headers/TableHead.svelte +175 -175
  87. package/dist/Components/Table/Misc/ColumnPanel.svelte +32 -32
  88. package/dist/Components/Table/Misc/ColumnPanelModal.svelte +29 -29
  89. package/dist/Components/Table/Misc/FilterInput.svelte +326 -326
  90. package/dist/Components/Table/Misc/FilterPanel.svelte +79 -79
  91. package/dist/Components/Table/Misc/FilterPanelModal.svelte +21 -21
  92. package/dist/Components/Table/Misc/ShareViewModal.svelte +118 -118
  93. package/dist/Components/Table/Misc/SidePanel.svelte +24 -24
  94. package/dist/Components/Table/Misc/TableConfigurationModal.svelte +318 -318
  95. package/dist/Components/Table/Misc/TableFooter.svelte +201 -201
  96. package/dist/Components/Table/Misc/TableHorizontalBar.svelte +112 -112
  97. package/dist/Components/Table/Misc/TableSidebar.svelte +116 -116
  98. package/dist/Components/Table/Misc/TableViewDropdown.svelte +25 -25
  99. package/dist/Components/Table/Misc/ToolboxPanel.svelte +60 -60
  100. package/dist/Components/Table/Misc/ToolboxPanelModal.svelte +63 -63
  101. package/dist/Components/Table/Misc/UpdateViewOptionsModal.svelte +101 -101
  102. package/dist/Components/Table/NestedTable.svelte +29 -29
  103. package/dist/Components/Table/Table.svelte +140 -140
  104. package/dist/Components/Test/TestContextConsumer.svelte +8 -8
  105. package/dist/Components/TextArea.svelte +92 -90
  106. package/dist/Components/TextInput.svelte +128 -117
  107. package/dist/Components/ThreeStateRadio.svelte +101 -101
  108. package/dist/Components/Touch/BoolCard.svelte +27 -27
  109. package/dist/Components/Touch/DateModal.svelte +98 -98
  110. package/dist/Components/Touch/EditCard.svelte +44 -44
  111. package/dist/Components/Touch/InfoCard.svelte +25 -25
  112. package/dist/Components/Touch/InfoTextCard.svelte +22 -22
  113. package/dist/Components/Touch/ModalExplanation.svelte +13 -13
  114. package/dist/Components/Touch/NumberKeyboard.svelte +81 -81
  115. package/dist/Components/Touch/NumberModal.svelte +49 -49
  116. package/dist/Components/Touch/PlusMinusCard.svelte +40 -40
  117. package/dist/Components/Touch/SelectModal.svelte +86 -86
  118. package/dist/Components/Touch/SummaryCard.svelte +74 -74
  119. package/dist/Components/Touch/TextAreaModal.svelte +53 -53
  120. package/dist/Components/Touch/TextModal.svelte +56 -56
  121. package/dist/Components/Touch/TouchCard.svelte +28 -28
  122. package/dist/Components/Touch/TouchModal.svelte +141 -141
  123. package/dist/Components/Touch/UtilityButton.svelte +63 -63
  124. package/dist/Components/VerticalTabGroup.svelte +38 -38
  125. package/dist/Components/VerticalTabGroupButton.svelte +46 -46
  126. package/dist/Helpers/Datamatrix.d.ts +19 -19
  127. package/dist/Helpers/Datamatrix.js +291 -291
  128. package/dist/Types/Examples/ExampleModal.svelte +27 -27
  129. package/dist/paraglide/README.md +1 -1
  130. package/dist/scss/_basics.scss +12 -12
  131. package/dist/scss/_colours.scss +140 -140
  132. package/dist/scss/_motion.scss +57 -57
  133. package/dist/scss/_sizing.scss +85 -85
  134. package/dist/scss/_transitions.scss +8 -8
  135. package/package.json +1 -1
@@ -1,28 +1,28 @@
1
- <svelte:options runes />
2
-
1
+ <svelte:options runes />
2
+
3
3
  <script lang="ts">import { m as i18n } from "../paraglide/messages.js";
4
4
  import Action from "./Action.svelte";
5
5
  import { Colour } from "../scss/colours.js";
6
6
  const { file, ondelete } = $props();
7
- </script>
8
-
9
- <div
10
- role="listitem"
11
- aria-label={file.name}
12
- >
13
- <span>{file.name}</span>
14
- <Action
15
- icon={{ name: 'circle-cross' }}
16
- backgroundColour={Colour['$transparent-0']}
17
- label={i18n['scoria.action.delete']()}
18
- onclick={ondelete}
19
- />
20
- </div>
21
-
7
+ </script>
8
+
9
+ <div
10
+ role="listitem"
11
+ aria-label={file.name}
12
+ >
13
+ <span>{file.name}</span>
14
+ <Action
15
+ icon={{ name: 'circle-cross' }}
16
+ backgroundColour={Colour['$transparent-0']}
17
+ label={i18n['scoria.action.delete']()}
18
+ onclick={ondelete}
19
+ />
20
+ </div>
21
+
22
22
  <style>div {
23
23
  display: flex;
24
24
  flex-flow: row nowrap;
25
25
  flex-grow: 1;
26
26
  align-items: center;
27
27
  gap: 0.375rem;
28
- }</style>
28
+ }</style>
@@ -1,5 +1,5 @@
1
- <svelte:options runes />
2
-
1
+ <svelte:options runes />
2
+
3
3
  <script lang="ts">import { m as i18n } from "../paraglide/messages.js";
4
4
  import { cssLength } from "../Helpers/Helpers.svelte.js";
5
5
  import { Colour, ColourSet } from "../scss/colours.js";
@@ -87,118 +87,118 @@ function ondragleave(e) {
87
87
  e.preventDefault();
88
88
  dragover = false;
89
89
  }
90
- </script>
91
-
92
- <label
93
- class:dragover
94
- class:for-modal={variant === InputVariant.Modal}
95
- {ondrop}
96
- {ondragover}
97
- {ondragleave}
98
- >
99
- {#if labelTop && variant !== InputVariant.Modal}
100
- <span
101
- class="top-label"
102
- class:for-default={variant === InputVariant.Default}
103
- >{labelTop}{#if optional}<i>&nbsp;- {i18n['scoria.label.optional']()}</i>{/if}</span
104
- >
105
- {#if variant === InputVariant.Default}
106
- <span class="border"
107
- >{labelTop}{#if optional}<i>&nbsp;- {i18n['scoria.label.optional']()}</i>{/if}</span
108
- >
109
- {/if}
110
- {/if}
111
- <div
112
- class="icon-container"
113
- class:for-modal={variant == InputVariant.Modal}
114
- >
115
- {#if leftIcon}
116
- <Icon
117
- name={leftIcon.name}
118
- size={leftIcon.size ?? Size.Medium}
119
- colour={leftIcon.colour}
120
- float
121
- left={cssLength('0.75rem')}
122
- top={cssLength('50%')}
123
- anchorX={cssLength('0')}
124
- anchorY={cssLength('-50%')}
125
- clickable={!!onLeftIconClick}
126
- onclick={onLeftIconClick}
127
- />
128
- {/if}
129
- <input
130
- hidden
131
- class:left-pad={leftIcon != undefined}
132
- class:right-pad={rightIcon != undefined}
133
- class:for-modal={variant == InputVariant.Modal}
134
- {onblur}
135
- {accept}
136
- {onfocus}
137
- type="file"
138
- bind:this={inputRef}
139
- {placeholder}
140
- {required}
141
- {disabled}
142
- {multiple}
143
- onchange={onPickerChange}
144
- />
145
-
146
- <div
147
- class="file-list"
148
- role="list"
149
- aria-label={i18n['scoria.label.selected_files']()}
150
- >
151
- {#if files.length}
152
- {#each files as file, index (file)}
153
- <FileCard
154
- {file}
155
- ondelete={() => {
156
- files = files.toSpliced(index, 1);
157
- onchange?.(files);
158
- }}
159
- />
160
- {/each}
161
- {:else}
162
- <p>
163
- {#if multiple}{i18n['scoria.text.dropzone_multiple']()}{:else}{i18n['scoria.text.dropzone_single']()}{/if}
164
- </p>
165
- {/if}
166
- </div>
167
- <div class="side">
168
- <Action
169
- colourSet={ColourSet.Secondary}
170
- backgroundColour={Colour['$transparent-0']}
171
- icon={{ name: 'upload' }}
172
- label={i18n['scoria.action.upload']()}
173
- size={Size.Medium}
174
- onclick={() => {
175
- openPicker();
176
- }}
177
- />
178
- </div>
179
- {#if rightIcon}
180
- <Icon
181
- name={rightIcon.name}
182
- size={rightIcon.size ?? Size.Medium}
183
- colour={rightIcon.colour}
184
- float
185
- right={cssLength(variant == InputVariant.Modal ? '1rem' : '0.5rem')}
186
- top={cssLength('50%')}
187
- anchorX={cssLength('0')}
188
- anchorY={cssLength('-50%')}
189
- clickable={!!onRightIconClick}
190
- onclick={onRightIconClick}
191
- />
192
- {/if}
193
- {#if labelRight}
194
- <span
195
- class="right-label"
196
- class:for-modal={variant == InputVariant.Modal}>{labelRight}</span
197
- >
198
- {/if}
199
- </div>
200
- </label>
201
-
90
+ </script>
91
+
92
+ <label
93
+ class:dragover
94
+ class:for-modal={variant === InputVariant.Modal}
95
+ {ondrop}
96
+ {ondragover}
97
+ {ondragleave}
98
+ >
99
+ {#if labelTop && variant !== InputVariant.Modal}
100
+ <span
101
+ class="top-label"
102
+ class:for-default={variant === InputVariant.Default}
103
+ >{labelTop}{#if optional}<i>&nbsp;- {i18n['scoria.label.optional']()}</i>{/if}</span
104
+ >
105
+ {#if variant === InputVariant.Default}
106
+ <span class="border"
107
+ >{labelTop}{#if optional}<i>&nbsp;- {i18n['scoria.label.optional']()}</i>{/if}</span
108
+ >
109
+ {/if}
110
+ {/if}
111
+ <div
112
+ class="icon-container"
113
+ class:for-modal={variant == InputVariant.Modal}
114
+ >
115
+ {#if leftIcon}
116
+ <Icon
117
+ name={leftIcon.name}
118
+ size={leftIcon.size ?? Size.Medium}
119
+ colour={leftIcon.colour}
120
+ float
121
+ left={cssLength('0.75rem')}
122
+ top={cssLength('50%')}
123
+ anchorX={cssLength('0')}
124
+ anchorY={cssLength('-50%')}
125
+ clickable={!!onLeftIconClick}
126
+ onclick={onLeftIconClick}
127
+ />
128
+ {/if}
129
+ <input
130
+ hidden
131
+ class:left-pad={leftIcon != undefined}
132
+ class:right-pad={rightIcon != undefined}
133
+ class:for-modal={variant == InputVariant.Modal}
134
+ {onblur}
135
+ {accept}
136
+ {onfocus}
137
+ type="file"
138
+ bind:this={inputRef}
139
+ {placeholder}
140
+ {required}
141
+ {disabled}
142
+ {multiple}
143
+ onchange={onPickerChange}
144
+ />
145
+
146
+ <div
147
+ class="file-list"
148
+ role="list"
149
+ aria-label={i18n['scoria.label.selected_files']()}
150
+ >
151
+ {#if files.length}
152
+ {#each files as file, index (file)}
153
+ <FileCard
154
+ {file}
155
+ ondelete={() => {
156
+ files = files.toSpliced(index, 1);
157
+ onchange?.(files);
158
+ }}
159
+ />
160
+ {/each}
161
+ {:else}
162
+ <p>
163
+ {#if multiple}{i18n['scoria.text.dropzone_multiple']()}{:else}{i18n['scoria.text.dropzone_single']()}{/if}
164
+ </p>
165
+ {/if}
166
+ </div>
167
+ <div class="side">
168
+ <Action
169
+ colourSet={ColourSet.Secondary}
170
+ backgroundColour={Colour['$transparent-0']}
171
+ icon={{ name: 'upload' }}
172
+ label={i18n['scoria.action.upload']()}
173
+ size={Size.Medium}
174
+ onclick={() => {
175
+ openPicker();
176
+ }}
177
+ />
178
+ </div>
179
+ {#if rightIcon}
180
+ <Icon
181
+ name={rightIcon.name}
182
+ size={rightIcon.size ?? Size.Medium}
183
+ colour={rightIcon.colour}
184
+ float
185
+ right={cssLength(variant == InputVariant.Modal ? '1rem' : '0.5rem')}
186
+ top={cssLength('50%')}
187
+ anchorX={cssLength('0')}
188
+ anchorY={cssLength('-50%')}
189
+ clickable={!!onRightIconClick}
190
+ onclick={onRightIconClick}
191
+ />
192
+ {/if}
193
+ {#if labelRight}
194
+ <span
195
+ class="right-label"
196
+ class:for-modal={variant == InputVariant.Modal}>{labelRight}</span
197
+ >
198
+ {/if}
199
+ </div>
200
+ </label>
201
+
202
202
  <style>input {
203
203
  box-sizing: border-box;
204
204
  height: 100%;
@@ -402,4 +402,4 @@ label {
402
402
 
403
403
  .dragover {
404
404
  background-color: rgba(31, 129, 160, 0.4);
405
- }</style>
405
+ }</style>
@@ -1,8 +1,8 @@
1
- <svelte:options runes />
2
-
3
- <script
4
- lang="ts"
5
- module
1
+ <svelte:options runes />
2
+
3
+ <script
4
+ lang="ts"
5
+ module
6
6
  >import { dev } from "$app/environment";
7
7
  import { loadingText } from "../Helpers/Helpers.svelte.js";
8
8
  import MultiSelect from "./MultiSelect.svelte";
@@ -13,11 +13,11 @@ const textTypes = new Set([
13
13
  "email",
14
14
  "tel"
15
15
  ]);
16
- </script>
17
-
18
- <script
19
- lang="ts"
20
- generics="V extends Record<string, unknown>,VP extends ValueProp<V>"
16
+ </script>
17
+
18
+ <script
19
+ lang="ts"
20
+ generics="V extends Record<string, unknown>,VP extends ValueProp<V>"
21
21
  >const { item, first, last } = $props();
22
22
  let value = $derived(isText(item) ? item.value ?? "" : "");
23
23
  function isText(item) {
@@ -44,118 +44,118 @@ function isSingleSelectPrimitive(item) {
44
44
  function isSingleSelectObject(item) {
45
45
  return "valueAsObject" in item && item.valueAsObject;
46
46
  }
47
- </script>
48
-
49
- <label
50
- class:first
51
- class:last
52
- >
53
- <div class="left">
54
- <span
55
- class:first
56
- class:last>{item.label}</span
57
- >
58
- </div>
59
- {#if isText(item)}
60
- <TextInput
61
- disabled={item.disabled}
62
- bind:value
63
- oninput={() => {
64
- item.updater(value);
65
- }}
66
- required={item.required}
67
- invalid={item.invalid}
68
- />
69
- {:else if isSelect(item)}
70
- {#if isMultiSelect(item)}
71
- {#await item.options}
72
- {loadingText()}
73
- {:then options}
74
- {#if isMultiSelectObject<V, VP>(item)}
75
- <MultiSelect
76
- name={item.name}
77
- {options}
78
- valueAsObject={true}
79
- labelProp={item.labelProp}
80
- valueProp={item.valueProp}
81
- selectedValues={item.value}
82
- invalid={item.invalid}
83
- onchange={(v: Array<V>) => {
84
- item.updater(v);
85
- }}
86
- />
87
- {:else if isMultiSelectPrimitive(item)}
88
- <MultiSelect
89
- name={item.name}
90
- {options}
91
- valueAsObject={false}
92
- labelProp={item.labelProp}
93
- valueProp={item.valueProp}
94
- selectedValues={item.value}
95
- invalid={item.invalid}
96
- onchange={(v: Array<V[VP]>) => {
97
- // `valueAsObject={false}` → primitives, not SelectOption objects.
98
- item.updater(v);
99
- }}
100
- />
101
- {/if}
102
- {/await}
103
- {:else if isSingleSelect(item)}
104
- {#await item.options}
105
- {loadingText()}
106
- {:then options}
107
- {#if isSingleSelectObject(item)}
108
- <SingleSelect
109
- {options}
110
- name={item.name}
111
- valueAsObject={true}
112
- labelProp={item.labelProp}
113
- valueProp={item.valueProp}
114
- value={item.value}
115
- required={item.required}
116
- clearable={!item.required}
117
- disabled={item.disabled}
118
- invalid={item.invalid}
119
- onchange={(v: V | null) => {
120
- item.updater(v);
121
- }}
122
- />
123
- {:else if isSingleSelectPrimitive(item)}
124
- <SingleSelect
125
- {options}
126
- name={item.name}
127
- valueAsObject={false}
128
- labelProp={item.labelProp}
129
- valueProp={item.valueProp}
130
- value={item.value}
131
- required={item.required}
132
- clearable={!item.required}
133
- disabled={item.disabled}
134
- invalid={item.invalid}
135
- onchange={(
136
- // `valueAsObject={false}` → primitive value, not a
137
- // SelectOption. `clearable` is on (since the field is
138
- // not required) so the callback must accept null.
139
- // The annotation collapses to `unknown | null` because
140
- // `V extends Record<string, unknown>` makes `V[VP]`
141
- // itself `unknown`.
142
- // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
143
- v: V[VP] | null
144
- ) => {
145
- item.updater(v);
146
- }}
147
- />
148
- {/if}
149
- {/await}
150
- {/if}
151
- {:else if dev}
152
- {@const type = item.type}
153
- unknown type: {type}
154
- <!-- eslint-disable-next-line svelte/no-at-debug-tags -->
155
- {@debug type}
156
- {/if}
157
- </label>
158
-
47
+ </script>
48
+
49
+ <label
50
+ class:first
51
+ class:last
52
+ >
53
+ <div class="left">
54
+ <span
55
+ class:first
56
+ class:last>{item.label}</span
57
+ >
58
+ </div>
59
+ {#if isText(item)}
60
+ <TextInput
61
+ disabled={item.disabled}
62
+ bind:value
63
+ oninput={() => {
64
+ item.updater(value);
65
+ }}
66
+ required={item.required}
67
+ invalid={item.invalid}
68
+ />
69
+ {:else if isSelect(item)}
70
+ {#if isMultiSelect(item)}
71
+ {#await item.options}
72
+ {loadingText()}
73
+ {:then options}
74
+ {#if isMultiSelectObject<V, VP>(item)}
75
+ <MultiSelect
76
+ name={item.name}
77
+ {options}
78
+ valueAsObject={true}
79
+ labelProp={item.labelProp}
80
+ valueProp={item.valueProp}
81
+ selectedValues={item.value}
82
+ invalid={item.invalid}
83
+ onchange={(v: Array<V>) => {
84
+ item.updater(v);
85
+ }}
86
+ />
87
+ {:else if isMultiSelectPrimitive(item)}
88
+ <MultiSelect
89
+ name={item.name}
90
+ {options}
91
+ valueAsObject={false}
92
+ labelProp={item.labelProp}
93
+ valueProp={item.valueProp}
94
+ selectedValues={item.value}
95
+ invalid={item.invalid}
96
+ onchange={(v: Array<V[VP]>) => {
97
+ // `valueAsObject={false}` → primitives, not SelectOption objects.
98
+ item.updater(v);
99
+ }}
100
+ />
101
+ {/if}
102
+ {/await}
103
+ {:else if isSingleSelect(item)}
104
+ {#await item.options}
105
+ {loadingText()}
106
+ {:then options}
107
+ {#if isSingleSelectObject(item)}
108
+ <SingleSelect
109
+ {options}
110
+ name={item.name}
111
+ valueAsObject={true}
112
+ labelProp={item.labelProp}
113
+ valueProp={item.valueProp}
114
+ value={item.value}
115
+ required={item.required}
116
+ clearable={!item.required}
117
+ disabled={item.disabled}
118
+ invalid={item.invalid}
119
+ onchange={(v: V | null) => {
120
+ item.updater(v);
121
+ }}
122
+ />
123
+ {:else if isSingleSelectPrimitive(item)}
124
+ <SingleSelect
125
+ {options}
126
+ name={item.name}
127
+ valueAsObject={false}
128
+ labelProp={item.labelProp}
129
+ valueProp={item.valueProp}
130
+ value={item.value}
131
+ required={item.required}
132
+ clearable={!item.required}
133
+ disabled={item.disabled}
134
+ invalid={item.invalid}
135
+ onchange={(
136
+ // `valueAsObject={false}` → primitive value, not a
137
+ // SelectOption. `clearable` is on (since the field is
138
+ // not required) so the callback must accept null.
139
+ // The annotation collapses to `unknown | null` because
140
+ // `V extends Record<string, unknown>` makes `V[VP]`
141
+ // itself `unknown`.
142
+ // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents
143
+ v: V[VP] | null
144
+ ) => {
145
+ item.updater(v);
146
+ }}
147
+ />
148
+ {/if}
149
+ {/await}
150
+ {/if}
151
+ {:else if dev}
152
+ {@const type = item.type}
153
+ unknown type: {type}
154
+ <!-- eslint-disable-next-line svelte/no-at-debug-tags -->
155
+ {@debug type}
156
+ {/if}
157
+ </label>
158
+
159
159
  <style>label {
160
160
  display: contents;
161
161
  --input-border-radius: 0;
@@ -174,4 +174,4 @@ label.first {
174
174
  }
175
175
  label.last {
176
176
  border-radius: 0 0 4px 4px;
177
- }</style>
177
+ }</style>
@@ -1,26 +1,26 @@
1
- <svelte:options runes />
2
-
3
- <script
4
- lang="ts"
5
- generics="V extends Record<string, unknown>,VP extends ValueProp<V>"
1
+ <svelte:options runes />
2
+
3
+ <script
4
+ lang="ts"
5
+ generics="V extends Record<string, unknown>,VP extends ValueProp<V>"
6
6
  >import GridInput from "./GridInput.svelte";
7
7
  const { items, header } = $props();
8
8
  const lastIndex = $derived(items.length - 1);
9
- </script>
10
-
11
- <div class="grid">
12
- {#if header}
13
- {@render header()}
14
- {/if}
15
- {#each items as item, index (item.label)}
16
- <GridInput
17
- {item}
18
- first={index == 0}
19
- last={index == lastIndex}
20
- />
21
- {/each}
22
- </div>
23
-
9
+ </script>
10
+
11
+ <div class="grid">
12
+ {#if header}
13
+ {@render header()}
14
+ {/if}
15
+ {#each items as item, index (item.label)}
16
+ <GridInput
17
+ {item}
18
+ first={index == 0}
19
+ last={index == lastIndex}
20
+ />
21
+ {/each}
22
+ </div>
23
+
24
24
  <style>.grid {
25
25
  display: grid;
26
26
  grid-template-columns: [label] 16rem [value] 1fr;
@@ -28,4 +28,4 @@ const lastIndex = $derived(items.length - 1);
28
28
  border: solid 1px #dae0e5;
29
29
  border-radius: 4px;
30
30
  background-color: #dae0e5;
31
- }</style>
31
+ }</style>