@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
@@ -1 +1 @@
1
- {"version":3,"file":"Select.js","names":["_vtp_readonlyProp","_vtp_bindable","_vtp_childrenProp","_vtp_restProps","_vue_shallowRef","_createVNode","_Fragment","_mergeProps"],"sources":["../../src/input/Select.tsx"],"sourcesContent":["/**\n * 下拉选择(WAI-ARIA 的 select-only combobox):点触发框弹出选项列表,单选或多选。\n *\n * <Field label=\"城市\"><Select items={['北京', '上海', '广州']} _value={city} placeholder=\"选择城市\" /></Field>\n * <Select items={tags} selectionMode=\"multiple\" _value={picked} clearable aria-label=\"标签\" />\n * <Select items={users} toOption={(user) => ({ value: user.id, label: user.name })} _value={id} />\n * <Select items={suppliers} searchable _value={supplier} /> 选项多时:弹出层顶部带搜索框\n *\n * <Select items={tags} selectionMode=\"multiple\" maxTagCount=\"responsive\" creatable onCreate={(text) => tags.push(text)} … />\n *\n * 组合已有的部件:外壳是输入框外壳(controlParts),弹出层用 useAnchoredPopover(与外壳同宽、最高到视口剩余空间),\n * 列表是 ListboxView(状态与键盘见 list-state.ts)。焦点一直在触发按钮上,高亮项经 aria-activedescendant 告诉读屏。\n *\n * 多选时已选的项是触发按钮前面的一排 Tag(不能放进 button 里:按钮里不能有按钮),各带移除按钮。\n * 这排标签只给指针用(aria-hidden、移除按钮不进 Tab 顺序):读屏从触发按钮里念出全部已选内容,\n * 键盘在列表里取消勾选,或在触发按钮(及空的搜索框)里按 Backspace 移除最后一项(同 TagsInput)。\n * maxTagCount 是数字时只显示前几个,'responsive' 时排成一行按宽度放,其余收进“+N”(SelectedTags,TreeSelect 共用)。\n *\n * 键盘:关闭时 ↓ / Enter / 空格打开(↑ 打开并高亮最后一项),单选时直接按字母选中以它开头的项(同原生 select);\n * 打开时 ↑↓、Home / End、Page Up / Down 移动,Enter / 空格选中(单选随后关闭),Esc、Tab 关闭。\n * 写了 name 时用隐藏的 input 随表单提交(多选时每个值一个)。\n *\n * searchable 时弹出层顶部有搜索框:打开后焦点在搜索框里,输入就过滤选项(按显示文字,忽略大小写与重音,或用 filter),\n * ↑↓ 移动、Enter 选中、Esc 关闭并把焦点还给触发按钮。已选的项被过滤掉、或 items 换了(远程搜索)时,\n * 触发框里仍显示它的文字(useSelectedOptions)。\n *\n * 远程选项:给 load 时打开就按搜索词请求,输入停下 300 ms 再请求,只采用最后一次(remote-items.ts);\n * 自己管请求时写 _search={keyword} 拿到搜索词、filter={false} 关掉本地过滤,items 与 loading 自己给。\n *\n * <Select searchable load={(q, signal) => http.get<User[]>('/users', { query: { q }, signal })} toOption={…} _value={owner} />\n *\n * creatable 时自带搜索框,输入的文字没有对应的选项时列表末尾多一项“新建“…””:选中后值就是这段文字,onCreate 报告它。\n *\n * 部件:Root(外壳)、Tags(多选时的那排标签)、Tag、Trigger(button,主元素)、Value、Clear、Chevron、Popover、\n * Search(TextField)、Listbox。\n */\nimport { ChevronDown, Plus, Search } from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { useId, watch, type VNodeChild } from 'vue';\nimport type { PresetIconButtonProps } from '../base/CloseButton';\nimport { buttonBaseStyles } from '../base/button-core';\nimport { Icon, type IconProps } from '../base/Icon';\nimport type { TagProps } from '../base/Tag';\nimport { visuallyHiddenStyles } from '../base/VisuallyHidden';\nimport { useLang, useTextMatcher } from '../config/context';\nimport { useAnchoredPopover, type FloatingPlacement } from '../utils/dom/floating';\nimport { openSetter, type OpenChangeProps } from '../utils/dom/open-change';\nimport { ListPopover } from './ListPopover';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { selectedValues, type SelectionProps } from '../utils/data/selection';\nimport {\n controlClear,\n controlParts,\n clickOnShell,\n focusOnShell,\n controlIcon,\n useControlAppearance,\n type ControlIconOptions,\n type ControlOptions,\n} from './control';\nimport { useFieldControl } from '../form/Field';\nimport { FormValue } from '../form/FormValue';\nimport { disclosureStyles } from '../utils/style/transitions';\nimport { activeOptionId, type ListboxViewProps, type OptionRenderState } from './Listbox';\nimport {\n handleListKeydown,\n useListState,\n useResultAnnouncement,\n useSelectedOptions,\n type ListboxOption,\n type OptionMapping,\n toListboxOption,\n} from './list-state';\nimport { useRemoteItems, type OptionsLoader } from './remote-items';\nimport { SelectedTags, type SelectedTagsProps } from './SelectedTags';\nimport { TextField, type TextFieldProps } from './TextField';\n\n/** 角色、展开状态与可用性由组件管理 */\nexport type SelectManaged =\n | 'type'\n | 'role'\n | 'value'\n | 'disabled'\n | 'aria-haspopup'\n | 'aria-expanded'\n | 'aria-controls'\n | 'aria-activedescendant'\n | 'aria-invalid'\n | 'aria-required'\n | 'aria-describedby';\n\n/** 下拉选择共有的属性;未声明的属性落到触发按钮(主元素)上,外壳用 propsRoot */\nexport interface SelectBaseProps<T>\n extends PartProps<'button', SelectManaged>, ControlOptions, ControlIconOptions, OpenChangeProps {\n /** 数据:ListboxOption、字符串,或任意数据加 toOption;有 load 时是第一次加载之前的选项(编辑页放上已选的那一项) */\n items?: readonly T[];\n /** 没有选择时显示的文字,默认取语言包(请选择) */\n placeholder?: string;\n /** 是否打开:父级可以写 _open={x} */\n _open?: boolean;\n /** 弹出位置,默认 bottom-start */\n placement?: FloatingPlacement;\n /** 有选择时显示清空按钮 */\n clearable?: boolean;\n /** 弹出层顶部带搜索框,输入过滤选项:选项多(供应商、人员、件号)时用 */\n searchable?: boolean;\n /** 搜索时怎样算匹配;默认显示文字包含输入(忽略大小写与重音)。false 时不在本地过滤(服务端按 search 过滤) */\n filter?: false | ((item: T, query: string) => boolean);\n /** 搜索框里的文字:打开时清空;父级写 _search={x} 拿到它(自己发请求时) */\n _search?: string;\n /** 远程选项:打开时与搜索词停下 300 ms 后调用,结果代替 items;只采用最后一次,被顶掉的请求 signal 中止 */\n load?: OptionsLoader<T>;\n /**\n * 可以新建选项(自带搜索框):输入的文字没有对应的选项时,列表末尾多一项“新建“…””,选中后值就是这段文字。\n * 在 onCreate 里把它加进 items(或存到服务端);不加时触发框里照样显示这段文字\n */\n creatable?: boolean;\n /** 新建了一项(creatable 时):参数是输入的文字,也就是选中的值 */\n onCreate?: (text: string) => void;\n /** 多选时触发框里最多显示几个标签,其余收进“+N”;'responsive' 时排成一行、按宽度放,放不下的收起 */\n maxTagCount?: number | 'responsive';\n /** 表单提交时的 name(用隐藏的 input) */\n name?: string;\n /** 不可用 */\n disabled?: boolean;\n /** 只读:能聚焦、能看到已选的内容,不能打开、不能清空 */\n readonly?: boolean;\n /** 必填 */\n required?: boolean;\n /** 校验未通过 */\n invalid?: boolean;\n /** 自定义选项内容:`{(option, { selected, active }) => …}` */\n children?: (item: T, state: OptionRenderState) => VNodeChild;\n /** 自定义触发框里显示的内容(已选的选项);默认单选显示文字、多选显示标签 */\n renderValue?: (selected: readonly T[]) => VNodeChild;\n /** 正在取选项(异步加载):没有选项时列表里是骨架行,已有选项时顶部显示进度条 */\n loading?: boolean;\n /** 没有选项时列表里显示的内容 */\n empty?: VNodeChild;\n /** 外壳的部件属性 */\n propsRoot?: PartProps<'div'>;\n /** 已选内容那一层的部件属性 */\n propsValue?: PartProps<'span'>;\n /** 多选时每个标签的部件属性 */\n propsTag?: Partial<TagProps>;\n /** 多选时那排标签的部件属性 */\n propsTags?: Partial<SelectedTagsProps>;\n /** 清空按钮的部件属性 */\n propsClear?: Partial<PresetIconButtonProps>;\n /** 下拉箭头的部件属性 */\n propsChevron?: Partial<IconProps>;\n /** 弹出层的部件属性 */\n propsPopover?: PartProps<'div', 'id' | 'popover'>;\n /** 列表的部件属性 */\n propsListbox?: Partial<ListboxViewProps<T>>;\n /** 搜索框的部件属性(searchable 时) */\n propsSearch?: Partial<TextFieldProps>;\n}\n\n/** 单选或多选;items 不是 ListboxOption 或字符串时要给 toOption */\nexport type SelectProps<T = ListboxOption> = SelectBaseProps<T> & SelectionProps & OptionMapping<T>;\n\n/** Select 的样式:root、trigger、value、placeholder、chevronOpen 等 */\nexport const selectStyles = css.create({\n // 在 ControlGroup 里也按内容宽(输入框才分剩余宽度)\n root: { cursor: 'pointer', flexGrow: 0 },\n // 去掉按钮默认外观用 buttonBaseStyles;像输入框一样没有自己的焦点环与波纹(焦点环画在外壳上)\n trigger: {\n display: 'flex',\n alignItems: 'center',\n flexGrow: 1,\n minWidth: 0,\n alignSelf: 'stretch',\n textAlign: 'start',\n cursor: 'inherit',\n outlineStyle: 'none',\n },\n value: {\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: '_xs',\n minWidth: 0,\n paddingBlock: '_xs',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n // 是真正的文字(不是原生 placeholder),要满足 4.5:1:用 textMuted 而不是 textPlaceholder\n placeholder: { color: '_textMuted' },\n // 多选时标签排在触发按钮前面(SelectedTags)占剩余宽度,触发按钮里只剩读屏用的文字\n triggerBehindTags: { flexGrow: 0 },\n chevronOpen: { rotate: '180deg' },\n // 弹出层顶部的搜索框占满宽度\n search: { width: '_full' },\n});\n\n/** creatable 时列表末尾那一项“新建“…””:不是 items 里的数据 */\nclass Creation {\n readonly text: string;\n constructor(text: string) {\n this.text = text;\n }\n}\n\n/** 下拉选择:触发框 + 弹出的选项列表 */\nexport const Select = _component(\n <T,>({\n items = [],\n toOption,\n selectionMode = 'single',\n _value: value = _bindable<string | string[] | null>(null),\n _open: open = _bindable(false),\n onOpenChange,\n placeholder,\n placement = 'bottom-start',\n clearable = false,\n searchable = false,\n filter,\n _search: search = _bindable(''),\n load,\n creatable = false,\n onCreate,\n maxTagCount,\n name,\n variant,\n size,\n radius,\n disabled,\n readonly,\n required,\n invalid,\n id,\n icon,\n children,\n renderValue,\n empty,\n loading = false,\n propsRoot,\n propsIcon,\n propsValue,\n propsTag,\n propsTags,\n propsClear,\n propsChevron,\n propsPopover,\n propsListbox,\n propsSearch,\n ...rest\n }: SelectProps<T>) => {\n const lang = useLang();\n const textMatcher = useTextMatcher();\n const listId = useId();\n const appearance = useControlAppearance(() => ({ variant, size, radius }));\n const control = useFieldControl(() => ({ id, invalid, required, disabled, readonly }));\n const multiple = () => selectionMode === 'multiple';\n const optionOf = (item: T) => toListboxOption(item, toOption);\n const remote = useRemoteItems({\n load: () => load,\n query: () => search,\n open: () => open,\n items: () => items,\n });\n // 本地过滤:有 load 或 filter={false} 时交给服务端\n const localFilter = () => !load && filter !== false;\n const matches = (item: T, text: string) =>\n filter ? filter(item, text) : textMatcher()(optionOf(item).label, text);\n // creatable 自带搜索框\n const withSearch = () => searchable || creatable;\n // creatable:输入的文字没有同名(或同值)的选项时,列表末尾多一项“新建”\n const creation = () => {\n const text = search.trim();\n if (!creatable || !text) return undefined;\n const exists = remote.items().some((item) => {\n const option = optionOf(item);\n return option.value === text || option.label.toLowerCase() === text.toLowerCase();\n });\n return exists ? undefined : new Creation(text);\n };\n const list = useListState<T | Creation>({\n items: () => {\n const all = remote.items();\n const shown =\n withSearch() && search && localFilter()\n ? all.filter((item) => matches(item, search))\n : all;\n const created = creation();\n return created ? [...shown, created] : shown;\n },\n toOption: (item) =>\n item instanceof Creation\n ? { value: item.text, label: lang.selectCreate(item.text), icon: Plus }\n : optionOf(item),\n selected: () => selectedValues(value),\n mode: () => selectionMode,\n onChange: (next) => {\n const created = creation();\n if (created && next.includes(created.text)) {\n onCreate?.(created.text);\n search = '';\n }\n value = multiple() ? [...next] : (next[0] ?? null);\n },\n // 单选时再点已选的一项不取消(同原生 select);要清空用清除按钮\n required: () => !multiple(),\n });\n // 已选项的文字取自全部 items(过滤掉的、远程搜索换掉的也在)\n const selectedOptions = useSelectedOptions({ items: remote.items, toOption: optionOf });\n let shell = _state.raw<HTMLElement | null>(null);\n let trigger = _state.raw<HTMLElement | null>(null);\n let panel = _state.raw<HTMLElement | null>(null);\n const setOpen = openSetter(\n () => open,\n (next) => (open = next),\n () => onOpenChange,\n );\n\n /** 多选时移除一项(标签的移除按钮、Backspace) */\n function remove(target: string) {\n value = selectedValues(value).filter((item) => item !== target);\n }\n\n function removeLast() {\n const last = selectedValues(value).at(-1);\n if (last !== undefined) remove(last);\n }\n\n function show(highlight: 'default' | 'last' = 'default', event?: Event) {\n search = '';\n list.activateDefault();\n if (highlight === 'last' && selectedValues(value).length === 0) list.move('last');\n setOpen(true, 'trigger', event);\n }\n\n useResultAnnouncement(() => ({ query: search, count: list.options.length }));\n\n // 输入搜索词:高亮第一个匹配的。打开时清空搜索词不算:那时高亮的是已选项\n watch(\n () => search,\n (text) => text && list.move('first'),\n );\n\n // 选中一项:单选时关闭\n function picked(event?: Event) {\n if (!multiple()) setOpen(false, 'select', event);\n }\n\n /** Ctrl / Cmd / Alt 组合键是浏览器的(刷新、复制、查找),不做按字母跳转 */\n const hasModifier = (event: KeyboardEvent) => event.altKey || event.ctrlKey || event.metaKey;\n\n function onKeydown(event: KeyboardEvent) {\n if (control().disabled || control().readonly) return;\n if (event.key === 'Backspace' && multiple()) {\n event.preventDefault();\n removeLast();\n return;\n }\n if (!open) {\n if (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n show('default', event);\n } else if (event.key === 'ArrowUp') {\n event.preventDefault();\n show('last', event);\n } else if (!multiple() && !hasModifier(event) && list.typeahead(event.key)) {\n // 同原生 select:关闭时按字母直接选中\n event.preventDefault();\n if (list.active !== undefined && !list.isSelected(list.active)) list.select(list.active);\n }\n return;\n }\n if (event.key === 'Tab') {\n setOpen(false, 'focus', event);\n return;\n }\n if (handleListKeydown(list, event, { space: true, typeahead: true }, () => picked(event))) {\n event.preventDefault();\n }\n }\n\n // 搜索框里:↑↓ 移动、Enter 选中(Home / End、空格留给输入),Tab 关闭后照常移到下一个;\n // 多选时空的搜索框里按 Backspace 移除最后一项\n function onSearchKeydown(event: KeyboardEvent) {\n if (event.key === 'Tab') {\n setOpen(false, 'focus', event);\n return;\n }\n if (event.key === 'Backspace' && !search && multiple()) {\n event.preventDefault();\n removeLast();\n return;\n }\n if (handleListKeydown(list, event, { homeEnd: false }, () => picked(event)))\n event.preventDefault();\n }\n\n function clear() {\n value = multiple() ? [] : null;\n trigger?.focus();\n }\n\n // 弹层贴着外壳、与它同宽;焦点一直在触发按钮上,关闭时不用归还(searchable 时见 onPanelToggle)\n const { onToggle } = useAnchoredPopover(\n () => ({\n open,\n anchor: shell,\n panel,\n floating: { placement, matchWidth: true, fitHeight: true },\n restoreFocus: false,\n }),\n { close: (reason, event) => setOpen(false, reason, event) },\n );\n\n // searchable:打开后焦点进搜索框;关闭时焦点还在弹层里(Esc、选中、点外面)就还给触发按钮\n function onPanelToggle(event: ToggleEvent) {\n onToggle(event);\n if (!withSearch()) return;\n if (event.newState === 'open') {\n panel?.querySelector<HTMLInputElement>('input[type=\"search\"]')?.focus();\n return;\n }\n const active = document.activeElement;\n if (!active || active === document.body || panel?.contains(active)) trigger?.focus();\n }\n\n return () => {\n const state = control();\n const values = selectedValues(value);\n const selected = selectedOptions(values);\n const off = state.disabled;\n // 只读:能聚焦,不能打开、不能改\n const locked = off || state.readonly;\n // 多选的默认显示:触发按钮前面一排标签,按钮里只留给读屏的文字\n const tagged = multiple() && !renderValue && selected.length > 0;\n const shown = tagged ? (\n <span {...css.attrs(visuallyHiddenStyles.hidden)}>\n {lang.selectSummary(selected.map((option) => option.label))}\n </span>\n ) : (\n (renderValue?.(\n selected.flatMap((option) => (option.item === undefined ? [] : [option.item])),\n ) ??\n (selected.length === 0 ? (\n <span {...css.attrs(selectStyles.placeholder)}>\n {placeholder ?? lang.selectPlaceholder}\n </span>\n ) : (\n selected[0]!.label\n )))\n );\n const tags = tagged && (\n <SelectedTags\n {...mergePartProps<SelectedTagsProps>(\n {\n tags: selected,\n maxTagCount,\n onRemove: locked ? undefined : remove,\n propsTag,\n },\n propsTags,\n )}\n />\n );\n const s = controlParts(appearance(), state);\n return (\n <>\n <div\n {...mergeAttrs<'div'>({ ...s.root, sx: [s.root.sx, selectStyles.root] }, propsRoot, {\n ref: _toRef(shell),\n // 点在外壳空白处(含多选的标签):焦点交给触发按钮,并与点触发按钮一样切换打开(只读时只聚焦)\n onPointerdown: off ? undefined : focusOnShell(() => trigger),\n onClick: locked\n ? undefined\n : clickOnShell(\n () => trigger,\n (event) => (open ? setOpen(false, 'trigger', event) : show('default', event)),\n ),\n })}\n data-state={open ? 'open' : 'closed'}\n data-invalid={state.invalid || undefined}\n data-disabled={off || undefined}\n >\n {controlIcon(s, icon, propsIcon)}\n {tags}\n <button\n {...mergeAttrs<'button'>(\n {\n sx: [\n buttonBaseStyles.root,\n selectStyles.trigger,\n tagged && selectStyles.triggerBehindTags,\n ],\n },\n rest,\n {\n ref: _toRef(trigger),\n id: state.id,\n type: 'button',\n role: 'combobox',\n disabled: off,\n 'aria-haspopup': 'listbox',\n 'aria-expanded': open,\n 'aria-controls': listId,\n 'aria-activedescendant': open ? activeOptionId(list, listId) : undefined,\n 'aria-invalid': state.invalid || undefined,\n 'aria-required': state.required || undefined,\n 'aria-readonly': state.readonly || undefined,\n 'aria-describedby': state.describedBy,\n onClick: (event: MouseEvent) => {\n // Safari 点击按钮不会聚焦它:焦点要在触发按钮上,键盘与 aria-activedescendant 才有效\n trigger?.focus();\n if (locked) return;\n if (open) setOpen(false, 'trigger', event);\n else show('default', event);\n },\n onKeydown,\n },\n )}\n >\n <span {...mergeAttrs<'span'>({ sx: selectStyles.value }, propsValue)}>{shown}</span>\n </button>\n {clearable && values.length > 0 && !locked && controlClear(s, propsClear, clear)}\n <Icon\n {...mergePartProps<IconProps>(\n {\n ...s.icon,\n icon: ChevronDown,\n sx: [s.icon.sx, disclosureStyles.icon, open && selectStyles.chevronOpen],\n },\n propsChevron,\n )}\n />\n <FormValue name={name} value={values} disabled={state.disabled} />\n </div>\n <ListPopover\n panelRef={_toRef(panel)}\n onToggle={onPanelToggle}\n size={appearance().size}\n labelledBy={state.labelledBy}\n label={rest['aria-label']}\n loading={loading || remote.loading()}\n onPick={() => picked()}\n header={\n withSearch() && (\n <TextField\n {...mergePartProps<TextFieldProps>(\n {\n icon: Search,\n variant: 'soft',\n placeholder: lang.selectSearch,\n 'aria-label': lang.selectSearch,\n propsRoot: { sx: selectStyles.search },\n },\n propsSearch,\n )}\n type=\"search\"\n _value={search}\n aria-controls={listId}\n aria-activedescendant={open ? activeOptionId(list, listId) : undefined}\n onKeydown={onSearchKeydown}\n />\n )\n }\n listbox={{\n list,\n id: listId,\n empty: remote.failure() ?? (search ? lang.selectNoMatch : empty),\n renderOption:\n children &&\n ((item: T | Creation, state: OptionRenderState) =>\n item instanceof Creation ? lang.selectCreate(item.text) : children(item, state)),\n multiple: multiple(),\n }}\n // 使用方按 T 写列表的部件属性;creatable 时多出的“新建”那一项由上面的 renderOption 处理\n propsListbox={propsListbox as Partial<ListboxViewProps<T | Creation>> | undefined}\n propsPopover={propsPopover}\n />\n </>\n );\n };\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"Select.js","names":["_vtp_readonlyProp","_vtp_bindable","_vtp_childrenProp","_vtp_restProps","_vue_shallowRef","_createVNode","_Fragment","_mergeProps"],"sources":["../../src/input/Select.tsx"],"sourcesContent":["/**\n * 下拉选择(WAI-ARIA 的 select-only combobox):点触发框弹出选项列表,单选或多选。\n *\n * <Field label=\"城市\"><Select items={['北京', '上海', '广州']} _value={city} placeholder=\"选择城市\" /></Field>\n * <Select items={tags} selectionMode=\"multiple\" _value={picked} clearable aria-label=\"标签\" />\n * <Select items={users} toOption={(user) => ({ value: user.id, label: user.name })} _value={id} />\n * <Select items={suppliers} searchable _value={supplier} /> 选项多时:弹出层顶部带搜索框\n *\n * <Select items={tags} selectionMode=\"multiple\" maxTagCount=\"responsive\" creatable onCreate={(text) => tags.push(text)} … />\n *\n * 组合已有的部件:外壳是输入框外壳(controlParts),弹出层用 useAnchoredPopover(与外壳同宽、最高到视口剩余空间),\n * 列表是 ListboxView(状态与键盘见 list-state.ts)。焦点一直在触发按钮上,高亮项经 aria-activedescendant 告诉读屏。\n *\n * 多选时已选的项是触发按钮前面的一排 Tag(不能放进 button 里:按钮里不能有按钮),各带移除按钮。\n * 这排标签只给指针用(aria-hidden、移除按钮不进 Tab 顺序):读屏从触发按钮里念出全部已选内容,\n * 键盘在列表里取消勾选,或在触发按钮(及空的搜索框)里按 Backspace 移除最后一项(同 TagsInput)。\n * maxTagCount 是数字时只显示前几个,'responsive' 时排成一行按宽度放,其余收进“+N”(SelectedTags,TreeSelect 共用)。\n *\n * 键盘:关闭时 ↓ / Enter / 空格打开(↑ 打开并高亮最后一项),单选时直接按字母选中以它开头的项(同原生 select);\n * 打开时 ↑↓、Home / End、Page Up / Down 移动,Enter / 空格选中(单选随后关闭),Esc、Tab 关闭。\n * 写了 name 时用隐藏的 input 随表单提交(多选时每个值一个)。\n *\n * searchable 时弹出层顶部有搜索框:打开后焦点在搜索框里,输入就过滤选项(按显示文字,忽略大小写与重音,或用 filter),\n * ↑↓ 移动、Enter 选中、Esc 关闭并把焦点还给触发按钮。已选的项被过滤掉、或 items 换了(远程搜索)时,\n * 触发框里仍显示它的文字(useSelectedOptions)。\n *\n * 远程选项:给 load 时打开就按搜索词请求,输入停下 300 ms 再请求,只采用最后一次(remote-items.ts);\n * 自己管请求时写 _search={keyword} 拿到搜索词、filter={false} 关掉本地过滤,items 与 loading 自己给。\n *\n * <Select searchable load={(q, signal) => http.get<User[]>('/users', { query: { q }, signal })} toOption={…} _value={owner} />\n *\n * creatable 时自带搜索框,输入的文字没有对应的选项时列表末尾多一项“新建“…””:选中后值就是这段文字,onCreate 报告它。\n *\n * 部件:Root(外壳)、Tags(多选时的那排标签)、Tag、Trigger(button,主元素)、Value、Clear、Chevron、Popover、\n * Search(TextField)、Listbox。\n */\nimport { ChevronDown, Plus, Search } from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { useId, watch, type VNodeChild } from 'vue';\nimport type { PresetIconButtonProps } from '../base/CloseButton';\nimport { buttonBaseStyles } from '../base/button-core';\nimport { Icon, type IconProps } from '../base/Icon';\nimport type { TagProps } from '../base/Tag';\nimport { visuallyHiddenStyles } from '../base/VisuallyHidden';\nimport { useLang, useTextMatcher } from '../config/context';\nimport { useAnchoredPopover, type FloatingPlacement } from '../utils/dom/floating';\nimport { openSetter, type OpenChangeProps } from '../utils/dom/open-change';\nimport { ListPopover } from './ListPopover';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { selectedValues, type SelectionProps } from '../utils/data/selection';\nimport {\n controlClear,\n controlParts,\n clickOnShell,\n focusOnShell,\n controlIcon,\n useControlAppearance,\n type ControlIconOptions,\n type ControlOptions,\n} from './control';\nimport { useFieldControl } from '../form/Field';\nimport { FormValue } from '../form/FormValue';\nimport { disclosureStyles } from '../utils/style/transitions';\nimport { activeOptionId, type ListboxViewProps, type OptionRenderState } from './Listbox';\nimport {\n handleListKeydown,\n useListState,\n useResultAnnouncement,\n useSelectedOptions,\n type ListboxOption,\n type OptionMapping,\n toListboxOption,\n} from './list-state';\nimport { useRemoteItems, type OptionsLoader } from './remote-items';\nimport { SelectedTags, type SelectedTagsProps } from './SelectedTags';\nimport { TextField, type TextFieldProps } from './TextField';\n\n/** 角色、展开状态与可用性由组件管理 */\nexport type SelectManaged =\n | 'type'\n | 'role'\n | 'value'\n | 'disabled'\n | 'aria-haspopup'\n | 'aria-expanded'\n | 'aria-controls'\n | 'aria-activedescendant'\n | 'aria-invalid'\n | 'aria-required'\n | 'aria-describedby';\n\n/** 下拉选择共有的属性;未声明的属性落到触发按钮(主元素)上,外壳用 propsRoot */\nexport interface SelectBaseProps<T>\n extends PartProps<'button', SelectManaged>, ControlOptions, ControlIconOptions, OpenChangeProps {\n /** 数据:ListboxOption、字符串,或任意数据加 toOption;有 load 时是第一次加载之前的选项(编辑页放上已选的那一项) */\n items?: readonly T[];\n /** 没有选择时显示的文字,默认取语言包(请选择) */\n placeholder?: string;\n /** 是否打开:父级可以写 _open={x} */\n _open?: boolean;\n /** 弹出位置,默认 bottom-start */\n placement?: FloatingPlacement;\n /** 有选择时显示清空按钮 */\n clearable?: boolean;\n /** 弹出层顶部带搜索框,输入过滤选项:选项多(供应商、人员、件号)时用 */\n searchable?: boolean;\n /** 搜索时怎样算匹配;默认显示文字包含输入(忽略大小写与重音)。false 时不在本地过滤(服务端按 search 过滤) */\n filter?: false | ((item: T, query: string) => boolean);\n /** 搜索框里的文字:打开时清空;父级写 _search={x} 拿到它(自己发请求时) */\n _search?: string;\n /** 远程选项:打开时与搜索词停下 300 ms 后调用,结果代替 items;只采用最后一次,被顶掉的请求 signal 中止 */\n load?: OptionsLoader<T>;\n /**\n * 可以新建选项(自带搜索框):输入的文字没有对应的选项时,列表末尾多一项“新建“…””,选中后值就是这段文字。\n * 在 onCreate 里把它加进 items(或存到服务端);不加时触发框里照样显示这段文字\n */\n creatable?: boolean;\n /** 新建了一项(creatable 时):参数是输入的文字,也就是选中的值 */\n onCreate?: (text: string) => void;\n /** 多选时触发框里最多显示几个标签,其余收进“+N”;'responsive' 时排成一行、按宽度放,放不下的收起 */\n maxTagCount?: number | 'responsive';\n /** 表单提交时的 name(用隐藏的 input) */\n name?: string;\n /** 不可用 */\n disabled?: boolean;\n /** 只读:能聚焦、能看到已选的内容,不能打开、不能清空 */\n readonly?: boolean;\n /** 必填 */\n required?: boolean;\n /** 校验未通过 */\n invalid?: boolean;\n /** 自定义选项内容:`{(option, { selected, active }) => …}` */\n children?: (item: T, state: OptionRenderState) => VNodeChild;\n /** 自定义触发框里显示的内容(已选的选项);默认单选显示文字、多选显示标签 */\n renderValue?: (selected: readonly T[]) => VNodeChild;\n /** 正在取选项(异步加载):没有选项时列表里是骨架行,已有选项时顶部显示进度条 */\n loading?: boolean;\n /** 没有选项时列表里显示的内容 */\n empty?: VNodeChild;\n /** 外壳的部件属性 */\n propsRoot?: PartProps<'div'>;\n /** 已选内容那一层的部件属性 */\n propsValue?: PartProps<'span'>;\n /** 多选时每个标签的部件属性 */\n propsTag?: Partial<TagProps>;\n /** 多选时那排标签的部件属性 */\n propsTags?: Partial<SelectedTagsProps>;\n /** 清空按钮的部件属性 */\n propsClear?: Partial<PresetIconButtonProps>;\n /** 下拉箭头的部件属性 */\n propsChevron?: Partial<IconProps>;\n /** 弹出层的部件属性 */\n propsPopover?: PartProps<'div', 'id' | 'popover'>;\n /** 列表的部件属性 */\n propsListbox?: Partial<ListboxViewProps<T>>;\n /** 搜索框的部件属性(searchable 时) */\n propsSearch?: Partial<TextFieldProps>;\n}\n\n/** 单选或多选;items 不是 ListboxOption 或字符串时要给 toOption */\nexport type SelectProps<T = ListboxOption> = SelectBaseProps<T> & SelectionProps & OptionMapping<T>;\n\n/** Select 的样式:root、trigger、value、placeholder、chevronOpen 等 */\nexport const selectStyles = css.create({\n // 在 ControlGroup 里也按内容宽(输入框才分剩余宽度)\n root: { cursor: 'pointer', flexGrow: 0 },\n // 去掉按钮默认外观用 buttonBaseStyles;像输入框一样没有自己的焦点环与波纹(焦点环画在外壳上)\n trigger: {\n display: 'flex',\n alignItems: 'center',\n flexGrow: 1,\n minWidth: 0,\n alignSelf: 'stretch',\n textAlign: 'start',\n cursor: 'inherit',\n outlineStyle: 'none',\n },\n value: {\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: '_xs',\n minWidth: 0,\n paddingBlock: '_xs',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n // 是真正的文字(不是原生 placeholder),要满足 4.5:1:用 textMuted 而不是 textPlaceholder\n placeholder: { color: '_textMuted' },\n // 多选时标签排在触发按钮前面(SelectedTags)占剩余宽度,触发按钮里只剩读屏用的文字\n triggerBehindTags: { flexGrow: 0 },\n chevronOpen: { rotate: '180deg' },\n // 弹出层顶部的搜索框占满宽度\n search: { width: '_full' },\n});\n\n/** creatable 时列表末尾那一项“新建“…””:不是 items 里的数据 */\nclass Creation {\n readonly text: string;\n constructor(text: string) {\n this.text = text;\n }\n}\n\n/** 下拉选择:触发框 + 弹出的选项列表 */\nexport const Select = _component(\n <T,>({\n items = [],\n toOption,\n selectionMode = 'single',\n _value: value = _bindable<string | string[] | null>(null),\n _open: open = _bindable(false),\n onOpenChange,\n placeholder,\n placement = 'bottom-start',\n clearable = false,\n searchable = false,\n filter,\n _search: search = _bindable(''),\n load,\n creatable = false,\n onCreate,\n maxTagCount,\n name,\n variant,\n size,\n radius,\n disabled,\n readonly,\n required,\n invalid,\n id,\n icon,\n children,\n renderValue,\n empty,\n loading = false,\n propsRoot,\n propsIcon,\n propsValue,\n propsTag,\n propsTags,\n propsClear,\n propsChevron,\n propsPopover,\n propsListbox,\n propsSearch,\n ...rest\n }: SelectProps<T>) => {\n const lang = useLang();\n const textMatcher = useTextMatcher();\n const listId = useId();\n const appearance = useControlAppearance(() => ({ variant, size, radius }));\n const control = useFieldControl(() => ({ id, invalid, required, disabled, readonly }));\n const multiple = () => selectionMode === 'multiple';\n const optionOf = (item: T) => toListboxOption(item, toOption);\n const remote = useRemoteItems({\n load: () => load,\n query: () => search,\n open: () => open,\n items: () => items,\n });\n // 本地过滤:有 load 或 filter={false} 时交给服务端\n const localFilter = () => !load && filter !== false;\n const matches = (item: T, text: string) =>\n filter ? filter(item, text) : textMatcher()(optionOf(item).label, text);\n // creatable 自带搜索框\n const withSearch = () => searchable || creatable;\n // creatable:输入的文字没有同名(或同值)的选项时,列表末尾多一项“新建”\n const creation = () => {\n const text = search.trim();\n if (!creatable || !text) return undefined;\n const exists = remote.items().some((item) => {\n const option = optionOf(item);\n return option.value === text || option.label.toLowerCase() === text.toLowerCase();\n });\n return exists ? undefined : new Creation(text);\n };\n const list = useListState<T | Creation>({\n items: () => {\n const all = remote.items();\n const shown =\n withSearch() && search && localFilter()\n ? all.filter((item) => matches(item, search))\n : all;\n const created = creation();\n return created ? [...shown, created] : shown;\n },\n toOption: (item) =>\n item instanceof Creation\n ? { value: item.text, label: lang.selectCreate(item.text), icon: Plus }\n : optionOf(item),\n selected: () => selectedValues(value),\n mode: () => selectionMode,\n onChange: (next) => {\n const created = creation();\n if (created && next.includes(created.text)) {\n onCreate?.(created.text);\n search = '';\n }\n value = multiple() ? [...next] : (next[0] ?? null);\n },\n // 单选时再点已选的一项不取消(同原生 select);要清空用清除按钮\n required: () => !multiple(),\n });\n // 已选项的文字取自全部 items(过滤掉的、远程搜索换掉的也在)\n const selectedOptions = useSelectedOptions({ items: remote.items, toOption: optionOf });\n let shell = _state.raw<HTMLElement | null>(null);\n let trigger = _state.raw<HTMLElement | null>(null);\n let panel = _state.raw<HTMLElement | null>(null);\n const setOpen = openSetter(\n () => open,\n (next) => (open = next),\n () => onOpenChange,\n );\n\n /** 多选时移除一项(标签的移除按钮、Backspace) */\n function remove(target: string) {\n value = selectedValues(value).filter((item) => item !== target);\n }\n\n function removeLast() {\n const last = selectedValues(value).at(-1);\n if (last !== undefined) remove(last);\n }\n\n function show(highlight: 'default' | 'last' = 'default', event?: Event) {\n search = '';\n list.activateDefault();\n if (highlight === 'last' && selectedValues(value).length === 0) list.move('last');\n setOpen(true, 'trigger', event);\n }\n\n useResultAnnouncement(() => ({ query: search, count: list.options.length }));\n\n // 输入搜索词:高亮第一个匹配的。打开时清空搜索词不算:那时高亮的是已选项\n watch(\n () => search,\n (text) => text && list.move('first'),\n );\n\n // 选中一项:单选时关闭\n function picked(event?: Event) {\n if (!multiple()) setOpen(false, 'select', event);\n }\n\n /** Ctrl / Cmd / Alt 组合键是浏览器的(刷新、复制、查找),不做按字母跳转 */\n const hasModifier = (event: KeyboardEvent) => event.altKey || event.ctrlKey || event.metaKey;\n\n function onKeydown(event: KeyboardEvent) {\n if (control().disabled || control().readonly) return;\n if (event.key === 'Backspace' && multiple()) {\n event.preventDefault();\n removeLast();\n return;\n }\n if (!open) {\n if (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n show('default', event);\n } else if (event.key === 'ArrowUp') {\n event.preventDefault();\n show('last', event);\n } else if (!multiple() && !hasModifier(event) && list.typeahead(event.key)) {\n // 同原生 select:关闭时按字母直接选中\n event.preventDefault();\n if (list.active !== undefined && !list.isSelected(list.active)) list.select(list.active);\n }\n return;\n }\n if (event.key === 'Tab') {\n setOpen(false, 'focus', event);\n return;\n }\n if (handleListKeydown(list, event, { space: true, typeahead: true }, () => picked(event))) {\n event.preventDefault();\n }\n }\n\n // 搜索框里:↑↓ 移动、Enter 选中(Home / End、空格留给输入),Tab 关闭后照常移到下一个;\n // 多选时空的搜索框里按 Backspace 移除最后一项\n function onSearchKeydown(event: KeyboardEvent) {\n if (event.key === 'Tab') {\n setOpen(false, 'focus', event);\n return;\n }\n if (event.key === 'Backspace' && !search && multiple()) {\n event.preventDefault();\n removeLast();\n return;\n }\n if (handleListKeydown(list, event, { homeEnd: false }, () => picked(event)))\n event.preventDefault();\n }\n\n function clear() {\n value = multiple() ? [] : null;\n trigger?.focus();\n }\n\n // 弹层贴着外壳、与它同宽;焦点一直在触发按钮上,关闭时不用归还(searchable 时见 onPanelToggle)\n const { onToggle } = useAnchoredPopover(\n () => ({\n open,\n anchor: shell,\n panel,\n floating: { placement, matchWidth: true, fitHeight: true },\n restoreFocus: false,\n }),\n { close: (reason, event) => setOpen(false, reason, event) },\n );\n\n // searchable:打开后焦点进搜索框;关闭时焦点还在弹层里(Esc、选中、点外面)就还给触发按钮\n function onPanelToggle(event: ToggleEvent) {\n onToggle(event);\n if (!withSearch()) return;\n if (event.newState === 'open') {\n panel?.querySelector<HTMLInputElement>('input[type=\"search\"]')?.focus();\n return;\n }\n const active = document.activeElement;\n if (!active || active === document.body || panel?.contains(active)) trigger?.focus();\n }\n\n return () => {\n const state = control();\n const values = selectedValues(value);\n const selected = selectedOptions(values);\n const off = state.disabled;\n // 只读:能聚焦,不能打开、不能改\n const locked = off || state.readonly;\n // 多选的默认显示:触发按钮前面一排标签,按钮里只留给读屏的文字\n const tagged = multiple() && !renderValue && selected.length > 0;\n const shown = tagged ? (\n <span {...css.attrs(visuallyHiddenStyles.hidden)}>\n {lang.selectSummary(selected.map((option) => option.label))}\n </span>\n ) : (\n (renderValue?.(\n selected.flatMap((option) => (option.item === undefined ? [] : [option.item])),\n ) ??\n (selected.length === 0 ? (\n <span {...css.attrs(selectStyles.placeholder)}>\n {placeholder ?? lang.selectPlaceholder}\n </span>\n ) : (\n selected[0]!.label\n )))\n );\n const tags = tagged && (\n <SelectedTags\n {...mergePartProps<SelectedTagsProps>(\n {\n tags: selected,\n maxTagCount,\n onRemove: locked ? undefined : remove,\n propsTag,\n },\n propsTags,\n )}\n />\n );\n const s = controlParts(appearance(), state);\n return (\n <>\n <div\n {...mergeAttrs<'div'>({ ...s.root, sx: [s.root.sx, selectStyles.root] }, propsRoot, {\n ref: _toRef(shell),\n // 点在外壳空白处(含多选的标签):焦点交给触发按钮,并与点触发按钮一样切换打开(只读时只聚焦)\n onPointerdown: off ? undefined : focusOnShell(() => trigger),\n onClick: locked\n ? undefined\n : clickOnShell(\n () => trigger,\n (event) => (open ? setOpen(false, 'trigger', event) : show('default', event)),\n ),\n })}\n data-state={open ? 'open' : 'closed'}\n data-invalid={state.invalid || undefined}\n data-disabled={off || undefined}\n >\n {controlIcon(s, icon, propsIcon)}\n {tags}\n <button\n {...mergeAttrs<'button'>(\n {\n sx: [\n buttonBaseStyles.root,\n selectStyles.trigger,\n tagged && selectStyles.triggerBehindTags,\n ],\n },\n rest,\n {\n ref: _toRef(trigger),\n id: state.id,\n type: 'button',\n role: 'combobox',\n disabled: off,\n 'aria-haspopup': 'listbox',\n 'aria-expanded': open,\n 'aria-controls': listId,\n 'aria-activedescendant': open ? activeOptionId(list, listId) : undefined,\n 'aria-invalid': state.invalid || undefined,\n 'aria-required': state.required || undefined,\n 'aria-readonly': state.readonly || undefined,\n 'aria-describedby': state.describedBy,\n onClick: (event: MouseEvent) => {\n // Safari 点击按钮不会聚焦它:焦点要在触发按钮上,键盘与 aria-activedescendant 才有效\n trigger?.focus();\n if (locked) return;\n if (open) setOpen(false, 'trigger', event);\n else show('default', event);\n },\n onKeydown,\n },\n )}\n >\n <span {...mergeAttrs<'span'>({ sx: selectStyles.value }, propsValue)}>{shown}</span>\n </button>\n {clearable && values.length > 0 && !locked && controlClear(s, propsClear, clear)}\n <Icon\n {...mergePartProps<IconProps>(\n {\n ...s.icon,\n icon: ChevronDown,\n sx: [s.icon.sx, disclosureStyles.icon, open && selectStyles.chevronOpen],\n },\n propsChevron,\n )}\n />\n <FormValue name={name} value={values} disabled={state.disabled} />\n </div>\n <ListPopover\n panelRef={_toRef(panel)}\n onToggle={onPanelToggle}\n size={appearance().size}\n labelledBy={state.labelledBy}\n label={rest['aria-label']}\n loading={loading || remote.loading()}\n onPick={() => picked()}\n header={\n withSearch() && (\n <TextField\n {...mergePartProps<TextFieldProps>(\n {\n icon: Search,\n variant: 'soft',\n placeholder: lang.selectSearch,\n 'aria-label': lang.selectSearch,\n propsRoot: { sx: selectStyles.search },\n },\n propsSearch,\n )}\n type=\"search\"\n _value={search}\n aria-controls={listId}\n aria-activedescendant={open ? activeOptionId(list, listId) : undefined}\n onKeydown={onSearchKeydown}\n />\n )\n }\n listbox={{\n list,\n id: listId,\n empty: remote.failure() ?? (search ? lang.selectNoMatch : empty),\n renderOption:\n children &&\n ((item: T | Creation, state: OptionRenderState) =>\n item instanceof Creation ? lang.selectCreate(item.text) : children(item, state)),\n multiple: multiple(),\n }}\n // 使用方按 T 写列表的部件属性;creatable 时多出的“新建”那一项由上面的 renderOption 处理\n propsListbox={propsListbox as Partial<ListboxViewProps<T | Creation>> | undefined}\n propsPopover={propsPopover}\n />\n </>\n );\n };\n },\n);\n"],"mappings":"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"}
@@ -2,8 +2,8 @@ import { useLang } from "../config/context.js";
2
2
  import { mergeAttrs, mergePartProps } from "../utils/props.js";
3
3
  import { Tag } from "../base/Tag.js";
4
4
  import { useOverflowItems } from "../utils/dom/overflow.js";
5
- import { createVNode, isVNode, mergeProps, shallowRef } from "vue";
6
- import { _component, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
5
+ import { createVNode, isVNode, shallowRef } from "vue";
6
+ import { _component, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
7
7
  import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
8
8
  //#region src/input/SelectedTags.tsx
9
9
  /** 一个已选的标签 */
@@ -53,7 +53,7 @@ var SelectedTags = /*#__PURE__*/ _component((_props, _ctx) => {
53
53
  return createVNode("span", mergeAttrs({ sx: [selectedTagsStyles.root, responsive && selectedTagsStyles.line] }, rest, {
54
54
  ref: row,
55
55
  "aria-hidden": "true"
56
- }), [shown.map((tag, index) => createVNode(Tag, mergeProps({ "key": tag.value }, mergePartProps({
56
+ }), [shown.map((tag, index) => createVNode(Tag, mergeJsxProps({ "key": tag.value }, mergePartProps({
57
57
  size: "sm",
58
58
  variant: "soft",
59
59
  onRemove: onRemove.value && (() => onRemove.value(tag.value)),
@@ -61,7 +61,7 @@ var SelectedTags = /*#__PURE__*/ _component((_props, _ctx) => {
61
61
  tabindex: -1,
62
62
  onPointerdown: keepFocus
63
63
  }
64
- }, propsTag.value), responsive ? overflow.itemProps(index) : {}), { default: () => [tag.label] })), (responsive || hiddenCount > 0) && createVNode(Tag, mergeProps({
64
+ }, propsTag.value), responsive ? overflow.itemProps(index) : {}), { default: () => [tag.label] })), (responsive || hiddenCount > 0) && createVNode(Tag, mergeJsxProps({
65
65
  "size": "sm",
66
66
  "variant": "soft"
67
67
  }, responsive ? overflow.restProps() : {}), _isSlot(_slot = lang.selectMoreTags(hiddenCount)) ? _slot : { default: () => [_slot] })]);
@@ -1 +1 @@
1
- {"version":3,"file":"SelectedTags.js","names":["_isVNode","_vtp_readonlyProp","_vtp_restProps","_vue_shallowRef","_createVNode","_mergeProps"],"sources":["../../src/input/SelectedTags.tsx"],"sourcesContent":["/**\n * 多选下拉的触发按钮前面那一排已选标签:Select、TreeSelect 共用。\n *\n * <SelectedTags tags={selected} maxTagCount=\"responsive\" onRemove={(value) => remove(value)} />\n *\n * 标签不能放进触发按钮里(按钮里不能有按钮),所以排在它前面。这排标签只给指针用:aria-hidden、移除按钮不进 Tab 顺序、\n * 按下时不抢焦点;读屏从触发按钮里念全部已选(lang.selectSummary),键盘在列表里取消勾选,或在触发按钮上按 Backspace。\n * maxTagCount 是数字时只显示前几个,'responsive' 时排成一行按宽度放(useOverflowItems),其余收进“+N”。\n * 未声明的属性落到这一排的 span 上。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { Tag, type TagProps } from '../base/Tag';\nimport { useLang } from '../config/context';\nimport { useOverflowItems } from '../utils/dom/overflow';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\n\n/** 一个已选的标签 */\nexport interface SelectedTag {\n /** 值:移除时交给 onRemove */\n value: string;\n /** 显示的文字 */\n label: string;\n}\n\n/** 未声明的属性落到这一排的 span 上 */\nexport interface SelectedTagsProps extends PartProps<'span', 'aria-hidden'> {\n /** 要显示的标签 */\n tags: readonly SelectedTag[];\n /** 最多显示几个,其余收进“+N”;'responsive' 时排成一行、按宽度放 */\n maxTagCount?: number | 'responsive';\n /** 点标签的移除按钮;不写时(只读、不可用)标签没有移除按钮 */\n onRemove?: (value: string) => void;\n /** 每个标签的部件属性 */\n propsTag?: Partial<TagProps>;\n}\n\n/** SelectedTags 的样式:root、line */\nexport const selectedTagsStyles = css.create({\n // 占触发框里剩下的宽度;触发按钮里只剩读屏用的文字\n root: {\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: '_xs',\n flexGrow: 1,\n minWidth: 0,\n paddingBlock: '_xs',\n },\n // responsive:一行,放不下的移出排版(useOverflowItems 要求容器 position: relative);\n // contain: inline-size 让这一行不按内容撑宽外壳(不然按内容宽度排版的祖先会被整行标签撑开,永远“放得下”)\n line: { flexWrap: 'nowrap', position: 'relative', overflow: 'hidden', contain: 'inline-size' },\n});\n\n/** 移除按钮按下时不抢焦点:焦点留在触发按钮上 */\nconst keepFocus = (event: PointerEvent) => event.preventDefault();\n\n/** 多选下拉的已选标签:可移除,可按数量或宽度收起 */\nexport const SelectedTags = _component(\n ({ tags, maxTagCount, onRemove, propsTag, ...rest }: SelectedTagsProps) => {\n const lang = useLang();\n let row = _state.raw<HTMLElement | null>(null);\n const overflow = useOverflowItems({\n container: () => (maxTagCount === 'responsive' ? row : null),\n count: () => tags.length,\n min: () => 1,\n });\n return () => {\n const responsive = maxTagCount === 'responsive';\n const shown =\n typeof maxTagCount === 'number' ? tags.slice(0, Math.max(0, maxTagCount)) : tags;\n const hiddenCount = responsive ? overflow.hidden : tags.length - shown.length;\n return (\n <span\n {...mergeAttrs<'span'>(\n { sx: [selectedTagsStyles.root, responsive && selectedTagsStyles.line] },\n rest,\n { ref: _toRef(row), 'aria-hidden': 'true' },\n )}\n >\n {shown.map((tag, index) => (\n <Tag\n key={tag.value}\n {...mergePartProps<TagProps>(\n {\n size: 'sm',\n variant: 'soft',\n onRemove: onRemove && (() => onRemove(tag.value)),\n propsRemove: { tabindex: -1, onPointerdown: keepFocus },\n },\n propsTag,\n )}\n {...(responsive ? overflow.itemProps(index) : {})}\n >\n {tag.label}\n </Tag>\n ))}\n {/* responsive 时“+N”一直在(没有折起的项时藏起来,但仍要量它的宽度) */}\n {(responsive || hiddenCount > 0) && (\n <Tag size=\"sm\" variant=\"soft\" {...(responsive ? overflow.restProps() : {})}>\n {lang.selectMoreTags(hiddenCount)}\n </Tag>\n )}\n </span>\n );\n };\n },\n);\n"],"mappings":";;;;;;;;;;AAyBA,SAAA,QAAA,GAAA;CAAA,OAAA,OAAA,MAAA,cAAA,OAAA,UAAA,SAAA,KAAA,CAAA,MAAA,qBAAA,CAAAA,QAAA,CAAA;AAAA;;AAaA,IAAa,qBAAqB,IAAI,OAAO;CAE3C,MAAM;EACJ,SAAS;EACT,UAAU;EACV,YAAY;EACZ,KAAK;EACL,UAAU;EACV,UAAU;EACV,cAAc;CAChB;CAGA,MAAM;EAAE,UAAU;EAAU,UAAU;EAAY,UAAU;EAAU,SAAS;CAAc;AAC/F,CAAC;;AAGD,IAAM,aAAa,UAAwB,MAAM,eAAe;;AAGhE,IAAa,eAAe,0BAC1B,QAAA,SAA2E;CAAA,MAAA,OAAAC,aAAA,QAAA,MAAA;CAAA,MAAA,cAAAA,aAAA,QAAA,aAAA;CAAA,MAAA,WAAAA,aAAA,QAAA,UAAA;CAAA,MAAA,WAAAA,aAAA,QAAA,UAAA;CAAA,MAA9B,OAAIC,UAAA,QAAA,MAAA,IAAA;CAC/C,MAAM,OAAO,QAAQ;CACrB,IAAI,MAAGC,WAAkC,IAAI;CAC7C,MAAM,WAAW,iBAAiB;EAChC,iBAAkB,YAAA,UAAgB,eAAY,IAAA,QAAS;EACvD,aAAa,KAAA,MAAK;EAClB,WAAW;CACb,CAAC;CACD,aAAa;EAAA,IAAA;EACX,MAAM,aAAa,YAAA,UAAgB;EACnC,MAAM,QACJ,OAAA,YAAA,UAAuB,WAAW,KAAA,MAAK,MAAM,GAAG,KAAK,IAAI,GAAC,YAAA,KAAa,CAAC,IAAC,KAAA;EAC3E,MAAM,cAAc,aAAa,SAAS,SAAS,KAAA,MAAK,SAAS,MAAM;EACvE,OAAAC,YAAA,QAEQ,WACF,EAAE,IAAI,CAAC,mBAAmB,MAAM,cAAc,mBAAmB,IAAI,EAAE,GACvE,MACA;GAAE,KAAG;GAAe,eAAe;EAAO,CAC5C,GAAC,CAEA,MAAM,KAAK,KAAK,UAAKA,YAAA,KAAAC,WAAA,EAAA,OAEb,IAAI,MAAK,GACV,eACF;GACE,MAAM;GACN,SAAS;GACT,UAAU,SAAA,gBAAmB,SAAA,MAAS,IAAI,KAAK;GAC/C,aAAa;IAAE,UAAU;IAAI,eAAe;GAAU;EACxD,GAAC,SAAA,KAEH,GACK,aAAa,SAAS,UAAU,KAAK,IAAI,CAAC,CAAC,GAAA,EAAA,eAAA,CAE/C,IAAI,KAAK,EAAA,CAAA,CAEb,IAEC,cAAc,cAAc,MAACD,YAAA,KAAAC,WAAA;GAAA,QAAA;GAAA,WAAA;EAAA,GACM,aAAa,SAAS,UAAU,IAAI,CAAC,CAAC,GAAA,QAAA,QACtE,KAAK,eAAe,WAAW,CAAC,IAAA,QAAA,EAAA,eAAA,CAAA,KAAA,EAAA,CAAA,CAEpC,CAAA;CAGP;AACF,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH"}
1
+ {"version":3,"file":"SelectedTags.js","names":["_isVNode","_vtp_readonlyProp","_vtp_restProps","_vue_shallowRef","_createVNode","_mergeProps"],"sources":["../../src/input/SelectedTags.tsx"],"sourcesContent":["/**\n * 多选下拉的触发按钮前面那一排已选标签:Select、TreeSelect 共用。\n *\n * <SelectedTags tags={selected} maxTagCount=\"responsive\" onRemove={(value) => remove(value)} />\n *\n * 标签不能放进触发按钮里(按钮里不能有按钮),所以排在它前面。这排标签只给指针用:aria-hidden、移除按钮不进 Tab 顺序、\n * 按下时不抢焦点;读屏从触发按钮里念全部已选(lang.selectSummary),键盘在列表里取消勾选,或在触发按钮上按 Backspace。\n * maxTagCount 是数字时只显示前几个,'responsive' 时排成一行按宽度放(useOverflowItems),其余收进“+N”。\n * 未声明的属性落到这一排的 span 上。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { Tag, type TagProps } from '../base/Tag';\nimport { useLang } from '../config/context';\nimport { useOverflowItems } from '../utils/dom/overflow';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\n\n/** 一个已选的标签 */\nexport interface SelectedTag {\n /** 值:移除时交给 onRemove */\n value: string;\n /** 显示的文字 */\n label: string;\n}\n\n/** 未声明的属性落到这一排的 span 上 */\nexport interface SelectedTagsProps extends PartProps<'span', 'aria-hidden'> {\n /** 要显示的标签 */\n tags: readonly SelectedTag[];\n /** 最多显示几个,其余收进“+N”;'responsive' 时排成一行、按宽度放 */\n maxTagCount?: number | 'responsive';\n /** 点标签的移除按钮;不写时(只读、不可用)标签没有移除按钮 */\n onRemove?: (value: string) => void;\n /** 每个标签的部件属性 */\n propsTag?: Partial<TagProps>;\n}\n\n/** SelectedTags 的样式:root、line */\nexport const selectedTagsStyles = css.create({\n // 占触发框里剩下的宽度;触发按钮里只剩读屏用的文字\n root: {\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: '_xs',\n flexGrow: 1,\n minWidth: 0,\n paddingBlock: '_xs',\n },\n // responsive:一行,放不下的移出排版(useOverflowItems 要求容器 position: relative);\n // contain: inline-size 让这一行不按内容撑宽外壳(不然按内容宽度排版的祖先会被整行标签撑开,永远“放得下”)\n line: { flexWrap: 'nowrap', position: 'relative', overflow: 'hidden', contain: 'inline-size' },\n});\n\n/** 移除按钮按下时不抢焦点:焦点留在触发按钮上 */\nconst keepFocus = (event: PointerEvent) => event.preventDefault();\n\n/** 多选下拉的已选标签:可移除,可按数量或宽度收起 */\nexport const SelectedTags = _component(\n ({ tags, maxTagCount, onRemove, propsTag, ...rest }: SelectedTagsProps) => {\n const lang = useLang();\n let row = _state.raw<HTMLElement | null>(null);\n const overflow = useOverflowItems({\n container: () => (maxTagCount === 'responsive' ? row : null),\n count: () => tags.length,\n min: () => 1,\n });\n return () => {\n const responsive = maxTagCount === 'responsive';\n const shown =\n typeof maxTagCount === 'number' ? tags.slice(0, Math.max(0, maxTagCount)) : tags;\n const hiddenCount = responsive ? overflow.hidden : tags.length - shown.length;\n return (\n <span\n {...mergeAttrs<'span'>(\n { sx: [selectedTagsStyles.root, responsive && selectedTagsStyles.line] },\n rest,\n { ref: _toRef(row), 'aria-hidden': 'true' },\n )}\n >\n {shown.map((tag, index) => (\n <Tag\n key={tag.value}\n {...mergePartProps<TagProps>(\n {\n size: 'sm',\n variant: 'soft',\n onRemove: onRemove && (() => onRemove(tag.value)),\n propsRemove: { tabindex: -1, onPointerdown: keepFocus },\n },\n propsTag,\n )}\n {...(responsive ? overflow.itemProps(index) : {})}\n >\n {tag.label}\n </Tag>\n ))}\n {/* responsive 时“+N”一直在(没有折起的项时藏起来,但仍要量它的宽度) */}\n {(responsive || hiddenCount > 0) && (\n <Tag size=\"sm\" variant=\"soft\" {...(responsive ? overflow.restProps() : {})}>\n {lang.selectMoreTags(hiddenCount)}\n </Tag>\n )}\n </span>\n );\n };\n },\n);\n"],"mappings":";;;;;;;;;;AAyBA,SAAA,QAAA,GAAA;CAAA,OAAA,OAAA,MAAA,cAAA,OAAA,UAAA,SAAA,KAAA,CAAA,MAAA,qBAAA,CAAAA,QAAA,CAAA;AAAA;;AAaA,IAAa,qBAAqB,IAAI,OAAO;CAE3C,MAAM;EACJ,SAAS;EACT,UAAU;EACV,YAAY;EACZ,KAAK;EACL,UAAU;EACV,UAAU;EACV,cAAc;CAChB;CAGA,MAAM;EAAE,UAAU;EAAU,UAAU;EAAY,UAAU;EAAU,SAAS;CAAc;AAC/F,CAAC;;AAGD,IAAM,aAAa,UAAwB,MAAM,eAAe;;AAGhE,IAAa,eAAe,0BAC1B,QAAA,SAA2E;CAAA,MAAA,OAAAC,aAAA,QAAA,MAAA;CAAA,MAAA,cAAAA,aAAA,QAAA,aAAA;CAAA,MAAA,WAAAA,aAAA,QAAA,UAAA;CAAA,MAAA,WAAAA,aAAA,QAAA,UAAA;CAAA,MAA9B,OAAIC,UAAA,QAAA,MAAA,IAAA;CAC/C,MAAM,OAAO,QAAQ;CACrB,IAAI,MAAGC,WAAkC,IAAI;CAC7C,MAAM,WAAW,iBAAiB;EAChC,iBAAkB,YAAA,UAAgB,eAAY,IAAA,QAAS;EACvD,aAAa,KAAA,MAAK;EAClB,WAAW;CACb,CAAC;CACD,aAAa;EAAA,IAAA;EACX,MAAM,aAAa,YAAA,UAAgB;EACnC,MAAM,QACJ,OAAA,YAAA,UAAuB,WAAW,KAAA,MAAK,MAAM,GAAG,KAAK,IAAI,GAAC,YAAA,KAAa,CAAC,IAAC,KAAA;EAC3E,MAAM,cAAc,aAAa,SAAS,SAAS,KAAA,MAAK,SAAS,MAAM;EACvE,OAAAC,YAAA,QAEQ,WACF,EAAE,IAAI,CAAC,mBAAmB,MAAM,cAAc,mBAAmB,IAAI,EAAE,GACvE,MACA;GAAE,KAAG;GAAe,eAAe;EAAO,CAC5C,GAAC,CAEA,MAAM,KAAK,KAAK,UAAKA,YAAA,KAAAC,cAAA,EAAA,OAEb,IAAI,MAAK,GACV,eACF;GACE,MAAM;GACN,SAAS;GACT,UAAU,SAAA,gBAAmB,SAAA,MAAS,IAAI,KAAK;GAC/C,aAAa;IAAE,UAAU;IAAI,eAAe;GAAU;EACxD,GAAC,SAAA,KAEH,GACK,aAAa,SAAS,UAAU,KAAK,IAAI,CAAC,CAAC,GAAA,EAAA,eAAA,CAE/C,IAAI,KAAK,EAAA,CAAA,CAEb,IAEC,cAAc,cAAc,MAACD,YAAA,KAAAC,cAAA;GAAA,QAAA;GAAA,WAAA;EAAA,GACM,aAAa,SAAS,UAAU,IAAI,CAAC,CAAC,GAAA,QAAA,QACtE,KAAK,eAAe,WAAW,CAAC,IAAA,QAAA,EAAA,eAAA,CAAA,KAAA,EAAA,CAAA,CAEpC,CAAA;CAGP;AACF,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH"}
@@ -10,8 +10,8 @@ import { inlineArrows, isRtl } from "../utils/dom/direction.js";
10
10
  import { toneFillStyles } from "../utils/style/tone-styles.js";
11
11
  import { useFieldControl } from "../form/Field.js";
12
12
  import { FormValue } from "../form/FormValue.js";
13
- import { createVNode, isVNode, mergeProps, shallowRef, useId } from "vue";
14
- import { _component, bindable, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
13
+ import { createVNode, isVNode, shallowRef, useId } from "vue";
14
+ import { _component, bindable, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
15
15
  import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
16
16
  //#region src/input/Slider.tsx
17
17
  /** 滑块方向 */
@@ -247,7 +247,7 @@ var Slider = /*#__PURE__*/ _component((_props, _ctx) => {
247
247
  const part = range ? index === 0 ? lang.sliderMin : lang.sliderMax : void 0;
248
248
  const ownLabel = rest["aria-label"];
249
249
  const labelledBy = defaultLabelledBy(rest, field.labelledBy);
250
- return createVNode("div", mergeProps({ "key": index }, mergeAttrs({ sx: [
250
+ return createVNode("div", mergeJsxProps({ "key": index }, mergeAttrs({ sx: [
251
251
  sliderStyles.thumb,
252
252
  focusRingStyles.visible,
253
253
  vertical ? sliderStyles.thumbVertical : sliderStyles.thumbHorizontal,
@@ -271,7 +271,7 @@ var Slider = /*#__PURE__*/ _component((_props, _ctx) => {
271
271
  onKeydown: (event) => onKeydown(index, event)
272
272
  }), { "data-index": range ? index : void 0 }), [part && labelledBy && createVNode(VisuallyHidden, { "id": `${labelId}-${index}` }, _isSlot(part) ? part : { default: () => [part] })]);
273
273
  };
274
- return createVNode("div", mergeProps(mergeAttrs({ sx: [
274
+ return createVNode("div", mergeJsxProps(mergeAttrs({ sx: [
275
275
  sliderStyles.root,
276
276
  vertical ? sliderStyles.vertical : sliderStyles.horizontal,
277
277
  labelled && (vertical ? sliderStyles.labelledVertical : sliderStyles.labelledHorizontal),
@@ -289,7 +289,7 @@ var Slider = /*#__PURE__*/ _component((_props, _ctx) => {
289
289
  createVNode("div", mergeAttrs({ sx: [sliderStyles.track, vertical ? sliderStyles.trackVertical : sliderStyles.trackHorizontal] }, propsTrack.value, { ref: track }), [createVNode("div", mergeAttrs({ sx: [sliderStyles.range, vertical ? sliderStyles.rangeVertical : sliderStyles.rangeHorizontal] }, propsRange.value, { sx: [position(start), vertical ? css.bind(sliderPositionStyles.height, () => [`${end - start}%`]) : css.bind(sliderPositionStyles.width, () => [`${end - start}%`])] }), null), normalized.map((mark) => {
290
290
  const percent = percentOf(mark.value);
291
291
  const own = typeof propsMark.value === "function" ? propsMark.value(mark) : propsMark.value;
292
- return createVNode("span", mergeProps({ "key": mark.value }, mergeAttrs({ sx: [
292
+ return createVNode("span", mergeJsxProps({ "key": mark.value }, mergeAttrs({ sx: [
293
293
  sliderStyles.mark,
294
294
  vertical ? sliderStyles.markVertical : sliderStyles.markHorizontal,
295
295
  percent >= start && percent <= end && sliderStyles.markActive
@@ -299,7 +299,7 @@ var Slider = /*#__PURE__*/ _component((_props, _ctx) => {
299
299
  normalized.map((mark) => {
300
300
  if (mark.label == null) return null;
301
301
  const own = typeof propsMarkLabel.value === "function" ? propsMarkLabel.value(mark) : propsMarkLabel.value;
302
- return createVNode("span", mergeProps({ "key": mark.value }, mergeAttrs({ sx: [sliderStyles.markLabel, vertical ? sliderStyles.markLabelVertical : sliderStyles.markLabelHorizontal] }, own, {
302
+ return createVNode("span", mergeJsxProps({ "key": mark.value }, mergeAttrs({ sx: [sliderStyles.markLabel, vertical ? sliderStyles.markLabelVertical : sliderStyles.markLabelHorizontal] }, own, {
303
303
  sx: position(percentOf(mark.value)),
304
304
  "aria-hidden": true
305
305
  })), [mark.label]);
@@ -1 +1 @@
1
- {"version":3,"file":"Slider.js","names":["_isVNode","_vtp_bindable","_vtp_readonlyProp","_vtp_restProps","_vue_shallowRef","_createVNode","_mergeProps"],"sources":["../../src/input/Slider.tsx"],"sourcesContent":["/**\n * 滑块:在一个范围里拖动选值(音量、进度、价格)。WAI-ARIA 的 Slider 模式:滑块是 role=\"slider\",\n * 方向键 ±step,Page Up / Page Down ±bigStep,Home / End 到两端;从右到左排版时横向的方向键反过来。\n * 点击轨道任意位置直接跳过去并接着拖动。参考 Radix Slider、React Aria useSlider。\n *\n * <Slider _value={volume} aria-label=\"音量\" />\n * <Slider _value={price} min={0} max={1000} step={50} valueText={(v) => `${v} 元`} />\n * <Slider _value={range} aria-label=\"价格\" marks={[0, { value: 500, label: '500' }, 1000]} /> 范围:[低, 高]\n *\n * value 是数组 [低, 高] 时是范围选择:两个滑块各自可聚焦、可拖动,不能交叉;点击轨道移动离得近的那个。\n * 两个滑块的名称在 aria-label(或 Field 的标签)后面加上“最小值”“最大值”,取值范围互相限制(同 WAI-ARIA 多滑块)。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { useId, type VNodeChild } from 'vue';\nimport { VisuallyHidden } from '../base/VisuallyHidden';\nimport { useLang } from '../config/context';\nimport { startMove } from '../utils/dom/move';\nimport { defaultLabelledBy, mergeAttrs, type PartProps } from '../utils/props';\nimport { focusRingStyles } from '../utils/style/styles';\nimport { toneFillStyles, type StatusTone } from '../utils/style/tone-styles';\nimport { fontSizeStyles, type TextSize } from '../utils/style/typography';\nimport { clamp, snapToStep } from '../utils/data/number';\nimport { inlineArrows, isRtl } from '../utils/dom/direction';\nimport { useFieldControl } from '../form/Field';\nimport { FormValue } from '../form/FormValue';\nimport { t } from '../config/theme/tokens';\n\n/** 滑块方向 */\nexport interface SliderOrientations {\n /** 横向(默认):起始端是最小值 */\n horizontal: unknown;\n /** 纵向:底端是最小值;高度由使用方给,默认 10em */\n vertical: unknown;\n}\n\n/** 单值,或范围 [低, 高] */\nexport type SliderValue = number | readonly [number, number];\n\n/** 轨道上的一个刻度 */\nexport interface SliderMark {\n /** 刻度所在的值 */\n value: number;\n /** 刻度下方(纵向时右侧)的文字 */\n label?: VNodeChild;\n}\n\n/** 角色、取值与可聚焦由组件管理 */\nexport type SliderManaged =\n | 'role'\n | 'tabindex'\n | 'aria-valuemin'\n | 'aria-valuemax'\n | 'aria-valuenow'\n | 'aria-valuetext'\n | 'aria-orientation'\n | 'aria-disabled';\n\n/** 未声明的属性落到滑块(role=\"slider\" 的主元素,范围时两个都有)上,名称写 aria-label;外层用 propsRoot */\nexport interface SliderProps<V extends SliderValue = number> extends PartProps<\n 'div',\n SliderManaged\n> {\n /** 当前值:父级写 _value={x} 双向绑定,拖动中实时写回;数组 [低, 高] 时是范围选择 */\n _value?: V;\n /** 最小值,默认 0 */\n min?: number;\n /** 最大值,默认 100 */\n max?: number;\n /** 步长,默认 1;取值总是对齐到 min + n × step */\n step?: number;\n /** Page Up / Page Down 的步长,默认为范围的十分之一(至少一个 step) */\n bigStep?: number;\n /** 方向,默认 horizontal */\n orientation?: keyof SliderOrientations;\n /** 不可用 */\n disabled?: boolean;\n /** 只读:滑块能聚焦、读屏念“只读”,拖动与方向键不改值(查看详情、审批时);外观照常 */\n readonly?: boolean;\n /** 字号档位,滑块与轨道随之缩放;不写时继承 */\n size?: TextSize;\n /** 已选范围与滑块描边的色调(与 Button、Badge 等同一套),默认 accent */\n tone?: StatusTone;\n /** 刻度:数字或带文字的 { value, label };有文字时滑块下方(纵向时右侧)留出位置 */\n marks?: readonly (number | SliderMark)[];\n /** 读屏念的取值文字(aria-valuetext),如 `(v) => \\`${v}%\\``;不写时念数字 */\n valueText?: (value: number) => string;\n /** 表单字段名:给了就带隐藏的 input(范围时两个同名),随表单提交 */\n name?: string;\n /** 一次操作结束(松开、按键)时的值:保存、发请求放在这里,不必每次移动都发 */\n onValueCommit?: (value: V) => void;\n /** 外层(轨道与滑块的容器)的部件属性 */\n propsRoot?: PartProps<'div'>;\n /** 轨道的部件属性 */\n propsTrack?: PartProps<'div'>;\n /** 已选范围(轨道上着色的部分)的部件属性;位置与长度由组件写 */\n propsRange?: PartProps<'div'>;\n /** 刻度点的部件属性 */\n propsMark?: PartProps<'span'> | ((mark: SliderMark) => PartProps<'span'>);\n /** 刻度文字的部件属性 */\n propsMarkLabel?: PartProps<'span'> | ((mark: SliderMark) => PartProps<'span'>);\n}\n\n/** Slider 的样式:root、horizontal、vertical、disabled、readonly、track、range、thumb、mark、markLabel 等 */\nexport const sliderStyles = css.create({\n root: {\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n // 触摸拖动不触发页面滚动\n touchAction: 'none',\n userSelect: 'none',\n cursor: 'pointer',\n },\n // 点击区域至少 24px(WCAG 2.5.8)。滑块的中心对准取值,两端各留半个滑块的外边距:\n // 滑块在最小、最大值时不伸出组件的盒子,不压到旁边的控件\n horizontal: {\n width: `calc(100% - ${t.space.lg} - ${t.space.xs})`,\n marginInline: `calc((${t.space.lg} + ${t.space.xs}) / 2)`,\n minHeight: '_minTarget',\n },\n vertical: {\n flexDirection: 'column',\n height: '10em',\n marginBlock: `calc((${t.space.lg} + ${t.space.xs}) / 2)`,\n minWidth: '_minTarget',\n },\n // 刻度文字放在轨道下方(纵向时右侧),给它留出位置\n labelledHorizontal: { paddingBlockEnd: '1.5em' },\n labelledVertical: { paddingInlineEnd: '3em' },\n disabled: { opacity: '_disabled', cursor: 'not-allowed' },\n readonly: { cursor: 'default' },\n track: {\n position: 'relative',\n flexGrow: 1,\n borderRadius: '_full',\n backgroundColor: '_fill',\n overflow: 'hidden',\n },\n trackHorizontal: { height: `calc(${t.space.xs} * 1.5)` },\n trackVertical: { width: `calc(${t.space.xs} * 1.5)` },\n range: { position: 'absolute', backgroundColor: 'var(--tone-fill)' },\n rangeHorizontal: { insetBlock: 0 },\n rangeVertical: { insetInline: 0 },\n thumb: {\n position: 'absolute',\n boxSizing: 'border-box',\n width: `calc(${t.space.lg} + ${t.space.xs})`,\n height: `calc(${t.space.lg} + ${t.space.xs})`,\n borderWidth: '_sm',\n borderStyle: 'solid',\n borderColor: 'var(--tone-fill)',\n borderRadius: '_full',\n backgroundColor: '_surface',\n boxShadow: '_sm',\n cursor: 'grab',\n },\n // 用逻辑方向的外边距把滑块的中心对准取值位置:从右到左排版时也对\n thumbHorizontal: { marginInlineStart: `calc((${t.space.lg} + ${t.space.xs}) / -2)` },\n thumbVertical: { marginBottom: `calc((${t.space.lg} + ${t.space.xs}) / -2)` },\n // 轨道里的小圆点;在已选范围里时换成反色\n mark: {\n position: 'absolute',\n width: '_space.xs',\n height: '_space.xs',\n borderRadius: '_full',\n backgroundColor: '_borderStrong',\n pointerEvents: 'none',\n },\n markHorizontal: { top: '50%', translate: { default: '-50% -50%', ':dir(rtl)': '50% -50%' } },\n markVertical: { left: '50%', translate: '-50% 50%' },\n markActive: { backgroundColor: 'var(--tone-on-fill)' },\n markLabel: {\n position: 'absolute',\n fontSize: '_sm',\n lineHeight: '_tight',\n color: '_textMuted',\n whiteSpace: 'nowrap',\n pointerEvents: 'none',\n },\n markLabelHorizontal: {\n top: `calc(50% + ${t.space.sm})`,\n translate: { default: '-50% -0.75em', ':dir(rtl)': '50% -0.75em' },\n },\n markLabelVertical: { left: `calc(50% + ${t.space.md})`, translate: '0 50%' },\n});\n\n// 位置是任意值,用动态样式(编译为 CSS 变量);单独一个 create,见 COMPONENTS.md §4\n/** Slider 的样式:inline(横向的起点)、size(横向的长度)、bottom、height(纵向) */\nexport const sliderPositionStyles = css.create({\n inline: (percent: string) => ({ insetInlineStart: percent }),\n width: (percent: string) => ({ width: percent }),\n bottom: (percent: string) => ({ bottom: percent }),\n height: (percent: string) => ({ height: percent }),\n});\n\n/** 滑块:在 min–max 之间按 step 拖动或用键盘选值;value 为 [低, 高] 时选一个范围 */\nexport const Slider = _component(\n <V extends SliderValue = number>({\n _value: value = _bindable<V>(0 as V),\n min = 0,\n max = 100,\n step = 1,\n bigStep,\n orientation = 'horizontal',\n disabled,\n readonly,\n size,\n tone = 'accent',\n marks,\n valueText,\n name,\n onValueCommit,\n propsRoot,\n propsTrack,\n propsRange,\n propsMark,\n propsMarkLabel,\n id,\n ...rest\n }: SliderProps<V>) => {\n const lang = useLang();\n // 在 Field 里时:标签作为名称、关联说明与错误、沿用不可用与只读\n const control = useFieldControl(() => ({ id, disabled, readonly }));\n /** 不接受改值:不可用或只读 */\n const off = () => control().disabled || control().readonly;\n const labelId = useId();\n let track = _state.raw<HTMLElement | null>(null);\n const thumbs: (HTMLElement | null)[] = [null, null];\n\n const isRange = () => Array.isArray(value);\n /** 各滑块的值(单值时只有一个) */\n const values = (): number[] => (Array.isArray(value) ? [...value] : [value as number]);\n /** 夹在范围内并对齐到步长 */\n const snap = (raw: number) => snapToStep(raw, step, min, max);\n const rtl = () => orientation === 'horizontal' && !!track && isRtl(track);\n\n /** 第 index 个滑块能取的范围:范围选择时不能越过另一个 */\n function bounds(index: number): [number, number] {\n if (!isRange()) return [min, max];\n const [low, high] = values() as [number, number];\n return index === 0 ? [min, high] : [low, max];\n }\n\n /** 改第 index 个滑块的值 */\n function set(index: number, raw: number) {\n const [lower, upper] = bounds(index);\n const next = clamp(snap(raw), lower, upper);\n if (!isRange()) {\n value = next as V;\n return;\n }\n const pair = values() as [number, number];\n pair[index] = next;\n value = pair as unknown as V;\n }\n\n /** 指针位置对应的值 */\n function valueAt(clientX: number, clientY: number) {\n const rect = track!.getBoundingClientRect();\n let ratio =\n orientation === 'vertical'\n ? (rect.bottom - clientY) / rect.height\n : (clientX - rect.left) / rect.width;\n if (rtl()) ratio = 1 - ratio;\n return snap(min + clamp(ratio, 0, 1) * (max - min));\n }\n\n /** 离 target 最近的滑块;两个重合时按方向选(往高处去的拿高的那个) */\n function nearest(target: number) {\n if (!isRange()) return 0;\n const [low, high] = values() as [number, number];\n if (low === high) return target > high ? 1 : 0;\n return Math.abs(target - low) <= Math.abs(target - high) ? 0 : 1;\n }\n\n function grab(event: PointerEvent) {\n if (off() || event.button !== 0 || !track) return;\n // 不让浏览器把焦点放到别处、开始选中文字;焦点交给滑块,键盘接着可以微调\n event.preventDefault();\n const target = valueAt(event.clientX, event.clientY);\n const index = nearest(target);\n thumbs[index]?.focus();\n set(index, target);\n startMove(event, {\n onMove: ({ clientX, clientY }) => set(index, valueAt(clientX, clientY)),\n onEnd: () => onValueCommit?.(value),\n });\n }\n\n function onKeydown(index: number, event: KeyboardEvent) {\n if (off()) return;\n const current = values()[index]!;\n const big = bigStep ?? Math.max(step, (max - min) / 10);\n // 从右到左排版时,横向的左右键反过来(右边是起点)\n const { forward, backward } = inlineArrows(rtl());\n const [lower, upper] = bounds(index);\n const next: Record<string, number> = {\n [forward]: current + step,\n ArrowUp: current + step,\n [backward]: current - step,\n ArrowDown: current - step,\n PageUp: current + big,\n PageDown: current - big,\n Home: lower,\n End: upper,\n };\n if (!(event.key in next)) return;\n event.preventDefault();\n set(index, next[event.key]!);\n onValueCommit?.(value);\n }\n\n const percentOf = (number: number) =>\n max > min ? ((clamp(number, min, max) - min) / (max - min)) * 100 : 0;\n\n return () => {\n const vertical = orientation === 'vertical';\n const field = control();\n const range = isRange();\n // 父级传入超出范围的值时按范围内显示(不改父级的值),滑块不会跑出轨道\n const shown = values().map((number) => clamp(number, min, max));\n const [start, end] = range\n ? [percentOf(shown[0]!), percentOf(shown[1]!)]\n : [0, percentOf(shown[0]!)];\n const normalized = (marks ?? []).map((mark) =>\n typeof mark === 'number' ? { value: mark } : mark,\n );\n const labelled = normalized.some((mark) => mark.label != null);\n const position = (percent: number) =>\n vertical\n ? sliderPositionStyles.bottom(`${percent}%`)\n : sliderPositionStyles.inline(`${percent}%`);\n\n const renderThumb = (number: number, index: number) => {\n const [lower, upper] = bounds(index);\n const part = range ? (index === 0 ? lang.sliderMin : lang.sliderMax) : undefined;\n const ownLabel = rest['aria-label'];\n // 范围时每个滑块的名称后面加“最小值 / 最大值”:有 aria-label 时拼在一起,用 Field 的标签时连上隐藏的文字\n const labelledBy = defaultLabelledBy(rest, field.labelledBy);\n return (\n <div\n key={index}\n {...mergeAttrs<'div'>(\n {\n sx: [\n sliderStyles.thumb,\n focusRingStyles.visible,\n vertical ? sliderStyles.thumbVertical : sliderStyles.thumbHorizontal,\n position(percentOf(number)),\n ],\n },\n rest,\n {\n ref: (element: unknown) => (thumbs[index] = element as HTMLElement | null),\n role: 'slider',\n id: index === 0 ? field.id : undefined,\n tabindex: field.disabled ? undefined : 0,\n 'aria-valuemin': lower,\n 'aria-valuemax': upper,\n 'aria-valuenow': number,\n 'aria-valuetext': valueText?.(number),\n 'aria-orientation': orientation,\n 'aria-disabled': field.disabled || undefined,\n 'aria-readonly': field.readonly || undefined,\n 'aria-label': part && ownLabel != null ? `${ownLabel} ${part}` : ownLabel,\n 'aria-labelledby':\n part && labelledBy ? `${labelledBy} ${labelId}-${index}` : labelledBy,\n 'aria-describedby': field.describedBy,\n 'aria-invalid': field.invalid || undefined,\n onKeydown: (event: KeyboardEvent) => onKeydown(index, event),\n },\n )}\n data-index={range ? index : undefined}\n >\n {part && labelledBy && (\n <VisuallyHidden id={`${labelId}-${index}`}>{part}</VisuallyHidden>\n )}\n </div>\n );\n };\n\n return (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n sliderStyles.root,\n vertical ? sliderStyles.vertical : sliderStyles.horizontal,\n labelled &&\n (vertical ? sliderStyles.labelledVertical : sliderStyles.labelledHorizontal),\n toneFillStyles[tone],\n size && fontSizeStyles[size],\n ],\n },\n propsRoot,\n {\n sx: [\n field.readonly && sliderStyles.readonly,\n field.disabled && sliderStyles.disabled,\n ],\n onPointerdown: grab,\n },\n )}\n data-disabled={field.disabled || undefined}\n data-readonly={field.readonly || undefined}\n data-orientation={orientation}\n data-range={range || undefined}\n >\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n sliderStyles.track,\n vertical ? sliderStyles.trackVertical : sliderStyles.trackHorizontal,\n ],\n },\n propsTrack,\n { ref: _toRef(track) },\n )}\n >\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n sliderStyles.range,\n vertical ? sliderStyles.rangeVertical : sliderStyles.rangeHorizontal,\n ],\n },\n propsRange,\n {\n sx: [\n position(start),\n vertical\n ? sliderPositionStyles.height(`${end - start}%`)\n : sliderPositionStyles.width(`${end - start}%`),\n ],\n },\n )}\n />\n {normalized.map((mark) => {\n const percent = percentOf(mark.value);\n const own = typeof propsMark === 'function' ? propsMark(mark) : propsMark;\n return (\n <span\n key={mark.value}\n {...mergeAttrs<'span'>(\n {\n sx: [\n sliderStyles.mark,\n vertical ? sliderStyles.markVertical : sliderStyles.markHorizontal,\n percent >= start && percent <= end && sliderStyles.markActive,\n ],\n },\n own,\n { sx: position(percent) },\n )}\n />\n );\n })}\n </div>\n {shown.map(renderThumb)}\n {normalized.map((mark) => {\n if (mark.label == null) return null;\n const own =\n typeof propsMarkLabel === 'function' ? propsMarkLabel(mark) : propsMarkLabel;\n return (\n <span\n key={mark.value}\n {...mergeAttrs<'span'>(\n {\n sx: [\n sliderStyles.markLabel,\n vertical ? sliderStyles.markLabelVertical : sliderStyles.markLabelHorizontal,\n ],\n },\n own,\n { sx: position(percentOf(mark.value)), 'aria-hidden': true },\n )}\n >\n {mark.label}\n </span>\n );\n })}\n <FormValue name={name} value={range ? shown : shown[0]} disabled={control().disabled} />\n </div>\n );\n };\n },\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AA0DA,SAAA,QAAA,GAAA;CAAA,OAAA,OAAA,MAAA,cAAA,OAAA,UAAA,SAAA,KAAA,CAAA,MAAA,qBAAA,CAAAA,QAAA,CAAA;AAAA;;AA8CA,IAAa,eAAe,IAAI,OAAO;CACrC,MAAM;EACJ,UAAU;EACV,SAAS;EACT,YAAY;EAEZ,aAAa;EACb,YAAY;EACZ,QAAQ;CACV;CAGA,YAAY;EACV,OAAO,eAAe,EAAE,MAAM,GAAE,KAAM,EAAE,MAAM,GAAE;EAChD,cAAc,SAAS,EAAE,MAAM,GAAE,KAAM,EAAE,MAAM,GAAE;EACjD,WAAW;CACb;CACA,UAAU;EACR,eAAe;EACf,QAAQ;EACR,aAAa,SAAS,EAAE,MAAM,GAAE,KAAM,EAAE,MAAM,GAAE;EAChD,UAAU;CACZ;CAEA,oBAAoB,EAAE,iBAAiB,QAAQ;CAC/C,kBAAkB,EAAE,kBAAkB,MAAM;CAC5C,UAAU;EAAE,SAAS;EAAa,QAAQ;CAAc;CACxD,UAAU,EAAE,QAAQ,UAAU;CAC9B,OAAO;EACL,UAAU;EACV,UAAU;EACV,cAAc;EACd,iBAAiB;EACjB,UAAU;CACZ;CACA,iBAAiB,EAAE,QAAQ,QAAQ,EAAE,MAAM,GAAE,SAAU;CACvD,eAAe,EAAE,OAAO,QAAQ,EAAE,MAAM,GAAE,SAAU;CACpD,OAAO;EAAE,UAAU;EAAY,iBAAiB;CAAmB;CACnE,iBAAiB,EAAE,YAAY,EAAE;CACjC,eAAe,EAAE,aAAa,EAAE;CAChC,OAAO;EACL,UAAU;EACV,WAAW;EACX,OAAO,QAAQ,EAAE,MAAM,GAAE,KAAM,EAAE,MAAM,GAAE;EACzC,QAAQ,QAAQ,EAAE,MAAM,GAAE,KAAM,EAAE,MAAM,GAAE;EAC1C,aAAa;EACb,aAAa;EACb,aAAa;EACb,cAAc;EACd,iBAAiB;EACjB,WAAW;EACX,QAAQ;CACV;CAEA,iBAAiB,EAAE,mBAAmB,SAAS,EAAE,MAAM,GAAE,KAAM,EAAE,MAAM,GAAE,SAAU;CACnF,eAAe,EAAE,cAAc,SAAS,EAAE,MAAM,GAAE,KAAM,EAAE,MAAM,GAAE,SAAU;CAE5E,MAAM;EACJ,UAAU;EACV,OAAO;EACP,QAAQ;EACR,cAAc;EACd,iBAAiB;EACjB,eAAe;CACjB;CACA,gBAAgB;EAAE,KAAK;EAAO,WAAW;GAAE,SAAS;GAAa,aAAa;EAAW;CAAE;CAC3F,cAAc;EAAE,MAAM;EAAO,WAAW;CAAW;CACnD,YAAY,EAAE,iBAAiB,sBAAsB;CACrD,WAAW;EACT,UAAU;EACV,UAAU;EACV,YAAY;EACZ,OAAO;EACP,YAAY;EACZ,eAAe;CACjB;CACA,qBAAqB;EACnB,KAAK,cAAc,EAAE,MAAM,GAAE;EAC7B,WAAW;GAAE,SAAS;GAAgB,aAAa;EAAc;CACnE;CACA,mBAAmB;EAAE,MAAM,cAAc,EAAE,MAAM,GAAE;EAAK,WAAW;CAAQ;AAC7E,CAAC;;AAID,IAAa,uBAAuB,IAAI,OAAO;CAC7C,SAAS,aAAqB,EAAE,kBAAkB,QAAQ;CAC1D,QAAQ,aAAqB,EAAE,OAAO,QAAQ;CAC9C,SAAS,aAAqB,EAAE,QAAQ,QAAQ;CAChD,SAAS,aAAqB,EAAE,QAAQ,QAAQ;AAClD,CAAC;;AAGD,IAAa,SAAS,0BACpB,QAAA,SAsBsB;CAAA,MAAA,QAAAC,SAAA,QAAA,gBArBS,GAAC,KAAA,IAAA;CAAA,MAAA,MAAAC,aAAA,QAAA,OACxB,CAAC;CAAA,MAAA,MAAAA,aAAA,QAAA,OACD,GAAG;CAAA,MAAA,OAAAA,aAAA,QAAA,QACF,CAAC;CAAA,MAAA,UAAAA,aAAA,QAAA,SAAA;CAAA,MAAA,cAAAA,aAAA,QAAA,eAEM,YAAY;CAAA,MAAA,WAAAA,aAAA,QAAA,UAAA;CAAA,MAAA,WAAAA,aAAA,QAAA,UAAA;CAAA,MAAA,OAAAA,aAAA,QAAA,MAAA;CAAA,MAAA,OAAAA,aAAA,QAAA,QAInB,QAAQ;CAAA,MAAA,QAAAA,aAAA,QAAA,OAAA;CAAA,MAAA,YAAAA,aAAA,QAAA,WAAA;CAAA,MAAA,OAAAA,aAAA,QAAA,MAAA;CAAA,MAAA,gBAAAA,aAAA,QAAA,eAAA;CAAA,MAAA,YAAAA,aAAA,QAAA,WAAA;CAAA,MAAA,aAAAA,aAAA,QAAA,YAAA;CAAA,MAAA,aAAAA,aAAA,QAAA,YAAA;CAAA,MAAA,YAAAA,aAAA,QAAA,WAAA;CAAA,MAAA,iBAAAA,aAAA,QAAA,gBAAA;CAAA,MAAA,KAAAA,aAAA,QAAA,IAAA;CAAA,MAWZ,OAAIC,UAAA,QAAA,MAAA,IAAA;CAEP,MAAM,OAAO,QAAQ;CAErB,MAAM,UAAU,uBAAuB;EAAE,IAAE,GAAA;EAAE,UAAQ,SAAA;EAAE,UAAQ,SAAA;CAAC,EAAE;;CAElE,MAAM,YAAY,QAAQ,CAAC,CAAC,YAAY,QAAQ,CAAC,CAAC;CAClD,MAAM,UAAU,MAAM;CACtB,IAAI,QAAKC,WAAkC,IAAI;CAC/C,MAAM,SAAiC,CAAC,MAAM,IAAI;CAElD,MAAM,gBAAgB,MAAM,QAAO,MAAA,KAAM;;CAEzC,MAAM,eAA0B,MAAM,QAAO,MAAA,KAAM,IAAI,CAAC,GAAA,MAAA,KAAQ,IAAI,CAAA,MAAA,KAAA;;CAEpE,MAAM,QAAQ,QAAgB,WAAW,KAAG,KAAA,OAAA,IAAA,OAAA,IAAA,KAAgB;CAC5D,MAAM,YAAY,YAAA,UAAgB,gBAAgB,CAAC,CAAA,MAAA,SAAU,MAAK,MAAA,KAAM;;CAGxE,SAAS,OAAO,OAAiC;EAC/C,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAA,IAAA,OAAA,IAAA,KAAA;EACvB,MAAM,CAAC,KAAK,QAAQ,OAAO;EAC3B,OAAO,UAAU,IAAI,CAAA,IAAA,OAAM,IAAI,IAAI,CAAC,KAAG,IAAA,KAAA;CACzC;;CAGA,SAAS,IAAI,OAAe,KAAa;EACvC,MAAM,CAAC,OAAO,SAAS,OAAO,KAAK;EACnC,MAAM,OAAO,MAAM,KAAK,GAAG,GAAG,OAAO,KAAK;EAC1C,IAAI,CAAC,QAAQ,GAAG;GACd,MAAA,QAAQ;GACR;EACF;EACA,MAAM,OAAO,OAAO;EACpB,KAAK,SAAS;EACd,MAAA,QAAQ;CACV;;CAGA,SAAS,QAAQ,SAAiB,SAAiB;EACjD,MAAM,OAAO,MAAA,MAAO,sBAAsB;EAC1C,IAAI,QACF,YAAA,UAAgB,cACX,KAAK,SAAS,WAAW,KAAK,UAC9B,UAAU,KAAK,QAAQ,KAAK;EACnC,IAAI,IAAI,GAAG,QAAQ,IAAI;EACvB,OAAO,KAAK,IAAA,QAAM,MAAM,OAAO,GAAG,CAAC,KAAK,IAAA,QAAA,IAAA,MAAU;CACpD;;CAGA,SAAS,QAAQ,QAAgB;EAC/B,IAAI,CAAC,QAAQ,GAAG,OAAO;EACvB,MAAM,CAAC,KAAK,QAAQ,OAAO;EAC3B,IAAI,QAAQ,MAAM,OAAO,SAAS,OAAO,IAAI;EAC7C,OAAO,KAAK,IAAI,SAAS,GAAG,KAAK,KAAK,IAAI,SAAS,IAAI,IAAI,IAAI;CACjE;CAEA,SAAS,KAAK,OAAqB;EACjC,IAAI,IAAI,KAAK,MAAM,WAAW,KAAK,CAAA,MAAA,OAAQ;EAE3C,MAAM,eAAe;EACrB,MAAM,SAAS,QAAQ,MAAM,SAAS,MAAM,OAAO;EACnD,MAAM,QAAQ,QAAQ,MAAM;EAC5B,OAAO,MAAM,EAAE,MAAM;EACrB,IAAI,OAAO,MAAM;EACjB,UAAU,OAAO;GACf,SAAS,EAAE,SAAS,cAAc,IAAI,OAAO,QAAQ,SAAS,OAAO,CAAC;GACtE,aAAa,cAAA,QAAA,MAAA,KAAqB;EACpC,CAAC;CACH;CAEA,SAAS,UAAU,OAAe,OAAsB;EACtD,IAAI,IAAI,GAAG;EACX,MAAM,UAAU,OAAO,CAAC,CAAC;EACzB,MAAM,MAAM,QAAA,SAAW,KAAK,IAAG,KAAA,QAAQ,IAAA,QAAA,IAAA,SAAa,EAAE;EAEtD,MAAM,EAAE,SAAS,aAAa,aAAa,IAAI,CAAC;EAChD,MAAM,CAAC,OAAO,SAAS,OAAO,KAAK;EACnC,MAAM,OAA+B;IAClC,UAAU,UAAO,KAAA;GAClB,SAAS,UAAO,KAAA;IACf,WAAW,UAAO,KAAA;GACnB,WAAW,UAAO,KAAA;GAClB,QAAQ,UAAU;GAClB,UAAU,UAAU;GACpB,MAAM;GACN,KAAK;EACP;EACA,IAAI,EAAE,MAAM,OAAO,OAAO;EAC1B,MAAM,eAAe;EACrB,IAAI,OAAO,KAAK,MAAM,IAAK;EAC3B,cAAA,QAAA,MAAA,KAAqB;CACvB;CAEA,MAAM,aAAa,WACjB,IAAA,QAAA,IAAA,SAAc,MAAM,QAAM,IAAA,OAAA,IAAA,KAAU,IAAC,IAAA,UAAW,IAAA,QAAA,IAAA,SAAc,MAAM;CAEtE,aAAa;EACX,MAAM,WAAW,YAAA,UAAgB;EACjC,MAAM,QAAQ,QAAQ;EACtB,MAAM,QAAQ,QAAQ;EAEtB,MAAM,QAAQ,OAAO,CAAC,CAAC,KAAK,WAAW,MAAM,QAAM,IAAA,OAAA,IAAA,KAAU,CAAC;EAC9D,MAAM,CAAC,OAAO,OAAO,QACjB,CAAC,UAAU,MAAM,EAAG,GAAG,UAAU,MAAM,EAAG,CAAC,IAC3C,CAAC,GAAG,UAAU,MAAM,EAAG,CAAC;EAC5B,MAAM,cAAc,MAAA,SAAS,CAAA,EAAA,CAAI,KAAK,SACpC,OAAO,SAAS,WAAW,EAAE,OAAO,KAAK,IAAI,IAC/C;EACA,MAAM,WAAW,WAAW,MAAM,SAAS,KAAK,SAAS,IAAI;EAC7D,MAAM,YAAY,YAChB,WACI,qBAAqB,OAAO,GAAG,QAAO,EAAG,IACzC,qBAAqB,OAAO,GAAG,QAAO,EAAG;EAE/C,MAAM,eAAe,QAAgB,UAAkB;GACrD,MAAM,CAAC,OAAO,SAAS,OAAO,KAAK;GACnC,MAAM,OAAO,QAAS,UAAU,IAAI,KAAK,YAAY,KAAK,YAAa,KAAA;GACvE,MAAM,WAAW,KAAK;GAEtB,MAAM,aAAa,kBAAkB,MAAM,MAAM,UAAU;GAC3D,OAAAC,YAAA,OAAAC,WAAA,EAAA,OAES,MAAK,GACN,WACF,EACE,IAAI;IACF,aAAa;IACb,gBAAgB;IAChB,WAAW,aAAa,gBAAgB,aAAa;IACrD,SAAS,UAAU,MAAM,CAAC;GAAC,EAE/B,GACA,MACA;IACE,MAAM,YAAsB,OAAO,SAAS;IAC5C,MAAM;IACN,IAAI,UAAU,IAAI,MAAM,KAAK,KAAA;IAC7B,UAAU,MAAM,WAAW,KAAA,IAAY;IACvC,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,kBAAkB,UAAA,QAAY,MAAM;IACpC,oBAAkB,YAAA;IAClB,iBAAiB,MAAM,YAAY,KAAA;IACnC,iBAAiB,MAAM,YAAY,KAAA;IACnC,cAAc,QAAQ,YAAY,OAAO,GAAG,SAAQ,GAAI,SAAS;IACjE,mBACE,QAAQ,aAAa,GAAG,WAAU,GAAI,QAAO,GAAI,UAAU;IAC7D,oBAAoB,MAAM;IAC1B,gBAAgB,MAAM,WAAW,KAAA;IACjC,YAAY,UAAyB,UAAU,OAAO,KAAK;GAC7D,CACF,GAAC,EAAA,cACW,QAAQ,QAAQ,KAAA,EAAS,CAAA,GAAA,CAEpC,QAAQ,cAAUD,YAAA,gBAAA,EAAA,MACG,GAAG,QAAO,GAAI,QAAO,GAAA,QAAG,IAAI,IAAJ,OAAI,EAAA,eAAA,CAAJ,IAAI,EAAA,CAAA,CACjD,CAAA;EAGP;EAEA,OAAAA,YAAA,OAAAC,WAEQ,WACF,EACE,IAAI;GACF,aAAa;GACb,WAAW,aAAa,WAAW,aAAa;GAChD,aACG,WAAW,aAAa,mBAAmB,aAAa;GAC3D,eAAc,KAAA;GACd,KAAA,SAAQ,eAAc,KAAA;EAAM,EAEhC,GAAC,UAAA,OAED;GACE,IAAI,CACF,MAAM,YAAY,aAAa,UAC/B,MAAM,YAAY,aAAa,QAAQ;GAEzC,eAAe;EACjB,CACF,GAAC;GAAA,iBACc,MAAM,YAAY,KAAA;GAAS,iBAC3B,MAAM,YAAY,KAAA;GAAS,oBAAA,YAAA;GAAA,cAE9B,SAAS,KAAA;EAAS,CAAA,GAAA;GAAAD,YAAA,OAGxB,WACF,EACE,IAAI,CACF,aAAa,OACb,WAAW,aAAa,gBAAgB,aAAa,eAAe,EAExE,GAAC,WAAA,OAED,EAAE,KAAG,MAAgB,CACvB,GAAC,CAAAA,YAAA,OAGK,WACF,EACE,IAAI,CACF,aAAa,OACb,WAAW,aAAa,gBAAgB,aAAa,eAAe,EAExE,GAAC,WAAA,OAED,EACE,IAAI,CACF,SAAS,KAAK,GACd,WAAQ,IAAA,KACJ,qBAAqB,cAAM,CAAC,GAAG,MAAM,MAAK,EAAG,CAAA,IAAA,IAAA,KAC7C,qBAAqB,aAAK,CAAC,GAAG,MAAM,MAAK,EAAG,CAAA,CAAC,EAErD,CACF,GAAC,IAAA,GAEF,WAAW,KAAK,SAAS;IACxB,MAAM,UAAU,UAAU,KAAK,KAAK;IACpC,MAAM,MAAM,OAAA,UAAA,UAAqB,aAAa,UAAA,MAAU,IAAI,IAAC,UAAA;IAC7D,OAAAA,YAAA,QAAAC,WAAA,EAAA,OAES,KAAK,MAAK,GACX,WACF,EACE,IAAI;KACF,aAAa;KACb,WAAW,aAAa,eAAe,aAAa;KACpD,WAAW,SAAS,WAAW,OAAO,aAAa;IAAU,EAEjE,GACA,KACA,EAAE,IAAI,SAAS,OAAO,EAAE,CAC1B,CAAC,GAAA,IAAA;GAGP,CAAC,CAAC,CAAA;GAEH,MAAM,IAAI,WAAW;GACrB,WAAW,KAAK,SAAS;IACxB,IAAI,KAAK,SAAS,MAAM,OAAO;IAC/B,MAAM,MACJ,OAAA,eAAA,UAA0B,aAAa,eAAA,MAAe,IAAI,IAAC,eAAA;IAC7D,OAAAD,YAAA,QAAAC,WAAA,EAAA,OAES,KAAK,MAAK,GACX,WACF,EACE,IAAI,CACF,aAAa,WACb,WAAW,aAAa,oBAAoB,aAAa,mBAAmB,EAEhF,GACA,KACA;KAAE,IAAI,SAAS,UAAU,KAAK,KAAK,CAAC;KAAG,eAAe;IAAK,CAC7D,CAAC,GAAA,CAEA,KAAK,KAAK,CAAA;GAGjB,CAAC;GAACD,YAAA,WAAA;IAAA,QAAA,KAAA;IAAA,SAC4B,QAAQ,QAAQ,MAAM;IAAE,YAAY,QAAQ,CAAC,CAAC;GAAQ,GAAA,IAAA;EAAA,CAAA;CAG1F;AACF,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH"}
1
+ {"version":3,"file":"Slider.js","names":["_isVNode","_vtp_bindable","_vtp_readonlyProp","_vtp_restProps","_vue_shallowRef","_createVNode","_mergeProps"],"sources":["../../src/input/Slider.tsx"],"sourcesContent":["/**\n * 滑块:在一个范围里拖动选值(音量、进度、价格)。WAI-ARIA 的 Slider 模式:滑块是 role=\"slider\",\n * 方向键 ±step,Page Up / Page Down ±bigStep,Home / End 到两端;从右到左排版时横向的方向键反过来。\n * 点击轨道任意位置直接跳过去并接着拖动。参考 Radix Slider、React Aria useSlider。\n *\n * <Slider _value={volume} aria-label=\"音量\" />\n * <Slider _value={price} min={0} max={1000} step={50} valueText={(v) => `${v} 元`} />\n * <Slider _value={range} aria-label=\"价格\" marks={[0, { value: 500, label: '500' }, 1000]} /> 范围:[低, 高]\n *\n * value 是数组 [低, 高] 时是范围选择:两个滑块各自可聚焦、可拖动,不能交叉;点击轨道移动离得近的那个。\n * 两个滑块的名称在 aria-label(或 Field 的标签)后面加上“最小值”“最大值”,取值范围互相限制(同 WAI-ARIA 多滑块)。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { useId, type VNodeChild } from 'vue';\nimport { VisuallyHidden } from '../base/VisuallyHidden';\nimport { useLang } from '../config/context';\nimport { startMove } from '../utils/dom/move';\nimport { defaultLabelledBy, mergeAttrs, type PartProps } from '../utils/props';\nimport { focusRingStyles } from '../utils/style/styles';\nimport { toneFillStyles, type StatusTone } from '../utils/style/tone-styles';\nimport { fontSizeStyles, type TextSize } from '../utils/style/typography';\nimport { clamp, snapToStep } from '../utils/data/number';\nimport { inlineArrows, isRtl } from '../utils/dom/direction';\nimport { useFieldControl } from '../form/Field';\nimport { FormValue } from '../form/FormValue';\nimport { t } from '../config/theme/tokens';\n\n/** 滑块方向 */\nexport interface SliderOrientations {\n /** 横向(默认):起始端是最小值 */\n horizontal: unknown;\n /** 纵向:底端是最小值;高度由使用方给,默认 10em */\n vertical: unknown;\n}\n\n/** 单值,或范围 [低, 高] */\nexport type SliderValue = number | readonly [number, number];\n\n/** 轨道上的一个刻度 */\nexport interface SliderMark {\n /** 刻度所在的值 */\n value: number;\n /** 刻度下方(纵向时右侧)的文字 */\n label?: VNodeChild;\n}\n\n/** 角色、取值与可聚焦由组件管理 */\nexport type SliderManaged =\n | 'role'\n | 'tabindex'\n | 'aria-valuemin'\n | 'aria-valuemax'\n | 'aria-valuenow'\n | 'aria-valuetext'\n | 'aria-orientation'\n | 'aria-disabled';\n\n/** 未声明的属性落到滑块(role=\"slider\" 的主元素,范围时两个都有)上,名称写 aria-label;外层用 propsRoot */\nexport interface SliderProps<V extends SliderValue = number> extends PartProps<\n 'div',\n SliderManaged\n> {\n /** 当前值:父级写 _value={x} 双向绑定,拖动中实时写回;数组 [低, 高] 时是范围选择 */\n _value?: V;\n /** 最小值,默认 0 */\n min?: number;\n /** 最大值,默认 100 */\n max?: number;\n /** 步长,默认 1;取值总是对齐到 min + n × step */\n step?: number;\n /** Page Up / Page Down 的步长,默认为范围的十分之一(至少一个 step) */\n bigStep?: number;\n /** 方向,默认 horizontal */\n orientation?: keyof SliderOrientations;\n /** 不可用 */\n disabled?: boolean;\n /** 只读:滑块能聚焦、读屏念“只读”,拖动与方向键不改值(查看详情、审批时);外观照常 */\n readonly?: boolean;\n /** 字号档位,滑块与轨道随之缩放;不写时继承 */\n size?: TextSize;\n /** 已选范围与滑块描边的色调(与 Button、Badge 等同一套),默认 accent */\n tone?: StatusTone;\n /** 刻度:数字或带文字的 { value, label };有文字时滑块下方(纵向时右侧)留出位置 */\n marks?: readonly (number | SliderMark)[];\n /** 读屏念的取值文字(aria-valuetext),如 `(v) => \\`${v}%\\``;不写时念数字 */\n valueText?: (value: number) => string;\n /** 表单字段名:给了就带隐藏的 input(范围时两个同名),随表单提交 */\n name?: string;\n /** 一次操作结束(松开、按键)时的值:保存、发请求放在这里,不必每次移动都发 */\n onValueCommit?: (value: V) => void;\n /** 外层(轨道与滑块的容器)的部件属性 */\n propsRoot?: PartProps<'div'>;\n /** 轨道的部件属性 */\n propsTrack?: PartProps<'div'>;\n /** 已选范围(轨道上着色的部分)的部件属性;位置与长度由组件写 */\n propsRange?: PartProps<'div'>;\n /** 刻度点的部件属性 */\n propsMark?: PartProps<'span'> | ((mark: SliderMark) => PartProps<'span'>);\n /** 刻度文字的部件属性 */\n propsMarkLabel?: PartProps<'span'> | ((mark: SliderMark) => PartProps<'span'>);\n}\n\n/** Slider 的样式:root、horizontal、vertical、disabled、readonly、track、range、thumb、mark、markLabel 等 */\nexport const sliderStyles = css.create({\n root: {\n position: 'relative',\n display: 'flex',\n alignItems: 'center',\n // 触摸拖动不触发页面滚动\n touchAction: 'none',\n userSelect: 'none',\n cursor: 'pointer',\n },\n // 点击区域至少 24px(WCAG 2.5.8)。滑块的中心对准取值,两端各留半个滑块的外边距:\n // 滑块在最小、最大值时不伸出组件的盒子,不压到旁边的控件\n horizontal: {\n width: `calc(100% - ${t.space.lg} - ${t.space.xs})`,\n marginInline: `calc((${t.space.lg} + ${t.space.xs}) / 2)`,\n minHeight: '_minTarget',\n },\n vertical: {\n flexDirection: 'column',\n height: '10em',\n marginBlock: `calc((${t.space.lg} + ${t.space.xs}) / 2)`,\n minWidth: '_minTarget',\n },\n // 刻度文字放在轨道下方(纵向时右侧),给它留出位置\n labelledHorizontal: { paddingBlockEnd: '1.5em' },\n labelledVertical: { paddingInlineEnd: '3em' },\n disabled: { opacity: '_disabled', cursor: 'not-allowed' },\n readonly: { cursor: 'default' },\n track: {\n position: 'relative',\n flexGrow: 1,\n borderRadius: '_full',\n backgroundColor: '_fill',\n overflow: 'hidden',\n },\n trackHorizontal: { height: `calc(${t.space.xs} * 1.5)` },\n trackVertical: { width: `calc(${t.space.xs} * 1.5)` },\n range: { position: 'absolute', backgroundColor: 'var(--tone-fill)' },\n rangeHorizontal: { insetBlock: 0 },\n rangeVertical: { insetInline: 0 },\n thumb: {\n position: 'absolute',\n boxSizing: 'border-box',\n width: `calc(${t.space.lg} + ${t.space.xs})`,\n height: `calc(${t.space.lg} + ${t.space.xs})`,\n borderWidth: '_sm',\n borderStyle: 'solid',\n borderColor: 'var(--tone-fill)',\n borderRadius: '_full',\n backgroundColor: '_surface',\n boxShadow: '_sm',\n cursor: 'grab',\n },\n // 用逻辑方向的外边距把滑块的中心对准取值位置:从右到左排版时也对\n thumbHorizontal: { marginInlineStart: `calc((${t.space.lg} + ${t.space.xs}) / -2)` },\n thumbVertical: { marginBottom: `calc((${t.space.lg} + ${t.space.xs}) / -2)` },\n // 轨道里的小圆点;在已选范围里时换成反色\n mark: {\n position: 'absolute',\n width: '_space.xs',\n height: '_space.xs',\n borderRadius: '_full',\n backgroundColor: '_borderStrong',\n pointerEvents: 'none',\n },\n markHorizontal: { top: '50%', translate: { default: '-50% -50%', ':dir(rtl)': '50% -50%' } },\n markVertical: { left: '50%', translate: '-50% 50%' },\n markActive: { backgroundColor: 'var(--tone-on-fill)' },\n markLabel: {\n position: 'absolute',\n fontSize: '_sm',\n lineHeight: '_tight',\n color: '_textMuted',\n whiteSpace: 'nowrap',\n pointerEvents: 'none',\n },\n markLabelHorizontal: {\n top: `calc(50% + ${t.space.sm})`,\n translate: { default: '-50% -0.75em', ':dir(rtl)': '50% -0.75em' },\n },\n markLabelVertical: { left: `calc(50% + ${t.space.md})`, translate: '0 50%' },\n});\n\n// 位置是任意值,用动态样式(编译为 CSS 变量);单独一个 create,见 COMPONENTS.md §4\n/** Slider 的样式:inline(横向的起点)、size(横向的长度)、bottom、height(纵向) */\nexport const sliderPositionStyles = css.create({\n inline: (percent: string) => ({ insetInlineStart: percent }),\n width: (percent: string) => ({ width: percent }),\n bottom: (percent: string) => ({ bottom: percent }),\n height: (percent: string) => ({ height: percent }),\n});\n\n/** 滑块:在 min–max 之间按 step 拖动或用键盘选值;value 为 [低, 高] 时选一个范围 */\nexport const Slider = _component(\n <V extends SliderValue = number>({\n _value: value = _bindable<V>(0 as V),\n min = 0,\n max = 100,\n step = 1,\n bigStep,\n orientation = 'horizontal',\n disabled,\n readonly,\n size,\n tone = 'accent',\n marks,\n valueText,\n name,\n onValueCommit,\n propsRoot,\n propsTrack,\n propsRange,\n propsMark,\n propsMarkLabel,\n id,\n ...rest\n }: SliderProps<V>) => {\n const lang = useLang();\n // 在 Field 里时:标签作为名称、关联说明与错误、沿用不可用与只读\n const control = useFieldControl(() => ({ id, disabled, readonly }));\n /** 不接受改值:不可用或只读 */\n const off = () => control().disabled || control().readonly;\n const labelId = useId();\n let track = _state.raw<HTMLElement | null>(null);\n const thumbs: (HTMLElement | null)[] = [null, null];\n\n const isRange = () => Array.isArray(value);\n /** 各滑块的值(单值时只有一个) */\n const values = (): number[] => (Array.isArray(value) ? [...value] : [value as number]);\n /** 夹在范围内并对齐到步长 */\n const snap = (raw: number) => snapToStep(raw, step, min, max);\n const rtl = () => orientation === 'horizontal' && !!track && isRtl(track);\n\n /** 第 index 个滑块能取的范围:范围选择时不能越过另一个 */\n function bounds(index: number): [number, number] {\n if (!isRange()) return [min, max];\n const [low, high] = values() as [number, number];\n return index === 0 ? [min, high] : [low, max];\n }\n\n /** 改第 index 个滑块的值 */\n function set(index: number, raw: number) {\n const [lower, upper] = bounds(index);\n const next = clamp(snap(raw), lower, upper);\n if (!isRange()) {\n value = next as V;\n return;\n }\n const pair = values() as [number, number];\n pair[index] = next;\n value = pair as unknown as V;\n }\n\n /** 指针位置对应的值 */\n function valueAt(clientX: number, clientY: number) {\n const rect = track!.getBoundingClientRect();\n let ratio =\n orientation === 'vertical'\n ? (rect.bottom - clientY) / rect.height\n : (clientX - rect.left) / rect.width;\n if (rtl()) ratio = 1 - ratio;\n return snap(min + clamp(ratio, 0, 1) * (max - min));\n }\n\n /** 离 target 最近的滑块;两个重合时按方向选(往高处去的拿高的那个) */\n function nearest(target: number) {\n if (!isRange()) return 0;\n const [low, high] = values() as [number, number];\n if (low === high) return target > high ? 1 : 0;\n return Math.abs(target - low) <= Math.abs(target - high) ? 0 : 1;\n }\n\n function grab(event: PointerEvent) {\n if (off() || event.button !== 0 || !track) return;\n // 不让浏览器把焦点放到别处、开始选中文字;焦点交给滑块,键盘接着可以微调\n event.preventDefault();\n const target = valueAt(event.clientX, event.clientY);\n const index = nearest(target);\n thumbs[index]?.focus();\n set(index, target);\n startMove(event, {\n onMove: ({ clientX, clientY }) => set(index, valueAt(clientX, clientY)),\n onEnd: () => onValueCommit?.(value),\n });\n }\n\n function onKeydown(index: number, event: KeyboardEvent) {\n if (off()) return;\n const current = values()[index]!;\n const big = bigStep ?? Math.max(step, (max - min) / 10);\n // 从右到左排版时,横向的左右键反过来(右边是起点)\n const { forward, backward } = inlineArrows(rtl());\n const [lower, upper] = bounds(index);\n const next: Record<string, number> = {\n [forward]: current + step,\n ArrowUp: current + step,\n [backward]: current - step,\n ArrowDown: current - step,\n PageUp: current + big,\n PageDown: current - big,\n Home: lower,\n End: upper,\n };\n if (!(event.key in next)) return;\n event.preventDefault();\n set(index, next[event.key]!);\n onValueCommit?.(value);\n }\n\n const percentOf = (number: number) =>\n max > min ? ((clamp(number, min, max) - min) / (max - min)) * 100 : 0;\n\n return () => {\n const vertical = orientation === 'vertical';\n const field = control();\n const range = isRange();\n // 父级传入超出范围的值时按范围内显示(不改父级的值),滑块不会跑出轨道\n const shown = values().map((number) => clamp(number, min, max));\n const [start, end] = range\n ? [percentOf(shown[0]!), percentOf(shown[1]!)]\n : [0, percentOf(shown[0]!)];\n const normalized = (marks ?? []).map((mark) =>\n typeof mark === 'number' ? { value: mark } : mark,\n );\n const labelled = normalized.some((mark) => mark.label != null);\n const position = (percent: number) =>\n vertical\n ? sliderPositionStyles.bottom(`${percent}%`)\n : sliderPositionStyles.inline(`${percent}%`);\n\n const renderThumb = (number: number, index: number) => {\n const [lower, upper] = bounds(index);\n const part = range ? (index === 0 ? lang.sliderMin : lang.sliderMax) : undefined;\n const ownLabel = rest['aria-label'];\n // 范围时每个滑块的名称后面加“最小值 / 最大值”:有 aria-label 时拼在一起,用 Field 的标签时连上隐藏的文字\n const labelledBy = defaultLabelledBy(rest, field.labelledBy);\n return (\n <div\n key={index}\n {...mergeAttrs<'div'>(\n {\n sx: [\n sliderStyles.thumb,\n focusRingStyles.visible,\n vertical ? sliderStyles.thumbVertical : sliderStyles.thumbHorizontal,\n position(percentOf(number)),\n ],\n },\n rest,\n {\n ref: (element: unknown) => (thumbs[index] = element as HTMLElement | null),\n role: 'slider',\n id: index === 0 ? field.id : undefined,\n tabindex: field.disabled ? undefined : 0,\n 'aria-valuemin': lower,\n 'aria-valuemax': upper,\n 'aria-valuenow': number,\n 'aria-valuetext': valueText?.(number),\n 'aria-orientation': orientation,\n 'aria-disabled': field.disabled || undefined,\n 'aria-readonly': field.readonly || undefined,\n 'aria-label': part && ownLabel != null ? `${ownLabel} ${part}` : ownLabel,\n 'aria-labelledby':\n part && labelledBy ? `${labelledBy} ${labelId}-${index}` : labelledBy,\n 'aria-describedby': field.describedBy,\n 'aria-invalid': field.invalid || undefined,\n onKeydown: (event: KeyboardEvent) => onKeydown(index, event),\n },\n )}\n data-index={range ? index : undefined}\n >\n {part && labelledBy && (\n <VisuallyHidden id={`${labelId}-${index}`}>{part}</VisuallyHidden>\n )}\n </div>\n );\n };\n\n return (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n sliderStyles.root,\n vertical ? sliderStyles.vertical : sliderStyles.horizontal,\n labelled &&\n (vertical ? sliderStyles.labelledVertical : sliderStyles.labelledHorizontal),\n toneFillStyles[tone],\n size && fontSizeStyles[size],\n ],\n },\n propsRoot,\n {\n sx: [\n field.readonly && sliderStyles.readonly,\n field.disabled && sliderStyles.disabled,\n ],\n onPointerdown: grab,\n },\n )}\n data-disabled={field.disabled || undefined}\n data-readonly={field.readonly || undefined}\n data-orientation={orientation}\n data-range={range || undefined}\n >\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n sliderStyles.track,\n vertical ? sliderStyles.trackVertical : sliderStyles.trackHorizontal,\n ],\n },\n propsTrack,\n { ref: _toRef(track) },\n )}\n >\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n sliderStyles.range,\n vertical ? sliderStyles.rangeVertical : sliderStyles.rangeHorizontal,\n ],\n },\n propsRange,\n {\n sx: [\n position(start),\n vertical\n ? sliderPositionStyles.height(`${end - start}%`)\n : sliderPositionStyles.width(`${end - start}%`),\n ],\n },\n )}\n />\n {normalized.map((mark) => {\n const percent = percentOf(mark.value);\n const own = typeof propsMark === 'function' ? propsMark(mark) : propsMark;\n return (\n <span\n key={mark.value}\n {...mergeAttrs<'span'>(\n {\n sx: [\n sliderStyles.mark,\n vertical ? sliderStyles.markVertical : sliderStyles.markHorizontal,\n percent >= start && percent <= end && sliderStyles.markActive,\n ],\n },\n own,\n { sx: position(percent) },\n )}\n />\n );\n })}\n </div>\n {shown.map(renderThumb)}\n {normalized.map((mark) => {\n if (mark.label == null) return null;\n const own =\n typeof propsMarkLabel === 'function' ? propsMarkLabel(mark) : propsMarkLabel;\n return (\n <span\n key={mark.value}\n {...mergeAttrs<'span'>(\n {\n sx: [\n sliderStyles.markLabel,\n vertical ? sliderStyles.markLabelVertical : sliderStyles.markLabelHorizontal,\n ],\n },\n own,\n { sx: position(percentOf(mark.value)), 'aria-hidden': true },\n )}\n >\n {mark.label}\n </span>\n );\n })}\n <FormValue name={name} value={range ? shown : shown[0]} disabled={control().disabled} />\n </div>\n );\n };\n },\n);\n"],"mappings":"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"}
@@ -5,8 +5,8 @@ import { useDelayedLoading } from "../utils/motion/delayed-loading.js";
5
5
  import { Spinner } from "../base/Spinner.js";
6
6
  import { useFieldControl } from "../form/Field.js";
7
7
  import { choiceInputStyles, choiceParts, syncChecked, useChoiceAppearance } from "./choice-styles.js";
8
- import { createVNode, mergeProps } from "vue";
9
- import { _component, bindable, childrenProp, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
8
+ import { createVNode } from "vue";
9
+ import { _component, bindable, childrenProp, 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/input/Switch.tsx
12
12
  /** 角色、勾选状态与可用性由组件管理;原生的 size 属性让给字号档位 */
@@ -120,7 +120,7 @@ var Switch = /*#__PURE__*/ _component((_props, _ctx) => {
120
120
  on ? switchStyles.contentOn : switchStyles.contentOff,
121
121
  on !== checked.value && switchStyles.contentHidden
122
122
  ] }, propsContent.value, { "aria-hidden": true }), [createVNode("span", mergeAttrs({ sx: switchStyles.contentText }, propsContentText.value), [child])]);
123
- return createVNode("label", mergeProps(mergeAttrs(s.root, propsRoot.value), {
123
+ return createVNode("label", mergeJsxProps(mergeAttrs(s.root, propsRoot.value), {
124
124
  "data-state": checked.value ? "checked" : "unchecked",
125
125
  "data-disabled": state.disabled || void 0,
126
126
  "data-readonly": state.readonly || void 0,
@@ -1 +1 @@
1
- {"version":3,"file":"Switch.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_createVNode","_mergeProps"],"sources":["../../src/input/Switch.tsx"],"sourcesContent":["/**\n * 开关(原生 input type=\"checkbox\" + role=\"switch\"):立即生效的开 / 关设置,如“接收通知”。\n * 需要提交才生效的选项用 Checkbox。结构与样式见 choice-styles.ts:input 画成轨道,滑块叠在上面。\n *\n * <Switch _checked={notify}>接收通知</Switch>\n *\n * 读屏念“开关,开 / 关”;空格切换(原生)。在 Field 里时关联说明与错误、沿用其状态。\n * 切换要等接口时用 loading:滑块里转圈、点击无效。轨道里可以放文字或图标(checkedContent / uncheckedContent),对读屏隐藏。\n * 部件:Root(label)、Control(叠放层)、Thumb(滑块)、Content(轨道里的文字)、ContentText(文字的字号层)、Spinner、Label(文字);未声明的属性落到 input 上。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { VNodeChild } from 'vue';\nimport { useFieldControl } from '../form/Field';\nimport { Spinner, type SpinnerProps } from '../base/Spinner';\nimport { useDelayedLoading } from '../utils/motion/delayed-loading';\nimport { hasContent, mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { focusRingStyles } from '../utils/style/styles';\nimport type { StatusTone } from '../utils/style/tone-styles';\nimport type { TextSize } from '../utils/style/typography';\nimport { choiceInputStyles, choiceParts, syncChecked, useChoiceAppearance } from './choice-styles';\nimport { t } from '../config/theme/tokens';\n\n/** 角色、勾选状态与可用性由组件管理;原生的 size 属性让给字号档位 */\nexport type SwitchManaged =\n | 'type'\n | 'role'\n | 'checked'\n | 'disabled'\n | 'required'\n | 'size'\n | 'aria-invalid'\n | 'aria-describedby'\n | 'aria-busy';\n\n/** 未声明的属性落到 input 上;外层 label 用 propsRoot */\nexport interface SwitchProps extends PartProps<'input', SwitchManaged> {\n /** 是否打开:父级写 _checked={x} */\n _checked?: boolean;\n /** 不可用 */\n disabled?: boolean;\n /** 只读:能聚焦、读屏念“只读”,不能切换(查看详情、审批时);外观照常 */\n readonly?: boolean;\n /** 必填 */\n required?: boolean;\n /** 校验未通过 */\n invalid?: boolean;\n /** 切换中(如等接口返回):滑块里显示加载指示,点击无效,带 aria-busy */\n loading?: boolean;\n /** 打开时轨道里的文字或图标(如“开”、对勾);给了它或 uncheckedContent 时轨道随内容加宽 */\n checkedContent?: VNodeChild;\n /** 关闭时轨道里的文字或图标 */\n uncheckedContent?: VNodeChild;\n /** 字号档位;不写时继承上下文字号 */\n size?: TextSize;\n /** 打开时轨道的色调(与 Button、Badge 等同一套),默认 accent;可以用 defaults.Choice 统一改 */\n tone?: StatusTone;\n /** 外层 label 的部件属性 */\n propsRoot?: PartProps<'label'>;\n /** 叠放层的部件属性 */\n propsControl?: PartProps<'span'>;\n /** 滑块的部件属性 */\n propsThumb?: PartProps<'span'>;\n /** 轨道里文字(开、关两份)的部件属性 */\n propsContent?: PartProps<'span'>;\n /** 轨道里文字的内层(定字号、字重)的部件属性;改字号写这里,外层的内边距才仍按开关的字号算 */\n propsContentText?: PartProps<'span'>;\n /** 加载指示的部件属性 */\n propsSpinner?: Partial<SpinnerProps>;\n /** 文字的部件属性 */\n propsLabel?: PartProps<'span'>;\n /** 文字 */\n children?: VNodeChild;\n}\n\n/** Switch 的样式:track、trackWide、trackOff、thumb、thumbOn、content、contentOn、contentOff、contentHidden、contentText、spinner */\nexport const switchStyles = css.create({\n track: { width: '2.25em', height: '1.25em', borderRadius: '_full', borderColor: 'transparent' },\n // 轨道里有文字:宽度随文字(两份文字叠在同一格里,取较宽的,切换时宽度不跳)\n trackWide: { width: '_full', minWidth: '2.25em' },\n trackOff: { backgroundColor: '_borderStrong' },\n // 滑块靠起始边,打开后移到结束边:用逻辑方向的外边距,从右到左排版自动反过来\n thumb: {\n display: 'grid',\n placeItems: 'center',\n justifySelf: 'start',\n width: '0.875em',\n height: '0.875em',\n marginInlineStart: '0.1875em',\n borderRadius: '_full',\n backgroundColor: '_background',\n boxShadow: '_sm',\n transition: `margin-inline-start ${t.durations.sm} ${t.easings.standard}`,\n },\n // 移到结束边:百分比相对整条轨道,轨道随文字加宽时同样贴边\n thumbOn: { marginInlineStart: 'calc(100% - 1.0625em)', backgroundColor: 'var(--tone-on-fill)' },\n // 用 flex 居中:按行内文字排时随外层的行高落在基线上,图标会比轨道中线偏下\n content: {\n gridArea: '1 / 1',\n justifySelf: 'stretch',\n alignSelf: 'center',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n whiteSpace: 'nowrap',\n pointerEvents: 'none',\n },\n // 文字在滑块的另一侧\n contentOn: {\n paddingInlineStart: '0.5em',\n paddingInlineEnd: '1.375em',\n color: 'var(--tone-on-fill)',\n },\n contentOff: { paddingInlineStart: '1.375em', paddingInlineEnd: '0.5em', color: '_text' },\n contentHidden: { visibility: 'hidden' },\n // 字号缩在里层:外层的内边距按开关的字号算,给滑块留的位置才够\n contentText: {\n display: 'flex',\n alignItems: 'center',\n fontSize: '_xs',\n fontWeight: '_semibold',\n lineHeight: 1,\n },\n spinner: { width: '0.75em', height: '0.75em', color: 'var(--tone-fill)' },\n});\n\n/** 开关:立即生效的开 / 关 */\nexport const Switch = _component(\n ({\n _checked: checked = _bindable(false),\n disabled,\n readonly,\n required,\n invalid,\n size,\n tone,\n loading = false,\n checkedContent,\n uncheckedContent,\n id,\n propsRoot,\n propsControl,\n propsThumb,\n propsContent,\n propsContentText,\n propsSpinner,\n propsLabel,\n children,\n ...rest\n }: SwitchProps) => {\n const control = useFieldControl(() => ({ id, invalid, required, disabled, readonly }));\n const appearance = useChoiceAppearance(() => ({ size, tone }));\n // 很快完成的切换不闪加载指示;点击拦截、aria-busy 按真实的 loading\n const spinner = useDelayedLoading(() => loading);\n return () => {\n const state = control();\n const s = choiceParts(appearance(), { disabled: state.disabled, readonly: state.readonly });\n const wide = checkedContent != null || uncheckedContent != null;\n const content = (on: boolean, child: VNodeChild) => (\n <span\n {...mergeAttrs<'span'>(\n {\n sx: [\n switchStyles.content,\n on ? switchStyles.contentOn : switchStyles.contentOff,\n on !== checked && switchStyles.contentHidden,\n ],\n },\n propsContent,\n { 'aria-hidden': true },\n )}\n >\n <span {...mergeAttrs<'span'>({ sx: switchStyles.contentText }, propsContentText)}>\n {child}\n </span>\n </span>\n );\n return (\n <label\n {...mergeAttrs<'label'>(s.root, propsRoot)}\n data-state={checked ? 'checked' : 'unchecked'}\n data-disabled={state.disabled || undefined}\n data-readonly={state.readonly || undefined}\n data-loading={loading || undefined}\n >\n <span {...mergeAttrs<'span'>(s.control, propsControl)}>\n <input\n {...mergeAttrs<'input'>(\n {\n ...s.input,\n sx: [\n s.input.sx,\n focusRingStyles.tight,\n switchStyles.track,\n wide && switchStyles.trackWide,\n checked ? choiceInputStyles.checked : switchStyles.trackOff,\n state.invalid && choiceInputStyles.invalid,\n ],\n },\n rest,\n {\n type: 'checkbox',\n role: 'switch',\n id: state.id,\n checked,\n disabled: state.disabled,\n required: state.required,\n 'aria-invalid': state.invalid || undefined,\n 'aria-readonly': state.readonly || undefined,\n 'aria-describedby': state.describedBy,\n 'aria-busy': loading || undefined,\n // 切换中、只读时不接受切换:拦下 click,勾选状态就不变\n onClick: (event: MouseEvent) => {\n if (loading || state.readonly) event.preventDefault();\n },\n onChange: (event: Event) => {\n const target = event.target as HTMLInputElement;\n checked = target.checked;\n syncChecked([target], () => checked);\n },\n },\n )}\n />\n {wide && content(true, checkedContent)}\n {wide && content(false, uncheckedContent)}\n <span\n {...mergeAttrs<'span'>(\n {\n ...s.indicator,\n sx: [s.indicator.sx, switchStyles.thumb, checked && switchStyles.thumbOn],\n },\n propsThumb,\n )}\n >\n {spinner.value && (\n <Spinner\n {...mergePartProps<SpinnerProps>(\n { propsIcon: { sx: switchStyles.spinner } },\n propsSpinner,\n )}\n />\n )}\n </span>\n </span>\n {hasContent(children) && (\n <span {...mergeAttrs<'span'>(s.label, propsLabel)}>{children}</span>\n )}\n </label>\n );\n };\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"Switch.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_createVNode","_mergeProps"],"sources":["../../src/input/Switch.tsx"],"sourcesContent":["/**\n * 开关(原生 input type=\"checkbox\" + role=\"switch\"):立即生效的开 / 关设置,如“接收通知”。\n * 需要提交才生效的选项用 Checkbox。结构与样式见 choice-styles.ts:input 画成轨道,滑块叠在上面。\n *\n * <Switch _checked={notify}>接收通知</Switch>\n *\n * 读屏念“开关,开 / 关”;空格切换(原生)。在 Field 里时关联说明与错误、沿用其状态。\n * 切换要等接口时用 loading:滑块里转圈、点击无效。轨道里可以放文字或图标(checkedContent / uncheckedContent),对读屏隐藏。\n * 部件:Root(label)、Control(叠放层)、Thumb(滑块)、Content(轨道里的文字)、ContentText(文字的字号层)、Spinner、Label(文字);未声明的属性落到 input 上。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { VNodeChild } from 'vue';\nimport { useFieldControl } from '../form/Field';\nimport { Spinner, type SpinnerProps } from '../base/Spinner';\nimport { useDelayedLoading } from '../utils/motion/delayed-loading';\nimport { hasContent, mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { focusRingStyles } from '../utils/style/styles';\nimport type { StatusTone } from '../utils/style/tone-styles';\nimport type { TextSize } from '../utils/style/typography';\nimport { choiceInputStyles, choiceParts, syncChecked, useChoiceAppearance } from './choice-styles';\nimport { t } from '../config/theme/tokens';\n\n/** 角色、勾选状态与可用性由组件管理;原生的 size 属性让给字号档位 */\nexport type SwitchManaged =\n | 'type'\n | 'role'\n | 'checked'\n | 'disabled'\n | 'required'\n | 'size'\n | 'aria-invalid'\n | 'aria-describedby'\n | 'aria-busy';\n\n/** 未声明的属性落到 input 上;外层 label 用 propsRoot */\nexport interface SwitchProps extends PartProps<'input', SwitchManaged> {\n /** 是否打开:父级写 _checked={x} */\n _checked?: boolean;\n /** 不可用 */\n disabled?: boolean;\n /** 只读:能聚焦、读屏念“只读”,不能切换(查看详情、审批时);外观照常 */\n readonly?: boolean;\n /** 必填 */\n required?: boolean;\n /** 校验未通过 */\n invalid?: boolean;\n /** 切换中(如等接口返回):滑块里显示加载指示,点击无效,带 aria-busy */\n loading?: boolean;\n /** 打开时轨道里的文字或图标(如“开”、对勾);给了它或 uncheckedContent 时轨道随内容加宽 */\n checkedContent?: VNodeChild;\n /** 关闭时轨道里的文字或图标 */\n uncheckedContent?: VNodeChild;\n /** 字号档位;不写时继承上下文字号 */\n size?: TextSize;\n /** 打开时轨道的色调(与 Button、Badge 等同一套),默认 accent;可以用 defaults.Choice 统一改 */\n tone?: StatusTone;\n /** 外层 label 的部件属性 */\n propsRoot?: PartProps<'label'>;\n /** 叠放层的部件属性 */\n propsControl?: PartProps<'span'>;\n /** 滑块的部件属性 */\n propsThumb?: PartProps<'span'>;\n /** 轨道里文字(开、关两份)的部件属性 */\n propsContent?: PartProps<'span'>;\n /** 轨道里文字的内层(定字号、字重)的部件属性;改字号写这里,外层的内边距才仍按开关的字号算 */\n propsContentText?: PartProps<'span'>;\n /** 加载指示的部件属性 */\n propsSpinner?: Partial<SpinnerProps>;\n /** 文字的部件属性 */\n propsLabel?: PartProps<'span'>;\n /** 文字 */\n children?: VNodeChild;\n}\n\n/** Switch 的样式:track、trackWide、trackOff、thumb、thumbOn、content、contentOn、contentOff、contentHidden、contentText、spinner */\nexport const switchStyles = css.create({\n track: { width: '2.25em', height: '1.25em', borderRadius: '_full', borderColor: 'transparent' },\n // 轨道里有文字:宽度随文字(两份文字叠在同一格里,取较宽的,切换时宽度不跳)\n trackWide: { width: '_full', minWidth: '2.25em' },\n trackOff: { backgroundColor: '_borderStrong' },\n // 滑块靠起始边,打开后移到结束边:用逻辑方向的外边距,从右到左排版自动反过来\n thumb: {\n display: 'grid',\n placeItems: 'center',\n justifySelf: 'start',\n width: '0.875em',\n height: '0.875em',\n marginInlineStart: '0.1875em',\n borderRadius: '_full',\n backgroundColor: '_background',\n boxShadow: '_sm',\n transition: `margin-inline-start ${t.durations.sm} ${t.easings.standard}`,\n },\n // 移到结束边:百分比相对整条轨道,轨道随文字加宽时同样贴边\n thumbOn: { marginInlineStart: 'calc(100% - 1.0625em)', backgroundColor: 'var(--tone-on-fill)' },\n // 用 flex 居中:按行内文字排时随外层的行高落在基线上,图标会比轨道中线偏下\n content: {\n gridArea: '1 / 1',\n justifySelf: 'stretch',\n alignSelf: 'center',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n whiteSpace: 'nowrap',\n pointerEvents: 'none',\n },\n // 文字在滑块的另一侧\n contentOn: {\n paddingInlineStart: '0.5em',\n paddingInlineEnd: '1.375em',\n color: 'var(--tone-on-fill)',\n },\n contentOff: { paddingInlineStart: '1.375em', paddingInlineEnd: '0.5em', color: '_text' },\n contentHidden: { visibility: 'hidden' },\n // 字号缩在里层:外层的内边距按开关的字号算,给滑块留的位置才够\n contentText: {\n display: 'flex',\n alignItems: 'center',\n fontSize: '_xs',\n fontWeight: '_semibold',\n lineHeight: 1,\n },\n spinner: { width: '0.75em', height: '0.75em', color: 'var(--tone-fill)' },\n});\n\n/** 开关:立即生效的开 / 关 */\nexport const Switch = _component(\n ({\n _checked: checked = _bindable(false),\n disabled,\n readonly,\n required,\n invalid,\n size,\n tone,\n loading = false,\n checkedContent,\n uncheckedContent,\n id,\n propsRoot,\n propsControl,\n propsThumb,\n propsContent,\n propsContentText,\n propsSpinner,\n propsLabel,\n children,\n ...rest\n }: SwitchProps) => {\n const control = useFieldControl(() => ({ id, invalid, required, disabled, readonly }));\n const appearance = useChoiceAppearance(() => ({ size, tone }));\n // 很快完成的切换不闪加载指示;点击拦截、aria-busy 按真实的 loading\n const spinner = useDelayedLoading(() => loading);\n return () => {\n const state = control();\n const s = choiceParts(appearance(), { disabled: state.disabled, readonly: state.readonly });\n const wide = checkedContent != null || uncheckedContent != null;\n const content = (on: boolean, child: VNodeChild) => (\n <span\n {...mergeAttrs<'span'>(\n {\n sx: [\n switchStyles.content,\n on ? switchStyles.contentOn : switchStyles.contentOff,\n on !== checked && switchStyles.contentHidden,\n ],\n },\n propsContent,\n { 'aria-hidden': true },\n )}\n >\n <span {...mergeAttrs<'span'>({ sx: switchStyles.contentText }, propsContentText)}>\n {child}\n </span>\n </span>\n );\n return (\n <label\n {...mergeAttrs<'label'>(s.root, propsRoot)}\n data-state={checked ? 'checked' : 'unchecked'}\n data-disabled={state.disabled || undefined}\n data-readonly={state.readonly || undefined}\n data-loading={loading || undefined}\n >\n <span {...mergeAttrs<'span'>(s.control, propsControl)}>\n <input\n {...mergeAttrs<'input'>(\n {\n ...s.input,\n sx: [\n s.input.sx,\n focusRingStyles.tight,\n switchStyles.track,\n wide && switchStyles.trackWide,\n checked ? choiceInputStyles.checked : switchStyles.trackOff,\n state.invalid && choiceInputStyles.invalid,\n ],\n },\n rest,\n {\n type: 'checkbox',\n role: 'switch',\n id: state.id,\n checked,\n disabled: state.disabled,\n required: state.required,\n 'aria-invalid': state.invalid || undefined,\n 'aria-readonly': state.readonly || undefined,\n 'aria-describedby': state.describedBy,\n 'aria-busy': loading || undefined,\n // 切换中、只读时不接受切换:拦下 click,勾选状态就不变\n onClick: (event: MouseEvent) => {\n if (loading || state.readonly) event.preventDefault();\n },\n onChange: (event: Event) => {\n const target = event.target as HTMLInputElement;\n checked = target.checked;\n syncChecked([target], () => checked);\n },\n },\n )}\n />\n {wide && content(true, checkedContent)}\n {wide && content(false, uncheckedContent)}\n <span\n {...mergeAttrs<'span'>(\n {\n ...s.indicator,\n sx: [s.indicator.sx, switchStyles.thumb, checked && switchStyles.thumbOn],\n },\n propsThumb,\n )}\n >\n {spinner.value && (\n <Spinner\n {...mergePartProps<SpinnerProps>(\n { propsIcon: { sx: switchStyles.spinner } },\n propsSpinner,\n )}\n />\n )}\n </span>\n </span>\n {hasContent(children) && (\n <span {...mergeAttrs<'span'>(s.label, propsLabel)}>{children}</span>\n )}\n </label>\n );\n };\n },\n);\n"],"mappings":"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"}
@@ -11,8 +11,8 @@ import { controlClear, controlIcon, controlParts, focusOnShell, useControlAppear
11
11
  import { activeOptionId } from "./Listbox.js";
12
12
  import { FormValue } from "../form/FormValue.js";
13
13
  import { ListPopover } from "./ListPopover.js";
14
- import { Fragment, createVNode, isVNode, mergeProps, shallowRef, useId, vModelText, watch, withDirectives } from "vue";
15
- import { _component, bindable, childrenProp, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
14
+ import { Fragment, createVNode, isVNode, shallowRef, useId, vModelText, watch, withDirectives } from "vue";
15
+ import { _component, bindable, childrenProp, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
16
16
  import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
17
17
  //#region src/input/TagsInput.tsx
18
18
  /** 角色、展开状态与可用性由组件管理 */
@@ -198,7 +198,7 @@ var TagsInput = /*#__PURE__*/ _component((_props, _ctx) => {
198
198
  const state = control();
199
199
  const s = controlParts(appearance(), state);
200
200
  const editable = !state.disabled && !state.readonly;
201
- return createVNode(Fragment, null, [createVNode("div", mergeProps(mergeAttrs({
201
+ return createVNode(Fragment, null, [createVNode("div", mergeJsxProps(mergeAttrs({
202
202
  ...s.root,
203
203
  sx: [s.root.sx, tagsInputStyles.root]
204
204
  }, propsRoot.value, {
@@ -214,9 +214,9 @@ var TagsInput = /*#__PURE__*/ _component((_props, _ctx) => {
214
214
  value.value.map((tag) => {
215
215
  let _slot;
216
216
  const own = typeof propsTag.value === "function" ? propsTag.value(tag) : propsTag.value;
217
- return createVNode(Tag, mergeProps({ "key": tag }, mergePartProps({ variant: "surface" }, own, { onRemove: editable ? () => remove(tag) : void 0 }), { "data-tag": "" }), _isSlot(_slot = labelOf(tag)) ? _slot : { default: () => [_slot] });
217
+ return createVNode(Tag, mergeJsxProps({ "key": tag }, mergePartProps({ variant: "surface" }, own, { onRemove: editable ? () => remove(tag) : void 0 }), { "data-tag": "" }), _isSlot(_slot = labelOf(tag)) ? _slot : { default: () => [_slot] });
218
218
  }),
219
- withDirectives(createVNode("input", mergeProps(mergeAttrs({
219
+ withDirectives(createVNode("input", mergeJsxProps(mergeAttrs({
220
220
  ...s.input,
221
221
  sx: [s.input.sx, tagsInputStyles.input]
222
222
  }, rest, {