@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
@@ -0,0 +1,168 @@
1
+ export const SCHEMA_FORM_LIMITS = Object.freeze({ depth: 32, nodes: 10_000, characters: 1_048_576 });
2
+ const unsafe = new Set(['__proto__', 'prototype', 'constructor']);
3
+ const record = (value) => value !== null
4
+ && typeof value === 'object' && !Array.isArray(value)
5
+ && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null);
6
+ function safeKey(key) {
7
+ if (unsafe.has(key))
8
+ throw new Error('Unsafe form field');
9
+ }
10
+ /** wire 模式仅省略对象的 undefined;数组的空洞/undefined 不能偷偷转成 null。 */
11
+ function copy(value, wire) {
12
+ const active = new Set();
13
+ let nodes = 0, characters = 0;
14
+ function visit(current, depth) {
15
+ if (++nodes > SCHEMA_FORM_LIMITS.nodes || depth > SCHEMA_FORM_LIMITS.depth)
16
+ throw new Error('Form value exceeds limits');
17
+ if (current === undefined && !wire)
18
+ return undefined;
19
+ if (current === null || typeof current === 'boolean')
20
+ return current;
21
+ if (typeof current === 'number' && Number.isFinite(current))
22
+ return current;
23
+ if (typeof current === 'string') {
24
+ characters += current.length;
25
+ if (characters > SCHEMA_FORM_LIMITS.characters)
26
+ throw new Error('Form text exceeds limits');
27
+ return current;
28
+ }
29
+ if ((!record(current) && !Array.isArray(current)) || active.has(current))
30
+ throw new Error('Expected acyclic plain form data');
31
+ active.add(current);
32
+ try {
33
+ if (Reflect.ownKeys(current).some(key => typeof key === 'symbol'))
34
+ throw new Error('Symbol values are not JSON fields');
35
+ if (Array.isArray(current)) {
36
+ if (current.length > SCHEMA_FORM_LIMITS.nodes)
37
+ throw new Error('Form array exceeds limits');
38
+ const result = [];
39
+ for (let index = 0; index < current.length; index++) {
40
+ const descriptor = Object.getOwnPropertyDescriptor(current, String(index));
41
+ if (!descriptor || !('value' in descriptor))
42
+ throw new Error('Sparse arrays and accessors are not form data');
43
+ result.push(visit(descriptor.value, depth + 1));
44
+ }
45
+ if (Object.keys(current).some(key => !/^(0|[1-9][0-9]*)$/u.test(key) || Number(key) >= current.length)) {
46
+ throw new Error('Array properties are not JSON fields');
47
+ }
48
+ return result;
49
+ }
50
+ const result = {};
51
+ for (const key of Object.keys(current)) {
52
+ safeKey(key);
53
+ characters += key.length;
54
+ if (characters > SCHEMA_FORM_LIMITS.characters)
55
+ throw new Error('Form text exceeds limits');
56
+ const descriptor = Object.getOwnPropertyDescriptor(current, key);
57
+ if (!descriptor || !('value' in descriptor))
58
+ throw new Error('Accessors are not form data');
59
+ if (!wire || descriptor.value !== undefined)
60
+ result[key] = visit(descriptor.value, depth + 1);
61
+ }
62
+ return result;
63
+ }
64
+ finally {
65
+ active.delete(current);
66
+ }
67
+ }
68
+ return visit(value, 0);
69
+ }
70
+ /** Svelte 代理也通过普通数据属性读取;回调永远收不到活跃草稿的引用。 */
71
+ export function schemaFormSnapshot(value) {
72
+ if (!record(value))
73
+ throw new Error('Form root must be an object');
74
+ return copy(value, true);
75
+ }
76
+ /** 默认值只填“缺失的键”;显式 undefined/null/false/0/空串都表示调用方的决定。 */
77
+ export function initializeSchemaForm(schema, value) {
78
+ if (!record(value))
79
+ throw new Error('Form root must be an object');
80
+ const active = new Set();
81
+ let nodes = 0;
82
+ function visit(node, current, present, required, depth) {
83
+ if (++nodes > SCHEMA_FORM_LIMITS.nodes || depth > SCHEMA_FORM_LIMITS.depth || !record(node) || active.has(node)) {
84
+ throw new Error('Form schema exceeds supported traversal limits');
85
+ }
86
+ active.add(node);
87
+ try {
88
+ if (!present) {
89
+ if (Object.hasOwn(node, 'default'))
90
+ current = copy(node.default, false);
91
+ else if (node.type === 'object' || node.properties)
92
+ current = {};
93
+ else if (node.type === 'array')
94
+ current = [];
95
+ else if (node.type === 'boolean' && required)
96
+ current = false;
97
+ }
98
+ if (record(current) && (node.type === 'object' || node.properties)) {
99
+ let result = current;
100
+ for (const [key, child] of Object.entries(node.properties ?? {})) {
101
+ safeKey(key);
102
+ const exists = Object.hasOwn(current, key);
103
+ const next = visit(child, exists ? current[key] : undefined, exists, node.required?.includes(key) ?? false, depth + 1);
104
+ if ((!exists && next !== undefined) || (exists && next !== current[key])) {
105
+ if (result === current)
106
+ result = { ...current };
107
+ result[key] = next;
108
+ }
109
+ }
110
+ return result;
111
+ }
112
+ if (Array.isArray(current) && node.type === 'array' && node.items) {
113
+ if (current.length > SCHEMA_FORM_LIMITS.nodes)
114
+ throw new Error('Form array exceeds limits');
115
+ const array = current;
116
+ const items = array.map(item => visit(node.items, item, true, true, depth + 1));
117
+ return items.some((item, index) => item !== array[index]) ? items : array;
118
+ }
119
+ return current;
120
+ }
121
+ finally {
122
+ active.delete(node);
123
+ }
124
+ }
125
+ return visit(schema, value, true, true, 0);
126
+ }
127
+ export function schemaFormArrayItem(schema) {
128
+ // 新增对象项也初始化其嵌套默认值及必填 false;数字留空,不猜测为 0。
129
+ const seed = Object.hasOwn(schema, 'default') ? copy(schema.default, false)
130
+ : schema.type === 'object' || schema.properties ? {}
131
+ : schema.type === 'array' ? [] : schema.type === 'boolean' ? false : schema.type === 'number' || schema.type === 'integer' ? undefined : '';
132
+ return initializeSchemaForm({ properties: { item: schema }, required: ['item'] }, { item: seed })['item'];
133
+ }
134
+ export function writeSchemaFormPath(value, path, nextValue) {
135
+ if (!path.length || path.length > SCHEMA_FORM_LIMITS.depth)
136
+ throw new Error('Invalid form path');
137
+ const next = copy(value, false);
138
+ let target = next;
139
+ for (const [index, key] of path.entries()) {
140
+ safeKey(key);
141
+ if (Array.isArray(target) && (!/^(0|[1-9][0-9]*)$/u.test(key) || Number(key) >= target.length))
142
+ throw new Error('Invalid array field');
143
+ if (index === path.length - 1) {
144
+ Reflect.set(target, key, copy(nextValue, false));
145
+ }
146
+ else {
147
+ let child = Object.hasOwn(target, key) ? Reflect.get(target, key) : undefined;
148
+ if (!record(child) && !Array.isArray(child)) {
149
+ child = {};
150
+ Reflect.set(target, key, child);
151
+ }
152
+ target = child;
153
+ }
154
+ }
155
+ return next;
156
+ }
157
+ /** option.value 是索引,不是 String(value):1 与 "1"、null 与 "null" 必须可区分。 */
158
+ export function schemaFormEnumIndex(choices, value) {
159
+ const index = choices.findIndex(choice => choice === value);
160
+ return index === -1 ? '' : String(index);
161
+ }
162
+ export function schemaFormEnumValue(choices, index) {
163
+ if (index === '')
164
+ return undefined;
165
+ if (!/^(0|[1-9][0-9]*)$/u.test(index) || !Object.hasOwn(choices, Number(index)))
166
+ throw new Error('Invalid form choice');
167
+ return choices[Number(index)];
168
+ }
@@ -12,7 +12,7 @@
12
12
  let { activities = [], showAutoRefresh = true }: Props = $props();
13
13
  let autoRefresh = $state(false);
14
14
  const i18n = useTranslation();
15
- const config: Record<string, { icon: Component; tone: string; action: string }> = {
15
+ const config: Record<ActivityItem['type'], { icon: Component; tone: string; action: string }> = {
16
16
  posted: { icon: MessageSquare, tone: 'svadmin-u-375dc44df6e9 svadmin-u-20aaf08a7ed1', action: i18n.t('publicProfile.activityPosted') },
17
17
  commented: { icon: MessageSquare, tone: 'svadmin-u-17a9f7af2265 svadmin-u-76747e5e02ff', action: i18n.t('publicProfile.activityCommented') },
18
18
  joined: { icon: UserPlus, tone: 'svadmin-u-2ef11f1cb219 svadmin-u-bfa603190748', action: i18n.t('publicProfile.activityJoined') },
@@ -23,5 +23,5 @@
23
23
 
24
24
  <section class="svadmin-u-3e7ce58d64fa">
25
25
  <div class="svadmin-u-60fbb7713999 svadmin-u-8dddea0773ed svadmin-u-1004c0c3954c svadmin-u-020ba687fa12 svadmin-u-64cac80d2e9a svadmin-u-3b9871a0bf93"><SectionHeader title={i18n.t("publicProfile.activity")} />{#if showAutoRefresh}<div class="svadmin-u-60fbb7713999 svadmin-u-3960ffc248d9 svadmin-u-44ee8ba0a421 svadmin-u-421ac2be5045 svadmin-u-ca6bcd4b6f3f svadmin-u-18049387f0af svadmin-u-eb6a3cef9686"><Button size="sm" variant={autoRefresh ? "default" : "ghost"} onclick={() => autoRefresh = true}>{i18n.t("common.on")}</Button><Button size="sm" variant={!autoRefresh ? "default" : "ghost"} onclick={() => autoRefresh = false}>{i18n.t("common.off")}</Button></div>{/if}</div>
26
- {#if activities.length === 0}<DataState state="empty" title={i18n.t('publicProfile.noActivity')} />{:else}<Card.Card><Card.CardContent class="svadmin-u-8a539c7fe216"><div class="svadmin-u-fa6acbf81d74 svadmin-u-e783642739e3">{#each activities as activity (activity.id)}{@const item = config[activity.type] ?? config.posted}<div class="svadmin-u-60fbb7713999 svadmin-u-60541e1e26f8 svadmin-u-1004c0c3954c svadmin-u-8e63407b5ceb">{#if activity.avatar}<Avatar src={activity.avatar} alt={activity.user} size="sm" />{:else}<span class={'svadmin-u-60fbb7713999 svadmin-u-d8f5213f0fe0 svadmin-u-012fbd121f37 svadmin-u-3960ffc248d9 svadmin-u-86843cf1e227 svadmin-u-ac204c108886 ' + item.tone}><item.icon class="svadmin-u-f7b5fa971871" /></span>{/if}<div class="svadmin-u-7e0b7cdf1a94 svadmin-u-36e579c0b41c"><p class="svadmin-u-fc7473ca09eb"><strong class="svadmin-u-d4108abe6359">{activity.user}</strong><span class="svadmin-u-bfa603190748"> {item.action} </span>{#if activity.target}<strong class="svadmin-u-d4108abe6359">{activity.target}</strong>{/if}</p>{#if activity.content}<p class="svadmin-u-b6b02c0ebef6 svadmin-u-fc7473ca09eb svadmin-u-bfa603190748">{activity.content}</p>{/if}<p class="svadmin-u-b6b02c0ebef6 svadmin-u-359090c2d529 svadmin-u-bfa603190748">{activity.timestamp}</p></div></div>{/each}</div></Card.CardContent></Card.Card>{/if}
26
+ {#if activities.length === 0}<DataState state="empty" title={i18n.t('publicProfile.noActivity')} />{:else}<Card.Card><Card.CardContent class="svadmin-u-8a539c7fe216"><div class="svadmin-u-fa6acbf81d74 svadmin-u-e783642739e3">{#each activities as activity (activity.id)}{@const item = config[activity.type] ?? config['posted']}<div class="svadmin-u-60fbb7713999 svadmin-u-60541e1e26f8 svadmin-u-1004c0c3954c svadmin-u-8e63407b5ceb">{#if activity.avatar}<Avatar src={activity.avatar} alt={activity.user} size="sm" />{:else}<span class={'svadmin-u-60fbb7713999 svadmin-u-d8f5213f0fe0 svadmin-u-012fbd121f37 svadmin-u-3960ffc248d9 svadmin-u-86843cf1e227 svadmin-u-ac204c108886 ' + item.tone}><item.icon class="svadmin-u-f7b5fa971871" /></span>{/if}<div class="svadmin-u-7e0b7cdf1a94 svadmin-u-36e579c0b41c"><p class="svadmin-u-fc7473ca09eb"><strong class="svadmin-u-d4108abe6359">{activity.user}</strong><span class="svadmin-u-bfa603190748"> {item.action} </span>{#if activity.target}<strong class="svadmin-u-d4108abe6359">{activity.target}</strong>{/if}</p>{#if activity.content}<p class="svadmin-u-b6b02c0ebef6 svadmin-u-fc7473ca09eb svadmin-u-bfa603190748">{activity.content}</p>{/if}<p class="svadmin-u-b6b02c0ebef6 svadmin-u-359090c2d529 svadmin-u-bfa603190748">{activity.timestamp}</p></div></div>{/each}</div></Card.CardContent></Card.Card>{/if}
27
27
  </section>
@@ -0,0 +1,19 @@
1
+ import { type ResourceRendering } from '../rendering/index.js';
2
+ /** Views mount this only when they have an explicit record ID. */
3
+ export declare function useRecordDetail(options: () => {
4
+ resourceName: string;
5
+ id: string | number;
6
+ rendering?: ResourceRendering | undefined;
7
+ }): {
8
+ query: import("@tanstack/query-core").QueryObserverResult<import("@svadmin/core").GetOneResult<import("@svadmin/core").BaseRecord & {
9
+ id: string | number;
10
+ }>, unknown> & {
11
+ overtime: import("@svadmin/core").OvertimeResult;
12
+ };
13
+ readonly rendering: ResourceRendering | undefined;
14
+ readonly resource: import("@svadmin/core").ResourceDefinition;
15
+ readonly fields: import("@svadmin/core").FieldDefinition[];
16
+ readonly canRead: boolean;
17
+ readonly checkingPermission: boolean;
18
+ refresh(): Promise<void>;
19
+ };
@@ -0,0 +1,34 @@
1
+ import { bindResourceRendering } from '../rendering/index.js';
2
+ import { captureAdminContext, useOne, useCan, useResourceContract } from '@svadmin/core';
3
+ /** Views mount this only when they have an explicit record ID. */
4
+ export function useRecordDetail(options) {
5
+ const context = captureAdminContext();
6
+ const binding = useResourceContract(() => options().resourceName);
7
+ const rendering = $derived(bindResourceRendering(options().rendering, binding.resource));
8
+ const resource = $derived(context.getResource(options().resourceName));
9
+ const permission = useCan(() => ({
10
+ resource: options().resourceName, action: 'show', id: options().id,
11
+ queryOptions: { enabled: resource.canShow !== false },
12
+ }));
13
+ const canRead = $derived(resource.canShow !== false && permission.allowed === true);
14
+ const query = useOne(() => {
15
+ void rendering;
16
+ return {
17
+ resource: binding.resource, id: options().id, dataProviderName: binding.dataProviderName,
18
+ queryOptions: { enabled: canRead },
19
+ };
20
+ });
21
+ return {
22
+ query,
23
+ get rendering() { return rendering; },
24
+ get resource() { return resource; },
25
+ get fields() { return resource.fields.filter(field => field.showInShow !== false); },
26
+ get canRead() { return canRead; },
27
+ get checkingPermission() { return permission.isLoading; },
28
+ async refresh() {
29
+ if (!canRead || query.isFetching)
30
+ return;
31
+ await query.refetch();
32
+ },
33
+ };
34
+ }
@@ -15,31 +15,31 @@ function isPositiveInteger(value, max) {
15
15
  function parseFilter(value, allowedFieldIds, budget, depth = 0) {
16
16
  if (depth > 20 || budget.remaining-- <= 0 || !isRecord(value))
17
17
  return undefined;
18
- if (typeof value.field === 'string') {
19
- if (!allowedFieldIds.has(value.field) || typeof value.operator !== 'string' || !CRUD_OPERATORS.has(value.operator) || !('value' in value)) {
18
+ if (typeof value['field'] === 'string') {
19
+ if (!allowedFieldIds.has(value['field']) || typeof value['operator'] !== 'string' || !CRUD_OPERATORS.has(value['operator']) || !('value' in value)) {
20
20
  return undefined;
21
21
  }
22
22
  return {
23
- field: value.field,
24
- operator: value.operator,
25
- value: value.value,
23
+ field: value['field'],
24
+ operator: value['operator'],
25
+ value: value['value'],
26
26
  };
27
27
  }
28
- if ((value.operator !== 'and' && value.operator !== 'or') || !Array.isArray(value.value))
28
+ if ((value['operator'] !== 'and' && value['operator'] !== 'or') || !Array.isArray(value['value']))
29
29
  return undefined;
30
- const children = value.value.map((entry) => parseFilter(entry, allowedFieldIds, budget, depth + 1));
30
+ const children = value['value'].map((entry) => parseFilter(entry, allowedFieldIds, budget, depth + 1));
31
31
  if (children.some((entry) => entry === undefined))
32
32
  return undefined;
33
- return { operator: value.operator, value: children };
33
+ return { operator: value['operator'], value: children };
34
34
  }
35
35
  function parseSorters(value, allowedFieldIds) {
36
36
  const sorters = [];
37
37
  for (const sorter of value) {
38
- if (!isRecord(sorter) || typeof sorter.field !== 'string' || !allowedFieldIds.has(sorter.field))
38
+ if (!isRecord(sorter) || typeof sorter['field'] !== 'string' || !allowedFieldIds.has(sorter['field']))
39
39
  return undefined;
40
- if (sorter.order !== 'asc' && sorter.order !== 'desc')
40
+ if (sorter['order'] !== 'asc' && sorter['order'] !== 'desc')
41
41
  return undefined;
42
- sorters.push({ field: sorter.field, order: sorter.order });
42
+ sorters.push({ field: sorter['field'], order: sorter['order'] });
43
43
  }
44
44
  return sorters;
45
45
  }
@@ -62,30 +62,30 @@ function parseColumnOrder(value, allowedColumnIds) {
62
62
  function parseState(value, allowedColumnIds) {
63
63
  if (!isRecord(value))
64
64
  return undefined;
65
- if (typeof value.search !== 'string' || value.search.length > 1_000)
65
+ if (typeof value['search'] !== 'string' || value['search'].length > 1_000)
66
66
  return undefined;
67
- if (!Array.isArray(value.filters) || !Array.isArray(value.sorters))
67
+ if (!Array.isArray(value['filters']) || !Array.isArray(value['sorters']))
68
68
  return undefined;
69
- if (!isRecord(value.pagination) || !isPositiveInteger(value.pagination.current, 1_000_000) || !isPositiveInteger(value.pagination.pageSize, 1_000)) {
69
+ if (!isRecord(value['pagination']) || !isPositiveInteger(value['pagination']['current'], 1_000_000) || !isPositiveInteger(value['pagination']['pageSize'], 1_000)) {
70
70
  return undefined;
71
71
  }
72
72
  const allowedFieldIds = new Set([...allowedColumnIds].filter((columnId) => !columnId.startsWith('_')));
73
73
  const filterBudget = { remaining: MAX_FILTER_NODES };
74
- const filters = value.filters.map((entry) => parseFilter(entry, allowedFieldIds, filterBudget));
74
+ const filters = value['filters'].map((entry) => parseFilter(entry, allowedFieldIds, filterBudget));
75
75
  if (filters.some((entry) => entry === undefined))
76
76
  return undefined;
77
- const sorters = parseSorters(value.sorters, allowedFieldIds);
78
- const columnVisibility = parseColumnVisibility(value.columnVisibility, allowedColumnIds);
79
- const columnOrder = parseColumnOrder(value.columnOrder, allowedColumnIds);
77
+ const sorters = parseSorters(value['sorters'], allowedFieldIds);
78
+ const columnVisibility = parseColumnVisibility(value['columnVisibility'], allowedColumnIds);
79
+ const columnOrder = parseColumnOrder(value['columnOrder'], allowedColumnIds);
80
80
  if (!sorters || !columnVisibility || !columnOrder)
81
81
  return undefined;
82
82
  return {
83
- search: value.search,
83
+ search: value['search'],
84
84
  filters: filters,
85
85
  sorters,
86
86
  pagination: {
87
- current: value.pagination.current,
88
- pageSize: value.pagination.pageSize,
87
+ current: value['pagination']['current'],
88
+ pageSize: value['pagination']['pageSize'],
89
89
  },
90
90
  columnVisibility,
91
91
  columnOrder,
@@ -96,22 +96,22 @@ export function readSavedListViews(raw, allowedColumnIds) {
96
96
  return [];
97
97
  try {
98
98
  const parsed = JSON.parse(raw);
99
- if (!isRecord(parsed) || parsed.version !== STORAGE_VERSION || !Array.isArray(parsed.views))
99
+ if (!isRecord(parsed) || parsed['version'] !== STORAGE_VERSION || !Array.isArray(parsed['views']))
100
100
  return [];
101
101
  const views = [];
102
102
  const seenIds = new Set();
103
- for (const entry of parsed.views.slice(0, MAX_SAVED_VIEWS)) {
104
- if (!isRecord(entry) || typeof entry.id !== 'string' || !entry.id.trim() || entry.id.length > 120)
103
+ for (const entry of parsed['views'].slice(0, MAX_SAVED_VIEWS)) {
104
+ if (!isRecord(entry) || typeof entry['id'] !== 'string' || !entry['id'].trim() || entry['id'].length > 120)
105
105
  continue;
106
- if (seenIds.has(entry.id))
106
+ if (seenIds.has(entry['id']))
107
107
  continue;
108
- if (typeof entry.name !== 'string' || !entry.name.trim() || entry.name.length > 60)
108
+ if (typeof entry['name'] !== 'string' || !entry['name'].trim() || entry['name'].length > 60)
109
109
  continue;
110
- const state = parseState(entry.state, allowedColumnIds);
110
+ const state = parseState(entry['state'], allowedColumnIds);
111
111
  if (!state)
112
112
  continue;
113
- seenIds.add(entry.id);
114
- views.push({ id: entry.id, name: entry.name.trim(), state });
113
+ seenIds.add(entry['id']);
114
+ views.push({ id: entry['id'], name: entry['name'].trim(), state });
115
115
  }
116
116
  return views;
117
117
  }
@@ -0,0 +1,14 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { SvarRecordId } from './svar-grid-operations.js';
3
+ export interface SvarCellContent {
4
+ readonly id: SvarRecordId;
5
+ readonly field: string;
6
+ readonly value: unknown;
7
+ readonly record: Record<string, unknown>;
8
+ }
9
+ export interface SvarCellContext {
10
+ readonly render: () => Snippet<[SvarCellContent]> | undefined;
11
+ readonly resolve: (row: unknown, column: unknown) => SvarCellContent | undefined;
12
+ }
13
+ /** 仅可信宿主可提供原生 snippet;不把引擎 api 或 exec 传给内容组件。 */
14
+ export declare const SVAR_CELL_CONTEXT: unique symbol;
@@ -0,0 +1,2 @@
1
+ /** 仅可信宿主可提供原生 snippet;不把引擎 api 或 exec 传给内容组件。 */
2
+ export const SVAR_CELL_CONTEXT = Symbol('svadmin.svar.cell');
@@ -0,0 +1,80 @@
1
+ /** SVAR 2.7 的窄适配契约。应用注入 Grid,未启用的页面无需安装或加载 SVAR。 */
2
+ export interface SvarColumn {
3
+ readonly key: string;
4
+ readonly label: string;
5
+ readonly width?: number;
6
+ readonly sortable?: boolean;
7
+ /** 首批内建列过滤只支持文本 contains;其他过滤通过资源 filters 传入。 */
8
+ readonly filterable?: boolean;
9
+ }
10
+ export interface SvarSort {
11
+ readonly field: string;
12
+ readonly order: 'asc' | 'desc';
13
+ }
14
+ export interface SvarTextFilter {
15
+ readonly field: string;
16
+ readonly operator: 'contains';
17
+ readonly value: string;
18
+ }
19
+ export interface SvarRow {
20
+ id: string;
21
+ data?: SvarRow[];
22
+ open?: boolean;
23
+ [key: string]: unknown;
24
+ }
25
+ export interface SvarEngineColumn {
26
+ id: string;
27
+ header: string | (string | {
28
+ filter: 'text';
29
+ })[];
30
+ width?: number;
31
+ flexgrow?: number;
32
+ sort: boolean;
33
+ resize: boolean;
34
+ treetoggle: boolean;
35
+ }
36
+ export interface SvarGridApi {
37
+ intercept(action: string, callback: (event: unknown) => false | undefined): void;
38
+ }
39
+ /** 仅使用已核对的上游属性;不暴露任意 editor、template 或事件执行入口。 */
40
+ export interface SvarGridEngineProps {
41
+ /** 上游声明带事件索引;适配层不直接转发任何事件 prop。 */
42
+ [event: `on${string}`]: never;
43
+ columns: SvarEngineColumn[];
44
+ data?: SvarRow[];
45
+ tree?: boolean;
46
+ split?: {
47
+ left?: number;
48
+ };
49
+ sizes?: {
50
+ rowHeight?: number;
51
+ headerHeight?: number;
52
+ columnWidth?: number;
53
+ };
54
+ sortMarks?: Record<string, {
55
+ order: 'asc' | 'desc';
56
+ index?: number;
57
+ }>;
58
+ filterValues?: Record<string, string>;
59
+ select?: boolean;
60
+ multiselect?: boolean;
61
+ reorder?: boolean;
62
+ draggableRows?: boolean;
63
+ undo?: boolean;
64
+ init?: (api: SvarGridApi) => void;
65
+ }
66
+ export declare function svarColumnId(key: string): string;
67
+ export declare function checkedSvarColumns(columns: readonly SvarColumn[]): SvarColumn[];
68
+ export declare function buildSvarColumns(columns: readonly SvarColumn[], tree: boolean): SvarEngineColumn[];
69
+ export declare function projectSvarRows(items: readonly Record<string, unknown>[], columns: readonly SvarColumn[], primaryKey?: string, childrenKey?: string): SvarRow[];
70
+ export declare function nextSvarSort(event: unknown, columns: readonly SvarColumn[], current: readonly SvarSort[]): SvarSort[] | undefined;
71
+ export declare function nextSvarFilter(event: unknown, columns: readonly SvarColumn[], current: readonly SvarTextFilter[]): SvarTextFilter[] | undefined;
72
+ export declare function svarSortMarks(sorters: readonly SvarSort[]): NonNullable<SvarGridEngineProps['sortMarks']>;
73
+ export declare function svarFilterValues(filters: readonly SvarTextFilter[]): Record<string, string>;
74
+ export declare const SVAR_BLOCKED_ACTIONS: readonly ["add-row", "delete-row", "update-row", "update-cell", "copy-row", "move-item", "open-editor", "editor", "undo", "redo", "export-data", "print"];
75
+ export declare function installSvarGuards(api: SvarGridApi, options: {
76
+ current: () => boolean;
77
+ server: () => boolean;
78
+ sort: (event: unknown) => void;
79
+ filter: (event: unknown) => void;
80
+ }): void;
@@ -0,0 +1,159 @@
1
+ const forbidden = new Set(['__proto__', 'prototype', 'constructor']);
2
+ function fieldName(value) {
3
+ return typeof value === 'string' && value.length > 0 && !forbidden.has(value);
4
+ }
5
+ export function svarColumnId(key) {
6
+ return `column:${encodeURIComponent(key)}`;
7
+ }
8
+ export function checkedSvarColumns(columns) {
9
+ if (!Array.isArray(columns) || columns.length === 0)
10
+ throw new Error('At least one grid column is required');
11
+ const ids = new Set();
12
+ return columns.map(column => {
13
+ if (!column || !fieldName(column.key) || typeof column.label !== 'string' || ids.has(column.key)) {
14
+ throw new Error('Invalid or duplicate grid column');
15
+ }
16
+ if (column.width !== undefined && (!Number.isFinite(column.width) || column.width < 40 || column.width > 4096)) {
17
+ throw new Error('Grid column width must be between 40 and 4096');
18
+ }
19
+ ids.add(column.key);
20
+ // 显式投影,拒绝将宿主对象上的 editor/template 等额外属性传入 Grid。
21
+ return {
22
+ key: column.key, label: column.label,
23
+ sortable: column.sortable === true, filterable: column.filterable === true,
24
+ ...(column.width === undefined ? {} : { width: column.width }),
25
+ };
26
+ });
27
+ }
28
+ export function buildSvarColumns(columns, tree) {
29
+ return columns.map((column, index) => ({
30
+ id: svarColumnId(column.key),
31
+ header: column.filterable ? [column.label, { filter: 'text' }] : column.label,
32
+ ...(column.width === undefined ? { flexgrow: 1 } : { width: column.width }),
33
+ sort: column.sortable === true, resize: true, treetoggle: tree && index === 0,
34
+ }));
35
+ }
36
+ function ownValue(record, key) {
37
+ const descriptor = Object.getOwnPropertyDescriptor(record, key);
38
+ if (!descriptor)
39
+ return undefined;
40
+ if (!('value' in descriptor))
41
+ throw new Error('Grid records must not contain accessors');
42
+ return descriptor.value;
43
+ }
44
+ function scalar(value) {
45
+ if (value == null)
46
+ return null;
47
+ if (typeof value === 'string' || typeof value === 'boolean')
48
+ return value;
49
+ if (typeof value === 'number' && Number.isFinite(value))
50
+ return value;
51
+ // 复杂字段需要独立格式化;不隐式调用用户对象的 toString/toJSON。
52
+ return '—';
53
+ }
54
+ export function projectSvarRows(items, columns, primaryKey = 'id', childrenKey) {
55
+ if (!Array.isArray(items) || !fieldName(primaryKey) || (childrenKey !== undefined && !fieldName(childrenKey))) {
56
+ throw new Error('Invalid grid data configuration');
57
+ }
58
+ const ids = new Set();
59
+ const ancestors = new Set();
60
+ function visit(rows, depth) {
61
+ if (depth > 64)
62
+ throw new Error('Grid tree is too deep');
63
+ return rows.map(record => {
64
+ if (!record || typeof record !== 'object' || Array.isArray(record) || ancestors.has(record)) {
65
+ throw new Error('Invalid or cyclic grid record');
66
+ }
67
+ const id = ownValue(record, primaryKey);
68
+ if (!(typeof id === 'string' && id.length > 0) && !(typeof id === 'number' && Number.isFinite(id))) {
69
+ throw new Error('Every grid record requires a stable string or finite number ID');
70
+ }
71
+ // SVAR 内部 ID 使用字符串;防止数字 1 与字符串 "1" 相互覆盖。
72
+ const key = `${typeof id === 'number' ? 'n' : 's'}:${id}`;
73
+ if (ids.has(key))
74
+ throw new Error('Duplicate grid record ID');
75
+ ids.add(key);
76
+ const row = { id: key };
77
+ for (const column of columns)
78
+ row[svarColumnId(column.key)] = scalar(ownValue(record, column.key));
79
+ if (childrenKey !== undefined) {
80
+ const children = ownValue(record, childrenKey);
81
+ if (children !== undefined && !Array.isArray(children))
82
+ throw new Error('Grid children must be an array');
83
+ if (Array.isArray(children) && children.length) {
84
+ ancestors.add(record);
85
+ row.data = visit(children, depth + 1);
86
+ ancestors.delete(record);
87
+ row.open = false;
88
+ }
89
+ }
90
+ return row;
91
+ });
92
+ }
93
+ return visit(items, 0);
94
+ }
95
+ function eventRecord(value) {
96
+ return value && typeof value === 'object' && !Array.isArray(value) ? value : undefined;
97
+ }
98
+ export function nextSvarSort(event, columns, current) {
99
+ const value = eventRecord(event);
100
+ if (!value || (value['order'] !== undefined && value['order'] !== 'asc' && value['order'] !== 'desc')
101
+ || (value['add'] !== undefined && typeof value['add'] !== 'boolean'))
102
+ return undefined;
103
+ const column = columns.find(column => svarColumnId(column.key) === value['key'] && column.sortable);
104
+ if (!column)
105
+ return undefined;
106
+ const existing = current.find(sort => sort.field === column.key);
107
+ const order = value['order'] ?? (existing?.order === 'asc' ? 'desc' : 'asc');
108
+ const next = value['add'] ? current.map(sort => ({ ...sort })) : [];
109
+ const index = next.findIndex(sort => sort.field === column.key);
110
+ const sort = { field: column.key, order };
111
+ if (index < 0)
112
+ next.push(sort);
113
+ else
114
+ next[index] = sort;
115
+ return next;
116
+ }
117
+ export function nextSvarFilter(event, columns, current) {
118
+ const value = eventRecord(event);
119
+ if (!value || (value['value'] != null && typeof value['value'] !== 'string'))
120
+ return undefined;
121
+ const column = columns.find(column => svarColumnId(column.key) === value['key'] && column.filterable);
122
+ if (!column)
123
+ return undefined;
124
+ const next = current.filter(filter => filter.field !== column.key).map(filter => ({ ...filter }));
125
+ if (typeof value['value'] === 'string' && value['value'] !== '') {
126
+ next.push({ field: column.key, operator: 'contains', value: value['value'] });
127
+ }
128
+ return next;
129
+ }
130
+ export function svarSortMarks(sorters) {
131
+ return Object.fromEntries(sorters.map((sort, index) => [svarColumnId(sort.field), { order: sort.order, index }]));
132
+ }
133
+ export function svarFilterValues(filters) {
134
+ return Object.fromEntries(filters.map(filter => [svarColumnId(filter.field), filter.value]));
135
+ }
136
+ export const SVAR_BLOCKED_ACTIONS = [
137
+ 'add-row', 'delete-row', 'update-row', 'update-cell', 'copy-row', 'move-item',
138
+ 'open-editor', 'editor', 'undo', 'redo', 'export-data', 'print',
139
+ ];
140
+ export function installSvarGuards(api, options) {
141
+ for (const action of SVAR_BLOCKED_ACTIONS)
142
+ api.intercept(action, () => false);
143
+ api.intercept('sort-rows', event => {
144
+ if (!options.current())
145
+ return false;
146
+ if (options.server()) {
147
+ options.sort(event);
148
+ return false;
149
+ }
150
+ });
151
+ api.intercept('filter-rows', event => {
152
+ if (!options.current())
153
+ return false;
154
+ if (options.server()) {
155
+ options.filter(event);
156
+ return false;
157
+ }
158
+ });
159
+ }