@zerodep-dev/vue-tsx-pro-ui 0.3.1 → 0.3.3

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 (620) hide show
  1. package/dist/base/Blockquote.d.ts +1 -1
  2. package/dist/base/Blockquote.js +1 -1
  3. package/dist/base/Blockquote.js.map +1 -1
  4. package/dist/base/ButtonGroup.d.ts +1 -1
  5. package/dist/base/ButtonGroup.js +1 -1
  6. package/dist/base/ButtonGroup.js.map +1 -1
  7. package/dist/base/Code.d.ts +1 -1
  8. package/dist/base/Code.js +1 -1
  9. package/dist/base/Code.js.map +1 -1
  10. package/dist/base/CodeBlock.d.ts +1 -1
  11. package/dist/base/CodeBlock.js +1 -1
  12. package/dist/base/CodeBlock.js.map +1 -1
  13. package/dist/base/CopyButton.d.ts +1 -1
  14. package/dist/base/CopyButton.js +1 -1
  15. package/dist/base/CopyButton.js.map +1 -1
  16. package/dist/base/Heading.d.ts +1 -1
  17. package/dist/base/Heading.js +1 -1
  18. package/dist/base/Heading.js.map +1 -1
  19. package/dist/base/Icon.d.ts +1 -1
  20. package/dist/base/Icon.js +1 -1
  21. package/dist/base/Icon.js.map +1 -1
  22. package/dist/base/Indicator.d.ts +1 -1
  23. package/dist/base/Indicator.js +1 -1
  24. package/dist/base/Indicator.js.map +1 -1
  25. package/dist/base/Kbd.d.ts +1 -1
  26. package/dist/base/Kbd.js +1 -1
  27. package/dist/base/Kbd.js.map +1 -1
  28. package/dist/base/Link.d.ts +1 -1
  29. package/dist/base/Link.js +1 -1
  30. package/dist/base/Link.js.map +1 -1
  31. package/dist/base/List.d.ts +1 -1
  32. package/dist/base/List.js +1 -1
  33. package/dist/base/List.js.map +1 -1
  34. package/dist/base/Mark.d.ts +1 -1
  35. package/dist/base/Mark.js +1 -1
  36. package/dist/base/Mark.js.map +1 -1
  37. package/dist/base/Spinner.d.ts +1 -1
  38. package/dist/base/Spinner.js +1 -1
  39. package/dist/base/Spinner.js.map +1 -1
  40. package/dist/base/StatusDot.d.ts +1 -1
  41. package/dist/base/StatusDot.js +1 -1
  42. package/dist/base/StatusDot.js.map +1 -1
  43. package/dist/base/Tag.d.ts +1 -1
  44. package/dist/base/Tag.js +1 -1
  45. package/dist/base/Tag.js.map +1 -1
  46. package/dist/base/Text.d.ts +1 -1
  47. package/dist/base/Text.js +1 -1
  48. package/dist/base/Text.js.map +1 -1
  49. package/dist/base/VisuallyHidden.d.ts +1 -1
  50. package/dist/base/VisuallyHidden.js +1 -1
  51. package/dist/base/VisuallyHidden.js.map +1 -1
  52. package/dist/base/badge-styles.d.ts +1 -1
  53. package/dist/base/badge-styles.js +1 -1
  54. package/dist/base/badge-styles.js.map +1 -1
  55. package/dist/base/button-core.d.ts +1 -1
  56. package/dist/base/button-core.js +1 -1
  57. package/dist/base/button-core.js.map +1 -1
  58. package/dist/charts/ChordChart.d.ts +1 -1
  59. package/dist/charts/ChordChart.js +1 -1
  60. package/dist/charts/ChordChart.js.map +1 -1
  61. package/dist/charts/DonutChart.d.ts +1 -1
  62. package/dist/charts/DonutChart.js +1 -1
  63. package/dist/charts/DonutChart.js.map +1 -1
  64. package/dist/charts/FunnelChart.d.ts +1 -1
  65. package/dist/charts/FunnelChart.js +1 -1
  66. package/dist/charts/FunnelChart.js.map +1 -1
  67. package/dist/charts/GraphChart.d.ts +1 -1
  68. package/dist/charts/GraphChart.js +1 -1
  69. package/dist/charts/GraphChart.js.map +1 -1
  70. package/dist/charts/MapChart.d.ts +1 -1
  71. package/dist/charts/MapChart.js +1 -1
  72. package/dist/charts/MapChart.js.map +1 -1
  73. package/dist/charts/RadarChart.d.ts +1 -1
  74. package/dist/charts/RadarChart.js +1 -1
  75. package/dist/charts/RadarChart.js.map +1 -1
  76. package/dist/charts/SankeyChart.d.ts +1 -1
  77. package/dist/charts/SankeyChart.js +1 -1
  78. package/dist/charts/SankeyChart.js.map +1 -1
  79. package/dist/charts/TreemapChart.d.ts +1 -1
  80. package/dist/charts/TreemapChart.js +1 -1
  81. package/dist/charts/TreemapChart.js.map +1 -1
  82. package/dist/charts/XYChart.d.ts +1 -1
  83. package/dist/charts/XYChart.js +1 -1
  84. package/dist/charts/XYChart.js.map +1 -1
  85. package/dist/charts/frame.d.ts +1 -1
  86. package/dist/charts/frame.js +1 -1
  87. package/dist/charts/frame.js.map +1 -1
  88. package/dist/code-editor/CodeEditor.js +1 -1
  89. package/dist/code-editor/CodeEditor.js.map +1 -1
  90. package/dist/config/Provider.d.ts +1 -1
  91. package/dist/config/Provider.js +1 -1
  92. package/dist/config/Provider.js.map +1 -1
  93. package/dist/config/createUi.d.ts +1 -1
  94. package/dist/config/createUi.js +1 -1
  95. package/dist/config/createUi.js.map +1 -1
  96. package/dist/config/theme/coffee.d.ts +1 -1
  97. package/dist/config/theme/coffee.js +1 -1
  98. package/dist/config/theme/coffee.js.map +1 -1
  99. package/dist/config/theme/cyberpunk.d.ts +1 -1
  100. package/dist/config/theme/cyberpunk.js +1 -1
  101. package/dist/config/theme/cyberpunk.js.map +1 -1
  102. package/dist/config/theme/dark.d.ts +1 -1
  103. package/dist/config/theme/dark.js +1 -1
  104. package/dist/config/theme/dark.js.map +1 -1
  105. package/dist/config/theme/festive.d.ts +1 -1
  106. package/dist/config/theme/festive.js +1 -1
  107. package/dist/config/theme/festive.js.map +1 -1
  108. package/dist/config/theme/forest.d.ts +1 -1
  109. package/dist/config/theme/forest.js +1 -1
  110. package/dist/config/theme/forest.js.map +1 -1
  111. package/dist/config/theme/high-contrast.d.ts +1 -1
  112. package/dist/config/theme/high-contrast.js +1 -1
  113. package/dist/config/theme/high-contrast.js.map +1 -1
  114. package/dist/config/theme/lemon.d.ts +1 -1
  115. package/dist/config/theme/lemon.js +1 -1
  116. package/dist/config/theme/lemon.js.map +1 -1
  117. package/dist/config/theme/light.d.ts +1 -1
  118. package/dist/config/theme/light.js +1 -1
  119. package/dist/config/theme/light.js.map +1 -1
  120. package/dist/config/theme/midnight.d.ts +1 -1
  121. package/dist/config/theme/midnight.js +1 -1
  122. package/dist/config/theme/midnight.js.map +1 -1
  123. package/dist/config/theme/ocean.d.ts +1 -1
  124. package/dist/config/theme/ocean.js +1 -1
  125. package/dist/config/theme/ocean.js.map +1 -1
  126. package/dist/config/theme/paper.d.ts +1 -1
  127. package/dist/config/theme/paper.js +1 -1
  128. package/dist/config/theme/paper.js.map +1 -1
  129. package/dist/config/theme/sakura.d.ts +1 -1
  130. package/dist/config/theme/sakura.js +1 -1
  131. package/dist/config/theme/sakura.js.map +1 -1
  132. package/dist/config/theme/theme.js +1 -1
  133. package/dist/config/theme/theme.js.map +1 -1
  134. package/dist/config/theme/tokens.d.ts +1 -1
  135. package/dist/config/theme/tokens.js +1 -1
  136. package/dist/config/theme/tokens.js.map +1 -1
  137. package/dist/date/CalendarBoard.d.ts +1 -1
  138. package/dist/date/CalendarBoard.js +1 -1
  139. package/dist/date/CalendarBoard.js.map +1 -1
  140. package/dist/date/CalendarView.d.ts +1 -1
  141. package/dist/date/CalendarView.js +1 -1
  142. package/dist/date/CalendarView.js.map +1 -1
  143. package/dist/date/Countdown.d.ts +1 -1
  144. package/dist/date/Countdown.js +1 -1
  145. package/dist/date/Countdown.js.map +1 -1
  146. package/dist/date/DatePicker.d.ts +1 -1
  147. package/dist/date/DatePicker.js +1 -1
  148. package/dist/date/DatePicker.js.map +1 -1
  149. package/dist/date/DateRangePicker.d.ts +1 -1
  150. package/dist/date/DateRangePicker.js +1 -1
  151. package/dist/date/DateRangePicker.js.map +1 -1
  152. package/dist/date/DateSegmentGroup.d.ts +1 -1
  153. package/dist/date/DateSegmentGroup.js +1 -1
  154. package/dist/date/DateSegmentGroup.js.map +1 -1
  155. package/dist/date/QuarterCalendar.js +1 -1
  156. package/dist/date/QuarterCalendar.js.map +1 -1
  157. package/dist/date/SegmentedField.d.ts +1 -1
  158. package/dist/date/SegmentedField.js +1 -1
  159. package/dist/date/SegmentedField.js.map +1 -1
  160. package/dist/date/TimePicker.d.ts +1 -1
  161. package/dist/date/TimePicker.js +1 -1
  162. package/dist/date/TimePicker.js.map +1 -1
  163. package/dist/date/picker-popover.d.ts +1 -1
  164. package/dist/date/picker-popover.js +1 -1
  165. package/dist/date/picker-popover.js.map +1 -1
  166. package/dist/diagram/Diagram.d.ts +1 -1
  167. package/dist/diagram/Diagram.js +1 -1
  168. package/dist/diagram/Diagram.js.map +1 -1
  169. package/dist/diagram/DiagramControls.d.ts +1 -1
  170. package/dist/diagram/DiagramControls.js +1 -1
  171. package/dist/diagram/DiagramControls.js.map +1 -1
  172. package/dist/diagram/DiagramLanes.d.ts +1 -1
  173. package/dist/diagram/DiagramLanes.js +1 -1
  174. package/dist/diagram/DiagramLanes.js.map +1 -1
  175. package/dist/diagram/DiagramMinimap.d.ts +1 -1
  176. package/dist/diagram/DiagramMinimap.js +1 -1
  177. package/dist/diagram/DiagramMinimap.js.map +1 -1
  178. package/dist/diagram/DiagramNode.d.ts +1 -1
  179. package/dist/diagram/DiagramNode.js +1 -1
  180. package/dist/diagram/DiagramNode.js.map +1 -1
  181. package/dist/display/Accordion.d.ts +1 -1
  182. package/dist/display/Accordion.js +1 -1
  183. package/dist/display/Accordion.js.map +1 -1
  184. package/dist/display/AnimatedNumber.d.ts +1 -1
  185. package/dist/display/AnimatedNumber.js +1 -1
  186. package/dist/display/AnimatedNumber.js.map +1 -1
  187. package/dist/display/Avatar.d.ts +1 -1
  188. package/dist/display/Avatar.js +1 -1
  189. package/dist/display/Avatar.js.map +1 -1
  190. package/dist/display/AvatarGroup.d.ts +1 -1
  191. package/dist/display/AvatarGroup.js +1 -1
  192. package/dist/display/AvatarGroup.js.map +1 -1
  193. package/dist/display/Card.d.ts +1 -1
  194. package/dist/display/Card.js +1 -1
  195. package/dist/display/Card.js.map +1 -1
  196. package/dist/display/Checklist.d.ts +1 -1
  197. package/dist/display/Checklist.js +1 -1
  198. package/dist/display/Checklist.js.map +1 -1
  199. package/dist/display/Collapse.d.ts +1 -1
  200. package/dist/display/Collapse.js +1 -1
  201. package/dist/display/Collapse.js.map +1 -1
  202. package/dist/display/Descriptions.d.ts +1 -1
  203. package/dist/display/Descriptions.js +1 -1
  204. package/dist/display/Descriptions.js.map +1 -1
  205. package/dist/display/Ellipsis.d.ts +1 -1
  206. package/dist/display/Ellipsis.js +1 -1
  207. package/dist/display/Ellipsis.js.map +1 -1
  208. package/dist/display/FieldCompare.d.ts +1 -1
  209. package/dist/display/FieldCompare.js +1 -1
  210. package/dist/display/FieldCompare.js.map +1 -1
  211. package/dist/display/Gauge.d.ts +1 -1
  212. package/dist/display/Gauge.js +1 -1
  213. package/dist/display/Gauge.js.map +1 -1
  214. package/dist/display/Image.d.ts +1 -1
  215. package/dist/display/Image.js +1 -1
  216. package/dist/display/Image.js.map +1 -1
  217. package/dist/display/ItemList.d.ts +1 -1
  218. package/dist/display/ItemList.js +1 -1
  219. package/dist/display/ItemList.js.map +1 -1
  220. package/dist/display/Marquee.d.ts +1 -1
  221. package/dist/display/Marquee.js +1 -1
  222. package/dist/display/Marquee.js.map +1 -1
  223. package/dist/display/ProportionBar.d.ts +1 -1
  224. package/dist/display/ProportionBar.js +1 -1
  225. package/dist/display/ProportionBar.js.map +1 -1
  226. package/dist/display/Sortable.d.ts +1 -1
  227. package/dist/display/Sortable.js +1 -1
  228. package/dist/display/Sortable.js.map +1 -1
  229. package/dist/display/Sparkline.d.ts +1 -1
  230. package/dist/display/Sparkline.js +1 -1
  231. package/dist/display/Sparkline.js.map +1 -1
  232. package/dist/display/Stat.d.ts +1 -1
  233. package/dist/display/Stat.js +1 -1
  234. package/dist/display/Stat.js.map +1 -1
  235. package/dist/display/Timeline.d.ts +1 -1
  236. package/dist/display/Timeline.js +1 -1
  237. package/dist/display/Timeline.js.map +1 -1
  238. package/dist/display/Tree.d.ts +1 -1
  239. package/dist/display/Tree.js +1 -1
  240. package/dist/display/Tree.js.map +1 -1
  241. package/dist/display/VirtualList.d.ts +2 -3
  242. package/dist/display/VirtualList.js +12 -22
  243. package/dist/display/VirtualList.js.map +1 -1
  244. package/dist/display/Watermark.d.ts +1 -1
  245. package/dist/display/Watermark.js +1 -1
  246. package/dist/display/Watermark.js.map +1 -1
  247. package/dist/docs-kit/CodeGroup.d.ts +1 -1
  248. package/dist/docs-kit/CodeGroup.js +1 -1
  249. package/dist/docs-kit/CodeGroup.js.map +1 -1
  250. package/dist/docs-kit/CodePreview.d.ts +1 -1
  251. package/dist/docs-kit/CodePreview.js +1 -1
  252. package/dist/docs-kit/CodePreview.js.map +1 -1
  253. package/dist/docs-kit/ColorSwatch.d.ts +1 -1
  254. package/dist/docs-kit/ColorSwatch.js +1 -1
  255. package/dist/docs-kit/ColorSwatch.js.map +1 -1
  256. package/dist/docs-kit/PropsTable.d.ts +1 -1
  257. package/dist/docs-kit/PropsTable.js +1 -1
  258. package/dist/docs-kit/PropsTable.js.map +1 -1
  259. package/dist/feedback/Alert.d.ts +1 -1
  260. package/dist/feedback/Alert.js +1 -1
  261. package/dist/feedback/Alert.js.map +1 -1
  262. package/dist/feedback/Banner.d.ts +1 -1
  263. package/dist/feedback/Banner.js +1 -1
  264. package/dist/feedback/Banner.js.map +1 -1
  265. package/dist/feedback/Empty.d.ts +1 -1
  266. package/dist/feedback/Empty.js +1 -1
  267. package/dist/feedback/Empty.js.map +1 -1
  268. package/dist/feedback/LoadingBar.d.ts +1 -1
  269. package/dist/feedback/LoadingBar.js +1 -1
  270. package/dist/feedback/LoadingBar.js.map +1 -1
  271. package/dist/feedback/LoadingOverlay.d.ts +1 -1
  272. package/dist/feedback/LoadingOverlay.js +1 -1
  273. package/dist/feedback/LoadingOverlay.js.map +1 -1
  274. package/dist/feedback/Progress.d.ts +1 -1
  275. package/dist/feedback/Progress.js +1 -1
  276. package/dist/feedback/Progress.js.map +1 -1
  277. package/dist/feedback/Result.d.ts +1 -1
  278. package/dist/feedback/Result.js +1 -1
  279. package/dist/feedback/Result.js.map +1 -1
  280. package/dist/feedback/Skeleton.d.ts +1 -1
  281. package/dist/feedback/Skeleton.js +1 -1
  282. package/dist/feedback/Skeleton.js.map +1 -1
  283. package/dist/feedback/SkeletonText.d.ts +1 -1
  284. package/dist/feedback/SkeletonText.js +1 -1
  285. package/dist/feedback/SkeletonText.js.map +1 -1
  286. package/dist/feedback/Toast.d.ts +1 -1
  287. package/dist/feedback/Toast.js +1 -1
  288. package/dist/feedback/Toast.js.map +1 -1
  289. package/dist/form/Field.d.ts +1 -1
  290. package/dist/form/Field.js +1 -1
  291. package/dist/form/Field.js.map +1 -1
  292. package/dist/form/FormErrorSummary.d.ts +1 -1
  293. package/dist/form/FormErrorSummary.js +1 -1
  294. package/dist/form/FormErrorSummary.js.map +1 -1
  295. package/dist/form/FormSection.d.ts +1 -1
  296. package/dist/form/FormSection.js +1 -1
  297. package/dist/form/FormSection.js.map +1 -1
  298. package/dist/form/schemas.d.ts +1 -1
  299. package/dist/form/schemas.js +1 -1
  300. package/dist/form/schemas.js.map +1 -1
  301. package/dist/input/Cascader.d.ts +1 -1
  302. package/dist/input/Cascader.js +1 -1
  303. package/dist/input/Cascader.js.map +1 -1
  304. package/dist/input/CharacterCount.d.ts +1 -1
  305. package/dist/input/CharacterCount.js +1 -1
  306. package/dist/input/CharacterCount.js.map +1 -1
  307. package/dist/input/Checkbox.d.ts +1 -1
  308. package/dist/input/Checkbox.js +1 -1
  309. package/dist/input/Checkbox.js.map +1 -1
  310. package/dist/input/ColorField.d.ts +1 -1
  311. package/dist/input/ColorField.js +1 -1
  312. package/dist/input/ColorField.js.map +1 -1
  313. package/dist/input/Combobox.d.ts +2 -2
  314. package/dist/input/Combobox.js +1 -1
  315. package/dist/input/Combobox.js.map +1 -1
  316. package/dist/input/ConditionBuilder.d.ts +1 -1
  317. package/dist/input/ConditionBuilder.js +1 -1
  318. package/dist/input/ConditionBuilder.js.map +1 -1
  319. package/dist/input/ControlGroup.d.ts +1 -1
  320. package/dist/input/ControlGroup.js +1 -1
  321. package/dist/input/ControlGroup.js.map +1 -1
  322. package/dist/input/FileDrop.d.ts +1 -1
  323. package/dist/input/FileDrop.js +1 -1
  324. package/dist/input/FileDrop.js.map +1 -1
  325. package/dist/input/ListPopover.d.ts +2 -2
  326. package/dist/input/ListPopover.js +1 -1
  327. package/dist/input/ListPopover.js.map +1 -1
  328. package/dist/input/Listbox.d.ts +2 -3
  329. package/dist/input/Listbox.js +8 -20
  330. package/dist/input/Listbox.js.map +1 -1
  331. package/dist/input/Mentions.d.ts +1 -1
  332. package/dist/input/Mentions.js +1 -1
  333. package/dist/input/Mentions.js.map +1 -1
  334. package/dist/input/NumberRangeField.d.ts +1 -1
  335. package/dist/input/NumberRangeField.js +1 -1
  336. package/dist/input/NumberRangeField.js.map +1 -1
  337. package/dist/input/OtpField.d.ts +1 -1
  338. package/dist/input/OtpField.js +1 -1
  339. package/dist/input/OtpField.js.map +1 -1
  340. package/dist/input/PeoplePicker.js +1 -1
  341. package/dist/input/PeoplePicker.js.map +1 -1
  342. package/dist/input/PeoplePickerPanel.d.ts +1 -1
  343. package/dist/input/PeoplePickerPanel.js +1 -1
  344. package/dist/input/PeoplePickerPanel.js.map +1 -1
  345. package/dist/input/Radio.d.ts +1 -1
  346. package/dist/input/Radio.js +1 -1
  347. package/dist/input/Radio.js.map +1 -1
  348. package/dist/input/Rating.d.ts +1 -1
  349. package/dist/input/Rating.js +1 -1
  350. package/dist/input/Rating.js.map +1 -1
  351. package/dist/input/Select.d.ts +2 -2
  352. package/dist/input/Select.js +1 -1
  353. package/dist/input/Select.js.map +1 -1
  354. package/dist/input/SelectedTags.d.ts +1 -1
  355. package/dist/input/SelectedTags.js +1 -1
  356. package/dist/input/SelectedTags.js.map +1 -1
  357. package/dist/input/Slider.d.ts +1 -1
  358. package/dist/input/Slider.js +1 -1
  359. package/dist/input/Slider.js.map +1 -1
  360. package/dist/input/Switch.d.ts +1 -1
  361. package/dist/input/Switch.js +1 -1
  362. package/dist/input/Switch.js.map +1 -1
  363. package/dist/input/TagsInput.d.ts +1 -1
  364. package/dist/input/TagsInput.js +1 -1
  365. package/dist/input/TagsInput.js.map +1 -1
  366. package/dist/input/Textarea.d.ts +1 -1
  367. package/dist/input/Textarea.js +1 -1
  368. package/dist/input/Textarea.js.map +1 -1
  369. package/dist/input/ToggleGroup.d.ts +1 -1
  370. package/dist/input/ToggleGroup.js +1 -1
  371. package/dist/input/ToggleGroup.js.map +1 -1
  372. package/dist/input/Transfer.d.ts +1 -1
  373. package/dist/input/Transfer.js +1 -1
  374. package/dist/input/Transfer.js.map +1 -1
  375. package/dist/input/TreeSelect.d.ts +1 -1
  376. package/dist/input/TreeSelect.js +1 -1
  377. package/dist/input/TreeSelect.js.map +1 -1
  378. package/dist/input/Upload.d.ts +1 -1
  379. package/dist/input/Upload.js +1 -1
  380. package/dist/input/Upload.js.map +1 -1
  381. package/dist/input/choice-styles.d.ts +1 -1
  382. package/dist/input/choice-styles.js +1 -1
  383. package/dist/input/choice-styles.js.map +1 -1
  384. package/dist/input/control.d.ts +1 -1
  385. package/dist/input/control.js +1 -1
  386. package/dist/input/control.js.map +1 -1
  387. package/dist/layout/Affix.d.ts +1 -1
  388. package/dist/layout/Affix.js +1 -1
  389. package/dist/layout/Affix.js.map +1 -1
  390. package/dist/layout/AsideLayout.d.ts +1 -1
  391. package/dist/layout/AsideLayout.js +1 -1
  392. package/dist/layout/AsideLayout.js.map +1 -1
  393. package/dist/layout/BackTop.d.ts +1 -1
  394. package/dist/layout/BackTop.js +1 -1
  395. package/dist/layout/BackTop.js.map +1 -1
  396. package/dist/layout/Container.d.ts +1 -1
  397. package/dist/layout/Container.js +1 -1
  398. package/dist/layout/Container.js.map +1 -1
  399. package/dist/layout/Flex.d.ts +1 -1
  400. package/dist/layout/Flex.js +1 -1
  401. package/dist/layout/Flex.js.map +1 -1
  402. package/dist/layout/Grid.d.ts +1 -1
  403. package/dist/layout/Grid.js +1 -1
  404. package/dist/layout/Grid.js.map +1 -1
  405. package/dist/layout/PageScrollbar.d.ts +1 -1
  406. package/dist/layout/PageScrollbar.js +1 -1
  407. package/dist/layout/PageScrollbar.js.map +1 -1
  408. package/dist/layout/Prose.d.ts +1 -1
  409. package/dist/layout/Prose.js +1 -1
  410. package/dist/layout/Prose.js.map +1 -1
  411. package/dist/layout/ResizeHandle.d.ts +1 -1
  412. package/dist/layout/ResizeHandle.js +1 -1
  413. package/dist/layout/ResizeHandle.js.map +1 -1
  414. package/dist/layout/ScrollArea.d.ts +1 -1
  415. package/dist/layout/ScrollArea.js +1 -1
  416. package/dist/layout/ScrollArea.js.map +1 -1
  417. package/dist/layout/Separator.d.ts +1 -1
  418. package/dist/layout/Separator.js +1 -1
  419. package/dist/layout/Separator.js.map +1 -1
  420. package/dist/layout/Splitter.d.ts +1 -1
  421. package/dist/layout/Splitter.js +1 -1
  422. package/dist/layout/Splitter.js.map +1 -1
  423. package/dist/layout/ViewportFill.d.ts +1 -1
  424. package/dist/layout/ViewportFill.js +1 -1
  425. package/dist/layout/ViewportFill.js.map +1 -1
  426. package/dist/navigation/Breadcrumbs.d.ts +1 -1
  427. package/dist/navigation/Breadcrumbs.js +1 -1
  428. package/dist/navigation/Breadcrumbs.js.map +1 -1
  429. package/dist/navigation/NavBar.d.ts +1 -1
  430. package/dist/navigation/NavBar.js +1 -1
  431. package/dist/navigation/NavBar.js.map +1 -1
  432. package/dist/navigation/NavList.d.ts +1 -1
  433. package/dist/navigation/NavList.js +1 -1
  434. package/dist/navigation/NavList.js.map +1 -1
  435. package/dist/navigation/PageJump.d.ts +1 -1
  436. package/dist/navigation/PageJump.js +1 -1
  437. package/dist/navigation/PageJump.js.map +1 -1
  438. package/dist/navigation/PageSizeSelect.d.ts +1 -1
  439. package/dist/navigation/PageSizeSelect.js +1 -1
  440. package/dist/navigation/PageSizeSelect.js.map +1 -1
  441. package/dist/navigation/Pager.d.ts +1 -1
  442. package/dist/navigation/Pager.js +1 -1
  443. package/dist/navigation/Pager.js.map +1 -1
  444. package/dist/navigation/Pagination.d.ts +1 -1
  445. package/dist/navigation/Pagination.js +1 -1
  446. package/dist/navigation/Pagination.js.map +1 -1
  447. package/dist/navigation/PaginationBar.d.ts +1 -1
  448. package/dist/navigation/PaginationBar.js +1 -1
  449. package/dist/navigation/PaginationBar.js.map +1 -1
  450. package/dist/navigation/SkipLink.d.ts +1 -1
  451. package/dist/navigation/SkipLink.js +1 -1
  452. package/dist/navigation/SkipLink.js.map +1 -1
  453. package/dist/navigation/Steps.d.ts +1 -1
  454. package/dist/navigation/Steps.js +1 -1
  455. package/dist/navigation/Steps.js.map +1 -1
  456. package/dist/navigation/TableOfContents.d.ts +1 -1
  457. package/dist/navigation/TableOfContents.js +1 -1
  458. package/dist/navigation/TableOfContents.js.map +1 -1
  459. package/dist/navigation/Tabs.d.ts +1 -1
  460. package/dist/navigation/Tabs.js +1 -1
  461. package/dist/navigation/Tabs.js.map +1 -1
  462. package/dist/navigation/Toolbar.d.ts +1 -1
  463. package/dist/navigation/Toolbar.js +1 -1
  464. package/dist/navigation/Toolbar.js.map +1 -1
  465. package/dist/overlay/CommandPalette.d.ts +2 -2
  466. package/dist/overlay/CommandPalette.js +1 -1
  467. package/dist/overlay/CommandPalette.js.map +1 -1
  468. package/dist/overlay/Dialog.d.ts +1 -1
  469. package/dist/overlay/Dialog.js +1 -1
  470. package/dist/overlay/Dialog.js.map +1 -1
  471. package/dist/overlay/Drawer.d.ts +1 -1
  472. package/dist/overlay/Drawer.js +1 -1
  473. package/dist/overlay/Drawer.js.map +1 -1
  474. package/dist/overlay/HoverCard.d.ts +1 -1
  475. package/dist/overlay/HoverCard.js +1 -1
  476. package/dist/overlay/HoverCard.js.map +1 -1
  477. package/dist/overlay/Lightbox.d.ts +1 -1
  478. package/dist/overlay/Lightbox.js +1 -1
  479. package/dist/overlay/Lightbox.js.map +1 -1
  480. package/dist/overlay/Menu.d.ts +1 -1
  481. package/dist/overlay/Menu.js +1 -1
  482. package/dist/overlay/Menu.js.map +1 -1
  483. package/dist/overlay/Popconfirm.d.ts +1 -1
  484. package/dist/overlay/Popconfirm.js +1 -1
  485. package/dist/overlay/Popconfirm.js.map +1 -1
  486. package/dist/overlay/Popover.d.ts +1 -1
  487. package/dist/overlay/Popover.js +1 -1
  488. package/dist/overlay/Popover.js.map +1 -1
  489. package/dist/overlay/Tooltip.d.ts +1 -1
  490. package/dist/overlay/Tooltip.js +1 -1
  491. package/dist/overlay/Tooltip.js.map +1 -1
  492. package/dist/overlay/Tour.d.ts +1 -1
  493. package/dist/overlay/Tour.js +1 -1
  494. package/dist/overlay/Tour.js.map +1 -1
  495. package/dist/overlay/detached.js +14 -1
  496. package/dist/overlay/detached.js.map +1 -1
  497. package/dist/patterns/ActionBar.d.ts +1 -1
  498. package/dist/patterns/ActionBar.js +1 -1
  499. package/dist/patterns/ActionBar.js.map +1 -1
  500. package/dist/patterns/AppShell.d.ts +1 -1
  501. package/dist/patterns/AppShell.js +1 -1
  502. package/dist/patterns/AppShell.js.map +1 -1
  503. package/dist/patterns/AuthLayout.d.ts +2 -2
  504. package/dist/patterns/AuthLayout.js +2 -2
  505. package/dist/patterns/AuthLayout.js.map +1 -1
  506. package/dist/patterns/CommentThread.d.ts +1 -1
  507. package/dist/patterns/CommentThread.js +1 -1
  508. package/dist/patterns/CommentThread.js.map +1 -1
  509. package/dist/patterns/DataImport.d.ts +1 -1
  510. package/dist/patterns/DataImport.js +1 -1
  511. package/dist/patterns/DataImport.js.map +1 -1
  512. package/dist/patterns/FilterBar.d.ts +1 -1
  513. package/dist/patterns/FilterBar.js +1 -1
  514. package/dist/patterns/FilterBar.js.map +1 -1
  515. package/dist/patterns/KanbanBoard.d.ts +1 -1
  516. package/dist/patterns/KanbanBoard.js +1 -1
  517. package/dist/patterns/KanbanBoard.js.map +1 -1
  518. package/dist/patterns/NotificationCenter.d.ts +1 -1
  519. package/dist/patterns/NotificationCenter.js +1 -1
  520. package/dist/patterns/NotificationCenter.js.map +1 -1
  521. package/dist/patterns/QueryTable.d.ts +1 -1
  522. package/dist/patterns/QueryTable.js +1 -3
  523. package/dist/patterns/QueryTable.js.map +1 -1
  524. package/dist/patterns/SlideCaptcha.d.ts +1 -1
  525. package/dist/patterns/SlideCaptcha.js +1 -1
  526. package/dist/patterns/SlideCaptcha.js.map +1 -1
  527. package/dist/patterns/StepsForm.d.ts +1 -1
  528. package/dist/patterns/StepsForm.js +1 -1
  529. package/dist/patterns/StepsForm.js.map +1 -1
  530. package/dist/table/ColumnHeaderActions.d.ts +1 -1
  531. package/dist/table/ColumnHeaderActions.js +1 -1
  532. package/dist/table/ColumnHeaderActions.js.map +1 -1
  533. package/dist/table/ColumnSettings.d.ts +1 -1
  534. package/dist/table/ColumnSettings.js +1 -1
  535. package/dist/table/ColumnSettings.js.map +1 -1
  536. package/dist/table/ColumnTable.d.ts +1 -1
  537. package/dist/table/ColumnTable.js +1 -1
  538. package/dist/table/ColumnTable.js.map +1 -1
  539. package/dist/table/DataTable.js +1 -1
  540. package/dist/table/DataTable.js.map +1 -1
  541. package/dist/table/DataTableView.d.ts +1 -4
  542. package/dist/table/DataTableView.js +33 -27
  543. package/dist/table/DataTableView.js.map +1 -1
  544. package/dist/table/PivotTable.d.ts +1 -1
  545. package/dist/table/PivotTable.js +1 -1
  546. package/dist/table/PivotTable.js.map +1 -1
  547. package/dist/table/SelectionBar.d.ts +1 -1
  548. package/dist/table/SelectionBar.js +1 -1
  549. package/dist/table/SelectionBar.js.map +1 -1
  550. package/dist/table/Table.d.ts +1 -1
  551. package/dist/table/Table.js +1 -1
  552. package/dist/table/Table.js.map +1 -1
  553. package/dist/table/TreeDataTable.d.ts +1 -1
  554. package/dist/table/TreeDataTable.js +1 -1
  555. package/dist/table/TreeDataTable.js.map +1 -1
  556. package/dist/table/table-styles.d.ts +2 -2
  557. package/dist/table/table-styles.js +1 -14
  558. package/dist/table/table-styles.js.map +1 -1
  559. package/dist/theme-customize/ThemeCustomizer.d.ts +1 -1
  560. package/dist/theme-customize/ThemeCustomizer.js +1 -1
  561. package/dist/theme-customize/ThemeCustomizer.js.map +1 -1
  562. package/dist/theme-customize/ThemeThumbnail.d.ts +1 -1
  563. package/dist/theme-customize/ThemeThumbnail.js +1 -1
  564. package/dist/theme-customize/ThemeThumbnail.js.map +1 -1
  565. package/dist/theme-customize/design-tokens.js +1 -1
  566. package/dist/theme-customize/design-tokens.js.map +1 -1
  567. package/dist/three/core/EffectSurface.d.ts +1 -1
  568. package/dist/three/core/EffectSurface.js +1 -1
  569. package/dist/three/core/EffectSurface.js.map +1 -1
  570. package/dist/three/core/ThreeCanvas.d.ts +1 -1
  571. package/dist/three/core/ThreeCanvas.js +1 -1
  572. package/dist/three/core/ThreeCanvas.js.map +1 -1
  573. package/dist/three/effects/Confetti.d.ts +1 -1
  574. package/dist/three/effects/Confetti.js +1 -1
  575. package/dist/three/effects/Confetti.js.map +1 -1
  576. package/dist/three/globe/Globe.d.ts +1 -1
  577. package/dist/three/globe/Globe.js +1 -1
  578. package/dist/three/globe/Globe.js.map +1 -1
  579. package/dist/three/model/ModelViewer.d.ts +1 -1
  580. package/dist/three/model/ModelViewer.js +1 -1
  581. package/dist/three/model/ModelViewer.js.map +1 -1
  582. package/dist/utils/dom/floating.d.ts +1 -1
  583. package/dist/utils/dom/floating.js +1 -1
  584. package/dist/utils/dom/floating.js.map +1 -1
  585. package/dist/utils/dom/ripple.d.ts +1 -1
  586. package/dist/utils/dom/ripple.js +1 -1
  587. package/dist/utils/dom/ripple.js.map +1 -1
  588. package/dist/utils/props.js +1 -1
  589. package/dist/utils/props.js.map +1 -1
  590. package/dist/utils/style/attached.d.ts +1 -1
  591. package/dist/utils/style/attached.js +1 -1
  592. package/dist/utils/style/attached.js.map +1 -1
  593. package/dist/utils/style/item-styles.d.ts +1 -1
  594. package/dist/utils/style/item-styles.js +1 -1
  595. package/dist/utils/style/item-styles.js.map +1 -1
  596. package/dist/utils/style/markers.d.ts +1 -1
  597. package/dist/utils/style/markers.js +1 -1
  598. package/dist/utils/style/markers.js.map +1 -1
  599. package/dist/utils/style/shimmer.d.ts +1 -1
  600. package/dist/utils/style/shimmer.js +1 -1
  601. package/dist/utils/style/shimmer.js.map +1 -1
  602. package/dist/utils/style/styles.d.ts +1 -1
  603. package/dist/utils/style/styles.js +1 -1
  604. package/dist/utils/style/styles.js.map +1 -1
  605. package/dist/utils/style/swatch-styles.d.ts +1 -1
  606. package/dist/utils/style/swatch-styles.js +1 -1
  607. package/dist/utils/style/swatch-styles.js.map +1 -1
  608. package/dist/utils/style/tone-styles.d.ts +1 -1
  609. package/dist/utils/style/tone-styles.js +1 -1
  610. package/dist/utils/style/tone-styles.js.map +1 -1
  611. package/dist/utils/style/transitions.d.ts +1 -1
  612. package/dist/utils/style/transitions.js +1 -1
  613. package/dist/utils/style/transitions.js.map +1 -1
  614. package/dist/utils/style/typography.d.ts +1 -1
  615. package/dist/utils/style/typography.js +1 -1
  616. package/dist/utils/style/typography.js.map +1 -1
  617. package/dist/utils/style/vars.d.ts +1 -1
  618. package/dist/utils/style/vars.js +1 -1
  619. package/dist/utils/style/vars.js.map +1 -1
  620. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"PeoplePickerPanel.js","names":["_isVNode","_vtp_readonlyProp","_vtp_bindable","_vtp_restProps","_vtp_untrack","_vue_ref","_vue_shallowRef","_vue_computed","_createVNode","_mergeProps"],"sources":["../../src/input/PeoplePickerPanel.tsx"],"sourcesContent":["/**\n * 人员与组织选择面板:左边按组织架构一层层找(面包屑回到上层),或搜索、看角色与最近选过的,勾选;右边是已选的,可以移除、清空。\n * PeoplePicker 把它放进对话框;也可以直接放在页面、抽屉里。数据见 people.ts(source)。\n *\n * <PeoplePickerPanel source={source} _value={members} types={['user', 'department']} recentKey=\"project-members\" />\n *\n * - 部门的“下级”进到下一层(不能选部门时点整行也是进去),面包屑点哪一级回到哪一级。\n * - 搜索框有字时列表换成搜索结果(输入停下 300 ms 再搜,只采用最后一次),清空回到原来的页。\n * - types 决定能勾哪几种;max 限制个数,1 时勾一个就换掉原来的。勾过的记进“最近”(recentKey,存在浏览器里,最多 20 个)。\n * - 多选时列表上方有“全选”,只管这一页能勾的。\n *\n * 读屏:左右两个列表各有名称;每行的勾选框以名字为名;“下级”按钮的名称是“下级:某部门”,进去后焦点落到列表上。\n * 部件:Root(div)、Browse(左边)、Selected(右边)。\n */\nimport { Building, BriefcaseBusiness, ChevronRight, Search, X } from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { nextTick, ref, watch, type Ref, type VNodeChild } from 'vue';\nimport { Button } from '../base/Button';\nimport { Icon } from '../base/Icon';\nimport { IconButton } from '../base/IconButton';\nimport { Spinner } from '../base/Spinner';\nimport { Small, Strong } from '../base/Text';\nimport { useLang } from '../config/context';\nimport { Avatar } from '../display/Avatar';\nimport { ItemList, ItemListItem } from '../display/ItemList';\nimport { Breadcrumbs } from '../navigation/Breadcrumbs';\nimport { usePersistentState } from '../utils/dom/storage';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { useRequest } from '../utils/request/use-request';\nimport { Checkbox } from './Checkbox';\nimport {\n peopleKey,\n toPeopleValue,\n type PeopleEntry,\n type PeopleSource,\n type PeopleType,\n} from './people';\nimport { TextField, type TextFieldProps } from './TextField';\nimport { ToggleGroup, ToggleItem } from './ToggleGroup';\n\n/** 未声明的属性落到外层 div 上 */\nexport interface PeoplePickerPanelProps extends PartProps<'div'> {\n /** 数据来源 */\n source: PeopleSource;\n /** 选中的:父级写 _value={list} 双向绑定 */\n _value?: readonly PeopleEntry[];\n /** 能选哪几种,默认只有人员 */\n types?: readonly PeopleType[];\n /** 最多选几个;1 时勾一个就换掉原来的 */\n max?: number;\n /** 记“最近选过的”用的键(存在浏览器里);不写时没有“最近”页 */\n recentKey?: string;\n /** 两边列表的高度(CSS 长度),默认 '20rem' */\n listHeight?: string;\n /** 左边的部件属性 */\n propsBrowse?: PartProps<'div'>;\n /** 右边的部件属性 */\n propsSelected?: PartProps<'div'>;\n /** 搜索框的部件属性 */\n propsSearch?: Partial<TextFieldProps>;\n}\n\ntype Page = 'org' | 'roles' | 'recent';\n\n/** “最近”最多记几个 */\nconst RECENT_LIMIT = 20;\n\n/** PeoplePickerPanel 的样式:root、grid、browse、selected、header、list、start */\nexport const peoplePickerPanelStyles = css.create({\n // 按自己的宽度决定左右排还是上下排\n root: { containerType: 'inline-size', minWidth: 0 },\n grid: {\n display: 'grid',\n gap: '_md',\n gridTemplateColumns: {\n default: 'minmax(0, 1fr)',\n '@container (min-width: 36rem)': 'minmax(0, 3fr) minmax(0, 2fr)',\n },\n },\n browse: { display: 'flex', flexDirection: 'column', gap: '_sm', minWidth: 0 },\n selected: {\n display: 'flex',\n flexDirection: 'column',\n gap: '_sm',\n minWidth: 0,\n padding: '_sm',\n backgroundColor: '_surfaceMuted',\n borderWidth: '_xs',\n borderStyle: 'solid',\n borderColor: '_borderMuted',\n borderRadius: '_md',\n },\n header: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '_sm',\n minHeight: '2em',\n },\n list: { overflowY: 'auto', outlineStyle: 'none', minWidth: 0 },\n start: { display: 'flex', alignItems: 'center', gap: '_sm' },\n status: { display: 'flex', justifyContent: 'center', paddingBlock: '_lg', color: '_textMuted' },\n});\n\n/** 随属性变的样式:列表的高度 */\nexport const peoplePickerPanelDynamicStyles = css.create({\n height: (height: string) => ({ height }),\n});\n\n/** 人员与组织选择面板 */\nexport const PeoplePickerPanel = _component(\n ({\n source,\n _value: value = _bindable<readonly PeopleEntry[]>([]),\n types = ['user'],\n max,\n recentKey,\n listHeight = '20rem',\n propsBrowse,\n propsSelected,\n propsSearch,\n ...rest\n }: PeoplePickerPanelProps) => {\n const lang = useLang();\n // 存的键只在创建时取:换键要换一个面板\n const key = _untrack(recentKey);\n let recent = _fromRef(\n key\n ? usePersistentState<PeopleEntry[]>(`vtp.people.recent.${key}`, [])\n : (ref<PeopleEntry[]>([]) as Ref<PeopleEntry[]>),\n );\n let page = _state<Page>('org');\n let query = _state('');\n let path = _state<PeopleEntry[]>([]);\n let list = _state.raw<HTMLElement | null>(null);\n\n const searching = () => !!source.search && query.trim() !== '';\n const level = useRequest(\n (parent: PeopleEntry | null, signal) => source.children(parent, signal),\n { params: () => path.at(-1) ?? null, keepPrevious: false },\n );\n const found = useRequest((text: string, signal) => source.search!(text, signal), {\n params: () => query.trim(),\n debounce: 300,\n immediate: false,\n keepPrevious: false,\n enabled: searching,\n });\n const roles = useRequest((_: undefined, signal) => source.roles!(signal), {\n immediate: false,\n });\n watch(\n () => page,\n (next) => {\n if (next === 'roles' && roles.data == null && !roles.loading) {\n void roles.refresh();\n }\n },\n );\n\n const pages = (): Page[] => [\n 'org',\n ...(source.roles ? (['roles'] as const) : []),\n ...(key ? (['recent'] as const) : []),\n ];\n const pageLabel: Record<Page, () => string> = {\n org: () => lang.peopleOrg,\n roles: () => lang.peopleRoles,\n recent: () => lang.peopleRecent,\n };\n\n /** 现在列出的:搜索结果,或当前页 */\n const shown = (): { items: readonly PeopleEntry[]; loading: boolean } => {\n // 防抖等待时请求还没发出:没有结果也没出错就算加载中,不先显示\"没有找到\"\n if (searching()) {\n return {\n items: found.data ?? [],\n loading: found.loading || (found.data === undefined && !found.error),\n };\n }\n if (page === 'roles') return { items: roles.data ?? [], loading: roles.loading };\n if (page === 'recent') return { items: recent, loading: false };\n return { items: level.data ?? [], loading: level.loading };\n };\n\n const selectedKeys = _derived(new Set(value.map(peopleKey)));\n const pickable = (entry: PeopleEntry) => types.includes(entry.type);\n const drillable = (entry: PeopleEntry) =>\n entry.type === 'department' && entry.hasChildren !== false;\n const full = () => max != null && max > 1 && value.length >= max;\n\n function remember(entry: PeopleEntry) {\n if (!key) return;\n recent = [\n toPeopleValue(entry),\n ...recent.filter((item) => peopleKey(item) !== peopleKey(entry)),\n ].slice(0, RECENT_LIMIT);\n }\n\n function toggle(entry: PeopleEntry) {\n const id = peopleKey(entry);\n if (selectedKeys.has(id)) {\n value = value.filter((item) => peopleKey(item) !== id);\n return;\n }\n if (max === 1) value = [toPeopleValue(entry)];\n else if (full()) return;\n else value = [...value, toPeopleValue(entry)];\n remember(entry);\n }\n\n /** 全选这一页能勾的;都勾上了时全部取消。有上限时加到满为止 */\n function toggleAll(items: readonly PeopleEntry[]) {\n const candidates = items.filter(pickable);\n if (candidates.every((entry) => selectedKeys.has(peopleKey(entry)))) {\n const drop = new Set(candidates.map(peopleKey));\n value = value.filter((item) => !drop.has(peopleKey(item)));\n return;\n }\n const adding = candidates.filter((entry) => !selectedKeys.has(peopleKey(entry)));\n const room = max != null ? Math.max(0, max - value.length) : adding.length;\n value = [...value, ...adding.slice(0, room).map(toPeopleValue)];\n }\n\n /** 进到一个部门:从搜索结果进去时面包屑只有它(不知道它的上级) */\n function open(department: PeopleEntry) {\n path = searching() ? [department] : [...path, department];\n query = '';\n page = 'org';\n void nextTick(() => list?.focus());\n }\n\n function onRowClick(entry: PeopleEntry, event: MouseEvent) {\n // 勾选框、按钮自己处理\n if ((event.target as Element).closest('button,input,label,a')) return;\n if (pickable(entry)) toggle(entry);\n else if (drillable(entry)) open(entry);\n }\n\n /** 行首的圆形标记:人员是头像,部门、角色是图标 */\n const badge = (entry: PeopleEntry): VNodeChild =>\n entry.type === 'user' ? (\n <Avatar name={entry.name} src={entry.avatar} size=\"sm\" />\n ) : (\n <Avatar\n size=\"sm\"\n fallback={<Icon icon={entry.type === 'department' ? Building : BriefcaseBusiness} />}\n />\n );\n\n function renderRow(entry: PeopleEntry): VNodeChild {\n const id = peopleKey(entry);\n const checked = selectedKeys.has(id);\n return (\n <ItemListItem\n key={id}\n start={\n <span {...css.attrs(peoplePickerPanelStyles.start)}>\n {pickable(entry) && (\n <Checkbox\n _checked={checked}\n onUpdate:_checked={() => toggle(entry)}\n disabled={!checked && full()}\n aria-label={entry.name}\n />\n )}\n {badge(entry)}\n </span>\n }\n title={entry.name}\n description={entry.description}\n end={\n drillable(entry) && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n iconEnd={ChevronRight}\n aria-label={lang.peopleOpen(entry.name)}\n onClick={() => open(entry)}\n >\n {lang.peopleChildren}\n </Button>\n )\n }\n onClick={(event: MouseEvent) => onRowClick(entry, event)}\n />\n );\n }\n\n function renderBrowse(): VNodeChild {\n const { items, loading } = shown();\n const candidates = items.filter(pickable);\n const checkedCount = candidates.filter((entry) => selectedKeys.has(peopleKey(entry))).length;\n const height = peoplePickerPanelDynamicStyles.height(listHeight);\n return (\n <div {...mergeAttrs<'div'>({ sx: peoplePickerPanelStyles.browse }, propsBrowse)}>\n {source.search && (\n <TextField\n {...mergePartProps<TextFieldProps>(\n {\n icon: Search,\n placeholder: lang.peopleSearch,\n 'aria-label': lang.peopleSearch,\n clearable: true,\n },\n propsSearch,\n )}\n _value={query}\n />\n )}\n {!searching() && pages().length > 1 && (\n <ToggleGroup\n _value={page}\n onUpdate:_value={(next) => next && (page = next as Page)}\n required\n size=\"sm\"\n aria-label={lang.peoplePages}\n >\n {pages().map((item) => (\n <ToggleItem key={item} value={item}>\n {pageLabel[item]()}\n </ToggleItem>\n ))}\n </ToggleGroup>\n )}\n {!searching() && page === 'org' && (\n <Breadcrumbs\n items={[\n { key: '', label: lang.peopleRoot },\n ...path.map((department) => ({\n key: peopleKey(department),\n label: department.name,\n })),\n ]}\n onNavigate={(_, index) => (path = path.slice(0, index))}\n />\n )}\n {max !== 1 && candidates.length > 1 && (\n <Checkbox\n _checked={checkedCount === candidates.length}\n indeterminate={checkedCount > 0 && checkedCount < candidates.length}\n onUpdate:_checked={() => toggleAll(items)}\n size=\"sm\"\n >\n {lang.peopleSelectAll}\n </Checkbox>\n )}\n <div\n {...css.attrs(peoplePickerPanelStyles.list, height)}\n ref={(element: unknown) => (list = element as HTMLElement | null)}\n tabindex={-1}\n >\n {loading ? (\n <div {...css.attrs(peoplePickerPanelStyles.status)}>\n <Spinner label={lang.loading} />\n </div>\n ) : items.length === 0 ? (\n <Small sx={peoplePickerPanelStyles.status}>\n {searching() ? lang.peopleNoResult : lang.peopleEmpty}\n </Small>\n ) : (\n <ItemList\n hoverable\n density=\"compact\"\n aria-label={pageLabel[searching() ? 'org' : page]()}\n >\n {items.map(renderRow)}\n </ItemList>\n )}\n </div>\n </div>\n );\n }\n\n function renderSelected(): VNodeChild {\n return (\n <div {...mergeAttrs<'div'>({ sx: peoplePickerPanelStyles.selected }, propsSelected)}>\n <div {...css.attrs(peoplePickerPanelStyles.header)}>\n <Strong size=\"sm\">{lang.peopleCount(value.length, max)}</Strong>\n {value.length > 0 && (\n <Button variant=\"link\" size=\"sm\" onClick={() => (value = [])}>\n {lang.clear}\n </Button>\n )}\n </div>\n <div\n {...css.attrs(\n peoplePickerPanelStyles.list,\n peoplePickerPanelDynamicStyles.height(listHeight),\n )}\n >\n {value.length === 0 ? (\n <Small sx={peoplePickerPanelStyles.status}>{lang.peopleNothingSelected}</Small>\n ) : (\n <ItemList density=\"compact\" aria-label={lang.peopleSelected}>\n {value.map((entry) => (\n <ItemListItem\n key={peopleKey(entry)}\n start={badge(entry)}\n title={entry.name}\n description={entry.description ?? lang.peopleTypes[entry.type]}\n end={\n <IconButton\n icon={X}\n variant=\"ghost\"\n size=\"sm\"\n aria-label={lang.peopleRemove(entry.name)}\n onClick={() => toggle(entry)}\n />\n }\n />\n ))}\n </ItemList>\n )}\n </div>\n </div>\n );\n }\n\n return () => (\n <div {...mergeAttrs<'div'>({ sx: peoplePickerPanelStyles.root }, rest)}>\n <div {...css.attrs(peoplePickerPanelStyles.grid)}>\n {renderBrowse()}\n {renderSelected()}\n </div>\n </div>\n );\n },\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCA,SAAA,QAAA,GAAA;CAAA,OAAA,OAAA,MAAA,cAAA,OAAA,UAAA,SAAA,KAAA,CAAA,MAAA,qBAAA,CAAAA,QAAA,CAAA;AAAA;;AAyBA,IAAM,eAAe;;AAGrB,IAAa,0BAA0B,IAAI,OAAO;CAEhD,MAAM;EAAE,eAAe;EAAe,UAAU;CAAE;CAClD,MAAM;EACJ,SAAS;EACT,KAAK;EACL,qBAAqB;GACnB,SAAS;GACT,iCAAiC;EACnC;CACF;CACA,QAAQ;EAAE,SAAS;EAAQ,eAAe;EAAU,KAAK;EAAO,UAAU;CAAE;CAC5E,UAAU;EACR,SAAS;EACT,eAAe;EACf,KAAK;EACL,UAAU;EACV,SAAS;EACT,iBAAiB;EACjB,aAAa;EACb,aAAa;EACb,aAAa;EACb,cAAc;CAChB;CACA,QAAQ;EACN,SAAS;EACT,YAAY;EACZ,gBAAgB;EAChB,KAAK;EACL,WAAW;CACb;CACA,MAAM;EAAE,WAAW;EAAQ,cAAc;EAAQ,UAAU;CAAE;CAC7D,OAAO;EAAE,SAAS;EAAQ,YAAY;EAAU,KAAK;CAAM;CAC3D,QAAQ;EAAE,SAAS;EAAQ,gBAAgB;EAAU,cAAc;EAAO,OAAO;CAAa;AAChG,CAAC;;AAGD,IAAa,iCAAiC,IAAI,OAAO,EACvD,SAAS,YAAoB,EAAE,OAAO,GACxC,CAAC;;AAGD,IAAa,oBAAoB,0BAC/B,QAAA,SAW8B;CAAA,MAAA,SAAA,CAAA;CAAA,MAAA,SAAAC,aAAA,QAAA,QAAA;CAAA,MAAA,QAAAC,SAAA,QAAA,gBATsB,CAAA,GAAE,KAAA,IAAA;CAAA,MAAA,QAAAD,aAAA,QAAA,eAC5C,CAAC,MAAM,CAAC;CAAA,MAAA,MAAAA,aAAA,QAAA,KAAA;CAAA,MAAA,YAAAA,aAAA,QAAA,WAAA;CAAA,MAAA,aAAAA,aAAA,QAAA,cAGH,OAAO;CAAA,MAAA,cAAAA,aAAA,QAAA,aAAA;CAAA,MAAA,gBAAAA,aAAA,QAAA,eAAA;CAAA,MAAA,cAAAA,aAAA,QAAA,aAAA;CAAA,MAIjB,OAAIE,UAAA,QAAA,MAAA,IAAA;CAEP,MAAM,OAAO,QAAQ;CAErB,MAAM,MAAGC,cAAA,UAAA,KAAA;CACT,IAAI,SACF,MACI,mBAAkC,qBAAqB,OAAO,CAAA,CAAE,IAC/D,IAAmB,CAAA,CAAE;CAE5B,IAAI,OAAIC,IAAgB,KAAK;CAC7B,IAAI,QAAKA,IAAU,EAAE;CACrB,IAAI,OAAIA,IAAyB,CAAA,CAAE;CACnC,IAAI,OAAIC,WAAkC,IAAI;CAE9C,MAAM,kBAAkB,CAAC,CAAC,OAAA,MAAO,UAAU,MAAA,MAAM,KAAK,MAAM;CAC5D,MAAM,QAAQ,YACX,QAA4B,WAAW,OAAA,MAAO,SAAS,QAAQ,MAAM,GACtE;EAAE,cAAc,KAAA,MAAK,GAAG,EAAE,KAAK;EAAM,cAAc;CAAM,CAC3D;CACA,MAAM,QAAQ,YAAY,MAAc,WAAW,OAAA,MAAO,OAAQ,MAAM,MAAM,GAAG;EAC/E,cAAc,MAAA,MAAM,KAAK;EACzB,UAAU;EACV,WAAW;EACX,cAAc;EACd,SAAS;CACX,CAAC;CACD,MAAM,QAAQ,YAAY,GAAc,WAAW,OAAA,MAAO,MAAO,MAAM,GAAG,EACxE,WAAW,MACb,CAAC;CACD,YACE,KAAA,QACC,SAAS;EACR,IAAI,SAAS,WAAW,MAAM,QAAQ,QAAQ,CAAC,MAAM,SACnD,MAAW,QAAQ;CAEvB,CACF;CAEA,MAAM,cAAsB;EAC1B;EACA,GAAI,OAAA,MAAO,QAAS,CAAC,OAAO,IAAc,CAAA;EAC1C,GAAI,MAAO,CAAC,QAAQ,IAAc,CAAA;CAAG;CAEvC,MAAM,YAAwC;EAC5C,WAAW,KAAK;EAChB,aAAa,KAAK;EAClB,cAAc,KAAK;CACrB;;CAGA,MAAM,cAAmE;EAEvE,IAAI,UAAU,GACZ,OAAO;GACL,OAAO,MAAM,QAAQ,CAAA;GACrB,SAAS,MAAM,WAAY,MAAM,SAAS,KAAA,KAAa,CAAC,MAAM;EAChE;EAEF,IAAI,KAAA,UAAS,SAAS,OAAO;GAAE,OAAO,MAAM,QAAQ,CAAA;GAAI,SAAS,MAAM;EAAQ;EAC/E,IAAI,KAAA,UAAS,UAAU,OAAO;GAAE,OAAK,OAAA;GAAU,SAAS;EAAM;EAC9D,OAAO;GAAE,OAAO,MAAM,QAAQ,CAAA;GAAI,SAAS,MAAM;EAAQ;CAC3D;CAEA,MAAM,eAAYC,eAAY,IAAI,IAAI,MAAA,MAAM,IAAI,SAAS,CAAC,CAAC;CAC3D,MAAM,YAAY,UAAuB,MAAA,MAAM,SAAS,MAAM,IAAI;CAClE,MAAM,aAAa,UACjB,MAAM,SAAS,gBAAgB,MAAM,gBAAgB;CACvD,MAAM,aAAa,IAAA,SAAO,QAAQ,IAAA,QAAM,KAAK,MAAA,MAAM,UAAM,IAAA;CAEzD,SAAS,SAAS,OAAoB;EACpC,IAAI,CAAC,KAAK;EACV,OAAA,QAAS,CACP,cAAc,KAAK,GACnB,GAAG,OAAA,MAAO,QAAQ,SAAS,UAAU,IAAI,MAAM,UAAU,KAAK,CAAC,CAAC,CACjE,CAAC,MAAM,GAAG,YAAY;CACzB;CAEA,SAAS,OAAO,OAAoB;EAClC,MAAM,KAAK,UAAU,KAAK;EAC1B,IAAI,aAAA,MAAa,IAAI,EAAE,GAAG;GACxB,MAAA,QAAQ,MAAA,MAAM,QAAQ,SAAS,UAAU,IAAI,MAAM,EAAE;GACrD;EACF;EACA,IAAI,IAAA,UAAQ,GAAG,MAAA,QAAQ,CAAC,cAAc,KAAK,CAAC;OACvC,IAAI,KAAK,GAAG;OACZ,MAAA,QAAQ,CAAC,GAAA,MAAA,OAAU,cAAc,KAAK,CAAC;EAC5C,SAAS,KAAK;CAChB;;CAGA,SAAS,UAAU,OAA+B;EAChD,MAAM,aAAa,MAAM,OAAO,QAAQ;EACxC,IAAI,WAAW,OAAO,UAAU,aAAA,MAAa,IAAI,UAAU,KAAK,CAAC,CAAC,GAAG;GACnE,MAAM,OAAO,IAAI,IAAI,WAAW,IAAI,SAAS,CAAC;GAC9C,MAAA,QAAQ,MAAA,MAAM,QAAQ,SAAS,CAAC,KAAK,IAAI,UAAU,IAAI,CAAC,CAAC;GACzD;EACF;EACA,MAAM,SAAS,WAAW,QAAQ,UAAU,CAAC,aAAA,MAAa,IAAI,UAAU,KAAK,CAAC,CAAC;EAC/E,MAAM,OAAO,IAAA,SAAO,OAAO,KAAK,IAAI,GAAG,IAAA,QAAM,MAAA,MAAM,MAAM,IAAI,OAAO;EACpE,MAAA,QAAQ,CAAC,GAAA,MAAA,OAAU,GAAG,OAAO,MAAM,GAAG,IAAI,CAAC,CAAC,IAAI,aAAa,CAAC;CAChE;;CAGA,SAAS,KAAK,YAAyB;EACrC,KAAA,QAAO,UAAU,IAAI,CAAC,UAAU,IAAI,CAAC,GAAA,KAAA,OAAS,UAAU;EACxD,MAAA,QAAQ;EACR,KAAA,QAAO;EACP,eAAoB,KAAA,OAAM,MAAM,CAAC;CACnC;CAEA,SAAS,WAAW,OAAoB,OAAmB;EAEzD,IAAK,MAAM,OAAmB,QAAQ,sBAAsB,GAAG;EAC/D,IAAI,SAAS,KAAK,GAAG,OAAO,KAAK;OAC5B,IAAI,UAAU,KAAK,GAAG,KAAK,KAAK;CACvC;;CAGA,MAAM,SAAS,UACb,MAAM,SAAS,SAAMC,YAAA,QAAA;EAAA,QACL,MAAM;EAAI,OAAO,MAAM;EAAM,QAAA;CAAA,GAAA,IAAA,IAAAA,YAAA,QAAA;EAAA,QAAA;EAAA,YAAAA,YAAA,MAAA,EAAA,QAInB,MAAM,SAAS,eAAe,WAAW,kBAAiB,GAAA,IAAA;CAAA,GAAA,IAAA;CAItF,SAAS,UAAU,OAAgC;EACjD,MAAM,KAAK,UAAU,KAAK;EAC1B,MAAM,UAAU,aAAA,MAAa,IAAI,EAAE;EACnC,OAAAA,YAAA,cAAA;GAAA,OAES;GAAE,SAAAA,YAAA,QAEK,IAAI,MAAM,wBAAwB,KAAK,GAAC,CAC/C,SAAS,KAAK,KAACA,YAAA,UAAA;IAAA,YAEF;IAAO,2BACQ,OAAO,KAAK;IAAC,YAC5B,CAAC,WAAW,KAAK;IAAC,cAChB,MAAM;GAAI,GAAA,IAAA,GAGzB,MAAM,KAAK,CAAC,CAAA;GAAA,SAGV,MAAM;GAAI,eACJ,MAAM;GAAW,OAE5B,UAAU,KAAK,KAACA,YAAA,QAAA;IAAA,WAAA;IAAA,QAAA;IAAA,WAIH;IAAY,cACT,KAAK,WAAW,MAAM,IAAI;IAAC,iBACxB,KAAK,KAAK;GAAC,GAAA;IAAA,eAAA,CAEzB,KAAK,cAAc;IAAA,SAAA;GAAA,CAAA;GAEvB,YAEO,UAAsB,WAAW,OAAO,KAAK;EAAC,GAAA,IAAA;CAG9D;CAEA,SAAS,eAA2B;EAAA,IAAA,QAAA;EAClC,MAAM,EAAE,OAAO,YAAY,MAAM;EACjC,MAAM,aAAa,MAAM,OAAO,QAAQ;EACxC,MAAM,eAAe,WAAW,QAAQ,UAAU,aAAA,MAAa,IAAI,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC;EACtF,MAAM,SAAS,+BAA+B,OAAM,WAAA,KAAW;EAC/D,OAAAA,YAAA,OACW,WAAkB,EAAE,IAAI,wBAAwB,OAAO,GAAC,YAAA,KAAa,GAAC;GAC5E,OAAA,MAAO,UAAMA,YAAA,WAAAC,cAEN,eACF;IACE,MAAM;IACN,aAAa,KAAK;IAClB,cAAc,KAAK;IACnB,WAAW;GACb,GAAC,YAAA,KAEH,GAAC;IAAA,UAAA,MAAA;IAAA,mBAAA,OAAA,OAAA,OAAA,MAAA,WAAA,MAAA,QAAA;GAAA,CAAA,GAAA,IAAA;GAIJ,CAAC,UAAU,KAAK,MAAM,CAAC,CAAC,SAAS,KAACD,YAAA,aAAA;IAAA,UAAA,KAAA;IAAA,mBAAA,OAAA,OAAA,OAAA,MAGb,SAAS,SAAS,KAAA,QAAO;IAAa,YAAA;IAAA,QAAA;IAAA,cAG5C,KAAK;GAAW,GAAA,QAAA,SAE3B,MAAM,CAAC,CAAC,KAAK,SAAI;IAAA,IAAA;IAAA,OAAAA,YAAA,YAAA;KAAA,OACC;KAAI,SAAS;IAAI,GAAA,QAAA,QAC/B,UAAU,KAAK,CAAC,CAAC,IAAA,QAAA,EAAA,eAAA,CAAA,KAAA,EAAA,CAAA;GAAA,CAErB,CAAC,IAAA,SAAA,EAAA,eAAA,CAAA,MAAA,EAAA,CAAA;GAGL,CAAC,UAAU,KAAK,KAAA,UAAS,SAAKA,YAAA,aAAA;IAAA,SAEpB,CACL;KAAE,KAAK;KAAI,OAAO,KAAK;IAAW,GAClC,GAAG,KAAA,MAAK,KAAK,gBAAgB;KAC3B,KAAK,UAAU,UAAU;KACzB,OAAO,WAAW;IACpB,EAAE,CAAC;IACJ,cAAA,OAAA,OAAA,OAAA,MACY,GAAG,UAAW,KAAA,QAAO,KAAA,MAAK,MAAM,GAAG,KAAK;GAAE,GAAA,IAAA;GAG1D,IAAA,UAAQ,KAAK,WAAW,SAAS,KAACA,YAAA,UAAA;IAAA,YAErB,iBAAiB,WAAW;IAAM,iBAC7B,eAAe,KAAK,eAAe,WAAW;IAAM,2BAC1C,UAAU,KAAK;IAAC,QAAA;GAAA,GAAA;IAAA,eAAA,CAGxC,KAAK,eAAe;IAAA,SAAA;GAAA,CAAA;GAExBA,YAAA,OAAAC,cAEK,IAAI,MAAM,wBAAwB,MAAM,MAAM,GAAC;IAAA,OAAA,OAAA,OAAA,OAAA,MAC7C,YAAsB,KAAA,QAAO;IAA8B,YACvD;GAAE,CAAA,GAAA,CAEX,UAAOD,YAAA,OACG,IAAI,MAAM,wBAAwB,MAAM,GAAC,CAAAA,YAAA,SAAA,EAAA,SAChC,KAAK,QAAO,GAAA,IAAA,CAAA,CAAA,IAE5B,MAAM,WAAW,IAACA,YAAA,OAAA,EAAA,MACT,wBAAwB,OAAM,GAAA;IAAA,eAAA,CACtC,UAAU,IAAI,KAAK,iBAAiB,KAAK,WAAW;IAAA,SAAA;GAAA,CAAA,IAAAA,YAAA,UAAA;IAAA,aAAA;IAAA,WAAA;IAAA,cAMzC,UAAU,UAAU,IAAI,QAAK,KAAA,MAAQ,CAAC;GAAC,GAAA,QAAA,SAElD,MAAM,IAAI,SAAS,CAAC,IAAA,SAAA,EAAA,eAAA,CAAA,MAAA,EAAA,CAAA,CAExB,CAAA;EAAA,CAAA;CAIT;CAEA,SAAS,iBAA6B;EACpC,OAAAA,YAAA,OACW,WAAkB,EAAE,IAAI,wBAAwB,SAAS,GAAC,cAAA,KAAe,GAAC,CAAAA,YAAA,OACxE,IAAI,MAAM,wBAAwB,MAAM,GAAC,CAAAA,YAAA,QAAA,EAAA,QAAA,KAAA,GAAA;GAAA,eAAA,CAC7B,KAAK,YAAY,MAAA,MAAM,QAAM,IAAA,KAAK,CAAC;GAAA,SAAA;EAAA,CAAA,GACrD,MAAA,MAAM,SAAS,KAACA,YAAA,QAAA;GAAA,WAAA;GAAA,QAAA;GAAA,WAAA,OAAA,OAAA,OAAA,WACkC,MAAA,QAAQ,CAAA;EAAG,GAAA;GAAA,eAAA,CACzD,KAAK,KAAK;GAAA,SAAA;EAAA,CAAA,CAEd,CAAA,GAAAA,YAAA,OAGG,IAAI,MACN,wBAAwB,MACxB,+BAA+B,OAAM,WAAA,KAAW,CAClD,GAAC,CAEA,MAAA,MAAM,WAAW,IAACA,YAAA,OAAA,EAAA,MACN,wBAAwB,OAAM,GAAA;GAAA,eAAA,CAAG,KAAK,qBAAqB;GAAA,SAAA;EAAA,CAAA,IAAAA,YAAA,UAAA;GAAA,WAAA;GAAA,cAE9B,KAAK;EAAc,GAAA;GAAA,eAAA,CACxD,MAAA,MAAM,KAAK,UAAKA,YAAA,cAAA;IAAA,OAER,UAAU,KAAK;IAAC,SACd,MAAM,KAAK;IAAC,SACZ,MAAM;IAAI,eACJ,MAAM,eAAe,KAAK,YAAY,MAAM;IAAK,OAAAA,YAAA,YAAA;KAAA,QAGpD;KAAC,WAAA;KAAA,QAAA;KAAA,cAGK,KAAK,aAAa,MAAM,IAAI;KAAC,iBAC1B,OAAO,KAAK;IAAC,GAAA,IAAA;GAAA,GAAA,IAAA,CAInC,CAAC;GAAA,SAAA;EAAA,CAAA,CAEL,CAAA,CAAA,CAAA;CAIT;CAEA,aAAOA,YAAA,OACI,WAAkB,EAAE,IAAI,wBAAwB,KAAK,GAAG,IAAI,GAAC,CAAAA,YAAA,OAC3D,IAAI,MAAM,wBAAwB,IAAI,GAAC,CAC7C,aAAa,GACb,eAAe,CAAC,CAAA,CAAA,CAAA;AAIzB,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH"}
1
+ {"version":3,"file":"PeoplePickerPanel.js","names":["_isVNode","_vtp_readonlyProp","_vtp_bindable","_vtp_restProps","_vtp_untrack","_vue_ref","_vue_shallowRef","_vue_computed","_createVNode","_mergeProps"],"sources":["../../src/input/PeoplePickerPanel.tsx"],"sourcesContent":["/**\n * 人员与组织选择面板:左边按组织架构一层层找(面包屑回到上层),或搜索、看角色与最近选过的,勾选;右边是已选的,可以移除、清空。\n * PeoplePicker 把它放进对话框;也可以直接放在页面、抽屉里。数据见 people.ts(source)。\n *\n * <PeoplePickerPanel source={source} _value={members} types={['user', 'department']} recentKey=\"project-members\" />\n *\n * - 部门的“下级”进到下一层(不能选部门时点整行也是进去),面包屑点哪一级回到哪一级。\n * - 搜索框有字时列表换成搜索结果(输入停下 300 ms 再搜,只采用最后一次),清空回到原来的页。\n * - types 决定能勾哪几种;max 限制个数,1 时勾一个就换掉原来的。勾过的记进“最近”(recentKey,存在浏览器里,最多 20 个)。\n * - 多选时列表上方有“全选”,只管这一页能勾的。\n *\n * 读屏:左右两个列表各有名称;每行的勾选框以名字为名;“下级”按钮的名称是“下级:某部门”,进去后焦点落到列表上。\n * 部件:Root(div)、Browse(左边)、Selected(右边)。\n */\nimport { Building, BriefcaseBusiness, ChevronRight, Search, X } from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { nextTick, ref, watch, type Ref, type VNodeChild } from 'vue';\nimport { Button } from '../base/Button';\nimport { Icon } from '../base/Icon';\nimport { IconButton } from '../base/IconButton';\nimport { Spinner } from '../base/Spinner';\nimport { Small, Strong } from '../base/Text';\nimport { useLang } from '../config/context';\nimport { Avatar } from '../display/Avatar';\nimport { ItemList, ItemListItem } from '../display/ItemList';\nimport { Breadcrumbs } from '../navigation/Breadcrumbs';\nimport { usePersistentState } from '../utils/dom/storage';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { useRequest } from '../utils/request/use-request';\nimport { Checkbox } from './Checkbox';\nimport {\n peopleKey,\n toPeopleValue,\n type PeopleEntry,\n type PeopleSource,\n type PeopleType,\n} from './people';\nimport { TextField, type TextFieldProps } from './TextField';\nimport { ToggleGroup, ToggleItem } from './ToggleGroup';\n\n/** 未声明的属性落到外层 div 上 */\nexport interface PeoplePickerPanelProps extends PartProps<'div'> {\n /** 数据来源 */\n source: PeopleSource;\n /** 选中的:父级写 _value={list} 双向绑定 */\n _value?: readonly PeopleEntry[];\n /** 能选哪几种,默认只有人员 */\n types?: readonly PeopleType[];\n /** 最多选几个;1 时勾一个就换掉原来的 */\n max?: number;\n /** 记“最近选过的”用的键(存在浏览器里);不写时没有“最近”页 */\n recentKey?: string;\n /** 两边列表的高度(CSS 长度),默认 '20rem' */\n listHeight?: string;\n /** 左边的部件属性 */\n propsBrowse?: PartProps<'div'>;\n /** 右边的部件属性 */\n propsSelected?: PartProps<'div'>;\n /** 搜索框的部件属性 */\n propsSearch?: Partial<TextFieldProps>;\n}\n\ntype Page = 'org' | 'roles' | 'recent';\n\n/** “最近”最多记几个 */\nconst RECENT_LIMIT = 20;\n\n/** PeoplePickerPanel 的样式:root、grid、browse、selected、header、list、start */\nexport const peoplePickerPanelStyles = css.create({\n // 按自己的宽度决定左右排还是上下排\n root: { containerType: 'inline-size', minWidth: 0 },\n grid: {\n display: 'grid',\n gap: '_md',\n gridTemplateColumns: {\n default: 'minmax(0, 1fr)',\n '@container (min-width: 36rem)': 'minmax(0, 3fr) minmax(0, 2fr)',\n },\n },\n browse: { display: 'flex', flexDirection: 'column', gap: '_sm', minWidth: 0 },\n selected: {\n display: 'flex',\n flexDirection: 'column',\n gap: '_sm',\n minWidth: 0,\n padding: '_sm',\n backgroundColor: '_surfaceMuted',\n borderWidth: '_xs',\n borderStyle: 'solid',\n borderColor: '_borderMuted',\n borderRadius: '_md',\n },\n header: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '_sm',\n minHeight: '2em',\n },\n list: { overflowY: 'auto', outlineStyle: 'none', minWidth: 0 },\n start: { display: 'flex', alignItems: 'center', gap: '_sm' },\n status: { display: 'flex', justifyContent: 'center', paddingBlock: '_lg', color: '_textMuted' },\n});\n\n/** 随属性变的样式:列表的高度 */\nexport const peoplePickerPanelDynamicStyles = css.create({\n height: (height: string) => ({ height }),\n});\n\n/** 人员与组织选择面板 */\nexport const PeoplePickerPanel = _component(\n ({\n source,\n _value: value = _bindable<readonly PeopleEntry[]>([]),\n types = ['user'],\n max,\n recentKey,\n listHeight = '20rem',\n propsBrowse,\n propsSelected,\n propsSearch,\n ...rest\n }: PeoplePickerPanelProps) => {\n const lang = useLang();\n // 存的键只在创建时取:换键要换一个面板\n const key = _untrack(recentKey);\n let recent = _fromRef(\n key\n ? usePersistentState<PeopleEntry[]>(`vtp.people.recent.${key}`, [])\n : (ref<PeopleEntry[]>([]) as Ref<PeopleEntry[]>),\n );\n let page = _state<Page>('org');\n let query = _state('');\n let path = _state<PeopleEntry[]>([]);\n let list = _state.raw<HTMLElement | null>(null);\n\n const searching = () => !!source.search && query.trim() !== '';\n const level = useRequest(\n (parent: PeopleEntry | null, signal) => source.children(parent, signal),\n { params: () => path.at(-1) ?? null, keepPrevious: false },\n );\n const found = useRequest((text: string, signal) => source.search!(text, signal), {\n params: () => query.trim(),\n debounce: 300,\n immediate: false,\n keepPrevious: false,\n enabled: searching,\n });\n const roles = useRequest((_: undefined, signal) => source.roles!(signal), {\n immediate: false,\n });\n watch(\n () => page,\n (next) => {\n if (next === 'roles' && roles.data == null && !roles.loading) {\n void roles.refresh();\n }\n },\n );\n\n const pages = (): Page[] => [\n 'org',\n ...(source.roles ? (['roles'] as const) : []),\n ...(key ? (['recent'] as const) : []),\n ];\n const pageLabel: Record<Page, () => string> = {\n org: () => lang.peopleOrg,\n roles: () => lang.peopleRoles,\n recent: () => lang.peopleRecent,\n };\n\n /** 现在列出的:搜索结果,或当前页 */\n const shown = (): { items: readonly PeopleEntry[]; loading: boolean } => {\n // 防抖等待时请求还没发出:没有结果也没出错就算加载中,不先显示\"没有找到\"\n if (searching()) {\n return {\n items: found.data ?? [],\n loading: found.loading || (found.data === undefined && !found.error),\n };\n }\n if (page === 'roles') return { items: roles.data ?? [], loading: roles.loading };\n if (page === 'recent') return { items: recent, loading: false };\n return { items: level.data ?? [], loading: level.loading };\n };\n\n const selectedKeys = _derived(new Set(value.map(peopleKey)));\n const pickable = (entry: PeopleEntry) => types.includes(entry.type);\n const drillable = (entry: PeopleEntry) =>\n entry.type === 'department' && entry.hasChildren !== false;\n const full = () => max != null && max > 1 && value.length >= max;\n\n function remember(entry: PeopleEntry) {\n if (!key) return;\n recent = [\n toPeopleValue(entry),\n ...recent.filter((item) => peopleKey(item) !== peopleKey(entry)),\n ].slice(0, RECENT_LIMIT);\n }\n\n function toggle(entry: PeopleEntry) {\n const id = peopleKey(entry);\n if (selectedKeys.has(id)) {\n value = value.filter((item) => peopleKey(item) !== id);\n return;\n }\n if (max === 1) value = [toPeopleValue(entry)];\n else if (full()) return;\n else value = [...value, toPeopleValue(entry)];\n remember(entry);\n }\n\n /** 全选这一页能勾的;都勾上了时全部取消。有上限时加到满为止 */\n function toggleAll(items: readonly PeopleEntry[]) {\n const candidates = items.filter(pickable);\n if (candidates.every((entry) => selectedKeys.has(peopleKey(entry)))) {\n const drop = new Set(candidates.map(peopleKey));\n value = value.filter((item) => !drop.has(peopleKey(item)));\n return;\n }\n const adding = candidates.filter((entry) => !selectedKeys.has(peopleKey(entry)));\n const room = max != null ? Math.max(0, max - value.length) : adding.length;\n value = [...value, ...adding.slice(0, room).map(toPeopleValue)];\n }\n\n /** 进到一个部门:从搜索结果进去时面包屑只有它(不知道它的上级) */\n function open(department: PeopleEntry) {\n path = searching() ? [department] : [...path, department];\n query = '';\n page = 'org';\n void nextTick(() => list?.focus());\n }\n\n function onRowClick(entry: PeopleEntry, event: MouseEvent) {\n // 勾选框、按钮自己处理\n if ((event.target as Element).closest('button,input,label,a')) return;\n if (pickable(entry)) toggle(entry);\n else if (drillable(entry)) open(entry);\n }\n\n /** 行首的圆形标记:人员是头像,部门、角色是图标 */\n const badge = (entry: PeopleEntry): VNodeChild =>\n entry.type === 'user' ? (\n <Avatar name={entry.name} src={entry.avatar} size=\"sm\" />\n ) : (\n <Avatar\n size=\"sm\"\n fallback={<Icon icon={entry.type === 'department' ? Building : BriefcaseBusiness} />}\n />\n );\n\n function renderRow(entry: PeopleEntry): VNodeChild {\n const id = peopleKey(entry);\n const checked = selectedKeys.has(id);\n return (\n <ItemListItem\n key={id}\n start={\n <span {...css.attrs(peoplePickerPanelStyles.start)}>\n {pickable(entry) && (\n <Checkbox\n _checked={checked}\n onUpdate:_checked={() => toggle(entry)}\n disabled={!checked && full()}\n aria-label={entry.name}\n />\n )}\n {badge(entry)}\n </span>\n }\n title={entry.name}\n description={entry.description}\n end={\n drillable(entry) && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n iconEnd={ChevronRight}\n aria-label={lang.peopleOpen(entry.name)}\n onClick={() => open(entry)}\n >\n {lang.peopleChildren}\n </Button>\n )\n }\n onClick={(event: MouseEvent) => onRowClick(entry, event)}\n />\n );\n }\n\n function renderBrowse(): VNodeChild {\n const { items, loading } = shown();\n const candidates = items.filter(pickable);\n const checkedCount = candidates.filter((entry) => selectedKeys.has(peopleKey(entry))).length;\n const height = peoplePickerPanelDynamicStyles.height(listHeight);\n return (\n <div {...mergeAttrs<'div'>({ sx: peoplePickerPanelStyles.browse }, propsBrowse)}>\n {source.search && (\n <TextField\n {...mergePartProps<TextFieldProps>(\n {\n icon: Search,\n placeholder: lang.peopleSearch,\n 'aria-label': lang.peopleSearch,\n clearable: true,\n },\n propsSearch,\n )}\n _value={query}\n />\n )}\n {!searching() && pages().length > 1 && (\n <ToggleGroup\n _value={page}\n onUpdate:_value={(next) => next && (page = next as Page)}\n required\n size=\"sm\"\n aria-label={lang.peoplePages}\n >\n {pages().map((item) => (\n <ToggleItem key={item} value={item}>\n {pageLabel[item]()}\n </ToggleItem>\n ))}\n </ToggleGroup>\n )}\n {!searching() && page === 'org' && (\n <Breadcrumbs\n items={[\n { key: '', label: lang.peopleRoot },\n ...path.map((department) => ({\n key: peopleKey(department),\n label: department.name,\n })),\n ]}\n onNavigate={(_, index) => (path = path.slice(0, index))}\n />\n )}\n {max !== 1 && candidates.length > 1 && (\n <Checkbox\n _checked={checkedCount === candidates.length}\n indeterminate={checkedCount > 0 && checkedCount < candidates.length}\n onUpdate:_checked={() => toggleAll(items)}\n size=\"sm\"\n >\n {lang.peopleSelectAll}\n </Checkbox>\n )}\n <div\n {...css.attrs(peoplePickerPanelStyles.list, height)}\n ref={(element: unknown) => (list = element as HTMLElement | null)}\n tabindex={-1}\n >\n {loading ? (\n <div {...css.attrs(peoplePickerPanelStyles.status)}>\n <Spinner label={lang.loading} />\n </div>\n ) : items.length === 0 ? (\n <Small sx={peoplePickerPanelStyles.status}>\n {searching() ? lang.peopleNoResult : lang.peopleEmpty}\n </Small>\n ) : (\n <ItemList\n hoverable\n density=\"compact\"\n aria-label={pageLabel[searching() ? 'org' : page]()}\n >\n {items.map(renderRow)}\n </ItemList>\n )}\n </div>\n </div>\n );\n }\n\n function renderSelected(): VNodeChild {\n return (\n <div {...mergeAttrs<'div'>({ sx: peoplePickerPanelStyles.selected }, propsSelected)}>\n <div {...css.attrs(peoplePickerPanelStyles.header)}>\n <Strong size=\"sm\">{lang.peopleCount(value.length, max)}</Strong>\n {value.length > 0 && (\n <Button variant=\"link\" size=\"sm\" onClick={() => (value = [])}>\n {lang.clear}\n </Button>\n )}\n </div>\n <div\n {...css.attrs(\n peoplePickerPanelStyles.list,\n peoplePickerPanelDynamicStyles.height(listHeight),\n )}\n >\n {value.length === 0 ? (\n <Small sx={peoplePickerPanelStyles.status}>{lang.peopleNothingSelected}</Small>\n ) : (\n <ItemList density=\"compact\" aria-label={lang.peopleSelected}>\n {value.map((entry) => (\n <ItemListItem\n key={peopleKey(entry)}\n start={badge(entry)}\n title={entry.name}\n description={entry.description ?? lang.peopleTypes[entry.type]}\n end={\n <IconButton\n icon={X}\n variant=\"ghost\"\n size=\"sm\"\n aria-label={lang.peopleRemove(entry.name)}\n onClick={() => toggle(entry)}\n />\n }\n />\n ))}\n </ItemList>\n )}\n </div>\n </div>\n );\n }\n\n return () => (\n <div {...mergeAttrs<'div'>({ sx: peoplePickerPanelStyles.root }, rest)}>\n <div {...css.attrs(peoplePickerPanelStyles.grid)}>\n {renderBrowse()}\n {renderSelected()}\n </div>\n </div>\n );\n },\n);\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';
1
+ import { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';
2
2
  import { type VNodeChild } from 'vue';
3
3
  import { type ListboxOption, type OptionMapping } from './list-state';
4
4
  import { type PartProps } from '../utils/props';
@@ -7,7 +7,7 @@ import { toListboxOption } from "./list-state.js";
7
7
  import { choiceInputStyles, choiceParts, choiceRecipe, readonlyChoiceHandlers, syncChecked, useChoiceAppearance } from "./choice-styles.js";
8
8
  import { createVNode, useId } from "vue";
9
9
  import { _component, bindable, childrenProp, createContext, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
10
- import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
10
+ import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
11
11
  //#region src/input/Radio.tsx
12
12
  /** RadioGroup 交给组内 Radio 的状态 */
13
13
  /** RadioGroup 的上下文:自定义的单选项可以 inject 它接入组 */
@@ -1 +1 @@
1
- {"version":3,"file":"Radio.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_createVNode","_mergeProps"],"sources":["../../src/input/Radio.tsx"],"sourcesContent":["/**\n * 单选组(role=\"radiogroup\")与单选项(原生 input type=\"radio\")。结构与样式见 choice-styles.ts。\n *\n * <Field label=\"配送方式\">\n * <RadioGroup _value={shipping}>\n * <Radio value=\"express\">快递</Radio>\n * <Radio value=\"pickup\">自提</Radio>\n * </RadioGroup>\n * </Field>\n *\n * 同一组的原生 radio 共用一个 name:Tab 只停在选中项(没有选中时停在第一项),方向键在组内移动并选中,\n * 这些都是浏览器的原生行为,不需要漫游焦点。组以 Field 的标签为名称(aria-labelledby),关联说明与错误。\n *\n * 部件(Radio):Root(label)、Control(叠放层)、Indicator(圆点)、Label(文字);未声明的属性落到 input 上。\n */\nimport { createContext, _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 { useFieldControl } from '../form/Field';\nimport { toListboxOption, type ListboxOption, type OptionMapping } from './list-state';\nimport { hasContent, defaultLabelledBy, mergeAttrs, 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 { useRecipe } from '../config/styles';\nimport {\n choiceInputStyles,\n choiceParts,\n choiceRecipe,\n useChoiceAppearance,\n type ChoiceOrientations,\n readonlyChoiceHandlers,\n syncChecked,\n} from './choice-styles';\nimport { t } from '../config/theme/tokens';\n\n/** RadioGroup 交给组内 Radio 的状态 */\nexport interface RadioGroupState {\n /** 选中的值 */\n readonly value: string | null;\n /** 原生单选框的 name:同组共用,方向键在组内移动 */\n readonly name: string;\n /** 整组不可用 */\n readonly disabled: boolean;\n /** 整组只读 */\n readonly readonly: boolean;\n /** 必填 */\n readonly required: boolean;\n /** 整组校验未通过 */\n readonly invalid: boolean;\n /** 字号档位;不写时继承 */\n readonly size: TextSize | undefined;\n /** 选中时的色调 */\n readonly tone: StatusTone;\n /** 选中一个值 */\n select(value: string): void;\n}\n\n/** RadioGroup 的上下文:自定义的单选项可以 inject 它接入组 */\nexport const RadioGroupContext = createContext<RadioGroupState>('RadioGroup');\n\n/** 未声明的属性落到 div(role=\"radiogroup\")上 */\nexport interface RadioGroupBaseProps<T> extends PartProps<'div', 'role'> {\n /** 选中项的值:父级写 _value={x};没有选中时是 null */\n _value?: string | null;\n /** 表单提交时的 name;不写时自动生成(同组的 radio 要共用一个 name 才互斥) */\n name?: string;\n /** 整组不可用 */\n disabled?: boolean;\n /** 整组只读:能聚焦、读屏念“只读”,选中项不能改(查看详情、审批时);外观照常 */\n readonly?: boolean;\n /** 必填 */\n required?: boolean;\n /** 校验未通过 */\n invalid?: boolean;\n /** 字号档位;不写时继承上下文字号 */\n size?: TextSize;\n /** 选中时的色调(与 Button、Badge 等同一套),默认 accent;可以用 defaults.Choice 统一改 */\n tone?: StatusTone;\n /** 排列方向,默认 vertical */\n orientation?: keyof ChoiceOrientations;\n /** 各项:ListboxOption(值、文字、说明、不可用)、字符串,或任意数据加 toOption;写了 children 时不用 */\n items?: readonly T[];\n /** Radio;不写时按 items 生成 */\n children?: VNodeChild;\n}\n\n/** RadioGroup 的属性:items 是 ListboxOption、字符串时不用 toOption */\nexport type RadioGroupProps<T = ListboxOption> = RadioGroupBaseProps<T> & OptionMapping<T>;\n\n/** 单选组:value 是选中项的值 */\nexport const RadioGroup = _component(\n <T = ListboxOption,>({\n _value: value = _bindable<string | null>(null),\n name,\n disabled,\n readonly,\n required,\n invalid,\n size,\n tone,\n orientation = 'vertical',\n id,\n items,\n toOption,\n children,\n ...rest\n }: RadioGroupProps<T>) => {\n const generatedName = useId();\n const control = useFieldControl(() => ({ id, disabled, readonly, required, invalid }));\n const appearance = useChoiceAppearance(() => ({ size, tone }));\n RadioGroupContext.provide({\n get value() {\n return value;\n },\n get name() {\n return name ?? generatedName;\n },\n get disabled() {\n return control().disabled;\n },\n get readonly() {\n return control().readonly;\n },\n get required() {\n return control().required;\n },\n get invalid() {\n return control().invalid;\n },\n get size() {\n return appearance().size;\n },\n get tone() {\n return appearance().tone;\n },\n select: (next) => (value = next),\n });\n\n return () => {\n const state = control();\n return (\n <div\n {...mergeAttrs<'div'>(appearance().recipe({ orientation }).group, rest, {\n id: state.id,\n role: 'radiogroup',\n 'aria-labelledby': defaultLabelledBy(rest, state.labelledBy),\n 'aria-describedby': state.describedBy,\n 'aria-invalid': state.invalid || undefined,\n 'aria-required': state.required || undefined,\n 'aria-readonly': state.readonly || undefined,\n })}\n data-orientation={orientation}\n data-disabled={state.disabled || undefined}\n data-readonly={state.readonly || undefined}\n >\n {children ??\n items?.map((item) => {\n const option = toListboxOption(item, toOption);\n return (\n <Radio\n key={option.value}\n value={option.value}\n disabled={option.disabled || undefined}\n description={option.description}\n >\n {option.label}\n </Radio>\n );\n })}\n </div>\n );\n };\n },\n);\n\n/** 选中、名称与可用性由组管理 */\nexport type RadioManaged = 'type' | 'name' | 'checked' | 'required' | 'size' | 'value';\n\n/** 未声明的属性落到 input 上;外层 label 用 propsRoot */\nexport interface RadioProps extends PartProps<'input', RadioManaged> {\n /** 这一项的值 */\n value: string;\n /** 这一项不可用 */\n disabled?: boolean;\n /** 外层 label 的部件属性 */\n propsRoot?: PartProps<'label'>;\n /** 叠放层的部件属性 */\n propsControl?: PartProps<'span'>;\n /** 圆点的部件属性 */\n propsIndicator?: PartProps<'span'>;\n /** 文字的部件属性 */\n propsLabel?: PartProps<'span'>;\n /** 文字下方的说明(aria-describedby) */\n description?: VNodeChild;\n /** 说明的部件属性 */\n propsDescription?: PartProps<'span'>;\n /** 文字 */\n children?: VNodeChild;\n}\n\n/** RadioGroup、Radio 的样式:circle、dot、dotChecked */\nexport const radioStyles = css.create({\n circle: { width: '1.125em', height: '1.125em', borderRadius: '_full' },\n dot: {\n width: '0.45em',\n height: '0.45em',\n borderRadius: '_full',\n backgroundColor: 'var(--tone-on-fill)',\n transform: 'scale(0)',\n transition: `transform ${t.durations.sm} ${t.easings.standard}`,\n },\n dotChecked: { transform: 'none' },\n});\n\n/** 单选项:放在 RadioGroup 里 */\nexport const Radio = _component(\n ({\n value,\n disabled,\n propsRoot,\n propsControl,\n propsIndicator,\n propsLabel,\n description,\n propsDescription,\n children,\n ...rest\n }: RadioProps) => {\n const group = RadioGroupContext.inject();\n const descriptionId = `${useId()}-description`;\n const recipe = useRecipe(choiceRecipe);\n return () => {\n const checked = group.value === value;\n const off = disabled ?? group.disabled;\n const s = choiceParts(\n { size: group.size, tone: group.tone, recipe },\n { disabled: off, readonly: group.readonly },\n );\n return (\n <label\n {...mergeAttrs<'label'>(s.root, propsRoot)}\n data-state={checked ? 'checked' : 'unchecked'}\n data-disabled={off || undefined}\n data-readonly={group.readonly || 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 radioStyles.circle,\n checked && choiceInputStyles.checked,\n group.invalid && choiceInputStyles.invalid,\n ],\n },\n rest,\n {\n type: 'radio',\n name: group.name,\n value,\n checked,\n disabled: off,\n required: group.required,\n 'aria-describedby': hasContent(description) ? descriptionId : undefined,\n onChange: (event: Event) => {\n group.select(value);\n // 浏览器已经取消了同组原来选中的那个:整组一起对回父级的值\n const radios = (event.target as HTMLElement)\n .closest('[role=\"radiogroup\"]')\n ?.querySelectorAll<HTMLInputElement>('input[type=\"radio\"]');\n syncChecked([...(radios ?? [])], (input) => input.value === group.value);\n },\n ...(group.readonly && readonlyChoiceHandlers),\n },\n )}\n />\n <span\n {...mergeAttrs<'span'>(\n {\n ...s.indicator,\n sx: [s.indicator.sx, radioStyles.dot, checked && radioStyles.dotChecked],\n },\n propsIndicator,\n )}\n />\n </span>\n {(hasContent(children) || hasContent(description)) && (\n <span {...mergeAttrs<'span'>(s.label, propsLabel)}>\n {children}\n {hasContent(description) && (\n <span\n {...mergeAttrs<'span'>(s.description, propsDescription, {\n id: descriptionId,\n })}\n >\n {description}\n </span>\n )}\n </span>\n )}\n </label>\n );\n };\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"Radio.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_createVNode","_mergeProps"],"sources":["../../src/input/Radio.tsx"],"sourcesContent":["/**\n * 单选组(role=\"radiogroup\")与单选项(原生 input type=\"radio\")。结构与样式见 choice-styles.ts。\n *\n * <Field label=\"配送方式\">\n * <RadioGroup _value={shipping}>\n * <Radio value=\"express\">快递</Radio>\n * <Radio value=\"pickup\">自提</Radio>\n * </RadioGroup>\n * </Field>\n *\n * 同一组的原生 radio 共用一个 name:Tab 只停在选中项(没有选中时停在第一项),方向键在组内移动并选中,\n * 这些都是浏览器的原生行为,不需要漫游焦点。组以 Field 的标签为名称(aria-labelledby),关联说明与错误。\n *\n * 部件(Radio):Root(label)、Control(叠放层)、Indicator(圆点)、Label(文字);未声明的属性落到 input 上。\n */\nimport { createContext, _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { useId, type VNodeChild } from 'vue';\nimport { useFieldControl } from '../form/Field';\nimport { toListboxOption, type ListboxOption, type OptionMapping } from './list-state';\nimport { hasContent, defaultLabelledBy, mergeAttrs, 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 { useRecipe } from '../config/styles';\nimport {\n choiceInputStyles,\n choiceParts,\n choiceRecipe,\n useChoiceAppearance,\n type ChoiceOrientations,\n readonlyChoiceHandlers,\n syncChecked,\n} from './choice-styles';\nimport { t } from '../config/theme/tokens';\n\n/** RadioGroup 交给组内 Radio 的状态 */\nexport interface RadioGroupState {\n /** 选中的值 */\n readonly value: string | null;\n /** 原生单选框的 name:同组共用,方向键在组内移动 */\n readonly name: string;\n /** 整组不可用 */\n readonly disabled: boolean;\n /** 整组只读 */\n readonly readonly: boolean;\n /** 必填 */\n readonly required: boolean;\n /** 整组校验未通过 */\n readonly invalid: boolean;\n /** 字号档位;不写时继承 */\n readonly size: TextSize | undefined;\n /** 选中时的色调 */\n readonly tone: StatusTone;\n /** 选中一个值 */\n select(value: string): void;\n}\n\n/** RadioGroup 的上下文:自定义的单选项可以 inject 它接入组 */\nexport const RadioGroupContext = createContext<RadioGroupState>('RadioGroup');\n\n/** 未声明的属性落到 div(role=\"radiogroup\")上 */\nexport interface RadioGroupBaseProps<T> extends PartProps<'div', 'role'> {\n /** 选中项的值:父级写 _value={x};没有选中时是 null */\n _value?: string | null;\n /** 表单提交时的 name;不写时自动生成(同组的 radio 要共用一个 name 才互斥) */\n name?: string;\n /** 整组不可用 */\n disabled?: boolean;\n /** 整组只读:能聚焦、读屏念“只读”,选中项不能改(查看详情、审批时);外观照常 */\n readonly?: boolean;\n /** 必填 */\n required?: boolean;\n /** 校验未通过 */\n invalid?: boolean;\n /** 字号档位;不写时继承上下文字号 */\n size?: TextSize;\n /** 选中时的色调(与 Button、Badge 等同一套),默认 accent;可以用 defaults.Choice 统一改 */\n tone?: StatusTone;\n /** 排列方向,默认 vertical */\n orientation?: keyof ChoiceOrientations;\n /** 各项:ListboxOption(值、文字、说明、不可用)、字符串,或任意数据加 toOption;写了 children 时不用 */\n items?: readonly T[];\n /** Radio;不写时按 items 生成 */\n children?: VNodeChild;\n}\n\n/** RadioGroup 的属性:items 是 ListboxOption、字符串时不用 toOption */\nexport type RadioGroupProps<T = ListboxOption> = RadioGroupBaseProps<T> & OptionMapping<T>;\n\n/** 单选组:value 是选中项的值 */\nexport const RadioGroup = _component(\n <T = ListboxOption,>({\n _value: value = _bindable<string | null>(null),\n name,\n disabled,\n readonly,\n required,\n invalid,\n size,\n tone,\n orientation = 'vertical',\n id,\n items,\n toOption,\n children,\n ...rest\n }: RadioGroupProps<T>) => {\n const generatedName = useId();\n const control = useFieldControl(() => ({ id, disabled, readonly, required, invalid }));\n const appearance = useChoiceAppearance(() => ({ size, tone }));\n RadioGroupContext.provide({\n get value() {\n return value;\n },\n get name() {\n return name ?? generatedName;\n },\n get disabled() {\n return control().disabled;\n },\n get readonly() {\n return control().readonly;\n },\n get required() {\n return control().required;\n },\n get invalid() {\n return control().invalid;\n },\n get size() {\n return appearance().size;\n },\n get tone() {\n return appearance().tone;\n },\n select: (next) => (value = next),\n });\n\n return () => {\n const state = control();\n return (\n <div\n {...mergeAttrs<'div'>(appearance().recipe({ orientation }).group, rest, {\n id: state.id,\n role: 'radiogroup',\n 'aria-labelledby': defaultLabelledBy(rest, state.labelledBy),\n 'aria-describedby': state.describedBy,\n 'aria-invalid': state.invalid || undefined,\n 'aria-required': state.required || undefined,\n 'aria-readonly': state.readonly || undefined,\n })}\n data-orientation={orientation}\n data-disabled={state.disabled || undefined}\n data-readonly={state.readonly || undefined}\n >\n {children ??\n items?.map((item) => {\n const option = toListboxOption(item, toOption);\n return (\n <Radio\n key={option.value}\n value={option.value}\n disabled={option.disabled || undefined}\n description={option.description}\n >\n {option.label}\n </Radio>\n );\n })}\n </div>\n );\n };\n },\n);\n\n/** 选中、名称与可用性由组管理 */\nexport type RadioManaged = 'type' | 'name' | 'checked' | 'required' | 'size' | 'value';\n\n/** 未声明的属性落到 input 上;外层 label 用 propsRoot */\nexport interface RadioProps extends PartProps<'input', RadioManaged> {\n /** 这一项的值 */\n value: string;\n /** 这一项不可用 */\n disabled?: boolean;\n /** 外层 label 的部件属性 */\n propsRoot?: PartProps<'label'>;\n /** 叠放层的部件属性 */\n propsControl?: PartProps<'span'>;\n /** 圆点的部件属性 */\n propsIndicator?: PartProps<'span'>;\n /** 文字的部件属性 */\n propsLabel?: PartProps<'span'>;\n /** 文字下方的说明(aria-describedby) */\n description?: VNodeChild;\n /** 说明的部件属性 */\n propsDescription?: PartProps<'span'>;\n /** 文字 */\n children?: VNodeChild;\n}\n\n/** RadioGroup、Radio 的样式:circle、dot、dotChecked */\nexport const radioStyles = css.create({\n circle: { width: '1.125em', height: '1.125em', borderRadius: '_full' },\n dot: {\n width: '0.45em',\n height: '0.45em',\n borderRadius: '_full',\n backgroundColor: 'var(--tone-on-fill)',\n transform: 'scale(0)',\n transition: `transform ${t.durations.sm} ${t.easings.standard}`,\n },\n dotChecked: { transform: 'none' },\n});\n\n/** 单选项:放在 RadioGroup 里 */\nexport const Radio = _component(\n ({\n value,\n disabled,\n propsRoot,\n propsControl,\n propsIndicator,\n propsLabel,\n description,\n propsDescription,\n children,\n ...rest\n }: RadioProps) => {\n const group = RadioGroupContext.inject();\n const descriptionId = `${useId()}-description`;\n const recipe = useRecipe(choiceRecipe);\n return () => {\n const checked = group.value === value;\n const off = disabled ?? group.disabled;\n const s = choiceParts(\n { size: group.size, tone: group.tone, recipe },\n { disabled: off, readonly: group.readonly },\n );\n return (\n <label\n {...mergeAttrs<'label'>(s.root, propsRoot)}\n data-state={checked ? 'checked' : 'unchecked'}\n data-disabled={off || undefined}\n data-readonly={group.readonly || 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 radioStyles.circle,\n checked && choiceInputStyles.checked,\n group.invalid && choiceInputStyles.invalid,\n ],\n },\n rest,\n {\n type: 'radio',\n name: group.name,\n value,\n checked,\n disabled: off,\n required: group.required,\n 'aria-describedby': hasContent(description) ? descriptionId : undefined,\n onChange: (event: Event) => {\n group.select(value);\n // 浏览器已经取消了同组原来选中的那个:整组一起对回父级的值\n const radios = (event.target as HTMLElement)\n .closest('[role=\"radiogroup\"]')\n ?.querySelectorAll<HTMLInputElement>('input[type=\"radio\"]');\n syncChecked([...(radios ?? [])], (input) => input.value === group.value);\n },\n ...(group.readonly && readonlyChoiceHandlers),\n },\n )}\n />\n <span\n {...mergeAttrs<'span'>(\n {\n ...s.indicator,\n sx: [s.indicator.sx, radioStyles.dot, checked && radioStyles.dotChecked],\n },\n propsIndicator,\n )}\n />\n </span>\n {(hasContent(children) || hasContent(description)) && (\n <span {...mergeAttrs<'span'>(s.label, propsLabel)}>\n {children}\n {hasContent(description) && (\n <span\n {...mergeAttrs<'span'>(s.description, propsDescription, {\n id: descriptionId,\n })}\n >\n {description}\n </span>\n )}\n </span>\n )}\n </label>\n );\n };\n },\n);\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';
1
+ import { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';
2
2
  import { type IconData } from '../base/Icon';
3
3
  import { type PartProps } from '../utils/props';
4
4
  import { type TextSize } from '../utils/style/typography';
@@ -8,7 +8,7 @@ import { visuallyHiddenStyles } from "../base/VisuallyHidden.js";
8
8
  import { useFieldControl } from "../form/Field.js";
9
9
  import { createVNode, ref, useId } from "vue";
10
10
  import { _component, bindable, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
11
- import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
11
+ import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
12
12
  import { Star } from "@lucide/icons";
13
13
  //#region src/input/Rating.tsx
14
14
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"Rating.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_restProps","_vue_ref","_createVNode","_mergeProps"],"sources":["../../src/input/Rating.tsx"],"sourcesContent":["/**\n * 评分:几颗星(或别的图标)里选一个分数,供应商评价、满意度、优先级。可以半星,可以只读显示。\n *\n * <Field label=\"交付质量\"><Rating _value={score} /></Field>\n * <Rating value={4.5} readonly /> 只读:一个 role=\"img\",读“4.5 星,满分 5 星”\n * <Rating _value={score} allowHalf count={10} icon={Heart} tone=\"danger\" />\n *\n * 可编辑时是单选组(role=\"radiogroup\"):每颗星是一个原生 radio(视觉上隐藏),方向键、表单提交、读屏都是原生的;\n * 名称是“3 星”这样的文字(lang.ratingStar)。指针悬停时预览将要选的分数;再点一次已选的分数清空(clearable,默认开)。\n * 半星:每颗星左右各一半,各是一个 radio。部件:Root(div)、Star(span,每颗星)、Icon。\n */\nimport { Star } from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { SxStyles } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { useId } from 'vue';\nimport { Icon, type IconData } from '../base/Icon';\nimport { visuallyHiddenStyles } from '../base/VisuallyHidden';\nimport { useLang } from '../config/context';\nimport { useFieldControl } from '../form/Field';\nimport { defaultLabelledBy, mergeAttrs, type PartProps } from '../utils/props';\nimport { focusRingStyles } from '../utils/style/styles';\nimport { fontSizeStyles, type TextSize } from '../utils/style/typography';\nimport type { StatusTone } from '../utils/style/tone-styles';\nimport { t } from '../config/theme/tokens';\n\n/** 角色由组件管理 */\nexport type RatingManaged = 'role';\n\n/** 未声明的属性落到外层 div 上;名称写 aria-label,或放在 Field 里 */\nexport interface RatingProps extends PartProps<'div', RatingManaged> {\n /** 分数:父级写 _value={score};没有评分时是 null */\n _value?: number | null;\n /** 一共几颗星,默认 5 */\n count?: number;\n /** 可以选半颗 */\n allowHalf?: boolean;\n /** 再点一次已选的分数时清空,默认 true */\n clearable?: boolean;\n /** 图标,默认星星 */\n icon?: IconData;\n /** 选中的颜色,默认 warning(金黄) */\n tone?: StatusTone;\n /** 字号档位:图标随之缩放 */\n size?: TextSize;\n /** 只读:只显示分数(一个 role=\"img\") */\n readonly?: boolean;\n /** 不可用(不写时取 Field 的) */\n disabled?: boolean;\n /** 表单提交时的 name */\n name?: string;\n /** 每颗星的部件属性 */\n propsStar?: PartProps<'span'>;\n}\n\n/** Rating 的样式:root、star、readonly、icon、empty、fill、clip、clipIcon、whole、startHalf、endHalf、disabled */\nexport const ratingStyles = css.create({\n root: { display: 'inline-flex', alignItems: 'center', gap: '0.15em', lineHeight: 1 },\n // 每颗星:空心图标打底,填色的那层按比例裁出;radio 盖满(半星时左右各一半)\n star: {\n position: 'relative',\n display: 'inline-grid',\n width: '1.35em',\n height: '1.35em',\n borderRadius: '_sm',\n cursor: 'pointer',\n transition: `scale ${t.durations.sm} ${t.easings.standard}`,\n scale: { default: null, ':hover': '1.12' },\n },\n readonly: { cursor: 'default', scale: null },\n icon: { gridArea: '1 / 1', width: '100%', height: '100%' },\n empty: { color: '_borderStrong' },\n // 填色的那层:currentColor 填满图标\n fill: { fill: 'currentColor' },\n clip: { gridArea: '1 / 1', overflow: 'hidden', pointerEvents: 'none' },\n // 裁出来的那层按整颗星的大小画,不随裁出的宽度缩小\n clipIcon: { display: 'block', width: '1.35em', height: '1.35em', maxWidth: 'none' },\n // 点击区域:整颗;半星时起始边一半、结束边一半\n whole: { position: 'absolute', inset: 0 },\n startHalf: { position: 'absolute', insetBlock: 0, insetInlineStart: 0, width: '50%' },\n endHalf: { position: 'absolute', insetBlock: 0, insetInlineEnd: 0, width: '50%' },\n disabled: { opacity: '_disabled', cursor: 'not-allowed' },\n});\n\n// 选中的颜色用各色调的实色(金黄的星、红色的心):实心与空心靠形状区分,不只靠颜色;Windows 高对比下用系统高亮色\n/** Rating 的颜色:neutral、accent、info、success、warning、danger */\nexport const ratingToneStyles = css.create({\n neutral: { color: { default: '_textMuted', '@media (forced-colors: active)': 'Highlight' } },\n accent: { color: { default: '_accent', '@media (forced-colors: active)': 'Highlight' } },\n info: { color: { default: '_info', '@media (forced-colors: active)': 'Highlight' } },\n success: { color: { default: '_success', '@media (forced-colors: active)': 'Highlight' } },\n warning: { color: { default: '_warning', '@media (forced-colors: active)': 'Highlight' } },\n danger: { color: { default: '_danger', '@media (forced-colors: active)': 'Highlight' } },\n});\n\n/** 填色那层的宽度 */\nexport const ratingClipStyles = css.create({\n width: (percent: string) => ({ width: percent }),\n});\n\n/** 评分:一排可以点的星 */\nexport const Rating = _component(\n ({\n _value: value = _bindable<number | null>(null),\n count = 5,\n allowHalf = false,\n clearable = true,\n icon = Star,\n tone = 'warning',\n size,\n readonly,\n disabled,\n name,\n id,\n propsStar,\n ...rest\n }: RatingProps) => {\n const lang = useLang();\n const generatedName = useId();\n const control = useFieldControl(() => ({ id, disabled, readonly }));\n // 指针悬停时预览的分数\n let hover = _state<number | null>(null);\n\n /** 第 index 颗星(从 1 开始)填了多少:0、50、100 */\n const filled = (shown: number | null, index: number) =>\n shown == null ? 0 : shown >= index ? 100 : shown >= index - 0.5 ? 50 : 0;\n\n function pick(next: number) {\n value = clearable && value === next ? null : next;\n hover = null;\n }\n\n const starIcon = (percent: number) => [\n <Icon icon={icon} sx={[ratingStyles.icon, ratingStyles.empty]} />,\n percent > 0 && (\n <span {...css.attrs(ratingStyles.clip, ratingClipStyles.width(`${percent}%`))}>\n <Icon\n icon={icon}\n sx={[ratingStyles.clipIcon, ratingStyles.fill, ratingToneStyles[tone]]}\n />\n </span>\n ),\n ];\n\n return () => {\n const state = control();\n const stars = Array.from({ length: count }, (_, index) => index + 1);\n\n if (state.readonly) {\n return (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [ratingStyles.root, size && fontSizeStyles[size]],\n 'aria-labelledby': defaultLabelledBy(rest, state.labelledBy),\n },\n rest,\n { id: state.id, role: 'img', 'aria-label': lang.ratingSummary(value, count) },\n )}\n >\n {stars.map((index) => (\n <span\n key={index}\n aria-hidden=\"true\"\n {...mergeAttrs<'span'>(\n { sx: [ratingStyles.star, ratingStyles.readonly] },\n propsStar,\n )}\n >\n {starIcon(filled(value, index))}\n </span>\n ))}\n </div>\n );\n }\n\n const shown = hover ?? value;\n const radio = (score: number, sx: SxStyles) => (\n <label {...css.attrs(sx)} onPointerenter={() => (hover = score)}>\n <input\n type=\"radio\"\n name={name ?? generatedName}\n value={String(score)}\n checked={value === score}\n disabled={state.disabled}\n aria-label={lang.ratingStar(score)}\n onClick={() => pick(score)}\n {...css.attrs(visuallyHiddenStyles.hidden)}\n />\n </label>\n );\n return (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n ratingStyles.root,\n size && fontSizeStyles[size],\n state.disabled && ratingStyles.disabled,\n ],\n 'aria-labelledby': defaultLabelledBy(rest, state.labelledBy),\n },\n rest,\n {\n id: state.id,\n role: 'radiogroup',\n 'aria-describedby': state.describedBy,\n 'aria-disabled': state.disabled || undefined,\n onPointerleave: () => (hover = null),\n },\n )}\n >\n {stars.map((index) => (\n <span\n key={index}\n {...mergeAttrs<'span'>(\n {\n sx: [ratingStyles.star, focusRingStyles.within],\n },\n propsStar,\n )}\n data-state={\n filled(value, index) === 100 ? 'full' : filled(value, index) ? 'half' : 'empty'\n }\n >\n {starIcon(filled(shown, index))}\n {allowHalf && radio(index - 0.5, ratingStyles.startHalf)}\n {radio(index, allowHalf ? ratingStyles.endHalf : ratingStyles.whole)}\n </span>\n ))}\n </div>\n );\n };\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"Rating.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_restProps","_vue_ref","_createVNode","_mergeProps"],"sources":["../../src/input/Rating.tsx"],"sourcesContent":["/**\n * 评分:几颗星(或别的图标)里选一个分数,供应商评价、满意度、优先级。可以半星,可以只读显示。\n *\n * <Field label=\"交付质量\"><Rating _value={score} /></Field>\n * <Rating value={4.5} readonly /> 只读:一个 role=\"img\",读“4.5 星,满分 5 星”\n * <Rating _value={score} allowHalf count={10} icon={Heart} tone=\"danger\" />\n *\n * 可编辑时是单选组(role=\"radiogroup\"):每颗星是一个原生 radio(视觉上隐藏),方向键、表单提交、读屏都是原生的;\n * 名称是“3 星”这样的文字(lang.ratingStar)。指针悬停时预览将要选的分数;再点一次已选的分数清空(clearable,默认开)。\n * 半星:每颗星左右各一半,各是一个 radio。部件:Root(div)、Star(span,每颗星)、Icon。\n */\nimport { Star } from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { SxStyles } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { useId } from 'vue';\nimport { Icon, type IconData } from '../base/Icon';\nimport { visuallyHiddenStyles } from '../base/VisuallyHidden';\nimport { useLang } from '../config/context';\nimport { useFieldControl } from '../form/Field';\nimport { defaultLabelledBy, mergeAttrs, type PartProps } from '../utils/props';\nimport { focusRingStyles } from '../utils/style/styles';\nimport { fontSizeStyles, type TextSize } from '../utils/style/typography';\nimport type { StatusTone } from '../utils/style/tone-styles';\nimport { t } from '../config/theme/tokens';\n\n/** 角色由组件管理 */\nexport type RatingManaged = 'role';\n\n/** 未声明的属性落到外层 div 上;名称写 aria-label,或放在 Field 里 */\nexport interface RatingProps extends PartProps<'div', RatingManaged> {\n /** 分数:父级写 _value={score};没有评分时是 null */\n _value?: number | null;\n /** 一共几颗星,默认 5 */\n count?: number;\n /** 可以选半颗 */\n allowHalf?: boolean;\n /** 再点一次已选的分数时清空,默认 true */\n clearable?: boolean;\n /** 图标,默认星星 */\n icon?: IconData;\n /** 选中的颜色,默认 warning(金黄) */\n tone?: StatusTone;\n /** 字号档位:图标随之缩放 */\n size?: TextSize;\n /** 只读:只显示分数(一个 role=\"img\") */\n readonly?: boolean;\n /** 不可用(不写时取 Field 的) */\n disabled?: boolean;\n /** 表单提交时的 name */\n name?: string;\n /** 每颗星的部件属性 */\n propsStar?: PartProps<'span'>;\n}\n\n/** Rating 的样式:root、star、readonly、icon、empty、fill、clip、clipIcon、whole、startHalf、endHalf、disabled */\nexport const ratingStyles = css.create({\n root: { display: 'inline-flex', alignItems: 'center', gap: '0.15em', lineHeight: 1 },\n // 每颗星:空心图标打底,填色的那层按比例裁出;radio 盖满(半星时左右各一半)\n star: {\n position: 'relative',\n display: 'inline-grid',\n width: '1.35em',\n height: '1.35em',\n borderRadius: '_sm',\n cursor: 'pointer',\n transition: `scale ${t.durations.sm} ${t.easings.standard}`,\n scale: { default: null, ':hover': '1.12' },\n },\n readonly: { cursor: 'default', scale: null },\n icon: { gridArea: '1 / 1', width: '100%', height: '100%' },\n empty: { color: '_borderStrong' },\n // 填色的那层:currentColor 填满图标\n fill: { fill: 'currentColor' },\n clip: { gridArea: '1 / 1', overflow: 'hidden', pointerEvents: 'none' },\n // 裁出来的那层按整颗星的大小画,不随裁出的宽度缩小\n clipIcon: { display: 'block', width: '1.35em', height: '1.35em', maxWidth: 'none' },\n // 点击区域:整颗;半星时起始边一半、结束边一半\n whole: { position: 'absolute', inset: 0 },\n startHalf: { position: 'absolute', insetBlock: 0, insetInlineStart: 0, width: '50%' },\n endHalf: { position: 'absolute', insetBlock: 0, insetInlineEnd: 0, width: '50%' },\n disabled: { opacity: '_disabled', cursor: 'not-allowed' },\n});\n\n// 选中的颜色用各色调的实色(金黄的星、红色的心):实心与空心靠形状区分,不只靠颜色;Windows 高对比下用系统高亮色\n/** Rating 的颜色:neutral、accent、info、success、warning、danger */\nexport const ratingToneStyles = css.create({\n neutral: { color: { default: '_textMuted', '@media (forced-colors: active)': 'Highlight' } },\n accent: { color: { default: '_accent', '@media (forced-colors: active)': 'Highlight' } },\n info: { color: { default: '_info', '@media (forced-colors: active)': 'Highlight' } },\n success: { color: { default: '_success', '@media (forced-colors: active)': 'Highlight' } },\n warning: { color: { default: '_warning', '@media (forced-colors: active)': 'Highlight' } },\n danger: { color: { default: '_danger', '@media (forced-colors: active)': 'Highlight' } },\n});\n\n/** 填色那层的宽度 */\nexport const ratingClipStyles = css.create({\n width: (percent: string) => ({ width: percent }),\n});\n\n/** 评分:一排可以点的星 */\nexport const Rating = _component(\n ({\n _value: value = _bindable<number | null>(null),\n count = 5,\n allowHalf = false,\n clearable = true,\n icon = Star,\n tone = 'warning',\n size,\n readonly,\n disabled,\n name,\n id,\n propsStar,\n ...rest\n }: RatingProps) => {\n const lang = useLang();\n const generatedName = useId();\n const control = useFieldControl(() => ({ id, disabled, readonly }));\n // 指针悬停时预览的分数\n let hover = _state<number | null>(null);\n\n /** 第 index 颗星(从 1 开始)填了多少:0、50、100 */\n const filled = (shown: number | null, index: number) =>\n shown == null ? 0 : shown >= index ? 100 : shown >= index - 0.5 ? 50 : 0;\n\n function pick(next: number) {\n value = clearable && value === next ? null : next;\n hover = null;\n }\n\n const starIcon = (percent: number) => [\n <Icon icon={icon} sx={[ratingStyles.icon, ratingStyles.empty]} />,\n percent > 0 && (\n <span {...css.attrs(ratingStyles.clip, ratingClipStyles.width(`${percent}%`))}>\n <Icon\n icon={icon}\n sx={[ratingStyles.clipIcon, ratingStyles.fill, ratingToneStyles[tone]]}\n />\n </span>\n ),\n ];\n\n return () => {\n const state = control();\n const stars = Array.from({ length: count }, (_, index) => index + 1);\n\n if (state.readonly) {\n return (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [ratingStyles.root, size && fontSizeStyles[size]],\n 'aria-labelledby': defaultLabelledBy(rest, state.labelledBy),\n },\n rest,\n { id: state.id, role: 'img', 'aria-label': lang.ratingSummary(value, count) },\n )}\n >\n {stars.map((index) => (\n <span\n key={index}\n aria-hidden=\"true\"\n {...mergeAttrs<'span'>(\n { sx: [ratingStyles.star, ratingStyles.readonly] },\n propsStar,\n )}\n >\n {starIcon(filled(value, index))}\n </span>\n ))}\n </div>\n );\n }\n\n const shown = hover ?? value;\n const radio = (score: number, sx: SxStyles) => (\n <label {...css.attrs(sx)} onPointerenter={() => (hover = score)}>\n <input\n type=\"radio\"\n name={name ?? generatedName}\n value={String(score)}\n checked={value === score}\n disabled={state.disabled}\n aria-label={lang.ratingStar(score)}\n onClick={() => pick(score)}\n {...css.attrs(visuallyHiddenStyles.hidden)}\n />\n </label>\n );\n return (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n ratingStyles.root,\n size && fontSizeStyles[size],\n state.disabled && ratingStyles.disabled,\n ],\n 'aria-labelledby': defaultLabelledBy(rest, state.labelledBy),\n },\n rest,\n {\n id: state.id,\n role: 'radiogroup',\n 'aria-describedby': state.describedBy,\n 'aria-disabled': state.disabled || undefined,\n onPointerleave: () => (hover = null),\n },\n )}\n >\n {stars.map((index) => (\n <span\n key={index}\n {...mergeAttrs<'span'>(\n {\n sx: [ratingStyles.star, focusRingStyles.within],\n },\n propsStar,\n )}\n data-state={\n filled(value, index) === 100 ? 'full' : filled(value, index) ? 'half' : 'empty'\n }\n >\n {starIcon(filled(shown, index))}\n {allowHalf && radio(index - 0.5, ratingStyles.startHalf)}\n {radio(index, allowHalf ? ratingStyles.endHalf : ratingStyles.whole)}\n </span>\n ))}\n </div>\n );\n };\n },\n);\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';
1
+ import { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';
2
2
  import { type VNodeChild } from 'vue';
3
3
  import type { PresetIconButtonProps } from '../base/CloseButton';
4
4
  import { type IconProps } from '../base/Icon';
@@ -58,7 +58,7 @@ export interface SelectBaseProps<T> extends PartProps<'button', SelectManaged>,
58
58
  children?: (item: T, state: OptionRenderState) => VNodeChild;
59
59
  /** 自定义触发框里显示的内容(已选的选项);默认单选显示文字、多选显示标签 */
60
60
  renderValue?: (selected: readonly T[]) => VNodeChild;
61
- /** 正在取选项(异步加载):没有选项时列表里是骨架行,已有选项时顶部显示进度条 */
61
+ /** 正在取选项(异步加载):列表里换成骨架行 */
62
62
  loading?: boolean;
63
63
  /** 没有选项时列表里显示的内容 */
64
64
  empty?: VNodeChild;
@@ -18,7 +18,7 @@ import { SelectedTags } from "./SelectedTags.js";
18
18
  import { TextField } from "./TextField.js";
19
19
  import { Fragment, createVNode, shallowRef, useId, watch } from "vue";
20
20
  import { _component, bindable, childrenProp, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
21
- import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
21
+ import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
22
22
  import { ChevronDown, Plus, Search } from "@lucide/icons";
23
23
  //#region src/input/Select.tsx
24
24
  /**
@@ -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 { 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,4 +1,4 @@
1
- import * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';
1
+ import { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';
2
2
  import { type TagProps } from '../base/Tag';
3
3
  import { type PartProps } from '../utils/props';
4
4
  /** 一个已选的标签 */
@@ -4,7 +4,7 @@ import { Tag } from "../base/Tag.js";
4
4
  import { useOverflowItems } from "../utils/dom/overflow.js";
5
5
  import { createVNode, isVNode, shallowRef } from "vue";
6
6
  import { _component, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
7
- import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
7
+ import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
8
8
  //#region src/input/SelectedTags.tsx
9
9
  /** 一个已选的标签 */
10
10
  /** 未声明的属性落到这一排的 span 上 */
@@ -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,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"}
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 { 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"}
@@ -1,4 +1,4 @@
1
- import * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';
1
+ import { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';
2
2
  import { type VNodeChild } from 'vue';
3
3
  import { type PartProps } from '../utils/props';
4
4
  import { type StatusTone } from '../utils/style/tone-styles';
@@ -12,7 +12,7 @@ import { useFieldControl } from "../form/Field.js";
12
12
  import { FormValue } from "../form/FormValue.js";
13
13
  import { createVNode, isVNode, shallowRef, useId } from "vue";
14
14
  import { _component, bindable, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
15
- import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
15
+ import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
16
16
  //#region src/input/Slider.tsx
17
17
  /** 滑块方向 */
18
18
  /** 单值,或范围 [低, 高] */