@svadmin/ui 0.70.0 → 0.73.0

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 (372) hide show
  1. package/README.md +40 -25
  2. package/THIRD_PARTY_NOTICES.md +52 -0
  3. package/dist/actions.js +1 -1
  4. package/dist/app.css +7804 -5188
  5. package/dist/app.theme.css +7738 -5173
  6. package/dist/class-properties.generated.d.ts +1 -0
  7. package/dist/class-properties.generated.js +2 -0
  8. package/dist/classnames.d.ts +8 -0
  9. package/dist/classnames.js +26 -0
  10. package/dist/component-registry.svelte.d.ts +33 -19
  11. package/dist/component-registry.svelte.js +6 -4
  12. package/dist/components/AdminApp.svelte +55 -53
  13. package/dist/components/AdminApp.svelte.d.ts +2 -2
  14. package/dist/components/ApiSettings.svelte +19 -1
  15. package/dist/components/AuditLogDrawer.svelte +14 -3
  16. package/dist/components/AutoForm.svelte +162 -50
  17. package/dist/components/AutoForm.svelte.d.ts +4 -0
  18. package/dist/components/AutoTable.svelte +599 -259
  19. package/dist/components/AutoTable.svelte.d.ts +6 -0
  20. package/dist/components/BoundRecordDetailDrawer.svelte +172 -0
  21. package/dist/components/BoundRecordDetailDrawer.svelte.d.ts +11 -0
  22. package/dist/components/Breadcrumbs.svelte +7 -4
  23. package/dist/components/CancelTaskButton.svelte +9 -5
  24. package/dist/components/ColumnHeaderFilter.svelte +4 -3
  25. package/dist/components/ColumnSettings.svelte +1 -0
  26. package/dist/components/ComboboxField.svelte +118 -36
  27. package/dist/components/ComboboxField.svelte.d.ts +5 -4
  28. package/dist/components/CreatePage.svelte +7 -1
  29. package/dist/components/CreatePage.svelte.d.ts +2 -0
  30. package/dist/components/DateRangeInput.svelte +75 -0
  31. package/dist/components/DateRangeInput.svelte.d.ts +25 -0
  32. package/dist/components/DateTimeInput.svelte +65 -0
  33. package/dist/components/DateTimeInput.svelte.d.ts +19 -0
  34. package/dist/components/DetailDrawer.svelte +4 -0
  35. package/dist/components/DetailDrawer.svelte.d.ts +1 -0
  36. package/dist/components/DevTools.svelte +8 -21
  37. package/dist/components/DraggableGrid.svelte +1 -0
  38. package/dist/components/DraggableHeader.svelte +5 -9
  39. package/dist/components/DraggableHeader.svelte.d.ts +43 -18
  40. package/dist/components/DraggableRowTable.svelte +2 -2
  41. package/dist/components/DynamicFormList.svelte +17 -17
  42. package/dist/components/DynamicFormList.svelte.d.ts +2 -1
  43. package/dist/components/EditPage.svelte +7 -1
  44. package/dist/components/EditPage.svelte.d.ts +2 -0
  45. package/dist/components/EditableTable.svelte +4 -0
  46. package/dist/components/ErrorPage.svelte +3 -1
  47. package/dist/components/FieldDisplay.svelte +14 -0
  48. package/dist/components/FieldDisplay.svelte.d.ts +7 -0
  49. package/dist/components/FieldRenderer.svelte +96 -20
  50. package/dist/components/FileUpload.svelte +250 -0
  51. package/dist/components/FileUpload.svelte.d.ts +32 -0
  52. package/dist/components/FilterBuilder.svelte +236 -268
  53. package/dist/components/FilterBuilder.svelte.d.ts +3 -0
  54. package/dist/components/FilterDropdown.svelte.d.ts +1 -1
  55. package/dist/components/Header.svelte +5 -6
  56. package/dist/components/ImportWizard.svelte +182 -94
  57. package/dist/components/InfiniteList.svelte +22 -8
  58. package/dist/components/InfiniteList.svelte.d.ts +5 -3
  59. package/dist/components/InlineEdit.svelte +114 -44
  60. package/dist/components/JsonSchemaForm.svelte +256 -95
  61. package/dist/components/JsonSchemaForm.svelte.d.ts +12 -1
  62. package/dist/components/Layout.svelte +20 -17
  63. package/dist/components/LazyTaskQueueDrawer.svelte +26 -0
  64. package/dist/components/LazyTaskQueueDrawer.svelte.d.ts +8 -0
  65. package/dist/components/ListPage.svelte +11 -6
  66. package/dist/components/ListPage.svelte.d.ts +2 -0
  67. package/dist/components/LoginPage.svelte +1 -1
  68. package/dist/components/MasterDetailView.svelte +3 -3
  69. package/dist/components/MediaLibraryModal.svelte +5 -2
  70. package/dist/components/MentionsInput.svelte +4 -3
  71. package/dist/components/MoneyInput.svelte +25 -0
  72. package/dist/components/MoneyInput.svelte.d.ts +20 -0
  73. package/dist/components/NavigateToResource.svelte +3 -2
  74. package/dist/components/NumberInput.svelte +25 -0
  75. package/dist/components/NumberInput.svelte.d.ts +19 -0
  76. package/dist/components/NumericInput.svelte +110 -0
  77. package/dist/components/NumericInput.svelte.d.ts +23 -0
  78. package/dist/components/PercentInput.svelte +25 -0
  79. package/dist/components/PercentInput.svelte.d.ts +20 -0
  80. package/dist/components/PermissionMatrix.svelte +4 -3
  81. package/dist/components/ProfilePage.svelte +2 -2
  82. package/dist/components/QuickEditDrawer.svelte +42 -0
  83. package/dist/components/QuickEditDrawer.svelte.d.ts +10 -0
  84. package/dist/components/RecordDetailDrawer.svelte +16 -108
  85. package/dist/components/RecordDetailDrawer.svelte.d.ts +2 -0
  86. package/dist/components/RecordRowActions.svelte +41 -0
  87. package/dist/components/RecordRowActions.svelte.d.ts +14 -0
  88. package/dist/components/ResourceAccessGuard.svelte +7 -5
  89. package/dist/components/ResourceOperationsPage.svelte +25 -19
  90. package/dist/components/ResourceOperationsPage.svelte.d.ts +5 -1
  91. package/dist/components/RetryTaskButton.svelte +9 -5
  92. package/dist/components/RowActions.svelte +5 -3
  93. package/dist/components/SensitiveDataMask.svelte +3 -3
  94. package/dist/components/SettingsPage.svelte +1 -1
  95. package/dist/components/ShowInferencer.svelte +4 -2
  96. package/dist/components/ShowInferencer.svelte.d.ts +2 -0
  97. package/dist/components/ShowPage.svelte +49 -39
  98. package/dist/components/ShowPage.svelte.d.ts +2 -0
  99. package/dist/components/Sidebar.svelte +15 -13
  100. package/dist/components/SplitPaneLayout.svelte +4 -2
  101. package/dist/components/SpreadsheetView.svelte +81 -286
  102. package/dist/components/StepsForm.svelte +166 -49
  103. package/dist/components/StepsForm.svelte.d.ts +1 -0
  104. package/dist/components/SvarAutoTable.svelte +39 -0
  105. package/dist/components/SvarAutoTable.svelte.d.ts +13 -0
  106. package/dist/components/SvarDataGrid.svelte +362 -0
  107. package/dist/components/SvarDataGrid.svelte.d.ts +57 -0
  108. package/dist/components/SvarGridCell.svelte +10 -0
  109. package/dist/components/SvarGridCell.svelte.d.ts +7 -0
  110. package/dist/components/SvarResourceRead.svelte +50 -0
  111. package/dist/components/SvarResourceRead.svelte.d.ts +23 -0
  112. package/dist/components/SvarResourceTable.svelte +63 -0
  113. package/dist/components/SvarResourceTable.svelte.d.ts +42 -0
  114. package/dist/components/SvarResourceTableView.svelte +364 -0
  115. package/dist/components/SvarResourceTableView.svelte.d.ts +4 -0
  116. package/dist/components/TaskDetails.svelte +20 -7
  117. package/dist/components/TaskList.svelte +19 -7
  118. package/dist/components/TaskQueueDrawer.svelte +92 -37
  119. package/dist/components/Toast.svelte +4 -2
  120. package/dist/components/TooltipButton.svelte +1 -1
  121. package/dist/components/TreeSelect.svelte +212 -30
  122. package/dist/components/TreeSelect.svelte.d.ts +3 -1
  123. package/dist/components/ValidatedField.svelte +27 -0
  124. package/dist/components/ValidatedField.svelte.d.ts +35 -0
  125. package/dist/components/account/ImportMembersPage.svelte +2 -2
  126. package/dist/components/account/SecurityLogPage.svelte +3 -1
  127. package/dist/components/account/SettingsEnterprisePage.svelte +7 -5
  128. package/dist/components/account/TeamMembersPage.svelte +1 -1
  129. package/dist/components/auto-table-grid.d.ts +26 -0
  130. package/dist/components/auto-table-grid.js +1 -0
  131. package/dist/components/buttons/CloneButton.svelte +6 -4
  132. package/dist/components/buttons/DeleteButton.svelte +95 -29
  133. package/dist/components/buttons/DeleteButton.svelte.d.ts +2 -0
  134. package/dist/components/buttons/EditButton.svelte +6 -4
  135. package/dist/components/buttons/ExportButton.svelte +22 -4
  136. package/dist/components/buttons/ImportButton.svelte +83 -38
  137. package/dist/components/buttons/ImportButton.svelte.d.ts +6 -10
  138. package/dist/components/buttons/RefreshButton.svelte +48 -8
  139. package/dist/components/buttons/ShowButton.svelte +6 -4
  140. package/dist/components/content/ApiKeyList.svelte +3 -1
  141. package/dist/components/content/ContentPageHeader.svelte +12 -9
  142. package/dist/components/content/ContentPageShell.svelte +8 -9
  143. package/dist/components/content/FileBrowser.svelte +35 -0
  144. package/dist/components/content/FileBrowser.svelte.d.ts +14 -0
  145. package/dist/components/content/FileList.svelte +3 -1
  146. package/dist/components/content/MemberList.svelte +3 -1
  147. package/dist/components/content/MetricBlock.svelte +10 -13
  148. package/dist/components/content/NetworkTable.svelte +6 -4
  149. package/dist/components/content/NetworkTable.svelte.d.ts +1 -0
  150. package/dist/components/content/PageToolbar.svelte +6 -10
  151. package/dist/components/content/SectionHeader.svelte +8 -13
  152. package/dist/components/content/SecurityEventTable.svelte +3 -1
  153. package/dist/components/content/SettingsFieldRow.svelte +9 -23
  154. package/dist/components/content/SettingsGroup.svelte +11 -27
  155. package/dist/components/content/StatusBadge.svelte +3 -8
  156. package/dist/components/content/StatusTabs.svelte +2 -2
  157. package/dist/components/content/WorkspaceLayout.svelte +8 -12
  158. package/dist/components/enterprise/filter-tree.d.ts +48 -0
  159. package/dist/components/enterprise/filter-tree.js +224 -0
  160. package/dist/components/enterprise/json-schema-form.d.ts +39 -0
  161. package/dist/components/enterprise/json-schema-form.js +195 -0
  162. package/dist/components/enterprise/recursive-schema-form.d.ts +30 -0
  163. package/dist/components/enterprise/recursive-schema-form.js +196 -0
  164. package/dist/components/enterprise/spreadsheet-formula.d.ts +12 -0
  165. package/dist/components/enterprise/spreadsheet-formula.js +245 -0
  166. package/dist/components/fieldComponentMap.d.ts +18 -13
  167. package/dist/components/fieldComponentMap.js +100 -47
  168. package/dist/components/fields/AvatarField.svelte +1 -1
  169. package/dist/components/fields/ChoiceField.svelte +16 -0
  170. package/dist/components/fields/ChoiceField.svelte.d.ts +10 -0
  171. package/dist/components/fields/CodeField.svelte +11 -12
  172. package/dist/components/fields/CodeField.svelte.d.ts +1 -1
  173. package/dist/components/fields/DateField.svelte +4 -3
  174. package/dist/components/fields/DateRangeField.svelte +2 -4
  175. package/dist/components/fields/ImageField.svelte +3 -1
  176. package/dist/components/fields/ImagesField.svelte +23 -0
  177. package/dist/components/fields/ImagesField.svelte.d.ts +6 -0
  178. package/dist/components/fields/JsonField.svelte +19 -13
  179. package/dist/components/fields/PasswordField.svelte +5 -0
  180. package/dist/components/fields/PasswordField.svelte.d.ts +6 -0
  181. package/dist/components/fields/date-field-value.d.ts +2 -0
  182. package/dist/components/fields/date-field-value.js +13 -0
  183. package/dist/components/fields/json-value.d.ts +11 -0
  184. package/dist/components/fields/json-value.js +28 -0
  185. package/dist/components/json-schema-form-state.d.ts +37 -0
  186. package/dist/components/json-schema-form-state.js +168 -0
  187. package/dist/components/profile/ActivityTimeline.svelte +2 -2
  188. package/dist/components/record-detail.svelte.d.ts +19 -0
  189. package/dist/components/record-detail.svelte.js +34 -0
  190. package/dist/components/saved-list-views.js +29 -29
  191. package/dist/components/svar-grid-cells.d.ts +14 -0
  192. package/dist/components/svar-grid-cells.js +2 -0
  193. package/dist/components/svar-grid-contract.d.ts +80 -0
  194. package/dist/components/svar-grid-contract.js +159 -0
  195. package/dist/components/svar-grid-interactions.d.ts +54 -0
  196. package/dist/components/svar-grid-interactions.js +174 -0
  197. package/dist/components/svar-grid-loading.d.ts +40 -0
  198. package/dist/components/svar-grid-loading.js +180 -0
  199. package/dist/components/svar-grid-operations.d.ts +37 -0
  200. package/dist/components/svar-grid-operations.js +186 -0
  201. package/dist/components/svar-grid-panes.d.ts +34 -0
  202. package/dist/components/svar-grid-panes.js +66 -0
  203. package/dist/components/svar-grid-resource-loading.d.ts +18 -0
  204. package/dist/components/svar-grid-resource-loading.js +68 -0
  205. package/dist/components/svar-grid-resource-session.svelte.d.ts +29 -0
  206. package/dist/components/svar-grid-resource-session.svelte.js +61 -0
  207. package/dist/components/table-contract.d.ts +13 -0
  208. package/dist/components/table-contract.js +42 -0
  209. package/dist/components/task-utils.js +4 -2
  210. package/dist/components/ui/alert/alert-variants.d.ts +2 -3
  211. package/dist/components/ui/alert/alert-variants.js +1 -2
  212. package/dist/components/ui/alert/alert.svelte +4 -5
  213. package/dist/components/ui/alert/alert.svelte.d.ts +3 -8
  214. package/dist/components/ui/alert/index.js +0 -2
  215. package/dist/components/ui/avatar/avatar-variants.d.ts +2 -3
  216. package/dist/components/ui/avatar/avatar-variants.js +1 -2
  217. package/dist/components/ui/avatar/avatar.svelte +5 -6
  218. package/dist/components/ui/avatar/avatar.svelte.d.ts +3 -8
  219. package/dist/components/ui/badge/badge-variants.d.ts +2 -3
  220. package/dist/components/ui/badge/badge-variants.js +3 -2
  221. package/dist/components/ui/badge/badge.svelte +4 -5
  222. package/dist/components/ui/badge/badge.svelte.d.ts +3 -8
  223. package/dist/components/ui/badge/index.js +0 -2
  224. package/dist/components/ui/button/button-variants.d.ts +2 -3
  225. package/dist/components/ui/button/button-variants.js +5 -3
  226. package/dist/components/ui/button/button.svelte +100 -44
  227. package/dist/components/ui/button/button.svelte.d.ts +8 -12
  228. package/dist/components/ui/button/index.js +0 -2
  229. package/dist/components/ui/command/command-dialog.svelte +3 -1
  230. package/dist/components/ui/command/command-dialog.svelte.d.ts +1 -1
  231. package/dist/components/ui/command/command-group.svelte +4 -2
  232. package/dist/components/ui/command/command-item.svelte +4 -2
  233. package/dist/components/ui/command/command-separator.svelte +3 -1
  234. package/dist/components/ui/command/index.d.ts +5 -5
  235. package/dist/components/ui/input/input.svelte +41 -24
  236. package/dist/components/ui/input/input.svelte.d.ts +5 -4
  237. package/dist/components/ui/sheet/sheet.svelte +9 -3
  238. package/dist/components/ui/sheet/sheet.svelte.d.ts +1 -0
  239. package/dist/components/ui/textarea/textarea.svelte +2 -1
  240. package/dist/components/ui/tooltip/tooltip.svelte +4 -2
  241. package/dist/components.css +3079 -0
  242. package/dist/design-contract.d.ts +13 -0
  243. package/dist/design-contract.js +11 -0
  244. package/dist/design-system.d.ts +15 -0
  245. package/dist/design-system.js +7 -0
  246. package/dist/index.d.ts +15 -1
  247. package/dist/index.js +9 -0
  248. package/dist/inline-value.d.ts +5 -0
  249. package/dist/inline-value.js +24 -0
  250. package/dist/numeric-input.d.ts +2 -0
  251. package/dist/numeric-input.js +9 -0
  252. package/dist/page-chrome.css +12 -49
  253. package/dist/recipes.d.ts +4 -0
  254. package/dist/recipes.js +4 -0
  255. package/dist/rendering/index.d.ts +87 -0
  256. package/dist/rendering/index.js +117 -0
  257. package/dist/styled-system/css/conditions.js +36 -0
  258. package/dist/styled-system/css/css.d.ts +22 -0
  259. package/dist/styled-system/css/css.js +45 -0
  260. package/dist/styled-system/css/cva.d.ts +6 -0
  261. package/dist/styled-system/css/cva.js +87 -0
  262. package/dist/styled-system/css/cx.d.ts +5 -0
  263. package/dist/styled-system/css/cx.js +15 -0
  264. package/dist/styled-system/css/index.d.ts +5 -0
  265. package/dist/styled-system/css/index.js +4 -0
  266. package/dist/styled-system/css/sva.d.ts +4 -0
  267. package/dist/styled-system/css/sva.js +46 -0
  268. package/dist/styled-system/helpers.js +316 -0
  269. package/dist/styled-system/patterns/aspect-ratio.d.ts +20 -0
  270. package/dist/styled-system/patterns/aspect-ratio.js +38 -0
  271. package/dist/styled-system/patterns/bleed.d.ts +21 -0
  272. package/dist/styled-system/patterns/bleed.js +24 -0
  273. package/dist/styled-system/patterns/box.d.ts +20 -0
  274. package/dist/styled-system/patterns/box.js +15 -0
  275. package/dist/styled-system/patterns/center.d.ts +20 -0
  276. package/dist/styled-system/patterns/center.js +21 -0
  277. package/dist/styled-system/patterns/circle.d.ts +20 -0
  278. package/dist/styled-system/patterns/circle.js +25 -0
  279. package/dist/styled-system/patterns/container.d.ts +20 -0
  280. package/dist/styled-system/patterns/container.js +21 -0
  281. package/dist/styled-system/patterns/cq.d.ts +21 -0
  282. package/dist/styled-system/patterns/cq.js +21 -0
  283. package/dist/styled-system/patterns/divider.d.ts +22 -0
  284. package/dist/styled-system/patterns/divider.js +25 -0
  285. package/dist/styled-system/patterns/flex.d.ts +26 -0
  286. package/dist/styled-system/patterns/flex.js +26 -0
  287. package/dist/styled-system/patterns/float.d.ts +23 -0
  288. package/dist/styled-system/patterns/float.js +52 -0
  289. package/dist/styled-system/patterns/grid-item.d.ts +25 -0
  290. package/dist/styled-system/patterns/grid-item.js +25 -0
  291. package/dist/styled-system/patterns/grid.d.ts +24 -0
  292. package/dist/styled-system/patterns/grid.js +27 -0
  293. package/dist/styled-system/patterns/hstack.d.ts +21 -0
  294. package/dist/styled-system/patterns/hstack.js +24 -0
  295. package/dist/styled-system/patterns/index.d.ts +21 -0
  296. package/dist/styled-system/patterns/index.js +20 -0
  297. package/dist/styled-system/patterns/link-overlay.d.ts +20 -0
  298. package/dist/styled-system/patterns/link-overlay.js +24 -0
  299. package/dist/styled-system/patterns/spacer.d.ts +20 -0
  300. package/dist/styled-system/patterns/spacer.js +25 -0
  301. package/dist/styled-system/patterns/square.d.ts +20 -0
  302. package/dist/styled-system/patterns/square.js +24 -0
  303. package/dist/styled-system/patterns/stack.d.ts +23 -0
  304. package/dist/styled-system/patterns/stack.js +24 -0
  305. package/dist/styled-system/patterns/visually-hidden.d.ts +20 -0
  306. package/dist/styled-system/patterns/visually-hidden.js +18 -0
  307. package/dist/styled-system/patterns/vstack.d.ts +21 -0
  308. package/dist/styled-system/patterns/vstack.js +24 -0
  309. package/dist/styled-system/patterns/wrap.d.ts +24 -0
  310. package/dist/styled-system/patterns/wrap.js +25 -0
  311. package/dist/styled-system/recipes/content-header.d.ts +31 -0
  312. package/dist/styled-system/recipes/content-header.js +65 -0
  313. package/dist/styled-system/recipes/content-page.d.ts +34 -0
  314. package/dist/styled-system/recipes/content-page.js +43 -0
  315. package/dist/styled-system/recipes/create-recipe.js +82 -0
  316. package/dist/styled-system/recipes/index.d.ts +17 -0
  317. package/dist/styled-system/recipes/index.js +16 -0
  318. package/dist/styled-system/recipes/metric-block.d.ts +34 -0
  319. package/dist/styled-system/recipes/metric-block.js +76 -0
  320. package/dist/styled-system/recipes/product-list.d.ts +31 -0
  321. package/dist/styled-system/recipes/product-list.js +73 -0
  322. package/dist/styled-system/recipes/product-section.d.ts +31 -0
  323. package/dist/styled-system/recipes/product-section.js +49 -0
  324. package/dist/styled-system/recipes/product-settings-row.d.ts +34 -0
  325. package/dist/styled-system/recipes/product-settings-row.js +58 -0
  326. package/dist/styled-system/recipes/product-settings.d.ts +31 -0
  327. package/dist/styled-system/recipes/product-settings.js +57 -0
  328. package/dist/styled-system/recipes/product-status.d.ts +34 -0
  329. package/dist/styled-system/recipes/product-status.js +45 -0
  330. package/dist/styled-system/recipes/product-toolbar.d.ts +31 -0
  331. package/dist/styled-system/recipes/product-toolbar.js +41 -0
  332. package/dist/styled-system/recipes/product-workspace.d.ts +34 -0
  333. package/dist/styled-system/recipes/product-workspace.js +58 -0
  334. package/dist/styled-system/recipes/surface-metric.d.ts +38 -0
  335. package/dist/styled-system/recipes/surface-metric.js +63 -0
  336. package/dist/styled-system/recipes/surface-table.d.ts +34 -0
  337. package/dist/styled-system/recipes/surface-table.js +62 -0
  338. package/dist/styled-system/recipes/ui-badge.d.ts +31 -0
  339. package/dist/styled-system/recipes/ui-badge.js +38 -0
  340. package/dist/styled-system/recipes/ui-button.d.ts +32 -0
  341. package/dist/styled-system/recipes/ui-button.js +43 -0
  342. package/dist/styled-system/recipes/ui-input.d.ts +31 -0
  343. package/dist/styled-system/recipes/ui-input.js +49 -0
  344. package/dist/styled-system/recipes/ui-textarea.d.ts +31 -0
  345. package/dist/styled-system/recipes/ui-textarea.js +24 -0
  346. package/dist/styled-system/styles.css +1257 -0
  347. package/dist/styled-system/tokens/index.d.ts +9 -0
  348. package/dist/styled-system/tokens/index.js +268 -0
  349. package/dist/styled-system/tokens/tokens.d.ts +36 -0
  350. package/dist/styled-system/types/composition.d.ts +227 -0
  351. package/dist/styled-system/types/conditions.d.ts +236 -0
  352. package/dist/styled-system/types/csstype.d.ts +22570 -0
  353. package/dist/styled-system/types/index.d.ts +6 -0
  354. package/dist/styled-system/types/parts.d.ts +8 -0
  355. package/dist/styled-system/types/pattern.d.ts +78 -0
  356. package/dist/styled-system/types/prop-type.d.ts +223 -0
  357. package/dist/styled-system/types/recipe.d.ts +181 -0
  358. package/dist/styled-system/types/selectors.d.ts +59 -0
  359. package/dist/styled-system/types/static-css.d.ts +56 -0
  360. package/dist/styled-system/types/style-props.d.ts +8088 -0
  361. package/dist/styled-system/types/system-types.d.ts +151 -0
  362. package/dist/styles/aliases.css +49 -0
  363. package/dist/styles/compatibility.epilogue.css +384 -0
  364. package/dist/styles/compatibility.prelude.css +5513 -0
  365. package/dist/styles/conditional-states.css +28 -0
  366. package/dist/styles/conditional-utilities.css +22 -0
  367. package/dist/styles/recipes.css +1262 -0
  368. package/dist/types.d.ts +3 -3
  369. package/dist/utils.d.ts +1 -1
  370. package/dist/utils.js +1 -1
  371. package/package.json +38 -14
  372. package/styles-compatibility.json +12 -0
@@ -1,6 +1,10 @@
1
1
  <script lang="ts">
2
+ import { onDestroy } from 'svelte';
3
+ import { definedReactiveOptions, definedOptions } from '@svadmin/core/options';
4
+
2
5
  import { ListTodo, Loader2, Plus, Search, RefreshCw } from '@lucide/svelte';
3
- import { getTaskProvider, useSubmitTask, useTaskList } from '@svadmin/core';
6
+ import { captureAdminContext, captureAuthSession, useSubmitTask, useTaskList } from '@svadmin/core';
7
+ import { decodeTaskSubmitOptions } from '@svadmin/core/schema';
4
8
  import { useTranslation } from '@svadmin/core/i18n';
5
9
  import type { TaskProvider, TaskRecord } from '@svadmin/core';
6
10
  import { Button } from './ui/button/index.js';
@@ -22,13 +26,14 @@
22
26
  } from './task-utils.js';
23
27
 
24
28
  const i18n = useTranslation();
29
+ const context = captureAdminContext();
25
30
 
26
31
  type AutoRefreshValue = '0' | '5000' | '15000' | '30000';
27
32
  type TaskTab = 'tasks' | 'dlq';
28
33
 
29
34
  let {
30
35
  open = $bindable(false),
31
- taskProvider = getTaskProvider({ optional: true }) as TaskProvider<TaskRecord> | undefined,
36
+ taskProvider,
32
37
  title,
33
38
  initialTab = 'tasks',
34
39
  }: {
@@ -38,8 +43,7 @@
38
43
  initialTab?: TaskTab;
39
44
  } = $props();
40
45
 
41
- // eslint-disable-next-line svelte/prefer-writable-derived
42
- let activeTab = $state<TaskTab>('tasks');
46
+ let activeTab = $derived(initialTab);
43
47
  let selectedTaskId = $state<string | null>(null);
44
48
  let searchQuery = $state('');
45
49
  let statusFilter = $state('all');
@@ -49,40 +53,79 @@
49
53
  let submitBodyText = $state(i18n.t('task.bodyPlaceholder'));
50
54
  let submitError = $state<string | null>(null);
51
55
  let submitOpen = $state(false);
56
+ let submitAttempt = $state.raw<object | null>(null);
57
+ let mounted = true;
58
+ onDestroy(() => { mounted = false; submitAttempt = null; });
59
+ const activeTaskProvider = $derived(taskProvider ?? context.taskProvider);
60
+ const taskScope = $derived({
61
+ provider: activeTaskProvider,
62
+ tenant: context.tenantCacheKey?.__svadminTenant,
63
+ auth: context.authProvider,
64
+ router: context.routerProvider,
65
+ session: captureAuthSession(context.authProvider),
66
+ });
67
+ let previousTaskScope: typeof taskScope | undefined;
68
+ function taskScopesEqual(left: typeof taskScope, right: typeof taskScope): boolean {
69
+ return left.provider === right.provider
70
+ && left.tenant === right.tenant
71
+ && left.auth === right.auth
72
+ && left.router === right.router
73
+ && left.session.cacheKey === right.session.cacheKey
74
+ && left.session.available === right.session.available;
75
+ }
76
+ function taskScopeIsCurrent(origin: typeof taskScope): boolean {
77
+ return mounted && taskScopesEqual(origin, taskScope) && origin.session.isCurrent();
78
+ }
79
+ $effect.pre(() => {
80
+ const scope = taskScope;
81
+ if (previousTaskScope && !taskScopesEqual(previousTaskScope, scope)) {
82
+ selectedTaskId = null;
83
+ submitAttempt = null;
84
+ submitOpen = false;
85
+ resetSubmitForm();
86
+ }
87
+ previousTaskScope = scope;
88
+ });
89
+ $effect.pre(() => {
90
+ if (!open) {
91
+ submitAttempt = null;
92
+ submitOpen = false;
93
+ }
94
+ });
52
95
 
53
96
  const refreshInterval = $derived.by<number | false>(() =>
54
97
  autoRefresh === '0' ? false : Number(autoRefresh),
55
98
  );
56
99
  const resolvedTitle = $derived(title ?? i18n.t('task.drawerTitle'));
57
100
 
58
- const taskQuery = useTaskList({
101
+ const taskQuery = useTaskList(definedReactiveOptions({
59
102
  get taskProvider() {
60
- return taskProvider;
103
+ return activeTaskProvider;
61
104
  },
62
105
  get queryOptions() {
63
106
  return {
64
- enabled: !!taskProvider,
107
+ enabled: !!activeTaskProvider,
65
108
  refetchInterval: refreshInterval,
66
109
  refetchIntervalInBackground: true,
67
110
  };
68
111
  },
69
- });
112
+ }));
70
113
 
71
- const dlqQuery = useTaskList({
114
+ const dlqQuery = useTaskList(definedReactiveOptions({
72
115
  get dlq() {
73
116
  return true;
74
117
  },
75
118
  get taskProvider() {
76
- return taskProvider;
119
+ return activeTaskProvider;
77
120
  },
78
121
  get queryOptions() {
79
122
  return {
80
- enabled: !!taskProvider && !!taskProvider?.listDlq,
123
+ enabled: !!activeTaskProvider && !!activeTaskProvider?.listDlq,
81
124
  refetchInterval: refreshInterval,
82
125
  refetchIntervalInBackground: true,
83
126
  };
84
127
  },
85
- });
128
+ }));
86
129
 
87
130
  const submitTask = useSubmitTask();
88
131
 
@@ -123,10 +166,6 @@
123
166
  allTasks.filter(isTaskActive).length,
124
167
  );
125
168
 
126
- $effect(() => {
127
- activeTab = initialTab;
128
- });
129
-
130
169
  $effect(() => {
131
170
  if (statusFilter !== 'all' && !availableStatuses.includes(statusFilter)) {
132
171
  statusFilter = 'all';
@@ -141,19 +180,19 @@
141
180
  }
142
181
 
143
182
  if (!selectedTaskId) {
144
- selectedTaskId = current[0].id;
183
+ selectedTaskId = current[0]?.id ?? null;
145
184
  return;
146
185
  }
147
186
 
148
187
  if (!current.some((task) => task.id === selectedTaskId)) {
149
- selectedTaskId = current[0].id;
188
+ selectedTaskId = current[0]?.id ?? null;
150
189
  }
151
190
  });
152
191
 
153
192
  function formatTime(value: unknown) {
154
- if (!value) return '—';
155
- const date = new Date(value as string | Date);
156
- if (Number.isNaN(date.getTime())) return String(value);
193
+ if (typeof value !== 'string' || !value) return '—';
194
+ const date = new Date(value);
195
+ if (Number.isNaN(date.getTime())) return '—';
157
196
  return date.toLocaleString();
158
197
  }
159
198
 
@@ -164,7 +203,14 @@
164
203
  submitError = null;
165
204
  }
166
205
 
206
+ function toggleSubmitForm(): void {
207
+ submitAttempt = null;
208
+ submitError = null;
209
+ submitOpen = !submitOpen;
210
+ }
211
+
167
212
  async function handleSubmitTask() {
213
+ if (!open || !submitOpen || submitAttempt || !activeTaskProvider || !taskScope.session.available) return;
168
214
  submitError = null;
169
215
  if (!submitTaskName.trim()) {
170
216
  submitError = i18n.t('validation.required');
@@ -174,32 +220,41 @@
174
220
  let body: Record<string, unknown> | undefined;
175
221
  if (submitBodyText.trim()) {
176
222
  try {
177
- body = JSON.parse(submitBodyText) as Record<string, unknown>;
223
+ const parsed: unknown = JSON.parse(submitBodyText);
224
+ body = decodeTaskSubmitOptions({ body: parsed }).body;
178
225
  } catch {
179
226
  submitError = i18n.t('task.invalidJson');
180
227
  return;
181
228
  }
182
229
  }
183
230
 
231
+ const origin = taskScope;
232
+ const attempt = {};
233
+ submitAttempt = attempt;
234
+ const current = () => submitAttempt === attempt && taskScopeIsCurrent(origin);
184
235
  try {
185
- const handle = await submitTask.mutation.mutateAsync({
236
+ const handle = await submitTask.mutation.mutateAsync(definedOptions({
186
237
  taskName: submitTaskName.trim(),
187
- taskProvider,
188
- options: {
238
+ taskProvider: activeTaskProvider,
239
+ options: definedOptions({
189
240
  body,
190
241
  idempotencyKey: submitIdempotencyKey.trim() || undefined,
191
- },
192
- });
242
+ }),
243
+ }));
244
+ if (!current()) return;
193
245
  activeTab = 'tasks';
194
- selectedTaskId = handle.id ?? null;
246
+ selectedTaskId = handle.id;
195
247
  submitOpen = false;
196
248
  resetSubmitForm();
197
- await Promise.all([
249
+ await Promise.allSettled([
198
250
  taskQuery.refetch?.(),
199
251
  dlqQuery.refetch?.(),
200
252
  ]);
201
253
  } catch (error) {
254
+ if (!current()) return;
202
255
  submitError = error instanceof Error ? error.message : i18n.t('task.submitFailed');
256
+ } finally {
257
+ if (submitAttempt === attempt) submitAttempt = null;
203
258
  }
204
259
  }
205
260
 
@@ -250,7 +305,7 @@
250
305
  </div>
251
306
  </div>
252
307
 
253
- {#if !taskProvider}
308
+ {#if !activeTaskProvider}
254
309
  <div class="svadmin-u-60fbb7713999 svadmin-u-36e579c0b41c svadmin-u-3960ffc248d9 svadmin-u-86843cf1e227 svadmin-u-0478c89a150f svadmin-u-fc7473ca09eb svadmin-u-bfa603190748">
255
310
  {i18n.t('common.configRequired')}
256
311
  </div>
@@ -277,7 +332,7 @@
277
332
  <RefreshCw class="svadmin-u-82cc6c6581cd svadmin-u-7fc7f732bf7e svadmin-u-bf600f8e029c" />
278
333
  {i18n.t('common.refresh')}
279
334
  </Button>
280
- <Button size="sm" onclick={() => submitOpen = !submitOpen}>
335
+ <Button size="sm" disabled={!taskScope.session.available} onclick={toggleSubmitForm}>
281
336
  <Plus class="svadmin-u-82cc6c6581cd svadmin-u-7fc7f732bf7e svadmin-u-bf600f8e029c" />
282
337
  {i18n.t('task.submitAction')}
283
338
  </Button>
@@ -328,14 +383,14 @@
328
383
  <Textarea id="task-body" bind:value={submitBodyText} class="svadmin-u-ee15a477cd9c svadmin-u-0e65706bcccd svadmin-u-359090c2d529" />
329
384
  </div>
330
385
  {#if submitError}
331
- <p class="svadmin-u-fc7473ca09eb svadmin-u-811148b13d1e">{submitError}</p>
386
+ <p role="alert" class="svadmin-u-fc7473ca09eb svadmin-u-811148b13d1e">{submitError}</p>
332
387
  {/if}
333
388
  <div class="svadmin-u-60fbb7713999 svadmin-u-1eb5c6df38c1 svadmin-u-77c08e015d14 svadmin-u-77a2a20e90d4">
334
- <Button variant="ghost" onclick={() => { submitOpen = false; submitError = null; }}>
389
+ <Button variant="ghost" onclick={toggleSubmitForm}>
335
390
  {i18n.t('common.cancel')}
336
391
  </Button>
337
- <Button onclick={() => void handleSubmitTask()} disabled={submitTask.mutation.isPending}>
338
- {#if submitTask.mutation.isPending}
392
+ <Button onclick={() => void handleSubmitTask()} disabled={submitAttempt !== null || !taskScope.session.available}>
393
+ {#if submitAttempt !== null}
339
394
  <Loader2 class="svadmin-u-82cc6c6581cd svadmin-u-7fc7f732bf7e svadmin-u-bf600f8e029c svadmin-u-afbdd13a380e" />
340
395
  {/if}
341
396
  {i18n.t('task.submitAction')}
@@ -347,7 +402,7 @@
347
402
 
348
403
  <TaskList
349
404
  tasks={filteredTasks}
350
- {taskProvider}
405
+ taskProvider={activeTaskProvider}
351
406
  dlq={activeTab === 'dlq'}
352
407
  title={activeTab === 'dlq' ? i18n.t('task.dlqTitle') : i18n.t('task.listTitle')}
353
408
  emptyText={activeTab === 'dlq' ? i18n.t('task.noDlq') : i18n.t('task.noTasks')}
@@ -363,7 +418,7 @@
363
418
  {#if selectedTaskId}
364
419
  <TaskDetails
365
420
  taskId={selectedTaskId}
366
- {taskProvider}
421
+ taskProvider={activeTaskProvider}
367
422
  useProviderData
368
423
  queryOptions={{
369
424
  refetchInterval: refreshInterval,
@@ -1,4 +1,6 @@
1
1
  <script lang="ts">
2
+ import { definedOptions } from '@svadmin/core/options';
3
+
2
4
  import { onMount } from 'svelte';
3
5
  import { Toaster, toast as sonner, type ToasterProps } from 'svelte-sonner';
4
6
  import {
@@ -29,7 +31,7 @@
29
31
  const queue = getToastQueue();
30
32
  if (queue.length > 0) {
31
33
  for (const t of queue) {
32
- const options = { duration: t.duration, id: t.key ?? t.id };
34
+ const options = definedOptions({ duration: t.duration, id: t.key ?? t.id });
33
35
  switch (t.type) {
34
36
  case 'success': sonner.success(t.message, options); break;
35
37
  case 'error': sonner.error(t.message, options); break;
@@ -86,7 +88,7 @@
86
88
  {#each getToasts().slice(-3) as item (item.id)}
87
89
  <UndoableNotification
88
90
  message={item.message}
89
- duration={item.duration}
91
+ {...definedOptions({ "duration": item.duration })}
90
92
  embedded
91
93
  managedExternally
92
94
  onUndo={() => undo(item.id, item.onUndo)}
@@ -60,7 +60,7 @@
60
60
  <Tooltip.Root bind:open>
61
61
  <Tooltip.Trigger aria-describedby={restProps['aria-describedby']}>
62
62
  {#snippet child({ props })}
63
- {@const primitiveOnclick = props.onclick as ((event: MouseEvent) => void) | undefined}
63
+ {@const primitiveOnclick = props['onclick'] as ((event: MouseEvent) => void) | undefined}
64
64
  {@const buttonProps = { ...mergeButtonProps(props), href, target, rel, variant, size, type, class: className, 'aria-label': restProps['aria-label'] ?? tooltip, 'aria-describedby': props['aria-describedby'], onclick: (event: MouseEvent) => handleClick(event, primitiveOnclick), disabled, tabindex } as any}
65
65
  <Button {...buttonProps}>
66
66
  {@render children()}
@@ -1,6 +1,9 @@
1
1
  <script lang="ts">
2
+ import { definedOptions } from '@svadmin/core/options';
3
+
2
4
  import { SvelteSet } from 'svelte/reactivity';
3
- import { ChevronRight, ChevronDown, Check, X, Search, ChevronsUpDown } from '@lucide/svelte';
5
+ import { onDestroy } from 'svelte';
6
+ import { ChevronRight, ChevronDown, Check, X, Search, ChevronsUpDown, Loader2, Minus, RotateCw } from '@lucide/svelte';
4
7
  import { cn } from '../utils.js';
5
8
  import * as Popover from './ui/popover/index.js';
6
9
  import { Input } from './ui/input/index.js';
@@ -11,6 +14,7 @@
11
14
  value: string | number;
12
15
  label: string;
13
16
  children?: TreeSelectOption[];
17
+ hasChildren?: boolean;
14
18
  disabled?: boolean;
15
19
  expanded?: boolean;
16
20
  }
@@ -26,12 +30,13 @@
26
30
  onlyLeafSelectable?: boolean;
27
31
  disabled?: boolean;
28
32
  allowClear?: boolean;
33
+ loadChildren?: (node: TreeSelectOption) => Promise<TreeSelectOption[]>;
29
34
  class?: string;
30
35
  onchange?: (value: string | number | (string | number)[] | undefined) => void;
31
36
  }
32
37
 
33
38
  let {
34
- options = [],
39
+ options = $bindable([]),
35
40
  value = $bindable(undefined),
36
41
  multiple = false,
37
42
  placeholder,
@@ -39,13 +44,22 @@
39
44
  onlyLeafSelectable = false,
40
45
  disabled = false,
41
46
  allowClear = true,
47
+ loadChildren,
42
48
  class: className,
43
49
  onchange,
44
50
  }: Props = $props();
45
51
 
46
52
  let open = $state(false);
47
53
  let searchQuery = $state('');
54
+ let loadingValues = new SvelteSet<string | number>();
55
+ let loadErrors = new SvelteSet<string | number>();
48
56
  let expandedNodes = new SvelteSet<string | number>();
57
+ let mounted = true;
58
+ const loads = new Map<string | number, {
59
+ node: TreeSelectOption;
60
+ loader: NonNullable<Props['loadChildren']>;
61
+ }>();
62
+ onDestroy(() => { mounted = false; loads.clear(); });
49
63
 
50
64
  // Map to quickly look up option info by value
51
65
  const optionMap = $derived.by(() => {
@@ -70,6 +84,19 @@
70
84
  return selectedValues.map((v) => optionMap.get(v)?.label ?? String(v));
71
85
  });
72
86
 
87
+ $effect.pre(() => {
88
+ const nodes = optionMap;
89
+ const loader = loadChildren;
90
+ const unavailable = disabled;
91
+ for (const [key, request] of loads) {
92
+ if (unavailable || nodes.get(key) !== request.node || loader !== request.loader) {
93
+ loads.delete(key);
94
+ loadingValues.delete(key);
95
+ loadErrors.delete(key);
96
+ }
97
+ }
98
+ });
99
+
73
100
  function toggleExpand(nodeValue: string | number, event?: MouseEvent) {
74
101
  event?.stopPropagation();
75
102
  if (expandedNodes.has(nodeValue)) {
@@ -79,32 +106,121 @@
79
106
  }
80
107
  }
81
108
 
109
+ function hasChildren(node: TreeSelectOption): boolean {
110
+ return Boolean(node.hasChildren ?? (node.children && node.children.length > 0));
111
+ }
112
+
82
113
  function isNodeExpanded(node: TreeSelectOption): boolean {
83
114
  if (searchQuery.trim()) return true; // Auto expand all on search
84
115
  return expandedNodes.has(node.value) || !!node.expanded;
85
116
  }
86
117
 
118
+ function selectableLeaves(node: TreeSelectOption): TreeSelectOption[] {
119
+ if (!hasChildren(node)) return node.disabled ? [] : [node];
120
+ if (!node.children) return [];
121
+ return (node.children ?? []).flatMap(selectableLeaves);
122
+ }
123
+
87
124
  function isSelected(val: string | number): boolean {
88
125
  return selectedValues.includes(val);
89
126
  }
90
127
 
91
- function handleSelect(node: TreeSelectOption) {
128
+ function isNodeSelected(node: TreeSelectOption): boolean {
129
+ if (!multiple || !hasChildren(node)) return isSelected(node.value);
130
+ const leaves = selectableLeaves(node);
131
+ return leaves.length > 0 && leaves.every((leaf) => isSelected(leaf.value));
132
+ }
133
+
134
+ function isPartiallySelected(node: TreeSelectOption): boolean {
135
+ if (!multiple || !hasChildren(node)) return false;
136
+ const leaves = selectableLeaves(node);
137
+ const count = leaves.filter((leaf) => isSelected(leaf.value)).length;
138
+ return count > 0 && count < leaves.length;
139
+ }
140
+
141
+ function updateOptionsChildren(nodes: TreeSelectOption[], target: string | number, children: TreeSelectOption[]): TreeSelectOption[] {
142
+ let changed = false;
143
+ const next = nodes.map((node) => {
144
+ if (node.value === target) {
145
+ changed = true;
146
+ return { ...node, children, hasChildren: children.length > 0 };
147
+ }
148
+ if (!node.children) return node;
149
+ const updated = updateOptionsChildren(node.children, target, children);
150
+ if (updated === node.children) return node;
151
+ changed = true;
152
+ return { ...node, children: updated };
153
+ });
154
+ return changed ? next : nodes;
155
+ }
156
+
157
+ async function ensureChildren(node: TreeSelectOption): Promise<boolean> {
158
+ if (!mounted || disabled || loadingValues.has(node.value)) return false;
159
+ if (!node.hasChildren || node.children) return true;
160
+ const currentNode = optionMap.get(node.value);
161
+ if (!loadChildren || !currentNode) return false;
162
+ const request = { node: currentNode, loader: loadChildren };
163
+ loads.set(node.value, request);
164
+ const current = () => mounted && !disabled && loads.get(node.value) === request
165
+ && optionMap.get(node.value) === request.node && loadChildren === request.loader;
166
+ loadingValues.add(node.value);
167
+ loadErrors.delete(node.value);
168
+ try {
169
+ const children = await request.loader(request.node);
170
+ if (!current()) return false;
171
+ options = updateOptionsChildren(options, node.value, children);
172
+ return true;
173
+ } catch {
174
+ if (current()) loadErrors.add(node.value);
175
+ return false;
176
+ } finally {
177
+ if (mounted && loads.get(node.value) === request) {
178
+ loads.delete(node.value);
179
+ loadingValues.delete(node.value);
180
+ }
181
+ }
182
+ }
183
+
184
+ async function toggleExpandAsync(node: TreeSelectOption, event?: MouseEvent): Promise<void> {
185
+ event?.stopPropagation();
186
+ if (!await ensureChildren(node)) return;
187
+ if (!mounted || disabled) return;
188
+ toggleExpand(node.value);
189
+ }
190
+
191
+ function retryChildren(node: TreeSelectOption, event: MouseEvent): void {
192
+ event.stopPropagation();
193
+ void toggleExpandAsync(node);
194
+ }
195
+
196
+ function setMultipleSelection(node: TreeSelectOption): void {
197
+ const leaves = selectableLeaves(node);
198
+ const leafValues = new Set(leaves.map((leaf) => leaf.value));
199
+ const shouldRemove = leaves.length > 0 && leaves.every((leaf) => isSelected(leaf.value));
200
+ const next = shouldRemove
201
+ ? selectedValues.filter((value) => !leafValues.has(value))
202
+ : [...selectedValues, ...leaves.map((leaf) => leaf.value).filter((value) => !isSelected(value))];
203
+ value = next;
204
+ onchange?.(next);
205
+ }
206
+
207
+ async function handleSelect(node: TreeSelectOption): Promise<void> {
92
208
  if (node.disabled) return;
93
- const hasChildren = node.children && node.children.length > 0;
94
- if (onlyLeafSelectable && hasChildren) {
95
- toggleExpand(node.value);
209
+ const nodeHasChildren = hasChildren(node);
210
+ if (onlyLeafSelectable && nodeHasChildren) {
211
+ await toggleExpandAsync(node);
96
212
  return;
97
213
  }
98
214
 
99
215
  if (multiple) {
100
- let next: (string | number)[];
101
- if (isSelected(node.value)) {
102
- next = selectedValues.filter((v) => v !== node.value);
103
- } else {
104
- next = [...selectedValues, node.value];
216
+ if (nodeHasChildren) setMultipleSelection(node);
217
+ else {
218
+ const next = isSelected(node.value)
219
+ ? selectedValues.filter((selected) => selected !== node.value)
220
+ : [...selectedValues, node.value];
221
+ value = next;
222
+ onchange?.(next);
105
223
  }
106
- value = next;
107
- onchange?.(next);
108
224
  } else {
109
225
  const next = node.value;
110
226
  value = next;
@@ -113,6 +229,59 @@
113
229
  }
114
230
  }
115
231
 
232
+ function findParent(nodes: TreeSelectOption[], target: string | number, parent?: TreeSelectOption): TreeSelectOption | undefined {
233
+ for (const node of nodes) {
234
+ if (node.value === target) return parent;
235
+ const match = node.children ? findParent(node.children, target, node) : undefined;
236
+ if (match) return match;
237
+ }
238
+ return undefined;
239
+ }
240
+
241
+ function focusTreeNode(valueToFocus: string | number): void {
242
+ const element = document.querySelector<HTMLElement>(`[data-tree-value="${CSS.escape(String(valueToFocus))}"]`);
243
+ element?.focus();
244
+ }
245
+
246
+ function focusSibling(nodeValue: string | number, offset: number): void {
247
+ const nodes = Array.from(document.querySelectorAll<HTMLElement>('[data-tree-value]'));
248
+ const index = nodes.findIndex((node) => node.dataset['treeValue'] === String(nodeValue));
249
+ const target = nodes[index + offset];
250
+ target?.focus();
251
+ }
252
+
253
+ function handleTreeKeydown(event: KeyboardEvent, node: TreeSelectOption, expanded: boolean): void {
254
+ const nodeHasChildren = hasChildren(node);
255
+ if (event.key === 'Enter' || event.key === ' ') {
256
+ event.preventDefault();
257
+ void handleSelect(node);
258
+ } else if (event.key === 'ArrowDown') {
259
+ event.preventDefault();
260
+ focusSibling(node.value, 1);
261
+ } else if (event.key === 'ArrowUp') {
262
+ event.preventDefault();
263
+ focusSibling(node.value, -1);
264
+ } else if (event.key === 'Home') {
265
+ event.preventDefault();
266
+ document.querySelector<HTMLElement>('[data-tree-value]')?.focus();
267
+ } else if (event.key === 'End') {
268
+ event.preventDefault();
269
+ const nodes = document.querySelectorAll<HTMLElement>('[data-tree-value]');
270
+ nodes[nodes.length - 1]?.focus();
271
+ } else if (event.key === 'ArrowRight' && nodeHasChildren) {
272
+ event.preventDefault();
273
+ if (!expanded) void toggleExpandAsync(node);
274
+ else focusTreeNode(node.children?.[0]?.value ?? node.value);
275
+ } else if (event.key === 'ArrowLeft') {
276
+ event.preventDefault();
277
+ if (nodeHasChildren && expanded) toggleExpand(node.value);
278
+ else {
279
+ const parent = findParent(options, node.value);
280
+ if (parent) focusTreeNode(parent.value);
281
+ }
282
+ }
283
+ }
284
+
116
285
  function clearAll(event?: MouseEvent) {
117
286
  event?.stopPropagation();
118
287
  const next = multiple ? [] : undefined;
@@ -140,10 +309,10 @@
140
309
  const matchChildren = filteredChildren && filteredChildren.length > 0;
141
310
 
142
311
  if (matchSelf || matchChildren) {
143
- filtered.push({
312
+ filtered.push(definedOptions({
144
313
  ...node,
145
314
  children: filteredChildren ?? node.children,
146
- });
315
+ }));
147
316
  }
148
317
  }
149
318
  return filtered;
@@ -153,17 +322,21 @@
153
322
  </script>
154
323
 
155
324
  {#snippet treeNode(node: TreeSelectOption, level: number)}
156
- {@const hasChildren = Boolean(node.children && node.children.length > 0)}
325
+ {@const nodeHasChildren = hasChildren(node)}
157
326
  {@const expanded = isNodeExpanded(node)}
158
- {@const selected = isSelected(node.value)}
159
- {@const selectable = !node.disabled && (!onlyLeafSelectable || !hasChildren)}
327
+ {@const selected = isNodeSelected(node)}
328
+ {@const partial = isPartiallySelected(node)}
329
+ {@const selectable = !node.disabled && (!onlyLeafSelectable || !nodeHasChildren)}
160
330
 
161
331
  <div class="svadmin-u-60fbb7713999 svadmin-u-8dddea0773ed">
162
332
  <div
163
333
  role="treeitem"
164
334
  tabindex="0"
165
335
  aria-selected={selected}
166
- aria-expanded={hasChildren ? expanded : undefined}
336
+ aria-checked={multiple ? (partial ? 'mixed' : selected) : undefined}
337
+ aria-level={level + 1}
338
+ aria-expanded={nodeHasChildren ? expanded : undefined}
339
+ data-tree-value={String(node.value)}
167
340
  class={cn(
168
341
  'group svadmin-u-60fbb7713999 svadmin-u-3960ffc248d9 svadmin-u-8ef2268efbbc svadmin-u-58284b4ea568 svadmin-u-421ac2be5045 svadmin-u-d5eab218aa34 svadmin-u-ec0091ee009b svadmin-u-359090c2d529 svadmin-u-ceb69a6b0e5f svadmin-u-34516836730d svadmin-u-7f6912283f11',
169
342
  selected ? 'svadmin-u-375dc44df6e9 svadmin-u-20aaf08a7ed1 svadmin-u-2689f3958069' : 'svadmin-u-68646cdcc246 svadmin-u-d4108abe6359',
@@ -173,21 +346,20 @@
173
346
  onclick={() => {
174
347
  if (selectable) handleSelect(node);
175
348
  }}
176
- onkeydown={(e) => {
177
- if (e.key === 'Enter' || e.key === ' ') {
178
- e.preventDefault();
179
- if (selectable) handleSelect(node);
180
- }
181
- }}
349
+ onkeydown={(e) => handleTreeKeydown(e, node, expanded)}
182
350
  >
183
351
  <div class="svadmin-u-60fbb7713999 svadmin-u-7e0b7cdf1a94 svadmin-u-3960ffc248d9 svadmin-u-58284b4ea568">
184
- {#if hasChildren}
352
+ {#if nodeHasChildren}
185
353
  <button
186
354
  type="button"
355
+ aria-label={`${node.label}: ${i18n.t('tree.toggleChildren')}`}
356
+ aria-busy={loadingValues.has(node.value)}
187
357
  class="svadmin-u-60fbb7713999 svadmin-u-11e59c6d5f6b svadmin-u-dc7972ebf3f3 svadmin-u-012fbd121f37 svadmin-u-3960ffc248d9 svadmin-u-86843cf1e227 svadmin-u-07389a777c1f svadmin-u-bfa603190748 svadmin-u-8e551981c8d7"
188
- onclick={(e) => toggleExpand(node.value, e)}
358
+ onclick={(e) => void toggleExpandAsync(node, e)}
189
359
  >
190
- {#if expanded}
360
+ {#if loadingValues.has(node.value)}
361
+ <Loader2 class="svadmin-u-7fc7f732bf7e svadmin-u-bf600f8e029c svadmin-u-afbdd13a380e" />
362
+ {:else if expanded}
191
363
  <ChevronDown class="svadmin-u-7fc7f732bf7e svadmin-u-bf600f8e029c" />
192
364
  {:else}
193
365
  <ChevronRight class="svadmin-u-7fc7f732bf7e svadmin-u-bf600f8e029c" />
@@ -200,12 +372,22 @@
200
372
  <span class="svadmin-u-f283ea9bea0e">{node.label}</span>
201
373
  </div>
202
374
 
203
- {#if selected}
375
+ {#if loadErrors.has(node.value)}
376
+ <span role="alert" class="svadmin-u-bfa603190748">{i18n.t('tree.loadFailed')}</span>
377
+ <button type="button" aria-label={`${node.label}: ${i18n.t('common.retry')}`}
378
+ title={i18n.t('common.retry')} onclick={(e) => retryChildren(node, e)}>
379
+ <RotateCw class="svadmin-u-7fc7f732bf7e svadmin-u-bf600f8e029c" />
380
+ </button>
381
+ {/if}
382
+
383
+ {#if partial}
384
+ <Minus class="svadmin-u-7fc7f732bf7e svadmin-u-bf600f8e029c svadmin-u-012fbd121f37 svadmin-u-20aaf08a7ed1" />
385
+ {:else if selected}
204
386
  <Check class="svadmin-u-7fc7f732bf7e svadmin-u-bf600f8e029c svadmin-u-012fbd121f37 svadmin-u-20aaf08a7ed1" />
205
387
  {/if}
206
388
  </div>
207
389
 
208
- {#if hasChildren && expanded && node.children}
390
+ {#if nodeHasChildren && expanded && node.children}
209
391
  <div role="group" class="svadmin-u-60fbb7713999 svadmin-u-8dddea0773ed">
210
392
  {#each node.children as child (child.value)}
211
393
  {@render treeNode(child, level + 1)}