@zerodep-dev/vue-tsx-pro-ui 0.2.0 → 0.3.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 (416) hide show
  1. package/dist/base/Badge.js +3 -3
  2. package/dist/base/Badge.js.map +1 -1
  3. package/dist/base/Can.d.ts +12 -0
  4. package/dist/base/Can.js +20 -0
  5. package/dist/base/Can.js.map +1 -0
  6. package/dist/base/ClientOnly.d.ts +10 -0
  7. package/dist/base/ClientOnly.js +18 -0
  8. package/dist/base/ClientOnly.js.map +1 -0
  9. package/dist/base/CloseButton.js +3 -3
  10. package/dist/base/CloseButton.js.map +1 -1
  11. package/dist/base/CodeBlock.js +5 -5
  12. package/dist/base/CodeBlock.js.map +1 -1
  13. package/dist/base/CopyButton.js +3 -3
  14. package/dist/base/CopyButton.js.map +1 -1
  15. package/dist/base/Icon.js +3 -3
  16. package/dist/base/Icon.js.map +1 -1
  17. package/dist/base/Indicator.js +3 -3
  18. package/dist/base/Indicator.js.map +1 -1
  19. package/dist/base/StatusDot.js +3 -3
  20. package/dist/base/StatusDot.js.map +1 -1
  21. package/dist/base/Tag.js +5 -5
  22. package/dist/base/Tag.js.map +1 -1
  23. package/dist/base/button-core.js +4 -4
  24. package/dist/base/button-core.js.map +1 -1
  25. package/dist/charts/AreaChart.js +3 -3
  26. package/dist/charts/AreaChart.js.map +1 -1
  27. package/dist/charts/BarChart.js +3 -3
  28. package/dist/charts/BarChart.js.map +1 -1
  29. package/dist/charts/ChordChart.js +3 -3
  30. package/dist/charts/ChordChart.js.map +1 -1
  31. package/dist/charts/ComboChart.js +3 -3
  32. package/dist/charts/ComboChart.js.map +1 -1
  33. package/dist/charts/DonutChart.js +3 -3
  34. package/dist/charts/DonutChart.js.map +1 -1
  35. package/dist/charts/FunnelChart.js +5 -5
  36. package/dist/charts/FunnelChart.js.map +1 -1
  37. package/dist/charts/GraphChart.js +3 -3
  38. package/dist/charts/GraphChart.js.map +1 -1
  39. package/dist/charts/LineChart.js +3 -3
  40. package/dist/charts/LineChart.js.map +1 -1
  41. package/dist/charts/MapChart.js +7 -7
  42. package/dist/charts/MapChart.js.map +1 -1
  43. package/dist/charts/RadarChart.js +16 -15
  44. package/dist/charts/RadarChart.js.map +1 -1
  45. package/dist/charts/SankeyChart.js +3 -3
  46. package/dist/charts/SankeyChart.js.map +1 -1
  47. package/dist/charts/ScatterChart.js +3 -3
  48. package/dist/charts/ScatterChart.js.map +1 -1
  49. package/dist/charts/TimelineChart.js +6 -5
  50. package/dist/charts/TimelineChart.js.map +1 -1
  51. package/dist/charts/TreemapChart.js +3 -3
  52. package/dist/charts/TreemapChart.js.map +1 -1
  53. package/dist/charts/WaterfallChart.js +3 -3
  54. package/dist/charts/WaterfallChart.js.map +1 -1
  55. package/dist/charts/XYChart.js +9 -7
  56. package/dist/charts/XYChart.js.map +1 -1
  57. package/dist/charts/frame.js +10 -8
  58. package/dist/charts/frame.js.map +1 -1
  59. package/dist/charts/single.js +4 -3
  60. package/dist/charts/single.js.map +1 -1
  61. package/dist/config/Provider.d.ts +3 -1
  62. package/dist/config/Provider.js +9 -4
  63. package/dist/config/Provider.js.map +1 -1
  64. package/dist/config/context.d.ts +18 -0
  65. package/dist/config/context.js +16 -1
  66. package/dist/config/context.js.map +1 -1
  67. package/dist/config/createUi.d.ts +20 -3
  68. package/dist/config/createUi.js +80 -49
  69. package/dist/config/createUi.js.map +1 -1
  70. package/dist/config/layout/preference.d.ts +43 -0
  71. package/dist/config/layout/preference.js +108 -0
  72. package/dist/config/layout/preference.js.map +1 -0
  73. package/dist/date/Calendar.js +3 -3
  74. package/dist/date/Calendar.js.map +1 -1
  75. package/dist/date/CalendarBoard.js +9 -9
  76. package/dist/date/CalendarBoard.js.map +1 -1
  77. package/dist/date/CalendarView.js +7 -7
  78. package/dist/date/CalendarView.js.map +1 -1
  79. package/dist/date/DateField.js +3 -3
  80. package/dist/date/DateField.js.map +1 -1
  81. package/dist/date/DatePicker.js +5 -5
  82. package/dist/date/DatePicker.js.map +1 -1
  83. package/dist/date/DateRangePicker.js +5 -5
  84. package/dist/date/DateRangePicker.js.map +1 -1
  85. package/dist/date/DateSegmentGroup.js +5 -5
  86. package/dist/date/DateSegmentGroup.js.map +1 -1
  87. package/dist/date/QuarterCalendar.js +6 -6
  88. package/dist/date/QuarterCalendar.js.map +1 -1
  89. package/dist/date/RangeCalendar.js +3 -3
  90. package/dist/date/RangeCalendar.js.map +1 -1
  91. package/dist/date/SegmentedField.js +3 -3
  92. package/dist/date/SegmentedField.js.map +1 -1
  93. package/dist/date/TimeField.js +3 -3
  94. package/dist/date/TimeField.js.map +1 -1
  95. package/dist/date/TimePicker.js +4 -4
  96. package/dist/date/TimePicker.js.map +1 -1
  97. package/dist/date/date-segments.js +1 -1
  98. package/dist/date/date-segments.js.map +1 -1
  99. package/dist/date/picker-popover.js +3 -2
  100. package/dist/date/picker-popover.js.map +1 -1
  101. package/dist/diagram/Diagram.js +12 -12
  102. package/dist/diagram/Diagram.js.map +1 -1
  103. package/dist/diagram/DiagramLanes.js +3 -3
  104. package/dist/diagram/DiagramLanes.js.map +1 -1
  105. package/dist/diagram/DiagramMinimap.js +4 -4
  106. package/dist/diagram/DiagramMinimap.js.map +1 -1
  107. package/dist/display/Accordion.js +6 -6
  108. package/dist/display/Accordion.js.map +1 -1
  109. package/dist/display/AnimatedNumber.js +4 -4
  110. package/dist/display/AnimatedNumber.js.map +1 -1
  111. package/dist/display/Avatar.js +4 -4
  112. package/dist/display/Avatar.js.map +1 -1
  113. package/dist/display/Checklist.js +7 -7
  114. package/dist/display/Checklist.js.map +1 -1
  115. package/dist/display/Collapse.js +8 -5
  116. package/dist/display/Collapse.js.map +1 -1
  117. package/dist/display/Collapsible.js +3 -3
  118. package/dist/display/Collapsible.js.map +1 -1
  119. package/dist/display/Descriptions.js +5 -5
  120. package/dist/display/Descriptions.js.map +1 -1
  121. package/dist/display/Ellipsis.js +3 -3
  122. package/dist/display/Ellipsis.js.map +1 -1
  123. package/dist/display/FieldCompare.js +4 -4
  124. package/dist/display/FieldCompare.js.map +1 -1
  125. package/dist/display/Gauge.js +11 -11
  126. package/dist/display/Gauge.js.map +1 -1
  127. package/dist/display/Image.js +4 -4
  128. package/dist/display/Image.js.map +1 -1
  129. package/dist/display/Marquee.js +3 -3
  130. package/dist/display/Marquee.js.map +1 -1
  131. package/dist/display/ProportionBar.js +4 -4
  132. package/dist/display/ProportionBar.js.map +1 -1
  133. package/dist/display/Sortable.js +4 -4
  134. package/dist/display/Sortable.js.map +1 -1
  135. package/dist/display/Sparkline.js +6 -6
  136. package/dist/display/Sparkline.js.map +1 -1
  137. package/dist/display/Stat.js +3 -3
  138. package/dist/display/Stat.js.map +1 -1
  139. package/dist/display/Timeline.js +7 -7
  140. package/dist/display/Timeline.js.map +1 -1
  141. package/dist/display/Tree.js +10 -10
  142. package/dist/display/Tree.js.map +1 -1
  143. package/dist/display/VirtualList.js +7 -7
  144. package/dist/display/VirtualList.js.map +1 -1
  145. package/dist/display/Watermark.js +3 -3
  146. package/dist/display/Watermark.js.map +1 -1
  147. package/dist/docs-kit/CodeGroup.js +5 -5
  148. package/dist/docs-kit/CodeGroup.js.map +1 -1
  149. package/dist/docs-kit/CodePreview.js +6 -6
  150. package/dist/docs-kit/CodePreview.js.map +1 -1
  151. package/dist/docs-kit/PropsTable.js +4 -4
  152. package/dist/docs-kit/PropsTable.js.map +1 -1
  153. package/dist/feedback/Alert.js +5 -5
  154. package/dist/feedback/Alert.js.map +1 -1
  155. package/dist/feedback/Banner.js +5 -5
  156. package/dist/feedback/Banner.js.map +1 -1
  157. package/dist/feedback/Empty.js +4 -4
  158. package/dist/feedback/Empty.js.map +1 -1
  159. package/dist/feedback/LoadingBar.js +20 -13
  160. package/dist/feedback/LoadingBar.js.map +1 -1
  161. package/dist/feedback/LoadingOverlay.js +3 -3
  162. package/dist/feedback/LoadingOverlay.js.map +1 -1
  163. package/dist/feedback/Progress.js +14 -14
  164. package/dist/feedback/Progress.js.map +1 -1
  165. package/dist/feedback/Result.js +4 -4
  166. package/dist/feedback/Result.js.map +1 -1
  167. package/dist/feedback/SkeletonText.js +3 -3
  168. package/dist/feedback/SkeletonText.js.map +1 -1
  169. package/dist/feedback/Toast.js +6 -6
  170. package/dist/feedback/Toast.js.map +1 -1
  171. package/dist/form/Field.js +7 -7
  172. package/dist/form/Field.js.map +1 -1
  173. package/dist/form/Form.js +3 -3
  174. package/dist/form/Form.js.map +1 -1
  175. package/dist/form/FormErrorSummary.js +3 -3
  176. package/dist/form/FormErrorSummary.js.map +1 -1
  177. package/dist/form/FormSection.js +6 -6
  178. package/dist/form/FormSection.js.map +1 -1
  179. package/dist/index.d.ts +11 -6
  180. package/dist/index.js +10 -5
  181. package/dist/input/Autocomplete.js +3 -3
  182. package/dist/input/Autocomplete.js.map +1 -1
  183. package/dist/input/Cascader.js +7 -7
  184. package/dist/input/Cascader.js.map +1 -1
  185. package/dist/input/CharacterCount.js +3 -3
  186. package/dist/input/CharacterCount.js.map +1 -1
  187. package/dist/input/Checkbox.js +5 -5
  188. package/dist/input/Checkbox.js.map +1 -1
  189. package/dist/input/ColorField.js +4 -4
  190. package/dist/input/ColorField.js.map +1 -1
  191. package/dist/input/Combobox.js +4 -4
  192. package/dist/input/Combobox.js.map +1 -1
  193. package/dist/input/ConditionBuilder.js +15 -14
  194. package/dist/input/ConditionBuilder.js.map +1 -1
  195. package/dist/input/FileDrop.js +3 -3
  196. package/dist/input/FileDrop.js.map +1 -1
  197. package/dist/input/Listbox.js +9 -9
  198. package/dist/input/Listbox.js.map +1 -1
  199. package/dist/input/Mentions.js +3 -3
  200. package/dist/input/Mentions.js.map +1 -1
  201. package/dist/input/NumberField.js +3 -3
  202. package/dist/input/NumberField.js.map +1 -1
  203. package/dist/input/NumberRangeField.js +5 -5
  204. package/dist/input/NumberRangeField.js.map +1 -1
  205. package/dist/input/OtpField.js +5 -5
  206. package/dist/input/OtpField.js.map +1 -1
  207. package/dist/input/PeoplePicker.js +6 -6
  208. package/dist/input/PeoplePicker.js.map +1 -1
  209. package/dist/input/PeoplePickerPanel.js +4 -4
  210. package/dist/input/PeoplePickerPanel.js.map +1 -1
  211. package/dist/input/Radio.js +4 -4
  212. package/dist/input/Radio.js.map +1 -1
  213. package/dist/input/Rating.js +5 -5
  214. package/dist/input/Rating.js.map +1 -1
  215. package/dist/input/Select.js +4 -4
  216. package/dist/input/Select.js.map +1 -1
  217. package/dist/input/SelectedTags.js +4 -4
  218. package/dist/input/SelectedTags.js.map +1 -1
  219. package/dist/input/Slider.js +6 -6
  220. package/dist/input/Slider.js.map +1 -1
  221. package/dist/input/Switch.js +3 -3
  222. package/dist/input/Switch.js.map +1 -1
  223. package/dist/input/TagsInput.js +5 -5
  224. package/dist/input/TagsInput.js.map +1 -1
  225. package/dist/input/TextField.js +5 -5
  226. package/dist/input/TextField.js.map +1 -1
  227. package/dist/input/Textarea.js +4 -4
  228. package/dist/input/Textarea.js.map +1 -1
  229. package/dist/input/ToggleGroup.js +4 -4
  230. package/dist/input/ToggleGroup.js.map +1 -1
  231. package/dist/input/Transfer.js +8 -8
  232. package/dist/input/Transfer.js.map +1 -1
  233. package/dist/input/TreeSelect.js +6 -6
  234. package/dist/input/TreeSelect.js.map +1 -1
  235. package/dist/input/Upload.js +8 -8
  236. package/dist/input/Upload.js.map +1 -1
  237. package/dist/layout/Affix.js +4 -4
  238. package/dist/layout/Affix.js.map +1 -1
  239. package/dist/layout/ResizeHandle.d.ts +6 -2
  240. package/dist/layout/ResizeHandle.js +32 -9
  241. package/dist/layout/ResizeHandle.js.map +1 -1
  242. package/dist/layout/ScrollArea.js +3 -3
  243. package/dist/layout/ScrollArea.js.map +1 -1
  244. package/dist/layout/Separator.js +3 -3
  245. package/dist/layout/Separator.js.map +1 -1
  246. package/dist/layout/Splitter.js +3 -3
  247. package/dist/layout/Splitter.js.map +1 -1
  248. package/dist/layout/ViewportFill.d.ts +2 -2
  249. package/dist/layout/ViewportFill.js +4 -4
  250. package/dist/layout/ViewportFill.js.map +1 -1
  251. package/dist/navigation/Breadcrumbs.js +4 -4
  252. package/dist/navigation/Breadcrumbs.js.map +1 -1
  253. package/dist/navigation/NavBar.js +6 -6
  254. package/dist/navigation/NavBar.js.map +1 -1
  255. package/dist/navigation/NavList.d.ts +1 -0
  256. package/dist/navigation/NavList.js +20 -12
  257. package/dist/navigation/NavList.js.map +1 -1
  258. package/dist/navigation/NavMenu.d.ts +27 -0
  259. package/dist/navigation/NavMenu.js +54 -0
  260. package/dist/navigation/NavMenu.js.map +1 -0
  261. package/dist/navigation/PageJump.js +3 -3
  262. package/dist/navigation/PageJump.js.map +1 -1
  263. package/dist/navigation/PageSizeSelect.js +4 -4
  264. package/dist/navigation/PageSizeSelect.js.map +1 -1
  265. package/dist/navigation/Pagination.js +6 -6
  266. package/dist/navigation/Pagination.js.map +1 -1
  267. package/dist/navigation/PaginationBar.js +5 -5
  268. package/dist/navigation/PaginationBar.js.map +1 -1
  269. package/dist/navigation/Steps.js +4 -4
  270. package/dist/navigation/Steps.js.map +1 -1
  271. package/dist/navigation/TableOfContents.js +5 -5
  272. package/dist/navigation/TableOfContents.js.map +1 -1
  273. package/dist/navigation/Tabs.js +7 -7
  274. package/dist/navigation/Tabs.js.map +1 -1
  275. package/dist/navigation/Toolbar.js +3 -3
  276. package/dist/navigation/Toolbar.js.map +1 -1
  277. package/dist/overlay/AlertDialog.js +4 -4
  278. package/dist/overlay/AlertDialog.js.map +1 -1
  279. package/dist/overlay/CommandPalette.js +4 -4
  280. package/dist/overlay/CommandPalette.js.map +1 -1
  281. package/dist/overlay/ContextMenu.js +3 -3
  282. package/dist/overlay/ContextMenu.js.map +1 -1
  283. package/dist/overlay/Dialog.js +4 -4
  284. package/dist/overlay/Dialog.js.map +1 -1
  285. package/dist/overlay/Drawer.js +5 -5
  286. package/dist/overlay/Drawer.js.map +1 -1
  287. package/dist/overlay/HoverCard.js +5 -3
  288. package/dist/overlay/HoverCard.js.map +1 -1
  289. package/dist/overlay/Lightbox.js +5 -5
  290. package/dist/overlay/Lightbox.js.map +1 -1
  291. package/dist/overlay/Menu.js +7 -7
  292. package/dist/overlay/Menu.js.map +1 -1
  293. package/dist/overlay/ModalCore.js +9 -9
  294. package/dist/overlay/ModalCore.js.map +1 -1
  295. package/dist/overlay/Popconfirm.js +6 -6
  296. package/dist/overlay/Popconfirm.js.map +1 -1
  297. package/dist/overlay/Popover.js +5 -3
  298. package/dist/overlay/Popover.js.map +1 -1
  299. package/dist/overlay/Tooltip.js +5 -3
  300. package/dist/overlay/Tooltip.js.map +1 -1
  301. package/dist/overlay/Tour.js +8 -8
  302. package/dist/overlay/Tour.js.map +1 -1
  303. package/dist/overlay/detached.d.ts +2 -0
  304. package/dist/overlay/detached.js +73 -42
  305. package/dist/overlay/detached.js.map +1 -1
  306. package/dist/patterns/ActionBar.js +3 -3
  307. package/dist/patterns/ActionBar.js.map +1 -1
  308. package/dist/patterns/AppShell.d.ts +28 -1
  309. package/dist/patterns/AppShell.js +158 -52
  310. package/dist/patterns/AppShell.js.map +1 -1
  311. package/dist/patterns/AuthLayout.d.ts +28 -0
  312. package/dist/patterns/AuthLayout.js +77 -0
  313. package/dist/patterns/AuthLayout.js.map +1 -0
  314. package/dist/patterns/CommentThread.js +9 -9
  315. package/dist/patterns/CommentThread.js.map +1 -1
  316. package/dist/patterns/DataImport.js +4 -4
  317. package/dist/patterns/DataImport.js.map +1 -1
  318. package/dist/patterns/DeadlineBadge.js +3 -3
  319. package/dist/patterns/DeadlineBadge.js.map +1 -1
  320. package/dist/patterns/FilterBar.d.ts +11 -1
  321. package/dist/patterns/FilterBar.js +39 -10
  322. package/dist/patterns/FilterBar.js.map +1 -1
  323. package/dist/patterns/FormDialog.d.ts +18 -0
  324. package/dist/patterns/FormDialog.js +46 -0
  325. package/dist/patterns/FormDialog.js.map +1 -0
  326. package/dist/patterns/KanbanBoard.js +8 -8
  327. package/dist/patterns/KanbanBoard.js.map +1 -1
  328. package/dist/patterns/LayoutSwitcher.d.ts +12 -0
  329. package/dist/patterns/LayoutSwitcher.js +79 -0
  330. package/dist/patterns/LayoutSwitcher.js.map +1 -0
  331. package/dist/patterns/NotificationCenter.js +8 -8
  332. package/dist/patterns/NotificationCenter.js.map +1 -1
  333. package/dist/patterns/PageTabs.d.ts +12 -7
  334. package/dist/patterns/PageTabs.js +41 -29
  335. package/dist/patterns/PageTabs.js.map +1 -1
  336. package/dist/patterns/QueryTable.d.ts +7 -1
  337. package/dist/patterns/QueryTable.js +116 -81
  338. package/dist/patterns/QueryTable.js.map +1 -1
  339. package/dist/patterns/SlideCaptcha.d.ts +80 -0
  340. package/dist/patterns/SlideCaptcha.js +354 -0
  341. package/dist/patterns/SlideCaptcha.js.map +1 -0
  342. package/dist/patterns/StepsForm.js +7 -7
  343. package/dist/patterns/StepsForm.js.map +1 -1
  344. package/dist/patterns/ThemeSwitcher.js +3 -3
  345. package/dist/patterns/ThemeSwitcher.js.map +1 -1
  346. package/dist/patterns/index.d.ts +7 -3
  347. package/dist/patterns/index.js +5 -1
  348. package/dist/patterns/messages.d.ts +37 -1
  349. package/dist/patterns/messages.js +38 -2
  350. package/dist/patterns/messages.js.map +1 -1
  351. package/dist/table/ColumnHeaderActions.js +3 -3
  352. package/dist/table/ColumnHeaderActions.js.map +1 -1
  353. package/dist/table/ColumnResizer.js +3 -3
  354. package/dist/table/ColumnResizer.js.map +1 -1
  355. package/dist/table/ColumnSettings.js +5 -5
  356. package/dist/table/ColumnSettings.js.map +1 -1
  357. package/dist/table/ColumnTable.js +8 -8
  358. package/dist/table/ColumnTable.js.map +1 -1
  359. package/dist/table/DataTable.js +8 -8
  360. package/dist/table/DataTable.js.map +1 -1
  361. package/dist/table/DataTableView.js +21 -21
  362. package/dist/table/DataTableView.js.map +1 -1
  363. package/dist/table/PivotTable.js +3 -3
  364. package/dist/table/PivotTable.js.map +1 -1
  365. package/dist/table/SelectionBar.js +4 -4
  366. package/dist/table/SelectionBar.js.map +1 -1
  367. package/dist/table/TreeDataTable.js +5 -5
  368. package/dist/table/TreeDataTable.js.map +1 -1
  369. package/dist/theme-customize/ThemeCustomizer.js +7 -6
  370. package/dist/theme-customize/ThemeCustomizer.js.map +1 -1
  371. package/dist/theme-customize/ThemeThumbnail.js +3 -3
  372. package/dist/theme-customize/ThemeThumbnail.js.map +1 -1
  373. package/dist/three/background/AuroraBackground.js +3 -3
  374. package/dist/three/background/AuroraBackground.js.map +1 -1
  375. package/dist/three/background/MeshGradient.js +3 -3
  376. package/dist/three/background/MeshGradient.js.map +1 -1
  377. package/dist/three/background/ShaderBackground.js +3 -3
  378. package/dist/three/background/ShaderBackground.js.map +1 -1
  379. package/dist/three/core/EffectSurface.js +3 -3
  380. package/dist/three/core/EffectSurface.js.map +1 -1
  381. package/dist/three/core/ThreeCanvas.js +4 -4
  382. package/dist/three/core/ThreeCanvas.js.map +1 -1
  383. package/dist/three/effects/Confetti.js +3 -3
  384. package/dist/three/effects/Confetti.js.map +1 -1
  385. package/dist/three/effects/ParticleField.js +3 -3
  386. package/dist/three/effects/ParticleField.js.map +1 -1
  387. package/dist/three/effects/WaveGrid.js +3 -3
  388. package/dist/three/effects/WaveGrid.js.map +1 -1
  389. package/dist/three/globe/Globe.js +3 -3
  390. package/dist/three/globe/Globe.js.map +1 -1
  391. package/dist/three/model/ModelViewer.js +3 -3
  392. package/dist/three/model/ModelViewer.js.map +1 -1
  393. package/dist/utils/data/number.d.ts +5 -0
  394. package/dist/utils/data/number.js +8 -1
  395. package/dist/utils/data/number.js.map +1 -1
  396. package/dist/utils/dom/element.d.ts +3 -1
  397. package/dist/utils/dom/element.js +8 -4
  398. package/dist/utils/dom/element.js.map +1 -1
  399. package/dist/utils/dom/fullscreen.d.ts +1 -1
  400. package/dist/utils/dom/fullscreen.js +12 -8
  401. package/dist/utils/dom/fullscreen.js.map +1 -1
  402. package/dist/utils/dom/mounted.d.ts +7 -0
  403. package/dist/utils/dom/mounted.js +16 -0
  404. package/dist/utils/dom/mounted.js.map +1 -0
  405. package/dist/utils/dom/overflow.js +2 -1
  406. package/dist/utils/dom/overflow.js.map +1 -1
  407. package/dist/utils/dom/pan-zoom.js +2 -1
  408. package/dist/utils/dom/pan-zoom.js.map +1 -1
  409. package/dist/utils/props.js +3 -13
  410. package/dist/utils/props.js.map +1 -1
  411. package/dist/utils/request/http.d.ts +12 -0
  412. package/dist/utils/request/http.js +6 -2
  413. package/dist/utils/request/http.js.map +1 -1
  414. package/dist/utils/request/use-request.js +4 -2
  415. package/dist/utils/request/use-request.js.map +1 -1
  416. package/package.json +2 -2
@@ -0,0 +1,354 @@
1
+ import { mergeAttrs } from "../utils/props.js";
2
+ import { Icon } from "../base/Icon.js";
3
+ import { VisuallyHidden } from "../base/VisuallyHidden.js";
4
+ import { Spinner } from "../base/Spinner.js";
5
+ import { IconButton } from "../base/IconButton.js";
6
+ import { useMessages } from "../config/lang/messages.js";
7
+ import { patternsMessages } from "./messages.js";
8
+ import { Fragment, createVNode, ref, shallowRef, watch } from "vue";
9
+ import { _component, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
10
+ import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
11
+ import { Check, ChevronsRight, RefreshCw, X } from "@lucide/icons";
12
+ //#region src/patterns/SlideCaptcha.tsx
13
+ /**
14
+ * 拼图滑块验证:画面是服务端生成的背景图(有一个缺口)和一块拼图,拖动下面的滑块让拼图对准缺口,松手后把位置和拖动轨迹
15
+ * 交给服务端判定。组件只负责交互,不判对错:答案在服务端,每次给一张新图。
16
+ *
17
+ * <SlideCaptcha
18
+ * challenge={challenge} // 服务端给的图;还没拿到时为 null
19
+ * status={status} // idle / verifying / success / error,由父级按判定结果设置
20
+ * onRelease={(result) => verify(challenge.id, result)}
21
+ * onRefresh={loadChallenge}
22
+ * />
23
+ *
24
+ * - `challenge`:background、piece 是图片地址(data URL 或普通地址),width、height 是背景图的像素尺寸,pieceWidth 是拼图图片的宽度;
25
+ * 拼图图片和背景一样高,左边缘就是缺口的左边缘,所以位置换算成像素直接就是答案。
26
+ * - `onRelease` 交出 { x, track, duration }:x 是拼图左边缘在背景图里的像素位置,track 是(毫秒,位置)序列,
27
+ * 真人拖动有加减速和抖动,服务端据此区分脚本。
28
+ * - `status` 由父级控制:verifying 时不能拖,success 时锁定,error 时滑块晃一下;父级换了新的 challenge 或设回 idle 时滑块回到起点。
29
+ * - 键盘:聚焦滑块后 ←/→ 微调、Home/End、Enter 或空格松手。这类验证对读屏和运动障碍的用户不友好,应用应当另外提供别的方式。
30
+ */
31
+ /** 服务端给的一张拼图 */
32
+ /** 松手时交给服务端的内容 */
33
+ /** 验证码的状态:idle 可以拖,verifying 等服务端判定,success 通过,error 没对准 */
34
+ /** 未声明的属性落到外层 div 上 */
35
+ /** 键盘每次移动的距离(px) */
36
+ var KEY_STEP = 2;
37
+ /** 轨迹最多记多少个点,太长的拖动只留一部分 */
38
+ var MAX_POINTS = 240;
39
+ /** 滑块的宽度,也是滑块条的高度 */
40
+ var HANDLE = "2.75rem";
41
+ /** 松手回到起点时的过渡:带一点回弹 */
42
+ var SETTLE = "0.28s cubic-bezier(0.34, 1.4, 0.64, 1)";
43
+ /** SlideCaptcha 的样式:root、picture、image、piece、banner、track、fill、handle 等 */
44
+ var slideCaptchaStyles = css.create({
45
+ root: {
46
+ display: "flex",
47
+ flexDirection: "column",
48
+ gap: "_sm",
49
+ width: "_full",
50
+ userSelect: "none"
51
+ },
52
+ picture: {
53
+ position: "relative",
54
+ boxSizing: "border-box",
55
+ width: "_full",
56
+ overflow: "hidden",
57
+ borderRadius: "_md",
58
+ borderWidth: "_xs",
59
+ borderStyle: "solid",
60
+ borderColor: "_border",
61
+ backgroundColor: "_fill"
62
+ },
63
+ image: {
64
+ display: "block",
65
+ width: "_full",
66
+ height: "_full",
67
+ objectFit: "cover",
68
+ pointerEvents: "none",
69
+ userSelect: "none"
70
+ },
71
+ piece: {
72
+ position: "absolute",
73
+ top: 0,
74
+ height: "_full",
75
+ pointerEvents: "none",
76
+ filter: "drop-shadow(0 2px 6px rgb(0 0 0 / 0.45))"
77
+ },
78
+ pieceSettle: { transition: `left ${SETTLE}` },
79
+ refresh: {
80
+ position: "absolute",
81
+ top: "_xs",
82
+ insetInlineEnd: "_xs"
83
+ },
84
+ banner: {
85
+ position: "absolute",
86
+ insetInline: 0,
87
+ bottom: 0,
88
+ paddingBlock: "_xs",
89
+ paddingInline: "_md",
90
+ fontSize: "_sm",
91
+ textAlign: "center",
92
+ color: "white"
93
+ },
94
+ bannerSuccess: { backgroundColor: "rgb(22 163 74 / 0.88)" },
95
+ bannerError: { backgroundColor: "rgb(220 38 38 / 0.88)" },
96
+ loading: {
97
+ display: "flex",
98
+ alignItems: "center",
99
+ justifyContent: "center",
100
+ gap: "_sm",
101
+ height: "_full",
102
+ color: "_textMuted",
103
+ fontSize: "_sm"
104
+ },
105
+ track: {
106
+ position: "relative",
107
+ boxSizing: "border-box",
108
+ height: HANDLE,
109
+ overflow: "hidden",
110
+ borderRadius: "_md",
111
+ borderWidth: "_xs",
112
+ borderStyle: "solid",
113
+ borderColor: "_border",
114
+ backgroundColor: "_fill"
115
+ },
116
+ fill: {
117
+ position: "absolute",
118
+ insetBlock: 0,
119
+ insetInlineStart: 0,
120
+ backgroundColor: "_accentSoft"
121
+ },
122
+ fillSuccess: { backgroundColor: "_successSoft" },
123
+ fillError: { backgroundColor: "_dangerSoft" },
124
+ hint: {
125
+ position: "absolute",
126
+ inset: 0,
127
+ display: "flex",
128
+ alignItems: "center",
129
+ justifyContent: "center",
130
+ paddingInline: HANDLE,
131
+ color: "_textMuted",
132
+ fontSize: "_sm",
133
+ pointerEvents: "none"
134
+ },
135
+ handle: {
136
+ position: "absolute",
137
+ insetBlock: 0,
138
+ boxSizing: "border-box",
139
+ display: "flex",
140
+ alignItems: "center",
141
+ justifyContent: "center",
142
+ width: HANDLE,
143
+ borderRadius: "_md",
144
+ backgroundColor: "_surface",
145
+ boxShadow: "_sm",
146
+ color: "_accentText",
147
+ cursor: "grab",
148
+ touchAction: "none",
149
+ outlineOffset: "-2px"
150
+ },
151
+ handleActive: {
152
+ cursor: "grabbing",
153
+ boxShadow: "_md"
154
+ },
155
+ handleSuccess: { color: "_successText" },
156
+ handleError: { color: "_dangerText" },
157
+ locked: { cursor: "default" },
158
+ settle: { transition: `left ${SETTLE}, width ${SETTLE}` }
159
+ });
160
+ /** SlideCaptcha 的动态样式:位置用百分比,画面和滑块条按容器宽度缩放 */
161
+ var slideCaptchaDynamicStyles = css.create({
162
+ at: (percent) => ({ left: `${percent}%` }),
163
+ pieceWidth: (percent) => ({ width: `${percent}%` }),
164
+ ratio: (aspect) => ({ aspectRatio: String(aspect) }),
165
+ handleAt: (position) => ({ left: `calc(${position} * (100% - ${HANDLE}))` }),
166
+ fillTo: (position) => ({ width: `calc(${position} * (100% - ${HANDLE}) + ${HANDLE})` })
167
+ });
168
+ var clamp01 = (value) => Math.min(1, Math.max(0, value));
169
+ /** 拼图滑块验证:拖动滑块让拼图对准缺口,松手把位置与轨迹交给服务端判定 */
170
+ var SlideCaptcha = /*#__PURE__*/ _component((_props, _ctx) => {
171
+ const _cache = [];
172
+ const challenge = readonlyProp(_props, "challenge");
173
+ const status = readonlyProp(_props, "status", "idle");
174
+ const hint = readonlyProp(_props, "hint");
175
+ const errorText = readonlyProp(_props, "errorText");
176
+ const onRelease = readonlyProp(_props, "onRelease");
177
+ const onRefresh = readonlyProp(_props, "onRefresh");
178
+ const rest = restProps(_props, _ctx, true);
179
+ const messages = useMessages("patterns", patternsMessages);
180
+ let trackElement = shallowRef(null);
181
+ let handleElement = shallowRef(null);
182
+ let position = ref(0);
183
+ let dragging = ref(false);
184
+ let track = [];
185
+ let startedAt = 0;
186
+ const travel = () => challenge.value ? challenge.value.width - challenge.value.pieceWidth : 0;
187
+ const pixels = () => Math.round(position.value * travel());
188
+ const interactive = () => challenge.value !== null && status.value === "idle";
189
+ function record() {
190
+ if (!track.length) startedAt = performance.now();
191
+ if (track.length < MAX_POINTS) track.push({
192
+ t: Math.round(performance.now() - startedAt),
193
+ x: pixels()
194
+ });
195
+ }
196
+ function release() {
197
+ if (!track.length) return;
198
+ const result = {
199
+ x: pixels(),
200
+ track,
201
+ duration: Math.round(performance.now() - startedAt)
202
+ };
203
+ track = [];
204
+ onRelease.value?.(result);
205
+ }
206
+ function grab(event) {
207
+ if (!interactive() || !trackElement.value || !handleElement.value) return;
208
+ event.preventDefault();
209
+ handleElement.value.focus();
210
+ handleElement.value.setPointerCapture(event.pointerId);
211
+ const room = trackElement.value.clientWidth - handleElement.value.offsetWidth;
212
+ const startX = event.clientX;
213
+ const startPosition = position.value;
214
+ track = [];
215
+ record();
216
+ dragging.value = true;
217
+ const move = (next) => {
218
+ position.value = clamp01(startPosition + (next.clientX - startX) / Math.max(room, 1));
219
+ record();
220
+ };
221
+ const end = (next) => {
222
+ handleElement.value?.removeEventListener("pointermove", move);
223
+ handleElement.value?.removeEventListener("pointerup", end);
224
+ handleElement.value?.removeEventListener("pointercancel", end);
225
+ handleElement.value?.releasePointerCapture(next.pointerId);
226
+ dragging.value = false;
227
+ if (next.type === "pointercancel") {
228
+ position.value = 0;
229
+ track = [];
230
+ } else release();
231
+ };
232
+ handleElement.value.addEventListener("pointermove", move);
233
+ handleElement.value.addEventListener("pointerup", end);
234
+ handleElement.value.addEventListener("pointercancel", end);
235
+ }
236
+ function onKeydown(event) {
237
+ if (!interactive()) return;
238
+ const step = KEY_STEP / Math.max(travel(), 1);
239
+ const isRtl = !!trackElement.value && getComputedStyle(trackElement.value).direction === "rtl";
240
+ const forward = isRtl ? "ArrowLeft" : "ArrowRight";
241
+ const backward = isRtl ? "ArrowRight" : "ArrowLeft";
242
+ if (event.key === "Enter" || event.key === " ") {
243
+ event.preventDefault();
244
+ release();
245
+ return;
246
+ }
247
+ const next = event.key === forward ? clamp01(position.value + step) : event.key === backward ? clamp01(position.value - step) : event.key === "Home" ? 0 : event.key === "End" ? 1 : null;
248
+ if (next === null) return;
249
+ event.preventDefault();
250
+ position.value = next;
251
+ record();
252
+ }
253
+ watch(() => challenge.value?.id, () => {
254
+ position.value = 0;
255
+ track = [];
256
+ });
257
+ watch(() => status.value, (next, previous) => {
258
+ if (next === "idle" && previous !== "idle") {
259
+ position.value = 0;
260
+ track = [];
261
+ }
262
+ if (next === "error" && handleElement.value && !matchMedia("(prefers-reduced-motion: reduce)").matches) handleElement.value.animate([
263
+ { translate: "0" },
264
+ { translate: "-6px" },
265
+ { translate: "6px" },
266
+ { translate: "-4px" },
267
+ { translate: "4px" },
268
+ { translate: "0" }
269
+ ], { duration: 360 });
270
+ });
271
+ return () => {
272
+ const locked = !interactive();
273
+ const settling = !dragging.value;
274
+ const text = status.value === "verifying" ? messages.slideVerifying : status.value === "success" ? messages.slideSuccess : status.value === "error" ? errorText.value ?? messages.slideError : hint.value ?? messages.slideHint;
275
+ const icon = status.value === "success" ? Check : status.value === "error" ? X : ChevronsRight;
276
+ const piecePercent = challenge.value ? position.value * travel() / challenge.value.width * 100 : 0;
277
+ const pieceWidthPercent = challenge.value ? challenge.value.pieceWidth / challenge.value.width * 100 : 0;
278
+ const aspect = challenge.value ? challenge.value.width / challenge.value.height : 2;
279
+ return createVNode("div", mergeJsxProps(mergeAttrs({ sx: slideCaptchaStyles.root }, rest), { "aria-busy": status.value === "verifying" || void 0 }), [
280
+ createVNode("div", mergeAttrs({ sx: [slideCaptchaStyles.picture, css.bind(slideCaptchaDynamicStyles.ratio, () => [aspect])] }), [
281
+ challenge.value ? createVNode(Fragment, null, [createVNode("img", mergeJsxProps(mergeAttrs({ sx: slideCaptchaStyles.image }), {
282
+ "src": challenge.value.background,
283
+ "alt": "",
284
+ "draggable": false
285
+ }), null), createVNode("img", mergeJsxProps(mergeAttrs({ sx: [
286
+ slideCaptchaStyles.piece,
287
+ css.bind(slideCaptchaDynamicStyles.pieceWidth, () => [pieceWidthPercent]),
288
+ css.bind(slideCaptchaDynamicStyles.at, () => [piecePercent]),
289
+ settling && slideCaptchaStyles.pieceSettle
290
+ ] }), {
291
+ "src": challenge.value.piece,
292
+ "alt": "",
293
+ "draggable": false
294
+ }), null)]) : createVNode("div", mergeAttrs({ sx: slideCaptchaStyles.loading }), [createVNode(Spinner, null, null), messages.slideLoading]),
295
+ createVNode(IconButton, {
296
+ "sx": slideCaptchaStyles.refresh,
297
+ "icon": RefreshCw,
298
+ "size": "sm",
299
+ "variant": "ghost",
300
+ "tone": "neutral",
301
+ "aria-label": messages.slideRefresh,
302
+ "disabled": status.value === "verifying",
303
+ "onClick": _cache[0] || (_cache[0] = () => onRefresh.value?.())
304
+ }, null),
305
+ (status.value === "success" || status.value === "error") && createVNode("div", mergeAttrs({ sx: [slideCaptchaStyles.banner, status.value === "success" ? slideCaptchaStyles.bannerSuccess : slideCaptchaStyles.bannerError] }), [text])
306
+ ]),
307
+ createVNode("div", mergeAttrs({ sx: slideCaptchaStyles.track }, void 0, { ref: trackElement }), [
308
+ createVNode("div", mergeAttrs({ sx: [
309
+ slideCaptchaStyles.fill,
310
+ status.value === "success" && slideCaptchaStyles.fillSuccess,
311
+ status.value === "error" && slideCaptchaStyles.fillError,
312
+ settling && slideCaptchaStyles.settle,
313
+ css.bind(slideCaptchaDynamicStyles.fillTo, () => [position.value], true)
314
+ ] }), null),
315
+ createVNode("span", mergeJsxProps(mergeAttrs({ sx: slideCaptchaStyles.hint }), { "aria-hidden": "true" }), [position.value === 0 || status.value !== "idle" ? text : null]),
316
+ createVNode("div", mergeJsxProps(mergeAttrs({ sx: [
317
+ slideCaptchaStyles.handle,
318
+ dragging.value && slideCaptchaStyles.handleActive,
319
+ status.value === "success" && slideCaptchaStyles.handleSuccess,
320
+ status.value === "error" && slideCaptchaStyles.handleError,
321
+ locked && slideCaptchaStyles.locked,
322
+ settling && slideCaptchaStyles.settle,
323
+ css.bind(slideCaptchaDynamicStyles.handleAt, () => [position.value], true)
324
+ ] }, void 0, { ref: handleElement }), {
325
+ "role": "slider",
326
+ "aria-label": messages.slideLabel,
327
+ "aria-valuemin": 0,
328
+ "aria-valuemax": travel(),
329
+ "aria-valuenow": pixels(),
330
+ "aria-valuetext": messages.slidePosition(pixels()),
331
+ "aria-disabled": locked || void 0,
332
+ "tabindex": locked ? -1 : 0,
333
+ "onPointerdown": grab,
334
+ "onKeydown": onKeydown
335
+ }), [createVNode(Icon, { "icon": icon }, null)])
336
+ ]),
337
+ createVNode(VisuallyHidden, { "aria-live": "polite" }, { default: () => [status.value === "idle" ? "" : text] })
338
+ ]);
339
+ };
340
+ }, {
341
+ name: "SlideCaptcha",
342
+ props: [
343
+ "challenge",
344
+ "status",
345
+ "hint",
346
+ "errorText",
347
+ "onRelease",
348
+ "onRefresh"
349
+ ]
350
+ });
351
+ //#endregion
352
+ export { SlideCaptcha, slideCaptchaDynamicStyles, slideCaptchaStyles };
353
+
354
+ //# sourceMappingURL=SlideCaptcha.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SlideCaptcha.js","names":["_vtp_readonlyProp","_vtp_restProps","_vue_shallowRef","_vue_ref","_createVNode","_mergeProps","_Fragment"],"sources":["../../src/patterns/SlideCaptcha.tsx"],"sourcesContent":["/**\n * 拼图滑块验证:画面是服务端生成的背景图(有一个缺口)和一块拼图,拖动下面的滑块让拼图对准缺口,松手后把位置和拖动轨迹\n * 交给服务端判定。组件只负责交互,不判对错:答案在服务端,每次给一张新图。\n *\n * <SlideCaptcha\n * challenge={challenge} // 服务端给的图;还没拿到时为 null\n * status={status} // idle / verifying / success / error,由父级按判定结果设置\n * onRelease={(result) => verify(challenge.id, result)}\n * onRefresh={loadChallenge}\n * />\n *\n * - `challenge`:background、piece 是图片地址(data URL 或普通地址),width、height 是背景图的像素尺寸,pieceWidth 是拼图图片的宽度;\n * 拼图图片和背景一样高,左边缘就是缺口的左边缘,所以位置换算成像素直接就是答案。\n * - `onRelease` 交出 { x, track, duration }:x 是拼图左边缘在背景图里的像素位置,track 是(毫秒,位置)序列,\n * 真人拖动有加减速和抖动,服务端据此区分脚本。\n * - `status` 由父级控制:verifying 时不能拖,success 时锁定,error 时滑块晃一下;父级换了新的 challenge 或设回 idle 时滑块回到起点。\n * - 键盘:聚焦滑块后 ←/→ 微调、Home/End、Enter 或空格松手。这类验证对读屏和运动障碍的用户不友好,应用应当另外提供别的方式。\n */\nimport { Check, ChevronsRight, RefreshCw, X } from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { watch } from 'vue';\nimport { Icon } from '../base/Icon';\nimport { IconButton } from '../base/IconButton';\nimport { Spinner } from '../base/Spinner';\nimport { VisuallyHidden } from '../base/VisuallyHidden';\nimport { useMessages } from '../config/lang/messages';\nimport { mergeAttrs, type PartProps } from '../utils/props';\nimport { patternsMessages } from './messages';\n\n/** 服务端给的一张拼图 */\nexport interface SlideChallenge {\n /** 这一张的标识,换图时变;松手后连同结果一起交给服务端 */\n id: string;\n /** 背景图(带缺口) */\n background: string;\n /** 拼图图片:和背景一样高,左边缘对着缺口的左边缘 */\n piece: string;\n /** 背景图的宽(px) */\n width: number;\n /** 背景图的高(px) */\n height: number;\n /** 拼图图片的宽度(px) */\n pieceWidth: number;\n}\n\n/** 松手时交给服务端的内容 */\nexport interface SlideResult {\n /** 拼图左边缘在背景图里的位置(px,整数) */\n x: number;\n /** 拖动轨迹:距按下的毫秒数,和当时的位置(px) */\n track: { t: number; x: number }[];\n /** 从按下到松手的毫秒数 */\n duration: number;\n}\n\n/** 验证码的状态:idle 可以拖,verifying 等服务端判定,success 通过,error 没对准 */\nexport type SlideStatus = 'idle' | 'verifying' | 'success' | 'error';\n\n/** 未声明的属性落到外层 div 上 */\nexport interface SlideCaptchaProps extends PartProps<'div'> {\n /** 当前的拼图;还没拿到时为 null,显示加载中 */\n challenge: SlideChallenge | null;\n /** 状态,默认 idle */\n status?: SlideStatus;\n /** 滑块条上的提示,默认“向右拖动滑块,让拼图对准缺口” */\n hint?: string;\n /** 没对准时的提示(图片底部和滑块条上),默认“没对准,请再试一次”;服务端给了具体原因时用它 */\n errorText?: string;\n /** 松手:把结果发给服务端判定 */\n onRelease?: (result: SlideResult) => void;\n /** 点了“换一张” */\n onRefresh?: () => void;\n}\n\n/** 键盘每次移动的距离(px) */\nconst KEY_STEP = 2;\n/** 轨迹最多记多少个点,太长的拖动只留一部分 */\nconst MAX_POINTS = 240;\n/** 滑块的宽度,也是滑块条的高度 */\nconst HANDLE = '2.75rem';\n/** 松手回到起点时的过渡:带一点回弹 */\nconst SETTLE = '0.28s cubic-bezier(0.34, 1.4, 0.64, 1)';\n\n/** SlideCaptcha 的样式:root、picture、image、piece、banner、track、fill、handle 等 */\nexport const slideCaptchaStyles = css.create({\n root: {\n display: 'flex',\n flexDirection: 'column',\n gap: '_sm',\n width: '_full',\n userSelect: 'none',\n },\n picture: {\n position: 'relative',\n boxSizing: 'border-box',\n width: '_full',\n overflow: 'hidden',\n borderRadius: '_md',\n borderWidth: '_xs',\n borderStyle: 'solid',\n borderColor: '_border',\n backgroundColor: '_fill',\n },\n image: {\n display: 'block',\n width: '_full',\n height: '_full',\n objectFit: 'cover',\n pointerEvents: 'none',\n userSelect: 'none',\n },\n piece: {\n position: 'absolute',\n top: 0,\n height: '_full',\n pointerEvents: 'none',\n filter: 'drop-shadow(0 2px 6px rgb(0 0 0 / 0.45))',\n },\n pieceSettle: { transition: `left ${SETTLE}` },\n refresh: { position: 'absolute', top: '_xs', insetInlineEnd: '_xs' },\n // 盖在图上的结果条:底色固定为深色半透明,白字在任何背景图上都读得清\n banner: {\n position: 'absolute',\n insetInline: 0,\n bottom: 0,\n paddingBlock: '_xs',\n paddingInline: '_md',\n fontSize: '_sm',\n textAlign: 'center',\n color: 'white',\n },\n bannerSuccess: { backgroundColor: 'rgb(22 163 74 / 0.88)' },\n bannerError: { backgroundColor: 'rgb(220 38 38 / 0.88)' },\n loading: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '_sm',\n height: '_full',\n color: '_textMuted',\n fontSize: '_sm',\n },\n track: {\n position: 'relative',\n boxSizing: 'border-box',\n height: HANDLE,\n overflow: 'hidden',\n borderRadius: '_md',\n borderWidth: '_xs',\n borderStyle: 'solid',\n borderColor: '_border',\n backgroundColor: '_fill',\n },\n fill: {\n position: 'absolute',\n insetBlock: 0,\n insetInlineStart: 0,\n backgroundColor: '_accentSoft',\n },\n fillSuccess: { backgroundColor: '_successSoft' },\n fillError: { backgroundColor: '_dangerSoft' },\n hint: {\n position: 'absolute',\n inset: 0,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n paddingInline: HANDLE,\n color: '_textMuted',\n fontSize: '_sm',\n pointerEvents: 'none',\n },\n handle: {\n position: 'absolute',\n insetBlock: 0,\n boxSizing: 'border-box',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: HANDLE,\n borderRadius: '_md',\n backgroundColor: '_surface',\n boxShadow: '_sm',\n color: '_accentText',\n cursor: 'grab',\n touchAction: 'none',\n outlineOffset: '-2px',\n },\n handleActive: { cursor: 'grabbing', boxShadow: '_md' },\n handleSuccess: { color: '_successText' },\n handleError: { color: '_dangerText' },\n locked: { cursor: 'default' },\n // 松手后回到起点、或键盘微调时有过渡;拖动中跟手,不加过渡\n settle: { transition: `left ${SETTLE}, width ${SETTLE}` },\n});\n\n/** SlideCaptcha 的动态样式:位置用百分比,画面和滑块条按容器宽度缩放 */\nexport const slideCaptchaDynamicStyles = css.create({\n at: (percent: number) => ({ left: `${percent}%` }),\n pieceWidth: (percent: number) => ({ width: `${percent}%` }),\n ratio: (aspect: number) => ({ aspectRatio: String(aspect) }),\n // 滑块在条里的位置:条宽减去滑块宽的部分按比例走\n handleAt: (position: number) => ({ left: `calc(${position} * (100% - ${HANDLE}))` }),\n fillTo: (position: number) => ({ width: `calc(${position} * (100% - ${HANDLE}) + ${HANDLE})` }),\n});\n\nconst clamp01 = (value: number) => Math.min(1, Math.max(0, value));\n\n/** 拼图滑块验证:拖动滑块让拼图对准缺口,松手把位置与轨迹交给服务端判定 */\nexport const SlideCaptcha = _component(\n ({\n challenge,\n status = 'idle',\n hint,\n errorText,\n onRelease,\n onRefresh,\n ...rest\n }: SlideCaptchaProps) => {\n const messages = useMessages('patterns', patternsMessages);\n let trackElement = _state.raw<HTMLElement | null>(null);\n let handleElement = _state.raw<HTMLElement | null>(null);\n // 拼图左边缘的位置占“可移动距离”的比例(0 到 1)\n let position = _state(0);\n let dragging = _state(false);\n let track: SlideResult['track'] = [];\n let startedAt = 0;\n\n const travel = () => (challenge ? challenge.width - challenge.pieceWidth : 0);\n const pixels = () => Math.round(position * travel());\n const interactive = () => challenge !== null && status === 'idle';\n\n function record() {\n if (!track.length) startedAt = performance.now();\n if (track.length < MAX_POINTS) {\n track.push({ t: Math.round(performance.now() - startedAt), x: pixels() });\n }\n }\n\n function release() {\n if (!track.length) return;\n const result: SlideResult = {\n x: pixels(),\n track,\n duration: Math.round(performance.now() - startedAt),\n };\n track = [];\n onRelease?.(result);\n }\n\n function grab(event: PointerEvent) {\n if (!interactive() || !trackElement || !handleElement) return;\n event.preventDefault();\n handleElement.focus();\n handleElement.setPointerCapture(event.pointerId);\n const room = trackElement.clientWidth - handleElement.offsetWidth;\n const startX = event.clientX;\n const startPosition = position;\n track = [];\n record();\n dragging = true;\n const move = (next: PointerEvent) => {\n position = clamp01(startPosition + (next.clientX - startX) / Math.max(room, 1));\n record();\n };\n const end = (next: PointerEvent) => {\n handleElement?.removeEventListener('pointermove', move);\n handleElement?.removeEventListener('pointerup', end);\n handleElement?.removeEventListener('pointercancel', end);\n handleElement?.releasePointerCapture(next.pointerId);\n dragging = false;\n if (next.type === 'pointercancel') {\n position = 0;\n track = [];\n } else {\n release();\n }\n };\n handleElement.addEventListener('pointermove', move);\n handleElement.addEventListener('pointerup', end);\n handleElement.addEventListener('pointercancel', end);\n }\n\n function onKeydown(event: KeyboardEvent) {\n if (!interactive()) return;\n const step = KEY_STEP / Math.max(travel(), 1);\n const isRtl = !!trackElement && getComputedStyle(trackElement).direction === 'rtl';\n const forward = isRtl ? 'ArrowLeft' : 'ArrowRight';\n const backward = isRtl ? 'ArrowRight' : 'ArrowLeft';\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n release();\n return;\n }\n const next =\n event.key === forward\n ? clamp01(position + step)\n : event.key === backward\n ? clamp01(position - step)\n : event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? 1\n : null;\n if (next === null) return;\n event.preventDefault();\n position = next;\n record();\n }\n\n // 换了新图、或父级设回 idle(重试):滑块回到起点;没对准时滑块晃一下\n watch(\n () => challenge?.id,\n () => {\n position = 0;\n track = [];\n },\n );\n watch(\n () => status,\n (next, previous) => {\n if (next === 'idle' && previous !== 'idle') {\n position = 0;\n track = [];\n }\n if (\n next === 'error' &&\n handleElement &&\n !matchMedia('(prefers-reduced-motion: reduce)').matches\n ) {\n handleElement.animate(\n [\n { translate: '0' },\n { translate: '-6px' },\n { translate: '6px' },\n { translate: '-4px' },\n { translate: '4px' },\n { translate: '0' },\n ],\n { duration: 360 },\n );\n }\n },\n );\n\n return () => {\n const locked = !interactive();\n const settling = !dragging;\n const text =\n status === 'verifying'\n ? messages.slideVerifying\n : status === 'success'\n ? messages.slideSuccess\n : status === 'error'\n ? (errorText ?? messages.slideError)\n : (hint ?? messages.slideHint);\n const icon = status === 'success' ? Check : status === 'error' ? X : ChevronsRight;\n const piecePercent = challenge ? ((position * travel()) / challenge.width) * 100 : 0;\n const pieceWidthPercent = challenge ? (challenge.pieceWidth / challenge.width) * 100 : 0;\n const aspect = challenge ? challenge.width / challenge.height : 2;\n return (\n <div\n {...mergeAttrs<'div'>({ sx: slideCaptchaStyles.root }, rest)}\n aria-busy={status === 'verifying' || undefined}\n >\n <div\n {...mergeAttrs<'div'>({\n sx: [slideCaptchaStyles.picture, slideCaptchaDynamicStyles.ratio(aspect)],\n })}\n >\n {challenge ? (\n <>\n <img\n {...mergeAttrs<'img'>({ sx: slideCaptchaStyles.image })}\n src={challenge.background}\n alt=\"\"\n draggable={false}\n />\n <img\n {...mergeAttrs<'img'>({\n sx: [\n slideCaptchaStyles.piece,\n slideCaptchaDynamicStyles.pieceWidth(pieceWidthPercent),\n slideCaptchaDynamicStyles.at(piecePercent),\n settling && slideCaptchaStyles.pieceSettle,\n ],\n })}\n src={challenge.piece}\n alt=\"\"\n draggable={false}\n />\n </>\n ) : (\n <div {...mergeAttrs<'div'>({ sx: slideCaptchaStyles.loading })}>\n <Spinner />\n {messages.slideLoading}\n </div>\n )}\n <IconButton\n sx={slideCaptchaStyles.refresh}\n icon={RefreshCw}\n size=\"sm\"\n variant=\"ghost\"\n tone=\"neutral\"\n aria-label={messages.slideRefresh}\n disabled={status === 'verifying'}\n onClick={() => onRefresh?.()}\n />\n {(status === 'success' || status === 'error') && (\n <div\n {...mergeAttrs<'div'>({\n sx: [\n slideCaptchaStyles.banner,\n status === 'success'\n ? slideCaptchaStyles.bannerSuccess\n : slideCaptchaStyles.bannerError,\n ],\n })}\n >\n {text}\n </div>\n )}\n </div>\n <div\n {...mergeAttrs<'div'>({ sx: slideCaptchaStyles.track }, undefined, {\n ref: _toRef(trackElement),\n })}\n >\n <div\n {...mergeAttrs<'div'>({\n sx: [\n slideCaptchaStyles.fill,\n status === 'success' && slideCaptchaStyles.fillSuccess,\n status === 'error' && slideCaptchaStyles.fillError,\n settling && slideCaptchaStyles.settle,\n slideCaptchaDynamicStyles.fillTo(position),\n ],\n })}\n />\n <span {...mergeAttrs<'span'>({ sx: slideCaptchaStyles.hint })} aria-hidden=\"true\">\n {position === 0 || status !== 'idle' ? text : null}\n </span>\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n slideCaptchaStyles.handle,\n dragging && slideCaptchaStyles.handleActive,\n status === 'success' && slideCaptchaStyles.handleSuccess,\n status === 'error' && slideCaptchaStyles.handleError,\n locked && slideCaptchaStyles.locked,\n settling && slideCaptchaStyles.settle,\n slideCaptchaDynamicStyles.handleAt(position),\n ],\n },\n undefined,\n { ref: _toRef(handleElement) },\n )}\n role=\"slider\"\n aria-label={messages.slideLabel}\n aria-valuemin={0}\n aria-valuemax={travel()}\n aria-valuenow={pixels()}\n aria-valuetext={messages.slidePosition(pixels())}\n aria-disabled={locked || undefined}\n tabindex={locked ? -1 : 0}\n onPointerdown={grab}\n onKeydown={onKeydown}\n >\n <Icon icon={icon} />\n </div>\n </div>\n <VisuallyHidden aria-live=\"polite\">{status === 'idle' ? '' : text}</VisuallyHidden>\n </div>\n );\n };\n },\n);\n"],"mappings":"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"}
@@ -5,8 +5,8 @@ import { Form } from "../form/Form.js";
5
5
  import { Steps } from "../navigation/Steps.js";
6
6
  import { useMessages } from "../config/lang/messages.js";
7
7
  import { patternsMessages } from "./messages.js";
8
- import { createVNode, mergeProps, nextTick, shallowRef, useId } from "vue";
9
- import { _component, bindable, effect, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
8
+ import { createVNode, nextTick, shallowRef, useId } from "vue";
9
+ import { _component, bindable, effect, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
10
10
  import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
11
11
  //#region src/patterns/StepsForm.tsx
12
12
  /** 一步 */
@@ -69,8 +69,8 @@ var StepsForm = /*#__PURE__*/ _component((_props, _ctx) => {
69
69
  return () => {
70
70
  const step = steps.value[current.value];
71
71
  const last = current.value >= steps.value.length - 1;
72
- return createVNode(Form, mergeProps(rest, { "controller": form.value }), { default: () => [createVNode("div", css.attrs(stepsFormStyles.root), [
73
- createVNode(Steps, mergeProps(mergePartProps({ items: items() }, propsSteps.value, {
72
+ return createVNode(Form, mergeJsxProps(rest, { "controller": form.value }), { default: () => [createVNode("div", css.attrs(stepsFormStyles.root), [
73
+ createVNode(Steps, mergeJsxProps(mergePartProps({ items: items() }, propsSteps.value, {
74
74
  items: items(),
75
75
  navigable: true
76
76
  }), {
@@ -87,19 +87,19 @@ var StepsForm = /*#__PURE__*/ _component((_props, _ctx) => {
87
87
  createVNode(Flex, mergePartProps({
88
88
  justify: "end",
89
89
  gap: "sm"
90
- }, propsActions.value), { default: () => [current.value > 0 && createVNode(Button, mergeProps(mergePartProps({
90
+ }, propsActions.value), { default: () => [current.value > 0 && createVNode(Button, mergeJsxProps(mergePartProps({
91
91
  variant: "ghost",
92
92
  tone: "neutral"
93
93
  }, propsPrevious.value, { onClick: () => go(current.value - 1) }), { "key": "__site0" }), {
94
94
  default: () => [messages.stepsFormPrevious],
95
95
  $stable: true
96
- }), last ? createVNode(Button, mergeProps(mergePartProps({}, propsSubmit.value, {
96
+ }), last ? createVNode(Button, mergeJsxProps(mergePartProps({}, propsSubmit.value, {
97
97
  type: "submit",
98
98
  loading: form.value.submitting
99
99
  }), { "key": "__site1" }), {
100
100
  default: () => [submitText.value ?? messages.stepsFormSubmit],
101
101
  $stable: true
102
- }) : createVNode(Button, mergeProps(mergePartProps({}, propsNext.value, {
102
+ }) : createVNode(Button, mergeJsxProps(mergePartProps({}, propsNext.value, {
103
103
  loading: form.value.validating(),
104
104
  onClick: () => void next()
105
105
  }), { "key": "__site2" }), {
@@ -1 +1 @@
1
- {"version":3,"file":"StepsForm.js","names":["_vtp_readonlyProp","_vtp_bindable","_vtp_restProps","_vue_shallowRef","_createVNode","_mergeProps"],"sources":["../../src/patterns/StepsForm.tsx"],"sourcesContent":["/**\n * 分步表单:一份 useForm 的表单分成几步填(开户、准入申请、配置向导),上方是步骤条,下方是这一步的字段与“上一步 / 下一步 / 提交”。\n * 同 Ant Design ProComponents 的 StepsForm。\n *\n * <StepsForm\n * form={form}\n * _current={step}\n * steps={[\n * { title: '企业信息', fields: ['company', 'contact'], content: () => <>…form.Field…</> },\n * { title: '账号', fields: ['password', 'confirm'], content: () => <>…</> },\n * ]}\n * />\n *\n * - “下一步”只校验这一步的字段(form.validate(fields)),通过才往后走,没通过的错误立即显示;走过的步骤可以点回去。\n * - 最后一步是“提交”(表单的原生提交):整份校验没通过时跳到第一个有错的步骤,那一步在步骤条上标成出错。\n * - 换了一步焦点移到这一步的内容上(读屏念出第几步、标题),键盘接着往下填。\n *\n * 部件:Root(Form)、Steps、Panel(这一步的内容,div)、Actions(Flex)、Previous、Next、Submit(Button)。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { nextTick, useId, type VNodeChild } from 'vue';\nimport { Button, type ButtonProps } from '../base/Button';\nimport { useMessages } from '../config/lang/messages';\nimport { Form, type FormProps } from '../form/Form';\nimport type { FormControllerBase } from '../form/useForm';\nimport { Flex, type FlexProps } from '../layout/Flex';\nimport { Steps, type StepItem, type StepsProps } from '../navigation/Steps';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { patternsMessages } from './messages';\n\n/** 一步 */\nexport interface FormStep {\n /** 步骤条上的标题 */\n title: VNodeChild;\n /** 步骤条上的说明 */\n description?: VNodeChild;\n /** 这一步的字段路径(含子路径):“下一步”只校验它们,出错时这一步标成出错 */\n fields: readonly string[];\n /** 这一步的内容:form.Field 们 */\n content: () => VNodeChild;\n}\n\n/** 未声明的属性落到 Form(form 元素)上;标签布局、只读、不可用同 Form */\nexport interface StepsFormProps extends Omit<FormProps, 'controller' | 'children'> {\n /** useForm 的控制器 */\n form: FormControllerBase;\n /** 各步 */\n steps: readonly FormStep[];\n /** 当前第几步,从 0 开始:父级可以写 _current={x} */\n _current?: number;\n /** 提交按钮的文字,默认取文案(提交) */\n submitText?: VNodeChild;\n /** 步骤条(Steps)的部件属性 */\n propsSteps?: Partial<StepsProps>;\n /** 这一步内容外层的部件属性 */\n propsPanel?: PartProps<'div'>;\n /** 按钮行的部件属性 */\n propsActions?: Partial<FlexProps>;\n /** 上一步按钮的部件属性 */\n propsPrevious?: Partial<ButtonProps>;\n /** 下一步按钮的部件属性 */\n propsNext?: Partial<ButtonProps>;\n /** 提交按钮的部件属性 */\n propsSubmit?: Partial<ButtonProps>;\n}\n\n/** StepsForm 的样式:root、panel */\nexport const stepsFormStyles = css.create({\n root: { display: 'flex', flexDirection: 'column', gap: '_lg' },\n // 换步后焦点在这里:不画焦点环(内容本身不是控件),读屏念出它的名称\n panel: { display: 'flex', flexDirection: 'column', gap: '_md', outline: 'none' },\n});\n\n/** 字段 path 在这一步里:就是它,或是它的子路径(`address.city` 属于 `address`) */\nconst inStep = (step: FormStep, path: string) =>\n step.fields.some((field) => path === field || path.startsWith(`${field}.`));\n\n/** 分步表单:步骤条 + 这一步的字段 + 上一步、下一步、提交 */\nexport const StepsForm = _component(\n ({\n form,\n steps,\n _current: current = _bindable(0),\n submitText,\n propsSteps,\n propsPanel,\n propsActions,\n propsPrevious,\n propsNext,\n propsSubmit,\n ...rest\n }: StepsFormProps) => {\n const messages = useMessages('patterns', patternsMessages);\n const id = useId();\n let panel = _state.raw<HTMLElement | null>(null);\n\n /** 这一步有显示着的错误 */\n const hasError = (step: FormStep) =>\n Object.keys(form.errors).some((path) => inStep(step, path) && form.visibleError(path));\n\n /** 换到第 index 步,焦点移到这一步的内容上 */\n function go(index: number) {\n current = index;\n void nextTick(() => panel?.focus());\n }\n\n async function next() {\n const step = steps[current];\n if (step && (await form.validate(step.fields))) go(current + 1);\n }\n\n // 整份提交没通过:跳到第一个有错的步骤\n _effect(() => {\n if (form.submitCount === 0 || form.submitting) return;\n const first = steps.findIndex(hasError);\n if (first >= 0 && first !== current && !hasError(steps[current]!)) go(first);\n });\n\n const items = (): StepItem[] =>\n steps.map((step, index) => ({\n title: step.title,\n description: step.description,\n status: hasError(step) ? 'error' : undefined,\n // 只能点回走过的步骤\n disabled: index > current,\n }));\n\n return () => {\n const step = steps[current];\n const last = current >= steps.length - 1;\n return (\n <Form {...rest} controller={form}>\n <div {...css.attrs(stepsFormStyles.root)}>\n <Steps\n {...mergePartProps<StepsProps>({ items: items() }, propsSteps, {\n items: items(),\n navigable: true,\n })}\n _current={current}\n onUpdate:_current={(index: number) => go(index)}\n />\n <div\n {...mergeAttrs<'div'>({ sx: stepsFormStyles.panel }, propsPanel, {\n ref: _toRef(panel),\n id: `${id}-panel`,\n tabindex: -1,\n role: 'group',\n 'aria-label': messages.stepsFormStep(current + 1, steps.length),\n })}\n >\n {step?.content()}\n </div>\n <Flex {...mergePartProps<FlexProps>({ justify: 'end', gap: 'sm' }, propsActions)}>\n {current > 0 && (\n <Button\n {...mergePartProps<ButtonProps>(\n { variant: 'ghost', tone: 'neutral' },\n propsPrevious,\n { onClick: () => go(current - 1) },\n )}\n >\n {messages.stepsFormPrevious}\n </Button>\n )}\n {last ? (\n <Button\n {...mergePartProps<ButtonProps>({}, propsSubmit, {\n type: 'submit',\n loading: form.submitting,\n })}\n >\n {submitText ?? messages.stepsFormSubmit}\n </Button>\n ) : (\n <Button\n {...mergePartProps<ButtonProps>({}, propsNext, {\n loading: form.validating(),\n onClick: () => void next(),\n })}\n >\n {messages.stepsFormNext}\n </Button>\n )}\n </Flex>\n </div>\n </Form>\n );\n };\n },\n);\n"],"mappings":";;;;;;;;;;;;;;AAoEA,IAAa,kBAAkB,IAAI,OAAO;CACxC,MAAM;EAAE,SAAS;EAAQ,eAAe;EAAU,KAAK;CAAM;CAE7D,OAAO;EAAE,SAAS;EAAQ,eAAe;EAAU,KAAK;EAAO,SAAS;CAAO;AACjF,CAAC;;AAGD,IAAM,UAAU,MAAgB,SAC9B,KAAK,OAAO,MAAM,UAAU,SAAS,SAAS,KAAK,WAAW,GAAG,MAAK,EAAG,CAAC;;AAG5E,IAAa,YAAY,0BACvB,QAAA,SAYsB;CAAA,MAAA,SAAA,CAAA;CAAA,MAAA,OAAAA,aAAA,QAAA,MAAA;CAAA,MAAA,QAAAA,aAAA,QAAA,OAAA;CAAA,MAAA,UAAAC,SAAA,QAAA,kBATU,GAAC,KAAA,IAAA;CAAA,MAAA,aAAAD,aAAA,QAAA,YAAA;CAAA,MAAA,aAAAA,aAAA,QAAA,YAAA;CAAA,MAAA,aAAAA,aAAA,QAAA,YAAA;CAAA,MAAA,eAAAA,aAAA,QAAA,cAAA;CAAA,MAAA,gBAAAA,aAAA,QAAA,eAAA;CAAA,MAAA,YAAAA,aAAA,QAAA,WAAA;CAAA,MAAA,cAAAA,aAAA,QAAA,aAAA;CAAA,MAQ5B,OAAIE,UAAA,QAAA,MAAA,IAAA;CAEP,MAAM,WAAW,YAAY,YAAY,gBAAgB;CACzD,MAAM,KAAK,MAAM;CACjB,IAAI,QAAKC,WAAkC,IAAI;;CAG/C,MAAM,YAAY,SAChB,OAAO,KAAK,KAAA,MAAK,MAAM,CAAC,CAAC,MAAM,SAAS,OAAO,MAAM,IAAI,KAAK,KAAA,MAAK,aAAa,IAAI,CAAC;;CAGvF,SAAS,GAAG,OAAe;EACzB,QAAA,QAAU;EACV,eAAoB,MAAA,OAAO,MAAM,CAAC;CACpC;CAEA,eAAe,OAAO;EACpB,MAAM,OAAO,MAAA,MAAA,QAAA;EACb,IAAI,QAAS,MAAM,KAAA,MAAK,SAAS,KAAK,MAAM,GAAI,GAAG,QAAA,QAAU,CAAC;CAChE;CAGA,aAAc;EACZ,IAAI,KAAA,MAAK,gBAAgB,KAAK,KAAA,MAAK,YAAY;EAC/C,MAAM,QAAQ,MAAA,MAAM,UAAU,QAAQ;EACtC,IAAI,SAAS,KAAK,UAAK,QAAA,SAAgB,CAAC,SAAS,MAAA,MAAA,QAAA,MAAe,GAAG,GAAG,KAAK;CAC7E,CAAC;CAED,MAAM,cACJ,MAAA,MAAM,KAAK,MAAM,WAAW;EAC1B,OAAO,KAAK;EACZ,aAAa,KAAK;EAClB,QAAQ,SAAS,IAAI,IAAI,UAAU,KAAA;EAEnC,UAAU,QAAK,QAAA;CACjB,EAAE;CAEJ,aAAa;EACX,MAAM,OAAO,MAAA,MAAA,QAAA;EACb,MAAM,OAAO,QAAA,SAAW,MAAA,MAAM,SAAS;EACvC,OAAAC,YAAA,MAAAC,WACY,MAAI,EAAA,cAAA,KAAA,MAAA,CAAA,GAAA,EAAA,eAAA,CAAAD,YAAA,OACH,IAAI,MAAM,gBAAgB,IAAI,GAAC;GAAAA,YAAA,OAAAC,WAEhC,eAA2B,EAAE,OAAO,MAAM,EAAE,GAAC,WAAA,OAAc;IAC7D,OAAO,MAAM;IACb,WAAW;GACb,CAAC,GAAC;IAAA,YAAA,QAAA;IAAA,qBAAA,OAAA,OAAA,OAAA,MAEkB,UAAkB,GAAG,KAAK;GAAC,CAAA,GAAA,IAAA;GAAAD,YAAA,OAG3C,WAAkB,EAAE,IAAI,gBAAgB,MAAM,GAAC,WAAA,OAAc;IAC/D,KAAG;IACH,IAAI,GAAG,GAAE;IACT,UAAU;IACV,MAAM;IACN,cAAc,SAAS,cAAc,QAAA,QAAU,GAAG,MAAA,MAAM,MAAM;GAChE,CAAC,GAAC,CAED,MAAM,QAAQ,CAAC,CAAA;GAAAA,YAAA,MAER,eAA0B;IAAE,SAAS;IAAO,KAAK;GAAK,GAAC,aAAA,KAAc,GAAC,EAAA,eAAA,CAC7E,QAAA,QAAU,KAACA,YAAA,QAAAC,WAEJ,eACF;IAAE,SAAS;IAAS,MAAM;GAAU,GAAC,cAAA,OAErC,EAAE,eAAe,GAAG,QAAA,QAAU,CAAC,EAAE,CACnC,GAAC,EAAA,OAAA,UAAA,CAAA,GAAA;IAAA,eAAA,CAEA,SAAS,iBAAiB;IAAA,SAAA;GAAA,CAAA,GAG9B,OAAID,YAAA,QAAAC,WAEG,eAA4B,CAAC,GAAC,YAAA,OAAe;IAC/C,MAAM;IACN,SAAS,KAAA,MAAK;GAChB,CAAC,GAAC,EAAA,OAAA,UAAA,CAAA,GAAA;IAAA,eAAA,CAED,WAAA,SAAc,SAAS,eAAe;IAAA,SAAA;GAAA,CAAA,IAAAD,YAAA,QAAAC,WAInC,eAA4B,CAAC,GAAC,UAAA,OAAa;IAC7C,SAAS,KAAA,MAAK,WAAW;IACzB,eAAe,KAAK,KAAK;GAC3B,CAAC,GAAC,EAAA,OAAA,UAAA,CAAA,GAAA;IAAA,eAAA,CAED,SAAS,aAAa;IAAA,SAAA;GAAA,CAAA,CAE1B,EAAA,CAAA;EAAA,CAAA,CAAA,EAAA,CAAA;CAKX;AACF,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH"}
1
+ {"version":3,"file":"StepsForm.js","names":["_vtp_readonlyProp","_vtp_bindable","_vtp_restProps","_vue_shallowRef","_createVNode","_mergeProps"],"sources":["../../src/patterns/StepsForm.tsx"],"sourcesContent":["/**\n * 分步表单:一份 useForm 的表单分成几步填(开户、准入申请、配置向导),上方是步骤条,下方是这一步的字段与“上一步 / 下一步 / 提交”。\n * 同 Ant Design ProComponents 的 StepsForm。\n *\n * <StepsForm\n * form={form}\n * _current={step}\n * steps={[\n * { title: '企业信息', fields: ['company', 'contact'], content: () => <>…form.Field…</> },\n * { title: '账号', fields: ['password', 'confirm'], content: () => <>…</> },\n * ]}\n * />\n *\n * - “下一步”只校验这一步的字段(form.validate(fields)),通过才往后走,没通过的错误立即显示;走过的步骤可以点回去。\n * - 最后一步是“提交”(表单的原生提交):整份校验没通过时跳到第一个有错的步骤,那一步在步骤条上标成出错。\n * - 换了一步焦点移到这一步的内容上(读屏念出第几步、标题),键盘接着往下填。\n *\n * 部件:Root(Form)、Steps、Panel(这一步的内容,div)、Actions(Flex)、Previous、Next、Submit(Button)。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { nextTick, useId, type VNodeChild } from 'vue';\nimport { Button, type ButtonProps } from '../base/Button';\nimport { useMessages } from '../config/lang/messages';\nimport { Form, type FormProps } from '../form/Form';\nimport type { FormControllerBase } from '../form/useForm';\nimport { Flex, type FlexProps } from '../layout/Flex';\nimport { Steps, type StepItem, type StepsProps } from '../navigation/Steps';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { patternsMessages } from './messages';\n\n/** 一步 */\nexport interface FormStep {\n /** 步骤条上的标题 */\n title: VNodeChild;\n /** 步骤条上的说明 */\n description?: VNodeChild;\n /** 这一步的字段路径(含子路径):“下一步”只校验它们,出错时这一步标成出错 */\n fields: readonly string[];\n /** 这一步的内容:form.Field 们 */\n content: () => VNodeChild;\n}\n\n/** 未声明的属性落到 Form(form 元素)上;标签布局、只读、不可用同 Form */\nexport interface StepsFormProps extends Omit<FormProps, 'controller' | 'children'> {\n /** useForm 的控制器 */\n form: FormControllerBase;\n /** 各步 */\n steps: readonly FormStep[];\n /** 当前第几步,从 0 开始:父级可以写 _current={x} */\n _current?: number;\n /** 提交按钮的文字,默认取文案(提交) */\n submitText?: VNodeChild;\n /** 步骤条(Steps)的部件属性 */\n propsSteps?: Partial<StepsProps>;\n /** 这一步内容外层的部件属性 */\n propsPanel?: PartProps<'div'>;\n /** 按钮行的部件属性 */\n propsActions?: Partial<FlexProps>;\n /** 上一步按钮的部件属性 */\n propsPrevious?: Partial<ButtonProps>;\n /** 下一步按钮的部件属性 */\n propsNext?: Partial<ButtonProps>;\n /** 提交按钮的部件属性 */\n propsSubmit?: Partial<ButtonProps>;\n}\n\n/** StepsForm 的样式:root、panel */\nexport const stepsFormStyles = css.create({\n root: { display: 'flex', flexDirection: 'column', gap: '_lg' },\n // 换步后焦点在这里:不画焦点环(内容本身不是控件),读屏念出它的名称\n panel: { display: 'flex', flexDirection: 'column', gap: '_md', outline: 'none' },\n});\n\n/** 字段 path 在这一步里:就是它,或是它的子路径(`address.city` 属于 `address`) */\nconst inStep = (step: FormStep, path: string) =>\n step.fields.some((field) => path === field || path.startsWith(`${field}.`));\n\n/** 分步表单:步骤条 + 这一步的字段 + 上一步、下一步、提交 */\nexport const StepsForm = _component(\n ({\n form,\n steps,\n _current: current = _bindable(0),\n submitText,\n propsSteps,\n propsPanel,\n propsActions,\n propsPrevious,\n propsNext,\n propsSubmit,\n ...rest\n }: StepsFormProps) => {\n const messages = useMessages('patterns', patternsMessages);\n const id = useId();\n let panel = _state.raw<HTMLElement | null>(null);\n\n /** 这一步有显示着的错误 */\n const hasError = (step: FormStep) =>\n Object.keys(form.errors).some((path) => inStep(step, path) && form.visibleError(path));\n\n /** 换到第 index 步,焦点移到这一步的内容上 */\n function go(index: number) {\n current = index;\n void nextTick(() => panel?.focus());\n }\n\n async function next() {\n const step = steps[current];\n if (step && (await form.validate(step.fields))) go(current + 1);\n }\n\n // 整份提交没通过:跳到第一个有错的步骤\n _effect(() => {\n if (form.submitCount === 0 || form.submitting) return;\n const first = steps.findIndex(hasError);\n if (first >= 0 && first !== current && !hasError(steps[current]!)) go(first);\n });\n\n const items = (): StepItem[] =>\n steps.map((step, index) => ({\n title: step.title,\n description: step.description,\n status: hasError(step) ? 'error' : undefined,\n // 只能点回走过的步骤\n disabled: index > current,\n }));\n\n return () => {\n const step = steps[current];\n const last = current >= steps.length - 1;\n return (\n <Form {...rest} controller={form}>\n <div {...css.attrs(stepsFormStyles.root)}>\n <Steps\n {...mergePartProps<StepsProps>({ items: items() }, propsSteps, {\n items: items(),\n navigable: true,\n })}\n _current={current}\n onUpdate:_current={(index: number) => go(index)}\n />\n <div\n {...mergeAttrs<'div'>({ sx: stepsFormStyles.panel }, propsPanel, {\n ref: _toRef(panel),\n id: `${id}-panel`,\n tabindex: -1,\n role: 'group',\n 'aria-label': messages.stepsFormStep(current + 1, steps.length),\n })}\n >\n {step?.content()}\n </div>\n <Flex {...mergePartProps<FlexProps>({ justify: 'end', gap: 'sm' }, propsActions)}>\n {current > 0 && (\n <Button\n {...mergePartProps<ButtonProps>(\n { variant: 'ghost', tone: 'neutral' },\n propsPrevious,\n { onClick: () => go(current - 1) },\n )}\n >\n {messages.stepsFormPrevious}\n </Button>\n )}\n {last ? (\n <Button\n {...mergePartProps<ButtonProps>({}, propsSubmit, {\n type: 'submit',\n loading: form.submitting,\n })}\n >\n {submitText ?? messages.stepsFormSubmit}\n </Button>\n ) : (\n <Button\n {...mergePartProps<ButtonProps>({}, propsNext, {\n loading: form.validating(),\n onClick: () => void next(),\n })}\n >\n {messages.stepsFormNext}\n </Button>\n )}\n </Flex>\n </div>\n </Form>\n );\n };\n },\n);\n"],"mappings":"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"}
@@ -7,8 +7,8 @@ import { SYSTEM_THEME } from "../config/theme/boot.js";
7
7
  import { builtinThemeLabel, builtinThemes } from "../config/theme/builtin.js";
8
8
  import { useMessages } from "../config/lang/messages.js";
9
9
  import { patternsMessages } from "./messages.js";
10
- import { createVNode, isVNode, mergeProps } from "vue";
11
- import { _component, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
10
+ import { createVNode, isVNode } from "vue";
11
+ import { _component, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
12
12
  import { Citrus, Coffee, Contrast, Flower2, Monitor, Moon, MoonStar, Palette, PartyPopper, ScrollText, Sun, Trees, Waves, Zap } from "@lucide/icons";
13
13
  //#region src/patterns/ThemeSwitcher.tsx
14
14
  /**
@@ -64,7 +64,7 @@ var ThemeSwitcher = /*#__PURE__*/ _component((_props, _ctx) => {
64
64
  return () => {
65
65
  let _slot2;
66
66
  const choices = system.value ? [SYSTEM_THEME, ...preference.value.names] : [...preference.value.names];
67
- return createVNode(Menu$1, mergeProps(rest, { "trigger": _cache[0] || (_cache[0] = (props) => createVNode(IconButton, mergePartProps({
67
+ return createVNode(Menu$1, mergeJsxProps(rest, { "trigger": _cache[0] || (_cache[0] = (props) => createVNode(IconButton, mergePartProps({
68
68
  icon: iconOf(preference.value.preference),
69
69
  "aria-label": messages.themeLabel
70
70
  }, propsTrigger.value, {
@@ -1 +1 @@
1
- {"version":3,"file":"ThemeSwitcher.js","names":["_isVNode","_vtp_readonlyProp","_vtp_restProps","_createVNode","Menu","_mergeProps"],"sources":["../../src/patterns/ThemeSwitcher.tsx"],"sourcesContent":["/**\n * 主题切换:图标按钮弹出菜单,列出“跟随系统”与各套主题,配合 createThemePreference 使用。\n *\n * const preference = createThemePreference({ themes: { light: lightTheme, dark: darkTheme, paper: paperTheme } });\n * <ThemeSwitcher preference={preference} />\n *\n * 选中后新主题从按钮处圆形展开(revealTransition;不支持 View Transitions 或减少动态效果时直接切换)。\n * 按钮的图标表示当前的选择;内置主题(builtinThemes)与跟随系统有默认的文字和图标,其他主题用 labels、icons 补上。\n */\nimport {\n Citrus,\n Coffee,\n Contrast,\n Flower2,\n Monitor,\n Moon,\n MoonStar,\n Palette,\n PartyPopper,\n ScrollText,\n Sun,\n Trees,\n Waves,\n Zap,\n} from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { IconButton, type IconButtonProps } from '../base/IconButton';\nimport { useLang } from '../config/context';\nimport { useMessages } from '../config/lang/messages';\nimport { patternsMessages } from './messages';\nimport type { IconData } from '../base/Icon';\nimport { Menu, MenuRadioGroup, MenuRadioItem, type MenuProps } from '../overlay/Menu';\nimport { toElement } from '../utils/dom/element';\nimport { mergePartProps } from '../utils/props';\nimport { SYSTEM_THEME } from '../config/theme/boot';\nimport { builtinThemeLabel, builtinThemes, type BuiltinThemeName } from '../config/theme/builtin';\nimport type { ThemePreference } from '../config/theme/preference';\n\n/** 未声明的属性落到菜单(role=\"menu\" 的 div)上 */\nexport interface ThemeSwitcherProps<Name extends string> extends Omit<\n MenuProps,\n 'trigger' | 'children'\n> {\n /** createThemePreference 的结果 */\n preference: ThemePreference<Name>;\n /** 各选项的文字(键是主题名或 'system');内置主题与跟随系统默认取语言包,其他默认是主题名 */\n labels?: Partial<Record<Name | typeof SYSTEM_THEME, string>>;\n /** 各选项的图标;内置主题与跟随系统有默认图标,其他默认是调色板 */\n icons?: Partial<Record<Name | typeof SYSTEM_THEME, IconData>>;\n /** 列出“跟随系统”,默认 true */\n system?: boolean;\n /** 触发按钮的部件属性 */\n propsTrigger?: Partial<IconButtonProps>;\n}\n\n// 每套内置主题都要有图标:加主题时漏了这里类型检查会报错\nconst DEFAULT_ICONS: Record<BuiltinThemeName | typeof SYSTEM_THEME, IconData> = {\n [SYSTEM_THEME]: Monitor,\n light: Sun,\n dark: Moon,\n paper: ScrollText,\n midnight: MoonStar,\n 'high-contrast': Contrast,\n ocean: Waves,\n forest: Trees,\n lemon: Citrus,\n sakura: Flower2,\n festive: PartyPopper,\n cyberpunk: Zap,\n coffee: Coffee,\n};\n\n/** 主题切换(图标按钮 + 单选菜单):选中后从按钮处圆形展开新主题 */\nexport const ThemeSwitcher = _component(\n <Name extends string>({\n preference,\n labels,\n icons,\n system = true,\n propsTrigger,\n ...rest\n }: ThemeSwitcherProps<Name>) => {\n const lang = useLang();\n const messages = useMessages('patterns', patternsMessages);\n let button: HTMLElement | null = null;\n\n const labelOf = (name: string) =>\n (labels as Record<string, string | undefined> | undefined)?.[name] ??\n (name === SYSTEM_THEME\n ? lang.themeSystem\n : name in builtinThemes\n ? builtinThemeLabel(lang, name as BuiltinThemeName)\n : name);\n const iconOf = (name: string) =>\n (icons as Record<string, IconData | undefined> | undefined)?.[name] ??\n (DEFAULT_ICONS as Record<string, IconData | undefined>)[name] ??\n Palette;\n\n function choose(next: string) {\n const rect = button?.getBoundingClientRect();\n const origin = rect && { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 };\n void preference.set(next as Name, { origin });\n }\n\n return () => {\n const choices: string[] = system\n ? [SYSTEM_THEME, ...preference.names]\n : [...preference.names];\n return (\n <Menu\n {...rest}\n trigger={(props) => (\n <IconButton\n {...mergePartProps<IconButtonProps>(\n { icon: iconOf(preference.preference), 'aria-label': messages.themeLabel },\n propsTrigger,\n {\n ...props,\n ref: (value: unknown) => {\n props.ref(value);\n button = toElement(value);\n },\n },\n )}\n />\n )}\n >\n <MenuRadioGroup\n _value={preference.preference}\n onUpdate:_value={choose}\n aria-label={messages.themeLabel}\n >\n {choices.map((name) => (\n <MenuRadioItem key={name} value={name} icon={iconOf(name)}>\n {labelOf(name)}\n </MenuRadioItem>\n ))}\n </MenuRadioGroup>\n </Menu>\n );\n };\n },\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAsCA,SAAA,QAAA,GAAA;CAAA,OAAA,OAAA,MAAA,cAAA,OAAA,UAAA,SAAA,KAAA,CAAA,MAAA,qBAAA,CAAAA,QAAA,CAAA;AAAA;AAkBA,IAAM,gBAA0E;EAC7E,eAAe;CAChB,OAAO;CACP,MAAM;CACN,OAAO;CACP,UAAU;CACV,iBAAiB;CACjB,OAAO;CACP,QAAQ;CACR,OAAO;CACP,QAAQ;CACR,SAAS;CACT,WAAW;CACX,QAAQ;AACV;;AAGA,IAAa,gBAAgB,0BAC3B,QAAA,SAOgC;CAAA,MAAA,SAAA,CAAA;CAAA,MAAA,aAAAC,aAAA,QAAA,YAAA;CAAA,MAAA,SAAAA,aAAA,QAAA,QAAA;CAAA,MAAA,QAAAA,aAAA,QAAA,OAAA;CAAA,MAAA,SAAAA,aAAA,QAAA,UAHrB,IAAI;CAAA,MAAA,eAAAA,aAAA,QAAA,cAAA;CAAA,MAEV,OAAIC,UAAA,QAAA,MAAA,IAAA;CAEP,MAAM,OAAO,QAAQ;CACrB,MAAM,WAAW,YAAY,YAAY,gBAAgB;CACzD,IAAI,SAA6B;CAEjC,MAAM,WAAW,SACf,OAAA,QAA6D,UAC5D,SAAA,WACG,KAAK,cACL,QAAQ,gBACN,kBAAkB,MAAM,IAAwB,IAChD;CACR,MAAM,UAAU,SACd,MAAA,QAA8D,SAC7D,cAAuD,SACxD;CAEF,SAAS,OAAO,MAAc;EAC5B,MAAM,OAAO,QAAQ,sBAAsB;EAC3C,MAAM,SAAS,QAAQ;GAAE,GAAG,KAAK,OAAO,KAAK,QAAQ;GAAG,GAAG,KAAK,MAAM,KAAK,SAAS;EAAE;EACtF,WAAK,MAAW,IAAI,MAAc,EAAE,OAAO,CAAC;CAC9C;CAEA,aAAa;EAAA,IAAA;EACX,MAAM,UAAoB,OAAA,QACtB,CAAC,cAAc,GAAG,WAAA,MAAW,KAAK,IAClC,CAAC,GAAG,WAAA,MAAW,KAAK;EACxB,OAAAC,YAAAC,QAAAC,WAEQ,MAAI,EAAA,WAAA,OAAA,OAAA,OAAA,MACE,UAAKF,YAAA,YAEP,eACF;GAAE,MAAM,OAAO,WAAA,MAAW,UAAU;GAAG,cAAc,SAAS;EAAW,GAAC,aAAA,OAE1E;GACE,GAAG;GACH,MAAM,UAAmB;IACvB,MAAM,IAAI,KAAK;IACf,SAAS,UAAU,KAAK;GAC1B;EACF,CACF,GAAC,IAAA,GAEJ,CAAA,GAAA,EAAA,eAAA,CAAAA,YAAA,gBAAA;GAAA,UAGS,WAAA,MAAW;GAAU,mBACZ;GAAM,cACX,SAAS;EAAU,GAAA,QAAA,SAE9B,QAAQ,KAAK,SAAI;GAAA,IAAA;GAAA,OAAAA,YAAA,eAAA;IAAA,OACI;IAAI,SAAS;IAAI,QAAQ,OAAO,IAAI;GAAC,GAAA,QAAA,QACtD,QAAQ,IAAI,CAAC,IAAA,QAAA,EAAA,eAAA,CAAA,KAAA,EAAA,CAAA;EAAA,CAEjB,CAAC,IAAA,SAAA,EAAA,eAAA,CAAA,MAAA,EAAA,CAAA,CAAA,EAAA,CAAA;CAIV;AACF,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH"}
1
+ {"version":3,"file":"ThemeSwitcher.js","names":["_isVNode","_vtp_readonlyProp","_vtp_restProps","_createVNode","Menu","_mergeProps"],"sources":["../../src/patterns/ThemeSwitcher.tsx"],"sourcesContent":["/**\n * 主题切换:图标按钮弹出菜单,列出“跟随系统”与各套主题,配合 createThemePreference 使用。\n *\n * const preference = createThemePreference({ themes: { light: lightTheme, dark: darkTheme, paper: paperTheme } });\n * <ThemeSwitcher preference={preference} />\n *\n * 选中后新主题从按钮处圆形展开(revealTransition;不支持 View Transitions 或减少动态效果时直接切换)。\n * 按钮的图标表示当前的选择;内置主题(builtinThemes)与跟随系统有默认的文字和图标,其他主题用 labels、icons 补上。\n */\nimport {\n Citrus,\n Coffee,\n Contrast,\n Flower2,\n Monitor,\n Moon,\n MoonStar,\n Palette,\n PartyPopper,\n ScrollText,\n Sun,\n Trees,\n Waves,\n Zap,\n} from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { IconButton, type IconButtonProps } from '../base/IconButton';\nimport { useLang } from '../config/context';\nimport { useMessages } from '../config/lang/messages';\nimport { patternsMessages } from './messages';\nimport type { IconData } from '../base/Icon';\nimport { Menu, MenuRadioGroup, MenuRadioItem, type MenuProps } from '../overlay/Menu';\nimport { toElement } from '../utils/dom/element';\nimport { mergePartProps } from '../utils/props';\nimport { SYSTEM_THEME } from '../config/theme/boot';\nimport { builtinThemeLabel, builtinThemes, type BuiltinThemeName } from '../config/theme/builtin';\nimport type { ThemePreference } from '../config/theme/preference';\n\n/** 未声明的属性落到菜单(role=\"menu\" 的 div)上 */\nexport interface ThemeSwitcherProps<Name extends string> extends Omit<\n MenuProps,\n 'trigger' | 'children'\n> {\n /** createThemePreference 的结果 */\n preference: ThemePreference<Name>;\n /** 各选项的文字(键是主题名或 'system');内置主题与跟随系统默认取语言包,其他默认是主题名 */\n labels?: Partial<Record<Name | typeof SYSTEM_THEME, string>>;\n /** 各选项的图标;内置主题与跟随系统有默认图标,其他默认是调色板 */\n icons?: Partial<Record<Name | typeof SYSTEM_THEME, IconData>>;\n /** 列出“跟随系统”,默认 true */\n system?: boolean;\n /** 触发按钮的部件属性 */\n propsTrigger?: Partial<IconButtonProps>;\n}\n\n// 每套内置主题都要有图标:加主题时漏了这里类型检查会报错\nconst DEFAULT_ICONS: Record<BuiltinThemeName | typeof SYSTEM_THEME, IconData> = {\n [SYSTEM_THEME]: Monitor,\n light: Sun,\n dark: Moon,\n paper: ScrollText,\n midnight: MoonStar,\n 'high-contrast': Contrast,\n ocean: Waves,\n forest: Trees,\n lemon: Citrus,\n sakura: Flower2,\n festive: PartyPopper,\n cyberpunk: Zap,\n coffee: Coffee,\n};\n\n/** 主题切换(图标按钮 + 单选菜单):选中后从按钮处圆形展开新主题 */\nexport const ThemeSwitcher = _component(\n <Name extends string>({\n preference,\n labels,\n icons,\n system = true,\n propsTrigger,\n ...rest\n }: ThemeSwitcherProps<Name>) => {\n const lang = useLang();\n const messages = useMessages('patterns', patternsMessages);\n let button: HTMLElement | null = null;\n\n const labelOf = (name: string) =>\n (labels as Record<string, string | undefined> | undefined)?.[name] ??\n (name === SYSTEM_THEME\n ? lang.themeSystem\n : name in builtinThemes\n ? builtinThemeLabel(lang, name as BuiltinThemeName)\n : name);\n const iconOf = (name: string) =>\n (icons as Record<string, IconData | undefined> | undefined)?.[name] ??\n (DEFAULT_ICONS as Record<string, IconData | undefined>)[name] ??\n Palette;\n\n function choose(next: string) {\n const rect = button?.getBoundingClientRect();\n const origin = rect && { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 };\n void preference.set(next as Name, { origin });\n }\n\n return () => {\n const choices: string[] = system\n ? [SYSTEM_THEME, ...preference.names]\n : [...preference.names];\n return (\n <Menu\n {...rest}\n trigger={(props) => (\n <IconButton\n {...mergePartProps<IconButtonProps>(\n { icon: iconOf(preference.preference), 'aria-label': messages.themeLabel },\n propsTrigger,\n {\n ...props,\n ref: (value: unknown) => {\n props.ref(value);\n button = toElement(value);\n },\n },\n )}\n />\n )}\n >\n <MenuRadioGroup\n _value={preference.preference}\n onUpdate:_value={choose}\n aria-label={messages.themeLabel}\n >\n {choices.map((name) => (\n <MenuRadioItem key={name} value={name} icon={iconOf(name)}>\n {labelOf(name)}\n </MenuRadioItem>\n ))}\n </MenuRadioGroup>\n </Menu>\n );\n };\n },\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAsCA,SAAA,QAAA,GAAA;CAAA,OAAA,OAAA,MAAA,cAAA,OAAA,UAAA,SAAA,KAAA,CAAA,MAAA,qBAAA,CAAAA,QAAA,CAAA;AAAA;AAkBA,IAAM,gBAA0E;EAC7E,eAAe;CAChB,OAAO;CACP,MAAM;CACN,OAAO;CACP,UAAU;CACV,iBAAiB;CACjB,OAAO;CACP,QAAQ;CACR,OAAO;CACP,QAAQ;CACR,SAAS;CACT,WAAW;CACX,QAAQ;AACV;;AAGA,IAAa,gBAAgB,0BAC3B,QAAA,SAOgC;CAAA,MAAA,SAAA,CAAA;CAAA,MAAA,aAAAC,aAAA,QAAA,YAAA;CAAA,MAAA,SAAAA,aAAA,QAAA,QAAA;CAAA,MAAA,QAAAA,aAAA,QAAA,OAAA;CAAA,MAAA,SAAAA,aAAA,QAAA,UAHrB,IAAI;CAAA,MAAA,eAAAA,aAAA,QAAA,cAAA;CAAA,MAEV,OAAIC,UAAA,QAAA,MAAA,IAAA;CAEP,MAAM,OAAO,QAAQ;CACrB,MAAM,WAAW,YAAY,YAAY,gBAAgB;CACzD,IAAI,SAA6B;CAEjC,MAAM,WAAW,SACf,OAAA,QAA6D,UAC5D,SAAA,WACG,KAAK,cACL,QAAQ,gBACN,kBAAkB,MAAM,IAAwB,IAChD;CACR,MAAM,UAAU,SACd,MAAA,QAA8D,SAC7D,cAAuD,SACxD;CAEF,SAAS,OAAO,MAAc;EAC5B,MAAM,OAAO,QAAQ,sBAAsB;EAC3C,MAAM,SAAS,QAAQ;GAAE,GAAG,KAAK,OAAO,KAAK,QAAQ;GAAG,GAAG,KAAK,MAAM,KAAK,SAAS;EAAE;EACtF,WAAK,MAAW,IAAI,MAAc,EAAE,OAAO,CAAC;CAC9C;CAEA,aAAa;EAAA,IAAA;EACX,MAAM,UAAoB,OAAA,QACtB,CAAC,cAAc,GAAG,WAAA,MAAW,KAAK,IAClC,CAAC,GAAG,WAAA,MAAW,KAAK;EACxB,OAAAC,YAAAC,QAAAC,cAEQ,MAAI,EAAA,WAAA,OAAA,OAAA,OAAA,MACE,UAAKF,YAAA,YAEP,eACF;GAAE,MAAM,OAAO,WAAA,MAAW,UAAU;GAAG,cAAc,SAAS;EAAW,GAAC,aAAA,OAE1E;GACE,GAAG;GACH,MAAM,UAAmB;IACvB,MAAM,IAAI,KAAK;IACf,SAAS,UAAU,KAAK;GAC1B;EACF,CACF,GAAC,IAAA,GAEJ,CAAA,GAAA,EAAA,eAAA,CAAAA,YAAA,gBAAA;GAAA,UAGS,WAAA,MAAW;GAAU,mBACZ;GAAM,cACX,SAAS;EAAU,GAAA,QAAA,SAE9B,QAAQ,KAAK,SAAI;GAAA,IAAA;GAAA,OAAAA,YAAA,eAAA;IAAA,OACI;IAAI,SAAS;IAAI,QAAQ,OAAO,IAAI;GAAC,GAAA,QAAA,QACtD,QAAQ,IAAI,CAAC,IAAA,QAAA,EAAA,eAAA,CAAA,KAAA,EAAA,CAAA;EAAA,CAEjB,CAAC,IAAA,SAAA,EAAA,eAAA,CAAA,MAAA,EAAA,CAAA,CAAA,EAAA,CAAA;CAIV;AACF,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * 页面组合(子路径 `@zerodep-dev/vue-tsx-pro-ui/patterns`):用核心组件拼好的页面级部件,后台应用直接拿来搭页面:
3
3
  * 应用外壳 AppShell、页签区 PageTabs、查询表格 QueryTable、分步表单 StepsForm、数据导入 DataImport、吸底操作栏 ActionBar、筛选条 FilterBar、通知中心 NotificationCenter、
4
- * 留言 CommentThread、看板 KanbanBoard、时限标记 DeadlineBadge、主题切换 ThemeSwitcher、命令式的表单对话框 useFormDialog。
4
+ * 留言 CommentThread、看板 KanbanBoard、时限标记 DeadlineBadge、主题切换 ThemeSwitcher、布局切换 LayoutSwitcher、认证页版式 AuthLayout、拼图滑块验证 SlideCaptcha、命令式的表单对话框 useFormDialog。
5
5
  *
6
6
  * import { AppShell, FilterBar } from '@zerodep-dev/vue-tsx-pro-ui/patterns';
7
7
  *
@@ -9,15 +9,19 @@
9
9
  * 文案自带中英文(messages.ts),别的语言在 Lang.messages.patterns 里补。
10
10
  */
11
11
  export { ActionBar, actionBarStyles, type ActionBarProps } from './ActionBar';
12
- export { AppShell, AppShellBrand, appShellBrandStyles, AppShellContext, appShellDynamicStyles, appShellOffset, appShellStyles, type AppShellBrandProps, type AppShellProps, type AppShellSidebarModes, type AppShellState, } from './AppShell';
12
+ export { AppShell, AppShellBrand, appShellBrandStyles, AppShellContext, appShellDynamicStyles, appShellOffset, appShellStyles, type AppShellBrandProps, type AppShellProps, type AppShellSidebarModes, type AppShellSidebarSides, type AppShellState, } from './AppShell';
13
+ export { AuthLayout, authLayoutStyles, type AuthLayoutProps } from './AuthLayout';
13
14
  export { CommentComposer, commentStyles, CommentThread, type CommentAttachment, type CommentAuthor, type CommentComposerProps, type CommentDraft, type CommentItem, type CommentThreadProps, } from './CommentThread';
14
15
  export { DataImport, dataImportStyles, type DataImportProps, type ImportField } from './DataImport';
15
16
  export { DeadlineBadge, type DeadlineBadgeProps } from './DeadlineBadge';
16
17
  export { FilterBar, filterBarColumnStyles, filterBarStyles, type FilterBarManaged, type FilterBarProps, } from './FilterBar';
18
+ export { FormDialog, type FormDialogProps } from './FormDialog';
17
19
  export { KanbanBoard, kanbanBoardDynamicStyles, kanbanBoardStyles, type KanbanBoardProps, type KanbanCardState, type KanbanColumn, } from './KanbanBoard';
20
+ export { LayoutSwitcher, type LayoutSwitcherProps } from './LayoutSwitcher';
18
21
  export { NotificationCenter, notificationCenterStyles, NotificationList, notificationListStyles, type NotificationCenterProps, type NotificationItem, type NotificationListOptions, type NotificationListProps, type NotificationType, } from './NotificationCenter';
19
- export { PageTabs, type PageTab, type PageTabsProps } from './PageTabs';
22
+ export { PageTabs, type PageTab, type PageTabsProps, type PageTabsSource } from './PageTabs';
20
23
  export { QueryTable, queryTableStyles, type QueryTableProps } from './QueryTable';
24
+ export { SlideCaptcha, slideCaptchaDynamicStyles, slideCaptchaStyles, type SlideCaptchaProps, type SlideChallenge, type SlideResult, type SlideStatus, } from './SlideCaptcha';
21
25
  export { StepsForm, stepsFormStyles, type FormStep, type StepsFormProps } from './StepsForm';
22
26
  export { ThemeSwitcher, type ThemeSwitcherProps } from './ThemeSwitcher';
23
27
  export { useFormDialog, type FormDialogField, type FormDialogOptions } from './form-dialog';
@@ -1,15 +1,19 @@
1
1
  import { ActionBar, actionBarStyles } from "./ActionBar.js";
2
2
  import { patternsMessages } from "./messages.js";
3
3
  import { AppShell, AppShellBrand, AppShellContext, appShellBrandStyles, appShellDynamicStyles, appShellOffset, appShellStyles } from "./AppShell.js";
4
+ import { AuthLayout, authLayoutStyles } from "./AuthLayout.js";
4
5
  import { CommentComposer, CommentThread, commentStyles } from "./CommentThread.js";
5
6
  import { DataImport, dataImportStyles } from "./DataImport.js";
6
7
  import { DeadlineBadge } from "./DeadlineBadge.js";
7
8
  import { FilterBar, filterBarColumnStyles, filterBarStyles } from "./FilterBar.js";
9
+ import { FormDialog } from "./FormDialog.js";
8
10
  import { KanbanBoard, kanbanBoardDynamicStyles, kanbanBoardStyles } from "./KanbanBoard.js";
11
+ import { LayoutSwitcher } from "./LayoutSwitcher.js";
9
12
  import { NotificationCenter, NotificationList, notificationCenterStyles, notificationListStyles } from "./NotificationCenter.js";
10
13
  import { PageTabs } from "./PageTabs.js";
11
14
  import { QueryTable, queryTableStyles } from "./QueryTable.js";
15
+ import { SlideCaptcha, slideCaptchaDynamicStyles, slideCaptchaStyles } from "./SlideCaptcha.js";
12
16
  import { StepsForm, stepsFormStyles } from "./StepsForm.js";
13
17
  import { ThemeSwitcher } from "./ThemeSwitcher.js";
14
18
  import { useFormDialog } from "./form-dialog.js";
15
- export { ActionBar, AppShell, AppShellBrand, AppShellContext, CommentComposer, CommentThread, DataImport, DeadlineBadge, FilterBar, KanbanBoard, NotificationCenter, NotificationList, PageTabs, QueryTable, StepsForm, ThemeSwitcher, actionBarStyles, appShellBrandStyles, appShellDynamicStyles, appShellOffset, appShellStyles, commentStyles, dataImportStyles, filterBarColumnStyles, filterBarStyles, kanbanBoardDynamicStyles, kanbanBoardStyles, notificationCenterStyles, notificationListStyles, patternsMessages, queryTableStyles, stepsFormStyles, useFormDialog };
19
+ export { ActionBar, AppShell, AppShellBrand, AppShellContext, AuthLayout, CommentComposer, CommentThread, DataImport, DeadlineBadge, FilterBar, FormDialog, KanbanBoard, LayoutSwitcher, NotificationCenter, NotificationList, PageTabs, QueryTable, SlideCaptcha, StepsForm, ThemeSwitcher, actionBarStyles, appShellBrandStyles, appShellDynamicStyles, appShellOffset, appShellStyles, authLayoutStyles, commentStyles, dataImportStyles, filterBarColumnStyles, filterBarStyles, kanbanBoardDynamicStyles, kanbanBoardStyles, notificationCenterStyles, notificationListStyles, patternsMessages, queryTableStyles, slideCaptchaDynamicStyles, slideCaptchaStyles, stepsFormStyles, useFormDialog };