@zerodep-dev/vue-tsx-pro-ui 0.3.0 → 0.3.2

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 (616) 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 +1 -1
  242. package/dist/display/VirtualList.js +1 -1
  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 +1 -1
  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 +1 -1
  326. package/dist/input/ListPopover.js +1 -1
  327. package/dist/input/ListPopover.js.map +1 -1
  328. package/dist/input/Listbox.d.ts +1 -1
  329. package/dist/input/Listbox.js +1 -1
  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 +1 -1
  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 +1 -1
  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/patterns/ActionBar.d.ts +1 -1
  496. package/dist/patterns/ActionBar.js +1 -1
  497. package/dist/patterns/ActionBar.js.map +1 -1
  498. package/dist/patterns/AppShell.d.ts +1 -1
  499. package/dist/patterns/AppShell.js +1 -1
  500. package/dist/patterns/AppShell.js.map +1 -1
  501. package/dist/patterns/AuthLayout.d.ts +2 -2
  502. package/dist/patterns/AuthLayout.js +2 -2
  503. package/dist/patterns/AuthLayout.js.map +1 -1
  504. package/dist/patterns/CommentThread.d.ts +1 -1
  505. package/dist/patterns/CommentThread.js +1 -1
  506. package/dist/patterns/CommentThread.js.map +1 -1
  507. package/dist/patterns/DataImport.d.ts +1 -1
  508. package/dist/patterns/DataImport.js +1 -1
  509. package/dist/patterns/DataImport.js.map +1 -1
  510. package/dist/patterns/FilterBar.d.ts +1 -1
  511. package/dist/patterns/FilterBar.js +1 -1
  512. package/dist/patterns/FilterBar.js.map +1 -1
  513. package/dist/patterns/KanbanBoard.d.ts +1 -1
  514. package/dist/patterns/KanbanBoard.js +1 -1
  515. package/dist/patterns/KanbanBoard.js.map +1 -1
  516. package/dist/patterns/NotificationCenter.d.ts +1 -1
  517. package/dist/patterns/NotificationCenter.js +1 -1
  518. package/dist/patterns/NotificationCenter.js.map +1 -1
  519. package/dist/patterns/QueryTable.d.ts +1 -1
  520. package/dist/patterns/QueryTable.js +1 -1
  521. package/dist/patterns/QueryTable.js.map +1 -1
  522. package/dist/patterns/SlideCaptcha.d.ts +1 -1
  523. package/dist/patterns/SlideCaptcha.js +1 -1
  524. package/dist/patterns/SlideCaptcha.js.map +1 -1
  525. package/dist/patterns/StepsForm.d.ts +1 -1
  526. package/dist/patterns/StepsForm.js +1 -1
  527. package/dist/patterns/StepsForm.js.map +1 -1
  528. package/dist/table/ColumnHeaderActions.d.ts +1 -1
  529. package/dist/table/ColumnHeaderActions.js +1 -1
  530. package/dist/table/ColumnHeaderActions.js.map +1 -1
  531. package/dist/table/ColumnSettings.d.ts +1 -1
  532. package/dist/table/ColumnSettings.js +1 -1
  533. package/dist/table/ColumnSettings.js.map +1 -1
  534. package/dist/table/ColumnTable.d.ts +1 -1
  535. package/dist/table/ColumnTable.js +1 -1
  536. package/dist/table/ColumnTable.js.map +1 -1
  537. package/dist/table/DataTableView.d.ts +1 -1
  538. package/dist/table/DataTableView.js +1 -1
  539. package/dist/table/DataTableView.js.map +1 -1
  540. package/dist/table/PivotTable.d.ts +1 -1
  541. package/dist/table/PivotTable.js +1 -1
  542. package/dist/table/PivotTable.js.map +1 -1
  543. package/dist/table/SelectionBar.d.ts +1 -1
  544. package/dist/table/SelectionBar.js +1 -1
  545. package/dist/table/SelectionBar.js.map +1 -1
  546. package/dist/table/Table.d.ts +1 -1
  547. package/dist/table/Table.js +1 -1
  548. package/dist/table/Table.js.map +1 -1
  549. package/dist/table/TreeDataTable.d.ts +1 -1
  550. package/dist/table/TreeDataTable.js +1 -1
  551. package/dist/table/TreeDataTable.js.map +1 -1
  552. package/dist/table/table-styles.d.ts +1 -1
  553. package/dist/table/table-styles.js +1 -1
  554. package/dist/table/table-styles.js.map +1 -1
  555. package/dist/theme-customize/ThemeCustomizer.d.ts +1 -1
  556. package/dist/theme-customize/ThemeCustomizer.js +1 -1
  557. package/dist/theme-customize/ThemeCustomizer.js.map +1 -1
  558. package/dist/theme-customize/ThemeThumbnail.d.ts +1 -1
  559. package/dist/theme-customize/ThemeThumbnail.js +1 -1
  560. package/dist/theme-customize/ThemeThumbnail.js.map +1 -1
  561. package/dist/theme-customize/design-tokens.js +1 -1
  562. package/dist/theme-customize/design-tokens.js.map +1 -1
  563. package/dist/three/core/EffectSurface.d.ts +1 -1
  564. package/dist/three/core/EffectSurface.js +1 -1
  565. package/dist/three/core/EffectSurface.js.map +1 -1
  566. package/dist/three/core/ThreeCanvas.d.ts +1 -1
  567. package/dist/three/core/ThreeCanvas.js +1 -1
  568. package/dist/three/core/ThreeCanvas.js.map +1 -1
  569. package/dist/three/effects/Confetti.d.ts +1 -1
  570. package/dist/three/effects/Confetti.js +1 -1
  571. package/dist/three/effects/Confetti.js.map +1 -1
  572. package/dist/three/globe/Globe.d.ts +1 -1
  573. package/dist/three/globe/Globe.js +1 -1
  574. package/dist/three/globe/Globe.js.map +1 -1
  575. package/dist/three/model/ModelViewer.d.ts +1 -1
  576. package/dist/three/model/ModelViewer.js +1 -1
  577. package/dist/three/model/ModelViewer.js.map +1 -1
  578. package/dist/utils/dom/floating.d.ts +1 -1
  579. package/dist/utils/dom/floating.js +1 -1
  580. package/dist/utils/dom/floating.js.map +1 -1
  581. package/dist/utils/dom/ripple.d.ts +1 -1
  582. package/dist/utils/dom/ripple.js +1 -1
  583. package/dist/utils/dom/ripple.js.map +1 -1
  584. package/dist/utils/props.js +1 -1
  585. package/dist/utils/props.js.map +1 -1
  586. package/dist/utils/style/attached.d.ts +1 -1
  587. package/dist/utils/style/attached.js +1 -1
  588. package/dist/utils/style/attached.js.map +1 -1
  589. package/dist/utils/style/item-styles.d.ts +1 -1
  590. package/dist/utils/style/item-styles.js +1 -1
  591. package/dist/utils/style/item-styles.js.map +1 -1
  592. package/dist/utils/style/markers.d.ts +1 -1
  593. package/dist/utils/style/markers.js +1 -1
  594. package/dist/utils/style/markers.js.map +1 -1
  595. package/dist/utils/style/shimmer.d.ts +1 -1
  596. package/dist/utils/style/shimmer.js +1 -1
  597. package/dist/utils/style/shimmer.js.map +1 -1
  598. package/dist/utils/style/styles.d.ts +1 -1
  599. package/dist/utils/style/styles.js +1 -1
  600. package/dist/utils/style/styles.js.map +1 -1
  601. package/dist/utils/style/swatch-styles.d.ts +1 -1
  602. package/dist/utils/style/swatch-styles.js +1 -1
  603. package/dist/utils/style/swatch-styles.js.map +1 -1
  604. package/dist/utils/style/tone-styles.d.ts +1 -1
  605. package/dist/utils/style/tone-styles.js +1 -1
  606. package/dist/utils/style/tone-styles.js.map +1 -1
  607. package/dist/utils/style/transitions.d.ts +1 -1
  608. package/dist/utils/style/transitions.js +1 -1
  609. package/dist/utils/style/transitions.js.map +1 -1
  610. package/dist/utils/style/typography.d.ts +1 -1
  611. package/dist/utils/style/typography.js +1 -1
  612. package/dist/utils/style/typography.js.map +1 -1
  613. package/dist/utils/style/vars.d.ts +1 -1
  614. package/dist/utils/style/vars.js +1 -1
  615. package/dist/utils/style/vars.js.map +1 -1
  616. package/package.json +2 -2
@@ -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 PartProps } from '../utils/props';
3
3
  import type { TextSize } from '../utils/style/typography';
4
4
  import { type Condition, type ConditionField } from './condition';
@@ -14,7 +14,7 @@ import { NumberRangeField } from "./NumberRangeField.js";
14
14
  import { TagsInput } from "./TagsInput.js";
15
15
  import { createVNode, nextTick, ref, watch } from "vue";
16
16
  import { _component, bindable, mergeJsxProps, readonlyProp, restProps, untrack } from "@zerodep-dev/vue-tsx-pro-tsx";
17
- import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
17
+ import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
18
18
  import { Plus, Trash2, X } from "@lucide/icons";
19
19
  //#region src/input/ConditionBuilder.tsx
20
20
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ConditionBuilder.js","names":["_vtp_readonlyProp","_vtp_bindable","_vtp_restProps","_vtp_untrack","_vue_ref","_createVNode","_mergeProps"],"sources":["../../src/input/ConditionBuilder.tsx"],"sourcesContent":["/**\n * 条件构造器:编辑 all / any / not 加比较的条件树(Condition,见 condition.ts)。每条是“字段 · 比较方式 · 值”,\n * 比较方式随字段类型、值的输入随字段类型与比较方式;组的表头选满足方式(全部、任一、都不、不全),组里还能再加组。\n *\n * const fields: ConditionField[] = [\n * { name: 'amount', label: '金额', type: 'number' },\n * { name: 'category', label: '品类', type: 'select', options: [{ value: 'steel', label: '钢材' }, …] },\n * { name: 'owner', label: '经办人', type: 'select', input: ({ value, onChange, label }) => <UserPicker … /> },\n * ];\n * let condition = _state<Condition | null>(null);\n * <ConditionBuilder fields={fields} _value={condition} aria-label=\"审批条件\" />\n *\n * 写回的是只含填完整的比较的条件:没选字段、没填值的那几条留在界面上,不进 _value;一条也没有时是 null。\n * 根总是一个组({ all }、{ any },都不满足是 { not: { any } },不全满足是 { not: { all } });\n * 传进来的单条比较、嵌套的 not 按同样的规则读成组。父级改了 _value(与上次写回的不同)时整棵重读。\n *\n * 读屏:根与每个嵌套的组是 role=\"group\",每条比较也是一组(“条件 2”),三个控件各有名称(“字段”“比较方式”“金额的值”)。\n * 加了一条之后焦点落到它的字段上;删掉之后落到组的“添加条件”上。\n * 部件:Root(div)、Group(每个组)、Rule(每条比较)。\n */\nimport { Plus, Trash2, 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, watch, type VNodeChild } from 'vue';\nimport { Button } from '../base/Button';\nimport { IconButton } from '../base/IconButton';\nimport { Small } from '../base/Text';\nimport { useLang } from '../config/context';\nimport { t } from '../config/theme/tokens';\nimport { DatePicker } from '../date/DatePicker';\nimport { DateRangePicker } from '../date/DateRangePicker';\nimport { dataAttrs, mergeAttrs, type PartProps } from '../utils/props';\nimport type { TextSize } from '../utils/style/typography';\nimport {\n isRuleComplete,\n operatorLabel,\n toText,\n operatorsOf,\n valueShape,\n type Condition,\n type ConditionField,\n type ConditionOp,\n type ConditionRule,\n} from './condition';\nimport { NumberField } from './NumberField';\nimport { NumberRangeField } from './NumberRangeField';\nimport { Select } from './Select';\nimport { TagsInput } from './TagsInput';\nimport { TextField } from './TextField';\n\n/** 组的满足方式 */\nexport interface ConditionModes {\n /** 全部满足:{ all } */\n all: unknown;\n /** 任一满足:{ any } */\n any: unknown;\n /** 都不满足:{ not: { any } } */\n none: unknown;\n /** 不全满足:{ not: { all } } */\n notAll: unknown;\n}\n\n/** 组的满足方式 */\nexport type ConditionMode = keyof ConditionModes;\n\n/** 未声明的属性落到外层 div(role=\"group\")上:aria-label 写条件管什么 */\nexport interface ConditionBuilderProps extends PartProps<'div', 'role'> {\n /** 能参与比较的字段 */\n fields: readonly ConditionField[];\n /** 条件:父级写 _value={condition} 双向绑定;没有填完整的比较时是 null */\n _value?: Condition | null;\n /** 组最多嵌套几层,默认 2(根组里还能加一层组);1 时不能加组 */\n maxDepth?: number;\n /** 控件与按钮的字号档位,不写时继承 */\n size?: TextSize;\n /** 不可用 */\n disabled?: boolean;\n /** 每个组的部件属性 */\n propsGroup?: PartProps<'div'>;\n /** 每条比较的部件属性 */\n propsRule?: PartProps<'div'>;\n}\n\ninterface RuleNode {\n kind: 'rule';\n id: number;\n field: string | null;\n op: ConditionOp | null;\n value: unknown;\n}\n\ninterface GroupNode {\n kind: 'group';\n id: number;\n mode: ConditionMode;\n children: (RuleNode | GroupNode)[];\n}\n\nconst MODES: readonly ConditionMode[] = ['all', 'any', 'none', 'notAll'];\n\n/** ConditionBuilder 的样式:root、group、nested、header、rows、row、joiner、rule、field、op、value、range、actions、empty */\nexport const conditionBuilderStyles = css.create({\n root: { display: 'flex', flexDirection: 'column', gap: '_sm', minWidth: 0 },\n group: { display: 'flex', flexDirection: 'column', gap: '_sm', minWidth: 0 },\n // 嵌套的组:浅底加描边,和外层的条件分开\n nested: {\n flexGrow: 1,\n padding: '_sm',\n backgroundColor: '_surfaceMuted',\n borderWidth: '_xs',\n borderStyle: 'solid',\n borderColor: '_borderMuted',\n borderRadius: '_md',\n },\n header: { display: 'flex', alignItems: 'center', gap: '_sm' },\n rows: { display: 'flex', flexDirection: 'column', gap: '_sm' },\n row: { display: 'flex', alignItems: 'flex-start', gap: '_sm', minWidth: 0 },\n // 连接词(且、或)一列,宽度固定:各条的字段对齐\n joiner: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'flex-end',\n flexShrink: 0,\n width: '2em',\n // 与控件同高:连接词对着这一条的第一行\n minHeight: `max(${t.sizes.control}, ${t.sizes.minTarget})`,\n color: '_textMuted',\n },\n rule: {\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'flex-start',\n gap: '_sm',\n flexGrow: 1,\n minWidth: 0,\n },\n field: { flexGrow: 1, flexShrink: 1, flexBasis: '9rem', minWidth: '7rem', maxWidth: '14rem' },\n op: { flexGrow: 0, flexShrink: 1, flexBasis: '8rem', minWidth: '6rem' },\n // grid:里面的输入框拉满这一格(多选的标签按这个宽度排)\n value: { display: 'grid', flexGrow: 2, flexShrink: 1, flexBasis: '12rem', minWidth: '8rem' },\n range: { display: 'flex', alignItems: 'center', gap: '_xs' },\n actions: {\n display: 'flex',\n flexWrap: 'wrap',\n gap: '_xs',\n paddingInlineStart: 'calc(2em + 0.5rem)',\n },\n actionsRoot: { paddingInlineStart: 0 },\n removeGroup: { marginInlineStart: 'auto' },\n empty: { color: '_textMuted' },\n});\n\nlet nextId = 0;\nconst rule = (\n field: string | null = null,\n op: ConditionOp | null = null,\n value?: unknown,\n): RuleNode => ({\n kind: 'rule',\n id: ++nextId,\n field,\n op,\n value,\n});\nconst group = (mode: ConditionMode, children: (RuleNode | GroupNode)[] = []): GroupNode => ({\n kind: 'group',\n id: ++nextId,\n mode,\n children,\n});\n\n/** 条件读成界面上的组:not 包着 any 是“都不满足”、包着 all 是“不全满足”,包着单条比较是只有它的“都不满足” */\nfunction toGroup(condition: Condition): GroupNode {\n if ('all' in condition) return group('all', condition.all.map(toNode));\n if ('any' in condition) return group('any', condition.any.map(toNode));\n if ('not' in condition) {\n const inner = condition.not;\n if ('not' in inner) return toGroup(inner.not);\n if ('any' in inner) return group('none', inner.any.map(toNode));\n if ('all' in inner) return group('notAll', inner.all.map(toNode));\n return group('none', [toNode(inner)]);\n }\n return group('all', [toNode(condition)]);\n}\n\nfunction toNode(condition: Condition): RuleNode | GroupNode {\n return 'field' in condition\n ? rule(condition.field, condition.op, condition.value)\n : toGroup(condition);\n}\n\n/** 界面上的组写回条件:只留填完整的比较,空的组去掉 */\nfunction toCondition(node: GroupNode): Condition | null {\n const list = node.children.flatMap((child): Condition[] => {\n if (child.kind === 'group') {\n const nested = toCondition(child);\n return nested ? [nested] : [];\n }\n if (!child.field || !child.op) return [];\n const item: ConditionRule =\n valueShape(child.op) === 'none'\n ? { field: child.field, op: child.op }\n : { field: child.field, op: child.op, value: child.value };\n return isRuleComplete(item) ? [item] : [];\n });\n if (list.length === 0) return null;\n switch (node.mode) {\n case 'all':\n return { all: list };\n case 'any':\n return { any: list };\n case 'none':\n return { not: { any: list } };\n case 'notAll':\n return { not: { all: list } };\n }\n}\n\n/** 换比较方式时把值换成新的形状:一个值 ↔ 一组值 ↔ 范围,尽量留住已经填的 */\nfunction reshape(value: unknown, op: ConditionOp): unknown {\n const first = Array.isArray(value) ? value.find((item) => item != null && item !== '') : value;\n switch (valueShape(op)) {\n case 'none':\n return undefined;\n case 'list':\n return Array.isArray(value)\n ? value.filter((item) => item != null)\n : first == null\n ? []\n : [first];\n case 'range':\n return Array.isArray(value) && value.length === 2 ? value : [first ?? null, null];\n case 'single':\n return first;\n }\n}\n\n/** 选项的值写成文字(Select 的值是文字),选中后再换回原来的值 */\nconst optionKey = (value: unknown) => (value == null ? null : toText(value));\n\n/** 条件构造器 */\nexport const ConditionBuilder = _component(\n ({\n fields,\n _value: value = _bindable<Condition | null>(null),\n maxDepth = 2,\n size,\n disabled = false,\n propsGroup,\n propsRule,\n ...rest\n }: ConditionBuilderProps) => {\n const lang = useLang();\n let element: HTMLElement | null = null;\n // 初始值只取一次,之后由下面的 watch 跟随父级\n const initial = _untrack(value);\n // 上次写回的值:父级改成别的才整棵重读,自己写回的不重读(没填完的那几条还要留在界面上)\n let emitted = JSON.stringify(initial ?? null);\n let tree = _state<GroupNode>(initial ? toGroup(initial) : group('all'));\n\n watch(\n () => value,\n (next) => {\n const key = JSON.stringify(next ?? null);\n if (key === emitted) return;\n emitted = key;\n tree = next ? toGroup(next) : group('all');\n },\n );\n\n function commit() {\n const next = toCondition(tree);\n emitted = JSON.stringify(next);\n value = next;\n }\n\n const fieldOf = (name: string | null) => fields.find((field) => field.name === name);\n\n /** 渲染之后把焦点移到某个元素上(加了一条之后到它的字段,删掉之后到“添加条件”) */\n function focusLater(selector: string) {\n void nextTick(() => element?.querySelector<HTMLElement>(selector)?.focus());\n }\n\n function addRule(parent: GroupNode) {\n const added = rule();\n parent.children.push(added);\n focusLater(`[data-condition-rule=\"${added.id}\"] [data-condition-part=\"field\"]`);\n }\n\n function addGroup(parent: GroupNode) {\n const added = rule();\n parent.children.push(group('all', [added]));\n focusLater(`[data-condition-rule=\"${added.id}\"] [data-condition-part=\"field\"]`);\n }\n\n function remove(parent: GroupNode, child: RuleNode | GroupNode) {\n parent.children = parent.children.filter((item) => item !== child);\n commit();\n focusLater(`[data-condition-group=\"${parent.id}\"] > [data-condition-part=\"actions\"] button`);\n }\n\n function setField(node: RuleNode, name: string | null) {\n const field = fieldOf(name);\n node.field = name;\n const ops = field ? operatorsOf(field) : [];\n if (!node.op || !ops.includes(node.op)) node.op = ops[0] ?? null;\n // 换了字段,原来的值多半不适用:清空,是否型默认“是”\n node.value = node.op\n ? reshape(field?.type === 'boolean' ? true : undefined, node.op)\n : undefined;\n commit();\n }\n\n function setOp(node: RuleNode, op: ConditionOp) {\n node.op = op;\n node.value = reshape(node.value, op);\n commit();\n }\n\n function setValue(node: RuleNode, next: unknown) {\n node.value = next;\n commit();\n }\n\n /** 值的输入:随字段类型与比较方式 */\n function renderValue(node: RuleNode, field: ConditionField, op: ConditionOp): VNodeChild {\n const label = lang.conditionValue(field.label);\n const shape = valueShape(op);\n const onChange = (next: unknown) => setValue(node, next);\n const common = { size, disabled, 'aria-label': label };\n if (shape === 'none') return null;\n if (field.input) return field.input({ field, op, value: node.value, onChange, label });\n\n if (field.type === 'select' || field.type === 'boolean') {\n const options =\n field.type === 'boolean'\n ? [\n { value: true, label: lang.conditionTrue },\n { value: false, label: lang.conditionFalse },\n ]\n : (field.options ?? []);\n const items = options.map((option) => ({\n value: String(option.value),\n label: option.label,\n }));\n const back = (key: string | null) =>\n options.find((option) => String(option.value) === key)?.value;\n return shape === 'list' ? (\n <Select\n {...common}\n items={items}\n selectionMode=\"multiple\"\n maxTagCount=\"responsive\"\n _value={((node.value as unknown[] | undefined) ?? []).map(String)}\n onUpdate:_value={(keys) => onChange((keys as string[]).map(back))}\n />\n ) : (\n <Select\n {...common}\n items={items}\n _value={optionKey(node.value)}\n onUpdate:_value={(key) => onChange(back(key as string | null))}\n />\n );\n }\n\n if (shape === 'list') {\n return (\n <TagsInput\n {...common}\n _value={((node.value as unknown[] | undefined) ?? []).map(String)}\n onUpdate:_value={(list) =>\n onChange(\n field.type === 'number' ? list.map(Number).filter((n) => !Number.isNaN(n)) : list,\n )\n }\n />\n );\n }\n\n if (field.type === 'number') {\n return shape === 'range' ? (\n <NumberRangeField\n {...common}\n _value={(node.value as [number | null, number | null] | undefined) ?? [null, null]}\n onUpdate:_value={(range) => onChange([...range])}\n />\n ) : (\n <NumberField\n {...common}\n _value={(node.value as number | null | undefined) ?? null}\n onUpdate:_value={onChange}\n />\n );\n }\n\n if (field.type === 'date') {\n if (shape === 'range') {\n const [start, end] = (node.value as [string | null, string | null] | undefined) ?? [\n null,\n null,\n ];\n return (\n <DateRangePicker\n {...common}\n _value={start && end ? { start, end } : null}\n onUpdate:_value={(range) => onChange(range ? [range.start, range.end] : [null, null])}\n />\n );\n }\n return (\n <DatePicker\n {...common}\n _value={(node.value as string | null | undefined) ?? null}\n onUpdate:_value={onChange}\n />\n );\n }\n\n return (\n <TextField\n {...common}\n _value={(node.value as string | undefined) ?? ''}\n onUpdate:_value={onChange}\n />\n );\n }\n\n function renderRule(parent: GroupNode, node: RuleNode, index: number): VNodeChild {\n const field = fieldOf(node.field);\n const ops = field ? operatorsOf(field) : [];\n return (\n <div\n {...mergeAttrs<'div'>({ sx: conditionBuilderStyles.rule }, propsRule, {\n role: 'group',\n 'aria-label': lang.conditionRule(index + 1),\n ...dataAttrs({ 'data-condition-rule': node.id }),\n })}\n >\n <Select\n items={fields.map((item) => ({\n value: item.name,\n label: item.label,\n group: item.group,\n }))}\n _value={node.field}\n onUpdate:_value={(name) => setField(node, name as string | null)}\n searchable={fields.length > 8}\n placeholder={lang.conditionField}\n aria-label={lang.conditionField}\n size={size}\n disabled={disabled}\n propsRoot={{ sx: conditionBuilderStyles.field }}\n data-condition-part=\"field\"\n />\n <Select\n items={ops.map((op) => ({ value: op, label: operatorLabel(lang, field!.type, op) }))}\n _value={node.op}\n onUpdate:_value={(op) => op && setOp(node, op as ConditionOp)}\n aria-label={lang.conditionOperator}\n size={size}\n disabled={disabled || !field}\n propsRoot={{ sx: conditionBuilderStyles.op }}\n />\n {field && node.op && valueShape(node.op) !== 'none' && (\n <div {...css.attrs(conditionBuilderStyles.value)}>\n {renderValue(node, field, node.op)}\n </div>\n )}\n <IconButton\n icon={X}\n variant=\"ghost\"\n size={size}\n disabled={disabled}\n aria-label={lang.conditionRemoveRule}\n onClick={() => remove(parent, node)}\n />\n </div>\n );\n }\n\n function renderGroup(node: GroupNode, depth: number, parent?: GroupNode): VNodeChild {\n const nested = depth > 0;\n const joiner =\n node.mode === 'any' || node.mode === 'none' ? lang.conditionOr : lang.conditionAnd;\n return (\n <div\n {...mergeAttrs<'div'>(\n { sx: [conditionBuilderStyles.group, nested && conditionBuilderStyles.nested] },\n propsGroup,\n {\n ...(nested ? { role: 'group', 'aria-label': lang.conditionGroup } : {}),\n ...dataAttrs({ 'data-condition-group': node.id }),\n },\n )}\n >\n {(node.children.length > 0 || nested) && (\n <div {...css.attrs(conditionBuilderStyles.header)}>\n <Select\n items={MODES.map((mode) => ({ value: mode, label: lang.conditionModes[mode] }))}\n _value={node.mode}\n onUpdate:_value={(mode) => {\n if (!mode) return;\n node.mode = mode as ConditionMode;\n commit();\n }}\n aria-label={lang.conditionMode}\n size={size}\n disabled={disabled}\n />\n {nested && parent && (\n <IconButton\n icon={Trash2}\n variant=\"ghost\"\n size={size}\n disabled={disabled}\n aria-label={lang.conditionRemoveGroup}\n onClick={() => remove(parent, node)}\n sx={conditionBuilderStyles.removeGroup}\n />\n )}\n </div>\n )}\n {node.children.length === 0 ? (\n !nested && <Small sx={conditionBuilderStyles.empty}>{lang.conditionEmpty}</Small>\n ) : (\n <div {...css.attrs(conditionBuilderStyles.rows)}>\n {node.children.map((child, index) => (\n <div key={child.id} {...css.attrs(conditionBuilderStyles.row)}>\n <span {...css.attrs(conditionBuilderStyles.joiner)} aria-hidden=\"true\">\n {index > 0 ? joiner : ''}\n </span>\n {child.kind === 'rule'\n ? renderRule(node, child, index)\n : renderGroup(child, depth + 1, node)}\n </div>\n ))}\n </div>\n )}\n <div\n {...css.attrs(\n conditionBuilderStyles.actions,\n node.children.length === 0 && conditionBuilderStyles.actionsRoot,\n )}\n data-condition-part=\"actions\"\n >\n <Button\n variant=\"ghost\"\n size={size}\n icon={Plus}\n disabled={disabled}\n onClick={() => addRule(node)}\n >\n {lang.conditionAddRule}\n </Button>\n {depth + 1 < maxDepth && (\n <Button\n variant=\"ghost\"\n size={size}\n icon={Plus}\n disabled={disabled}\n onClick={() => addGroup(node)}\n >\n {lang.conditionAddGroup}\n </Button>\n )}\n </div>\n </div>\n );\n }\n\n return () => (\n <div\n {...mergeAttrs<'div'>({ sx: conditionBuilderStyles.root }, rest, {\n role: 'group',\n ref: (target: unknown) => (element = target as HTMLElement | null),\n })}\n >\n {renderGroup(tree, 0)}\n </div>\n );\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"ConditionBuilder.js","names":["_vtp_readonlyProp","_vtp_bindable","_vtp_restProps","_vtp_untrack","_vue_ref","_createVNode","_mergeProps"],"sources":["../../src/input/ConditionBuilder.tsx"],"sourcesContent":["/**\n * 条件构造器:编辑 all / any / not 加比较的条件树(Condition,见 condition.ts)。每条是“字段 · 比较方式 · 值”,\n * 比较方式随字段类型、值的输入随字段类型与比较方式;组的表头选满足方式(全部、任一、都不、不全),组里还能再加组。\n *\n * const fields: ConditionField[] = [\n * { name: 'amount', label: '金额', type: 'number' },\n * { name: 'category', label: '品类', type: 'select', options: [{ value: 'steel', label: '钢材' }, …] },\n * { name: 'owner', label: '经办人', type: 'select', input: ({ value, onChange, label }) => <UserPicker … /> },\n * ];\n * let condition = _state<Condition | null>(null);\n * <ConditionBuilder fields={fields} _value={condition} aria-label=\"审批条件\" />\n *\n * 写回的是只含填完整的比较的条件:没选字段、没填值的那几条留在界面上,不进 _value;一条也没有时是 null。\n * 根总是一个组({ all }、{ any },都不满足是 { not: { any } },不全满足是 { not: { all } });\n * 传进来的单条比较、嵌套的 not 按同样的规则读成组。父级改了 _value(与上次写回的不同)时整棵重读。\n *\n * 读屏:根与每个嵌套的组是 role=\"group\",每条比较也是一组(“条件 2”),三个控件各有名称(“字段”“比较方式”“金额的值”)。\n * 加了一条之后焦点落到它的字段上;删掉之后落到组的“添加条件”上。\n * 部件:Root(div)、Group(每个组)、Rule(每条比较)。\n */\nimport { Plus, Trash2, 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, watch, type VNodeChild } from 'vue';\nimport { Button } from '../base/Button';\nimport { IconButton } from '../base/IconButton';\nimport { Small } from '../base/Text';\nimport { useLang } from '../config/context';\nimport { t } from '../config/theme/tokens';\nimport { DatePicker } from '../date/DatePicker';\nimport { DateRangePicker } from '../date/DateRangePicker';\nimport { dataAttrs, mergeAttrs, type PartProps } from '../utils/props';\nimport type { TextSize } from '../utils/style/typography';\nimport {\n isRuleComplete,\n operatorLabel,\n toText,\n operatorsOf,\n valueShape,\n type Condition,\n type ConditionField,\n type ConditionOp,\n type ConditionRule,\n} from './condition';\nimport { NumberField } from './NumberField';\nimport { NumberRangeField } from './NumberRangeField';\nimport { Select } from './Select';\nimport { TagsInput } from './TagsInput';\nimport { TextField } from './TextField';\n\n/** 组的满足方式 */\nexport interface ConditionModes {\n /** 全部满足:{ all } */\n all: unknown;\n /** 任一满足:{ any } */\n any: unknown;\n /** 都不满足:{ not: { any } } */\n none: unknown;\n /** 不全满足:{ not: { all } } */\n notAll: unknown;\n}\n\n/** 组的满足方式 */\nexport type ConditionMode = keyof ConditionModes;\n\n/** 未声明的属性落到外层 div(role=\"group\")上:aria-label 写条件管什么 */\nexport interface ConditionBuilderProps extends PartProps<'div', 'role'> {\n /** 能参与比较的字段 */\n fields: readonly ConditionField[];\n /** 条件:父级写 _value={condition} 双向绑定;没有填完整的比较时是 null */\n _value?: Condition | null;\n /** 组最多嵌套几层,默认 2(根组里还能加一层组);1 时不能加组 */\n maxDepth?: number;\n /** 控件与按钮的字号档位,不写时继承 */\n size?: TextSize;\n /** 不可用 */\n disabled?: boolean;\n /** 每个组的部件属性 */\n propsGroup?: PartProps<'div'>;\n /** 每条比较的部件属性 */\n propsRule?: PartProps<'div'>;\n}\n\ninterface RuleNode {\n kind: 'rule';\n id: number;\n field: string | null;\n op: ConditionOp | null;\n value: unknown;\n}\n\ninterface GroupNode {\n kind: 'group';\n id: number;\n mode: ConditionMode;\n children: (RuleNode | GroupNode)[];\n}\n\nconst MODES: readonly ConditionMode[] = ['all', 'any', 'none', 'notAll'];\n\n/** ConditionBuilder 的样式:root、group、nested、header、rows、row、joiner、rule、field、op、value、range、actions、empty */\nexport const conditionBuilderStyles = css.create({\n root: { display: 'flex', flexDirection: 'column', gap: '_sm', minWidth: 0 },\n group: { display: 'flex', flexDirection: 'column', gap: '_sm', minWidth: 0 },\n // 嵌套的组:浅底加描边,和外层的条件分开\n nested: {\n flexGrow: 1,\n padding: '_sm',\n backgroundColor: '_surfaceMuted',\n borderWidth: '_xs',\n borderStyle: 'solid',\n borderColor: '_borderMuted',\n borderRadius: '_md',\n },\n header: { display: 'flex', alignItems: 'center', gap: '_sm' },\n rows: { display: 'flex', flexDirection: 'column', gap: '_sm' },\n row: { display: 'flex', alignItems: 'flex-start', gap: '_sm', minWidth: 0 },\n // 连接词(且、或)一列,宽度固定:各条的字段对齐\n joiner: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'flex-end',\n flexShrink: 0,\n width: '2em',\n // 与控件同高:连接词对着这一条的第一行\n minHeight: `max(${t.sizes.control}, ${t.sizes.minTarget})`,\n color: '_textMuted',\n },\n rule: {\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'flex-start',\n gap: '_sm',\n flexGrow: 1,\n minWidth: 0,\n },\n field: { flexGrow: 1, flexShrink: 1, flexBasis: '9rem', minWidth: '7rem', maxWidth: '14rem' },\n op: { flexGrow: 0, flexShrink: 1, flexBasis: '8rem', minWidth: '6rem' },\n // grid:里面的输入框拉满这一格(多选的标签按这个宽度排)\n value: { display: 'grid', flexGrow: 2, flexShrink: 1, flexBasis: '12rem', minWidth: '8rem' },\n range: { display: 'flex', alignItems: 'center', gap: '_xs' },\n actions: {\n display: 'flex',\n flexWrap: 'wrap',\n gap: '_xs',\n paddingInlineStart: 'calc(2em + 0.5rem)',\n },\n actionsRoot: { paddingInlineStart: 0 },\n removeGroup: { marginInlineStart: 'auto' },\n empty: { color: '_textMuted' },\n});\n\nlet nextId = 0;\nconst rule = (\n field: string | null = null,\n op: ConditionOp | null = null,\n value?: unknown,\n): RuleNode => ({\n kind: 'rule',\n id: ++nextId,\n field,\n op,\n value,\n});\nconst group = (mode: ConditionMode, children: (RuleNode | GroupNode)[] = []): GroupNode => ({\n kind: 'group',\n id: ++nextId,\n mode,\n children,\n});\n\n/** 条件读成界面上的组:not 包着 any 是“都不满足”、包着 all 是“不全满足”,包着单条比较是只有它的“都不满足” */\nfunction toGroup(condition: Condition): GroupNode {\n if ('all' in condition) return group('all', condition.all.map(toNode));\n if ('any' in condition) return group('any', condition.any.map(toNode));\n if ('not' in condition) {\n const inner = condition.not;\n if ('not' in inner) return toGroup(inner.not);\n if ('any' in inner) return group('none', inner.any.map(toNode));\n if ('all' in inner) return group('notAll', inner.all.map(toNode));\n return group('none', [toNode(inner)]);\n }\n return group('all', [toNode(condition)]);\n}\n\nfunction toNode(condition: Condition): RuleNode | GroupNode {\n return 'field' in condition\n ? rule(condition.field, condition.op, condition.value)\n : toGroup(condition);\n}\n\n/** 界面上的组写回条件:只留填完整的比较,空的组去掉 */\nfunction toCondition(node: GroupNode): Condition | null {\n const list = node.children.flatMap((child): Condition[] => {\n if (child.kind === 'group') {\n const nested = toCondition(child);\n return nested ? [nested] : [];\n }\n if (!child.field || !child.op) return [];\n const item: ConditionRule =\n valueShape(child.op) === 'none'\n ? { field: child.field, op: child.op }\n : { field: child.field, op: child.op, value: child.value };\n return isRuleComplete(item) ? [item] : [];\n });\n if (list.length === 0) return null;\n switch (node.mode) {\n case 'all':\n return { all: list };\n case 'any':\n return { any: list };\n case 'none':\n return { not: { any: list } };\n case 'notAll':\n return { not: { all: list } };\n }\n}\n\n/** 换比较方式时把值换成新的形状:一个值 ↔ 一组值 ↔ 范围,尽量留住已经填的 */\nfunction reshape(value: unknown, op: ConditionOp): unknown {\n const first = Array.isArray(value) ? value.find((item) => item != null && item !== '') : value;\n switch (valueShape(op)) {\n case 'none':\n return undefined;\n case 'list':\n return Array.isArray(value)\n ? value.filter((item) => item != null)\n : first == null\n ? []\n : [first];\n case 'range':\n return Array.isArray(value) && value.length === 2 ? value : [first ?? null, null];\n case 'single':\n return first;\n }\n}\n\n/** 选项的值写成文字(Select 的值是文字),选中后再换回原来的值 */\nconst optionKey = (value: unknown) => (value == null ? null : toText(value));\n\n/** 条件构造器 */\nexport const ConditionBuilder = _component(\n ({\n fields,\n _value: value = _bindable<Condition | null>(null),\n maxDepth = 2,\n size,\n disabled = false,\n propsGroup,\n propsRule,\n ...rest\n }: ConditionBuilderProps) => {\n const lang = useLang();\n let element: HTMLElement | null = null;\n // 初始值只取一次,之后由下面的 watch 跟随父级\n const initial = _untrack(value);\n // 上次写回的值:父级改成别的才整棵重读,自己写回的不重读(没填完的那几条还要留在界面上)\n let emitted = JSON.stringify(initial ?? null);\n let tree = _state<GroupNode>(initial ? toGroup(initial) : group('all'));\n\n watch(\n () => value,\n (next) => {\n const key = JSON.stringify(next ?? null);\n if (key === emitted) return;\n emitted = key;\n tree = next ? toGroup(next) : group('all');\n },\n );\n\n function commit() {\n const next = toCondition(tree);\n emitted = JSON.stringify(next);\n value = next;\n }\n\n const fieldOf = (name: string | null) => fields.find((field) => field.name === name);\n\n /** 渲染之后把焦点移到某个元素上(加了一条之后到它的字段,删掉之后到“添加条件”) */\n function focusLater(selector: string) {\n void nextTick(() => element?.querySelector<HTMLElement>(selector)?.focus());\n }\n\n function addRule(parent: GroupNode) {\n const added = rule();\n parent.children.push(added);\n focusLater(`[data-condition-rule=\"${added.id}\"] [data-condition-part=\"field\"]`);\n }\n\n function addGroup(parent: GroupNode) {\n const added = rule();\n parent.children.push(group('all', [added]));\n focusLater(`[data-condition-rule=\"${added.id}\"] [data-condition-part=\"field\"]`);\n }\n\n function remove(parent: GroupNode, child: RuleNode | GroupNode) {\n parent.children = parent.children.filter((item) => item !== child);\n commit();\n focusLater(`[data-condition-group=\"${parent.id}\"] > [data-condition-part=\"actions\"] button`);\n }\n\n function setField(node: RuleNode, name: string | null) {\n const field = fieldOf(name);\n node.field = name;\n const ops = field ? operatorsOf(field) : [];\n if (!node.op || !ops.includes(node.op)) node.op = ops[0] ?? null;\n // 换了字段,原来的值多半不适用:清空,是否型默认“是”\n node.value = node.op\n ? reshape(field?.type === 'boolean' ? true : undefined, node.op)\n : undefined;\n commit();\n }\n\n function setOp(node: RuleNode, op: ConditionOp) {\n node.op = op;\n node.value = reshape(node.value, op);\n commit();\n }\n\n function setValue(node: RuleNode, next: unknown) {\n node.value = next;\n commit();\n }\n\n /** 值的输入:随字段类型与比较方式 */\n function renderValue(node: RuleNode, field: ConditionField, op: ConditionOp): VNodeChild {\n const label = lang.conditionValue(field.label);\n const shape = valueShape(op);\n const onChange = (next: unknown) => setValue(node, next);\n const common = { size, disabled, 'aria-label': label };\n if (shape === 'none') return null;\n if (field.input) return field.input({ field, op, value: node.value, onChange, label });\n\n if (field.type === 'select' || field.type === 'boolean') {\n const options =\n field.type === 'boolean'\n ? [\n { value: true, label: lang.conditionTrue },\n { value: false, label: lang.conditionFalse },\n ]\n : (field.options ?? []);\n const items = options.map((option) => ({\n value: String(option.value),\n label: option.label,\n }));\n const back = (key: string | null) =>\n options.find((option) => String(option.value) === key)?.value;\n return shape === 'list' ? (\n <Select\n {...common}\n items={items}\n selectionMode=\"multiple\"\n maxTagCount=\"responsive\"\n _value={((node.value as unknown[] | undefined) ?? []).map(String)}\n onUpdate:_value={(keys) => onChange((keys as string[]).map(back))}\n />\n ) : (\n <Select\n {...common}\n items={items}\n _value={optionKey(node.value)}\n onUpdate:_value={(key) => onChange(back(key as string | null))}\n />\n );\n }\n\n if (shape === 'list') {\n return (\n <TagsInput\n {...common}\n _value={((node.value as unknown[] | undefined) ?? []).map(String)}\n onUpdate:_value={(list) =>\n onChange(\n field.type === 'number' ? list.map(Number).filter((n) => !Number.isNaN(n)) : list,\n )\n }\n />\n );\n }\n\n if (field.type === 'number') {\n return shape === 'range' ? (\n <NumberRangeField\n {...common}\n _value={(node.value as [number | null, number | null] | undefined) ?? [null, null]}\n onUpdate:_value={(range) => onChange([...range])}\n />\n ) : (\n <NumberField\n {...common}\n _value={(node.value as number | null | undefined) ?? null}\n onUpdate:_value={onChange}\n />\n );\n }\n\n if (field.type === 'date') {\n if (shape === 'range') {\n const [start, end] = (node.value as [string | null, string | null] | undefined) ?? [\n null,\n null,\n ];\n return (\n <DateRangePicker\n {...common}\n _value={start && end ? { start, end } : null}\n onUpdate:_value={(range) => onChange(range ? [range.start, range.end] : [null, null])}\n />\n );\n }\n return (\n <DatePicker\n {...common}\n _value={(node.value as string | null | undefined) ?? null}\n onUpdate:_value={onChange}\n />\n );\n }\n\n return (\n <TextField\n {...common}\n _value={(node.value as string | undefined) ?? ''}\n onUpdate:_value={onChange}\n />\n );\n }\n\n function renderRule(parent: GroupNode, node: RuleNode, index: number): VNodeChild {\n const field = fieldOf(node.field);\n const ops = field ? operatorsOf(field) : [];\n return (\n <div\n {...mergeAttrs<'div'>({ sx: conditionBuilderStyles.rule }, propsRule, {\n role: 'group',\n 'aria-label': lang.conditionRule(index + 1),\n ...dataAttrs({ 'data-condition-rule': node.id }),\n })}\n >\n <Select\n items={fields.map((item) => ({\n value: item.name,\n label: item.label,\n group: item.group,\n }))}\n _value={node.field}\n onUpdate:_value={(name) => setField(node, name as string | null)}\n searchable={fields.length > 8}\n placeholder={lang.conditionField}\n aria-label={lang.conditionField}\n size={size}\n disabled={disabled}\n propsRoot={{ sx: conditionBuilderStyles.field }}\n data-condition-part=\"field\"\n />\n <Select\n items={ops.map((op) => ({ value: op, label: operatorLabel(lang, field!.type, op) }))}\n _value={node.op}\n onUpdate:_value={(op) => op && setOp(node, op as ConditionOp)}\n aria-label={lang.conditionOperator}\n size={size}\n disabled={disabled || !field}\n propsRoot={{ sx: conditionBuilderStyles.op }}\n />\n {field && node.op && valueShape(node.op) !== 'none' && (\n <div {...css.attrs(conditionBuilderStyles.value)}>\n {renderValue(node, field, node.op)}\n </div>\n )}\n <IconButton\n icon={X}\n variant=\"ghost\"\n size={size}\n disabled={disabled}\n aria-label={lang.conditionRemoveRule}\n onClick={() => remove(parent, node)}\n />\n </div>\n );\n }\n\n function renderGroup(node: GroupNode, depth: number, parent?: GroupNode): VNodeChild {\n const nested = depth > 0;\n const joiner =\n node.mode === 'any' || node.mode === 'none' ? lang.conditionOr : lang.conditionAnd;\n return (\n <div\n {...mergeAttrs<'div'>(\n { sx: [conditionBuilderStyles.group, nested && conditionBuilderStyles.nested] },\n propsGroup,\n {\n ...(nested ? { role: 'group', 'aria-label': lang.conditionGroup } : {}),\n ...dataAttrs({ 'data-condition-group': node.id }),\n },\n )}\n >\n {(node.children.length > 0 || nested) && (\n <div {...css.attrs(conditionBuilderStyles.header)}>\n <Select\n items={MODES.map((mode) => ({ value: mode, label: lang.conditionModes[mode] }))}\n _value={node.mode}\n onUpdate:_value={(mode) => {\n if (!mode) return;\n node.mode = mode as ConditionMode;\n commit();\n }}\n aria-label={lang.conditionMode}\n size={size}\n disabled={disabled}\n />\n {nested && parent && (\n <IconButton\n icon={Trash2}\n variant=\"ghost\"\n size={size}\n disabled={disabled}\n aria-label={lang.conditionRemoveGroup}\n onClick={() => remove(parent, node)}\n sx={conditionBuilderStyles.removeGroup}\n />\n )}\n </div>\n )}\n {node.children.length === 0 ? (\n !nested && <Small sx={conditionBuilderStyles.empty}>{lang.conditionEmpty}</Small>\n ) : (\n <div {...css.attrs(conditionBuilderStyles.rows)}>\n {node.children.map((child, index) => (\n <div key={child.id} {...css.attrs(conditionBuilderStyles.row)}>\n <span {...css.attrs(conditionBuilderStyles.joiner)} aria-hidden=\"true\">\n {index > 0 ? joiner : ''}\n </span>\n {child.kind === 'rule'\n ? renderRule(node, child, index)\n : renderGroup(child, depth + 1, node)}\n </div>\n ))}\n </div>\n )}\n <div\n {...css.attrs(\n conditionBuilderStyles.actions,\n node.children.length === 0 && conditionBuilderStyles.actionsRoot,\n )}\n data-condition-part=\"actions\"\n >\n <Button\n variant=\"ghost\"\n size={size}\n icon={Plus}\n disabled={disabled}\n onClick={() => addRule(node)}\n >\n {lang.conditionAddRule}\n </Button>\n {depth + 1 < maxDepth && (\n <Button\n variant=\"ghost\"\n size={size}\n icon={Plus}\n disabled={disabled}\n onClick={() => addGroup(node)}\n >\n {lang.conditionAddGroup}\n </Button>\n )}\n </div>\n </div>\n );\n }\n\n return () => (\n <div\n {...mergeAttrs<'div'>({ sx: conditionBuilderStyles.root }, rest, {\n role: 'group',\n ref: (target: unknown) => (element = target as HTMLElement | null),\n })}\n >\n {renderGroup(tree, 0)}\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 PartProps } from '../utils/props';
4
4
  import { type AttachedOrientations } from '../utils/style/attached';
@@ -3,7 +3,7 @@ import { AttachedContext } from "../utils/style/attached.js";
3
3
  import { useFieldControl } from "../form/Field.js";
4
4
  import { createVNode } from "vue";
5
5
  import { _component, childrenProp, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
6
- import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
6
+ import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
7
7
  //#region src/input/ControlGroup.tsx
8
8
  /** 角色由组件管理 */
9
9
  /** 未声明的属性落到 div 上;aria-label 是这组输入的名称 */
@@ -1 +1 @@
1
- {"version":3,"file":"ControlGroup.js","names":["_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_createVNode"],"sources":["../../src/input/ControlGroup.tsx"],"sourcesContent":["/**\n * 组合输入(div,role=\"group\"):输入框、选择框、按钮连成一条,共用边框:币种 + 金额、协议 + 域名、搜索框 + 搜索按钮。\n *\n * <ControlGroup aria-label=\"金额\">\n * <Select items={currencies} _value={currency} aria-label=\"币种\" style=\"width: 6rem\" />\n * <NumberField _value={amount} aria-label=\"金额\" />\n * </ControlGroup>\n *\n * 里面的输入框外壳与按钮家族经 AttachedContext 得知自己在组里:去掉相邻一侧的圆角、边框叠在一起,\n * 聚焦的那个浮到上面,焦点环完整。输入框默认占满剩余宽度,选择框、按钮按内容宽。\n * 只有文字的前后缀(单位、https://)用输入框自己的 prefix / suffix,不必拆成两个控件。\n * 放在 Field 里时组是 Field 的控件:标签、说明经 aria-labelledby / aria-describedby 关联到组,点标签聚焦第一个控件;\n * 里面的各个控件不再拿 Field 的 id(会重复),各自写 aria-label。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { VNodeChild } from 'vue';\nimport { useFieldControl } from '../form/Field';\nimport { mergeAttrs, type PartProps } from '../utils/props';\nimport { AttachedContext, type AttachedOrientations } from '../utils/style/attached';\n\n/** 角色由组件管理 */\nexport type ControlGroupManaged = 'role';\n\n/** 未声明的属性落到 div 上;aria-label 是这组输入的名称 */\nexport interface ControlGroupProps extends PartProps<'div', ControlGroupManaged> {\n /**\n * 排列方向\n * @default 'horizontal'\n */\n orientation?: keyof AttachedOrientations;\n /** 不占满一行(行内排列),默认占满 */\n inline?: boolean;\n /** 输入框、选择框、按钮 */\n children?: VNodeChild;\n}\n\n/** ControlGroup 的样式:root、inline、vertical */\nexport const controlGroupStyles = css.create({\n // 输入框外壳(:not(button))分掉剩余宽度;按钮、选择框的触发器按内容宽\n root: { display: 'flex', alignItems: 'stretch', width: '100%' },\n inline: { display: 'inline-flex', width: 'auto' },\n vertical: { flexDirection: 'column' },\n});\n\n/** 组合输入:相连的一排输入框与按钮 */\nexport const ControlGroup = _component(\n ({ orientation = 'horizontal', inline = false, children, ...rest }: ControlGroupProps) => {\n // 组接 Field:里面的控件与 Field 隔开,不重复拿它的 id 与说明\n const field = useFieldControl(() => ({}));\n AttachedContext.provide({\n get orientation() {\n return orientation;\n },\n });\n return () => (\n <div\n {...mergeAttrs<'div'>(\n {\n id: field().id,\n 'aria-labelledby': field().labelledBy,\n 'aria-describedby': field().describedBy,\n sx: [\n controlGroupStyles.root,\n inline && controlGroupStyles.inline,\n orientation === 'vertical' && controlGroupStyles.vertical,\n ],\n },\n rest,\n { role: 'group' },\n )}\n >\n {children}\n </div>\n );\n },\n);\n"],"mappings":";;;;;;;;;;AAsCA,IAAa,qBAAqB,IAAI,OAAO;CAE3C,MAAM;EAAE,SAAS;EAAQ,YAAY;EAAW,OAAO;CAAO;CAC9D,QAAQ;EAAE,SAAS;EAAe,OAAO;CAAO;CAChD,UAAU,EAAE,eAAe,SAAS;AACtC,CAAC;;AAGD,IAAa,eAAe,0BAC1B,QAAA,SAA0F;CAAA,MAAA,cAAAA,aAAA,QAAA,eAAzE,YAAY;CAAA,MAAA,SAAAA,aAAA,QAAA,UAAW,KAAK;CAAA,MAAA,WAAAC,aAAA,MAAA;CAAA,MAAe,OAAIC,UAAA,QAAA,MAAA,KAAA;CAE9D,MAAM,QAAQ,uBAAuB,CAAC,EAAE;CACxC,gBAAgB,QAAQ,EACtB,IAAI,cAAc;EAChB,OAAA,YAAA;CACF,EACF,CAAC;CACD,aAAOC,YAAA,OAEC,WACF;EACE,IAAI,MAAM,CAAC,CAAC;EACZ,mBAAmB,MAAM,CAAC,CAAC;EAC3B,oBAAoB,MAAM,CAAC,CAAC;EAC5B,IAAI;GACF,mBAAmB;GACnB,OAAA,SAAU,mBAAmB;GAC7B,YAAA,UAAgB,cAAc,mBAAmB;EAAQ;CAE7D,GACA,MACA,EAAE,MAAM,QAAQ,CAClB,GAAC,CAAA,SAAA,KAAA,CAAA;AAKP,GAAC;CAAA,MAAA;CAAA,OAAA,CAAA,eAAA,QAAA;AAAA,CACH"}
1
+ {"version":3,"file":"ControlGroup.js","names":["_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_createVNode"],"sources":["../../src/input/ControlGroup.tsx"],"sourcesContent":["/**\n * 组合输入(div,role=\"group\"):输入框、选择框、按钮连成一条,共用边框:币种 + 金额、协议 + 域名、搜索框 + 搜索按钮。\n *\n * <ControlGroup aria-label=\"金额\">\n * <Select items={currencies} _value={currency} aria-label=\"币种\" style=\"width: 6rem\" />\n * <NumberField _value={amount} aria-label=\"金额\" />\n * </ControlGroup>\n *\n * 里面的输入框外壳与按钮家族经 AttachedContext 得知自己在组里:去掉相邻一侧的圆角、边框叠在一起,\n * 聚焦的那个浮到上面,焦点环完整。输入框默认占满剩余宽度,选择框、按钮按内容宽。\n * 只有文字的前后缀(单位、https://)用输入框自己的 prefix / suffix,不必拆成两个控件。\n * 放在 Field 里时组是 Field 的控件:标签、说明经 aria-labelledby / aria-describedby 关联到组,点标签聚焦第一个控件;\n * 里面的各个控件不再拿 Field 的 id(会重复),各自写 aria-label。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { VNodeChild } from 'vue';\nimport { useFieldControl } from '../form/Field';\nimport { mergeAttrs, type PartProps } from '../utils/props';\nimport { AttachedContext, type AttachedOrientations } from '../utils/style/attached';\n\n/** 角色由组件管理 */\nexport type ControlGroupManaged = 'role';\n\n/** 未声明的属性落到 div 上;aria-label 是这组输入的名称 */\nexport interface ControlGroupProps extends PartProps<'div', ControlGroupManaged> {\n /**\n * 排列方向\n * @default 'horizontal'\n */\n orientation?: keyof AttachedOrientations;\n /** 不占满一行(行内排列),默认占满 */\n inline?: boolean;\n /** 输入框、选择框、按钮 */\n children?: VNodeChild;\n}\n\n/** ControlGroup 的样式:root、inline、vertical */\nexport const controlGroupStyles = css.create({\n // 输入框外壳(:not(button))分掉剩余宽度;按钮、选择框的触发器按内容宽\n root: { display: 'flex', alignItems: 'stretch', width: '100%' },\n inline: { display: 'inline-flex', width: 'auto' },\n vertical: { flexDirection: 'column' },\n});\n\n/** 组合输入:相连的一排输入框与按钮 */\nexport const ControlGroup = _component(\n ({ orientation = 'horizontal', inline = false, children, ...rest }: ControlGroupProps) => {\n // 组接 Field:里面的控件与 Field 隔开,不重复拿它的 id 与说明\n const field = useFieldControl(() => ({}));\n AttachedContext.provide({\n get orientation() {\n return orientation;\n },\n });\n return () => (\n <div\n {...mergeAttrs<'div'>(\n {\n id: field().id,\n 'aria-labelledby': field().labelledBy,\n 'aria-describedby': field().describedBy,\n sx: [\n controlGroupStyles.root,\n inline && controlGroupStyles.inline,\n orientation === 'vertical' && controlGroupStyles.vertical,\n ],\n },\n rest,\n { role: 'group' },\n )}\n >\n {children}\n </div>\n );\n },\n);\n"],"mappings":";;;;;;;;;;AAsCA,IAAa,qBAAqB,IAAI,OAAO;CAE3C,MAAM;EAAE,SAAS;EAAQ,YAAY;EAAW,OAAO;CAAO;CAC9D,QAAQ;EAAE,SAAS;EAAe,OAAO;CAAO;CAChD,UAAU,EAAE,eAAe,SAAS;AACtC,CAAC;;AAGD,IAAa,eAAe,0BAC1B,QAAA,SAA0F;CAAA,MAAA,cAAAA,aAAA,QAAA,eAAzE,YAAY;CAAA,MAAA,SAAAA,aAAA,QAAA,UAAW,KAAK;CAAA,MAAA,WAAAC,aAAA,MAAA;CAAA,MAAe,OAAIC,UAAA,QAAA,MAAA,KAAA;CAE9D,MAAM,QAAQ,uBAAuB,CAAC,EAAE;CACxC,gBAAgB,QAAQ,EACtB,IAAI,cAAc;EAChB,OAAA,YAAA;CACF,EACF,CAAC;CACD,aAAOC,YAAA,OAEC,WACF;EACE,IAAI,MAAM,CAAC,CAAC;EACZ,mBAAmB,MAAM,CAAC,CAAC;EAC3B,oBAAoB,MAAM,CAAC,CAAC;EAC5B,IAAI;GACF,mBAAmB;GACnB,OAAA,SAAU,mBAAmB;GAC7B,YAAA,UAAgB,cAAc,mBAAmB;EAAQ;CAE7D,GACA,MACA,EAAE,MAAM,QAAQ,CAClB,GAAC,CAAA,SAAA,KAAA,CAAA;AAKP,GAAC;CAAA,MAAA;CAAA,OAAA,CAAA,eAAA,QAAA;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 IconProps } from '../base/Icon';
4
4
  import { type PartProps } from '../utils/props';
@@ -7,7 +7,7 @@ import { visuallyHiddenStyles } from "../base/VisuallyHidden.js";
7
7
  import { useFieldControl } from "../form/Field.js";
8
8
  import { Fragment, createVNode, ref } from "vue";
9
9
  import { _component, childrenProp, 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
  import { Upload } from "@lucide/icons";
12
12
  //#region src/input/FileDrop.tsx
13
13
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"FileDrop.js","names":["_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_vue_ref","_createVNode","_mergeProps","_Fragment","UploadIcon"],"sources":["../../src/input/FileDrop.tsx"],"sourcesContent":["/**\n * 选择文件的区域(label > input[type=file]):点击(或聚焦后按 Enter / 空格)打开文件对话框,也可以把文件拖进来。\n * 只负责选文件:选到的文件经 onFiles 交出去,不在 accept 里的经 onReject 交出去(拖放不受 accept 限制,这里补上)。\n * 列表、进度、重试见 Upload(建在它上面)。\n *\n * <FileDrop accept=\"image/*\" multiple onFiles={(files) => add(files)} />\n *\n * 原生 input 只是视觉上隐藏,焦点、键盘、读屏都是浏览器的;区域的文字是它的名称。拖着文件经过时写 data-dragging。\n * 在 Field 里时关联标签、说明与错误。部件:Root(label)、Input(input)、Icon、Hint(提示文字)、Description(说明)。\n */\nimport { Upload as UploadIcon } 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 { VNodeChild } from 'vue';\nimport { Icon, type IconProps } from '../base/Icon';\nimport { visuallyHiddenStyles } from '../base/VisuallyHidden';\nimport { useLang } from '../config/context';\nimport { hasContent, mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { focusRingStyles } from '../utils/style/styles';\nimport { useFieldControl } from '../form/Field';\nimport { t } from '../config/theme/tokens';\n\n/** 文件是否符合 accept(`image/*`、`.pdf`、`application/json` 这样的逗号分隔列表);accept 为空时都符合 */\nexport function matchesAccept(file: File, accept: string | undefined): boolean {\n const rules = (accept ?? '')\n .split(',')\n .map((rule) => rule.trim().toLowerCase())\n .filter(Boolean);\n if (rules.length === 0) return true;\n const name = file.name.toLowerCase();\n const type = file.type.toLowerCase();\n return rules.some((rule) => {\n if (rule.startsWith('.')) return name.endsWith(rule);\n if (rule.endsWith('/*')) return type.startsWith(rule.slice(0, -1));\n return type === rule;\n });\n}\n\n/** 文件、不可用、必填由组件管理;未声明的属性落到 input 上,外层 label 用 propsRoot */\nexport interface FileDropProps extends PartProps<\n 'input',\n 'type' | 'disabled' | 'required' | 'aria-invalid' | 'aria-describedby'\n> {\n /** 接受的文件类型(同原生 accept) */\n accept?: string;\n /** 可以选多个 */\n multiple?: boolean;\n /** 不可用 */\n disabled?: boolean;\n /** 必填 */\n required?: boolean;\n /** 只读:不能选文件(同不可用,文件输入框没有原生的只读) */\n readonly?: boolean;\n /** 校验未通过 */\n invalid?: boolean;\n /** 选到了文件(已按 accept 过滤) */\n onFiles?: (files: File[]) => void;\n /** 拖进来的文件里不在 accept 里的 */\n onReject?: (files: File[]) => void;\n /** 提示文字下面的说明(大小、类型限制) */\n description?: VNodeChild;\n /** 外层 label 的部件属性 */\n propsRoot?: PartProps<'label'>;\n /** 图标的部件属性 */\n propsIcon?: Partial<IconProps>;\n /** 提示文字的部件属性 */\n propsHint?: PartProps<'span'>;\n /** 提示文字下面的说明的部件属性 */\n propsDescription?: PartProps<'span'>;\n /** 区域里的内容;默认是图标、提示文字(取语言包)与 description */\n children?: VNodeChild;\n}\n\n/** FileDrop 的样式:root、dragging、disabled、invalid、icon、hint、description */\nexport const fileDropStyles = css.create({\n root: {\n boxSizing: 'border-box',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '_xs',\n width: '_full',\n minHeight: '8em',\n padding: '_lg',\n borderWidth: '_sm',\n borderStyle: 'dashed',\n borderColor: { default: '_borderStrong', ':hover': '_accent' },\n borderRadius: '_md',\n backgroundColor: '_surface',\n color: '_text',\n textAlign: 'center',\n cursor: 'pointer',\n transition: `border-color ${t.durations.sm} ${t.easings.standard}, background-color ${t.durations.sm} ${t.easings.standard}`,\n },\n dragging: { borderColor: '_accent', backgroundColor: '_accentSoft' },\n disabled: { opacity: '_disabled', cursor: 'not-allowed' },\n invalid: { borderColor: '_danger' },\n icon: { width: '1.5em', height: '1.5em', color: '_textMuted' },\n hint: { fontWeight: '_medium' },\n description: { fontSize: '_sm', color: '_textMuted' },\n});\n\n/** 选择文件的区域:点击打开文件对话框,或把文件拖进来 */\nexport const FileDrop = _component(\n ({\n accept,\n multiple = false,\n disabled,\n required,\n readonly,\n invalid,\n onFiles,\n onReject,\n description,\n id,\n propsRoot,\n propsIcon,\n propsHint,\n propsDescription,\n children,\n ...rest\n }: FileDropProps) => {\n const lang = useLang();\n const control = useFieldControl(() => ({ id, invalid, required, disabled, readonly }));\n const locked = () => control().disabled || control().readonly;\n let dragging = _state(false);\n // dragenter / dragleave 在子元素之间也会触发:计数,回到 0 才算离开\n let depth = 0;\n\n function deliver(list: FileList | null | undefined) {\n const files = [...(list ?? [])];\n const accepted = files.filter((file) => matchesAccept(file, accept));\n const rejected = files.filter((file) => !accepted.includes(file));\n const taken = multiple ? accepted : accepted.slice(0, 1);\n if (taken.length > 0) onFiles?.(taken);\n if (rejected.length > 0) onReject?.(rejected);\n }\n\n function onChange(event: Event) {\n const input = event.target as HTMLInputElement;\n deliver(input.files);\n // 清空:再选同一个文件也会触发 change\n input.value = '';\n }\n\n const accepting = (event: DragEvent) =>\n !locked() && (event.dataTransfer?.types.includes('Files') ?? false);\n\n const dragHandlers = {\n onDragenter: (event: DragEvent) => {\n if (!accepting(event)) return;\n event.preventDefault();\n depth++;\n dragging = true;\n },\n onDragover: (event: DragEvent) => {\n if (!accepting(event)) return;\n // 不阻止默认行为就不会触发 drop\n event.preventDefault();\n event.dataTransfer!.dropEffect = 'copy';\n },\n onDragleave: () => {\n depth = Math.max(0, depth - 1);\n if (depth === 0) dragging = false;\n },\n onDrop: (event: DragEvent) => {\n if (!accepting(event)) return;\n event.preventDefault();\n depth = 0;\n dragging = false;\n deliver(event.dataTransfer?.files);\n },\n };\n\n return () => {\n const field = control();\n return (\n <label\n {...mergeAttrs<'label'>(\n {\n sx: [\n fileDropStyles.root,\n // 原生 input 视觉上隐藏,焦点环画在整个区域上\n focusRingStyles.hasVisible,\n dragging && fileDropStyles.dragging,\n field.invalid && fileDropStyles.invalid,\n (field.disabled || field.readonly) && fileDropStyles.disabled,\n ],\n },\n propsRoot,\n dragHandlers,\n )}\n data-dragging={dragging || undefined}\n data-disabled={field.disabled || undefined}\n data-readonly={field.readonly || undefined}\n >\n <input\n {...mergeAttrs<'input'>({ sx: visuallyHiddenStyles.hidden }, rest, {\n type: 'file',\n id: field.id,\n accept,\n multiple,\n disabled: field.disabled || field.readonly,\n required: field.required,\n 'aria-invalid': field.invalid || undefined,\n 'aria-describedby': field.describedBy,\n onChange,\n })}\n />\n {children ?? (\n <>\n <Icon\n {...mergePartProps<IconProps>(\n { icon: UploadIcon, sx: fileDropStyles.icon },\n propsIcon,\n )}\n />\n <span {...mergeAttrs<'span'>({ sx: fileDropStyles.hint }, propsHint)}>\n {lang.fileDrop}\n </span>\n {hasContent(description) && (\n <span {...mergeAttrs<'span'>({ sx: fileDropStyles.description }, propsDescription)}>\n {description}\n </span>\n )}\n </>\n )}\n </label>\n );\n };\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"FileDrop.js","names":["_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_vue_ref","_createVNode","_mergeProps","_Fragment","UploadIcon"],"sources":["../../src/input/FileDrop.tsx"],"sourcesContent":["/**\n * 选择文件的区域(label > input[type=file]):点击(或聚焦后按 Enter / 空格)打开文件对话框,也可以把文件拖进来。\n * 只负责选文件:选到的文件经 onFiles 交出去,不在 accept 里的经 onReject 交出去(拖放不受 accept 限制,这里补上)。\n * 列表、进度、重试见 Upload(建在它上面)。\n *\n * <FileDrop accept=\"image/*\" multiple onFiles={(files) => add(files)} />\n *\n * 原生 input 只是视觉上隐藏,焦点、键盘、读屏都是浏览器的;区域的文字是它的名称。拖着文件经过时写 data-dragging。\n * 在 Field 里时关联标签、说明与错误。部件:Root(label)、Input(input)、Icon、Hint(提示文字)、Description(说明)。\n */\nimport { Upload as UploadIcon } from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { VNodeChild } from 'vue';\nimport { Icon, type IconProps } from '../base/Icon';\nimport { visuallyHiddenStyles } from '../base/VisuallyHidden';\nimport { useLang } from '../config/context';\nimport { hasContent, mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { focusRingStyles } from '../utils/style/styles';\nimport { useFieldControl } from '../form/Field';\nimport { t } from '../config/theme/tokens';\n\n/** 文件是否符合 accept(`image/*`、`.pdf`、`application/json` 这样的逗号分隔列表);accept 为空时都符合 */\nexport function matchesAccept(file: File, accept: string | undefined): boolean {\n const rules = (accept ?? '')\n .split(',')\n .map((rule) => rule.trim().toLowerCase())\n .filter(Boolean);\n if (rules.length === 0) return true;\n const name = file.name.toLowerCase();\n const type = file.type.toLowerCase();\n return rules.some((rule) => {\n if (rule.startsWith('.')) return name.endsWith(rule);\n if (rule.endsWith('/*')) return type.startsWith(rule.slice(0, -1));\n return type === rule;\n });\n}\n\n/** 文件、不可用、必填由组件管理;未声明的属性落到 input 上,外层 label 用 propsRoot */\nexport interface FileDropProps extends PartProps<\n 'input',\n 'type' | 'disabled' | 'required' | 'aria-invalid' | 'aria-describedby'\n> {\n /** 接受的文件类型(同原生 accept) */\n accept?: string;\n /** 可以选多个 */\n multiple?: boolean;\n /** 不可用 */\n disabled?: boolean;\n /** 必填 */\n required?: boolean;\n /** 只读:不能选文件(同不可用,文件输入框没有原生的只读) */\n readonly?: boolean;\n /** 校验未通过 */\n invalid?: boolean;\n /** 选到了文件(已按 accept 过滤) */\n onFiles?: (files: File[]) => void;\n /** 拖进来的文件里不在 accept 里的 */\n onReject?: (files: File[]) => void;\n /** 提示文字下面的说明(大小、类型限制) */\n description?: VNodeChild;\n /** 外层 label 的部件属性 */\n propsRoot?: PartProps<'label'>;\n /** 图标的部件属性 */\n propsIcon?: Partial<IconProps>;\n /** 提示文字的部件属性 */\n propsHint?: PartProps<'span'>;\n /** 提示文字下面的说明的部件属性 */\n propsDescription?: PartProps<'span'>;\n /** 区域里的内容;默认是图标、提示文字(取语言包)与 description */\n children?: VNodeChild;\n}\n\n/** FileDrop 的样式:root、dragging、disabled、invalid、icon、hint、description */\nexport const fileDropStyles = css.create({\n root: {\n boxSizing: 'border-box',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '_xs',\n width: '_full',\n minHeight: '8em',\n padding: '_lg',\n borderWidth: '_sm',\n borderStyle: 'dashed',\n borderColor: { default: '_borderStrong', ':hover': '_accent' },\n borderRadius: '_md',\n backgroundColor: '_surface',\n color: '_text',\n textAlign: 'center',\n cursor: 'pointer',\n transition: `border-color ${t.durations.sm} ${t.easings.standard}, background-color ${t.durations.sm} ${t.easings.standard}`,\n },\n dragging: { borderColor: '_accent', backgroundColor: '_accentSoft' },\n disabled: { opacity: '_disabled', cursor: 'not-allowed' },\n invalid: { borderColor: '_danger' },\n icon: { width: '1.5em', height: '1.5em', color: '_textMuted' },\n hint: { fontWeight: '_medium' },\n description: { fontSize: '_sm', color: '_textMuted' },\n});\n\n/** 选择文件的区域:点击打开文件对话框,或把文件拖进来 */\nexport const FileDrop = _component(\n ({\n accept,\n multiple = false,\n disabled,\n required,\n readonly,\n invalid,\n onFiles,\n onReject,\n description,\n id,\n propsRoot,\n propsIcon,\n propsHint,\n propsDescription,\n children,\n ...rest\n }: FileDropProps) => {\n const lang = useLang();\n const control = useFieldControl(() => ({ id, invalid, required, disabled, readonly }));\n const locked = () => control().disabled || control().readonly;\n let dragging = _state(false);\n // dragenter / dragleave 在子元素之间也会触发:计数,回到 0 才算离开\n let depth = 0;\n\n function deliver(list: FileList | null | undefined) {\n const files = [...(list ?? [])];\n const accepted = files.filter((file) => matchesAccept(file, accept));\n const rejected = files.filter((file) => !accepted.includes(file));\n const taken = multiple ? accepted : accepted.slice(0, 1);\n if (taken.length > 0) onFiles?.(taken);\n if (rejected.length > 0) onReject?.(rejected);\n }\n\n function onChange(event: Event) {\n const input = event.target as HTMLInputElement;\n deliver(input.files);\n // 清空:再选同一个文件也会触发 change\n input.value = '';\n }\n\n const accepting = (event: DragEvent) =>\n !locked() && (event.dataTransfer?.types.includes('Files') ?? false);\n\n const dragHandlers = {\n onDragenter: (event: DragEvent) => {\n if (!accepting(event)) return;\n event.preventDefault();\n depth++;\n dragging = true;\n },\n onDragover: (event: DragEvent) => {\n if (!accepting(event)) return;\n // 不阻止默认行为就不会触发 drop\n event.preventDefault();\n event.dataTransfer!.dropEffect = 'copy';\n },\n onDragleave: () => {\n depth = Math.max(0, depth - 1);\n if (depth === 0) dragging = false;\n },\n onDrop: (event: DragEvent) => {\n if (!accepting(event)) return;\n event.preventDefault();\n depth = 0;\n dragging = false;\n deliver(event.dataTransfer?.files);\n },\n };\n\n return () => {\n const field = control();\n return (\n <label\n {...mergeAttrs<'label'>(\n {\n sx: [\n fileDropStyles.root,\n // 原生 input 视觉上隐藏,焦点环画在整个区域上\n focusRingStyles.hasVisible,\n dragging && fileDropStyles.dragging,\n field.invalid && fileDropStyles.invalid,\n (field.disabled || field.readonly) && fileDropStyles.disabled,\n ],\n },\n propsRoot,\n dragHandlers,\n )}\n data-dragging={dragging || undefined}\n data-disabled={field.disabled || undefined}\n data-readonly={field.readonly || undefined}\n >\n <input\n {...mergeAttrs<'input'>({ sx: visuallyHiddenStyles.hidden }, rest, {\n type: 'file',\n id: field.id,\n accept,\n multiple,\n disabled: field.disabled || field.readonly,\n required: field.required,\n 'aria-invalid': field.invalid || undefined,\n 'aria-describedby': field.describedBy,\n onChange,\n })}\n />\n {children ?? (\n <>\n <Icon\n {...mergePartProps<IconProps>(\n { icon: UploadIcon, sx: fileDropStyles.icon },\n propsIcon,\n )}\n />\n <span {...mergeAttrs<'span'>({ sx: fileDropStyles.hint }, propsHint)}>\n {lang.fileDrop}\n </span>\n {hasContent(description) && (\n <span {...mergeAttrs<'span'>({ sx: fileDropStyles.description }, propsDescription)}>\n {description}\n </span>\n )}\n </>\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 { Ref, VNodeChild } from 'vue';
3
3
  import { type PartProps } from '../utils/props';
4
4
  import type { TextSize } from '../utils/style/typography';
@@ -5,7 +5,7 @@ import { anchoredPanelSx, floatingStyles } from "../utils/dom/floating.js";
5
5
  import { ListboxView } from "./Listbox.js";
6
6
  import { createVNode, shallowRef } from "vue";
7
7
  import { _component, readonlyProp } from "@zerodep-dev/vue-tsx-pro-tsx";
8
- import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
8
+ import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
9
9
  //#region src/input/ListPopover.tsx
10
10
  /** 弹层的属性由组件管理 */
11
11
  /** ListPopover 的属性 */
@@ -1 +1 @@
1
- {"version":3,"file":"ListPopover.js","names":["_vtp_readonlyProp","_vue_shallowRef","_createVNode"],"sources":["../../src/input/ListPopover.tsx"],"sourcesContent":["/**\n * 选项弹出层(div popover=\"auto\"):Select、Combobox、TagsInput 共用。锚定的浮层面板、浮层滚动条,\n * 里面是虚拟滚动的选项列表(ListboxView,滚动容器就是这里的 ScrollArea 视口)。\n *\n * const { onToggle } = useAnchoredPopover(…, panel, …);\n * <ListPopover panelRef={_toRef(panel)} onToggle={onToggle} size={size} label={…}\n * listbox={{ list, id, empty, renderOption }} propsListbox={propsListbox} onPick={pick} />\n *\n * 开关与定位由父组件的 useAnchoredPopover 管(它要拿到面板元素);这里只负责渲染。\n * 弹层渲染在顶层、不是输入框外壳的后代,不继承外壳的字号:按同一个 size 设置。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { Ref, VNodeChild } from 'vue';\nimport { ScrollArea } from '../layout/ScrollArea';\nimport { anchoredPanelSx, floatingStyles } from '../utils/dom/floating';\nimport { toElement } from '../utils/dom/element';\nimport { hasContent, mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport type { TextSize } from '../utils/style/typography';\nimport { ListboxView, type ListboxViewProps } from './Listbox';\n\n/** 弹层的属性由组件管理 */\nexport type ListPopoverManaged = 'popover';\n\n/** ListPopover 的属性 */\nexport interface ListPopoverProps<T> {\n /** 面板元素(父组件里 _toRef(panel)):交给 useAnchoredPopover 定位 */\n panelRef: Ref<HTMLElement | null>;\n /** 面板的 toggle 事件:交给 useAnchoredPopover,同步开关状态 */\n onToggle: (event: ToggleEvent) => void;\n /** 字号档位:同输入框外壳 */\n size?: TextSize;\n /** 列表的名称:外部标签的 id(有它时优先) */\n labelledBy?: string;\n /** 列表的名称:没有外部标签时用这段文字(aria-label) */\n label?: string;\n /** 加载中:列表显示骨架或顶部进度条 */\n loading?: boolean;\n /** 点选了一项 */\n onPick?: (value: string) => void;\n /** 列表的组件自己给的属性(list、id、渲染方式…),使用方的 propsListbox 可以覆盖 */\n listbox: ListboxViewProps<T>;\n /** 列表上方、不随列表滚动的内容(Select 的搜索框) */\n header?: VNodeChild;\n /** 使用方给列表的部件属性 */\n propsListbox?: Partial<ListboxViewProps<T>>;\n /** 使用方给弹层面板的部件属性 */\n propsPopover?: PartProps<'div', ListPopoverManaged>;\n}\n\n/** ListPopover 的样式:panel、header */\nexport const listPopoverStyles = css.create({\n panel: { maxWidth: 'calc(100vw - 2em)' },\n header: {\n flexShrink: 0,\n padding: '_xs',\n borderBlockEndWidth: '_xs',\n borderBlockEndStyle: 'solid',\n borderBlockEndColor: '_borderMuted',\n },\n});\n\n/** 选项弹出层:锚定的面板、浮层滚动条与选项列表 */\nexport const ListPopover = _component(\n <T,>({\n panelRef,\n onToggle,\n size,\n labelledBy,\n label,\n loading,\n onPick,\n listbox,\n header,\n propsListbox,\n propsPopover,\n }: ListPopoverProps<T>) => {\n let scroller = _state.raw<HTMLElement | null>(null);\n return () => (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [anchoredPanelSx(size), floatingStyles.scrollPanel, listPopoverStyles.panel],\n },\n propsPopover,\n { ref: panelRef, popover: 'auto', onToggle },\n )}\n >\n {/* 使用方常写 cond && <…/>:false 同 undefined,不渲染带分隔线的空头部 */}\n {hasContent(header) && <div {...css.attrs(listPopoverStyles.header)}>{header}</div>}\n <ScrollArea\n focusable={false}\n sx={floatingStyles.scrollArea}\n propsViewport={{ ref: (element: unknown) => (scroller = toElement(element)) }}\n >\n <ListboxView\n {...mergePartProps<ListboxViewProps<T>>(listbox, propsListbox, {\n id: listbox.id,\n // 这里的 ScrollArea 视口是滚动容器:选项虚拟滚动\n scroller,\n loading,\n 'aria-labelledby': labelledBy,\n 'aria-label': labelledBy ? undefined : label,\n onPick,\n })}\n />\n </ScrollArea>\n </div>\n );\n },\n);\n"],"mappings":";;;;;;;;;;;;AAmDA,IAAa,oBAAoB,IAAI,OAAO;CAC1C,OAAO,EAAE,UAAU,oBAAoB;CACvC,QAAQ;EACN,YAAY;EACZ,SAAS;EACT,qBAAqB;EACrB,qBAAqB;EACrB,qBAAqB;CACvB;AACF,CAAC;;AAGD,IAAa,cAAc,0BACzB,QAAA,SAY2B;CAAA,MAAA,SAAA,CAAA;CAAA,MAAA,WAAAA,aAAA,QAAA,UAAA;CAAA,MAAA,WAAAA,aAAA,QAAA,UAAA;CAAA,MAAA,OAAAA,aAAA,QAAA,MAAA;CAAA,MAAA,aAAAA,aAAA,QAAA,YAAA;CAAA,MAAA,QAAAA,aAAA,QAAA,OAAA;CAAA,MAAA,UAAAA,aAAA,QAAA,SAAA;CAAA,MAAA,SAAAA,aAAA,QAAA,QAAA;CAAA,MAAA,UAAAA,aAAA,QAAA,SAAA;CAAA,MAAA,SAAAA,aAAA,QAAA,QAAA;CAAA,MAAA,eAAAA,aAAA,QAAA,cAAA;CAAA,MAAA,eAAAA,aAAA,QAAA,cAAA;CACzB,IAAI,WAAQC,WAAkC,IAAI;CAClD,aAAOC,YAAA,OAEC,WACF,EACE,IAAI;EAAC,gBAAe,KAAA,KAAK;EAAG,eAAe;EAAa,kBAAkB;CAAK,EACjF,GAAC,aAAA,OAED;EAAE,KAAG,SAAA;EAAY,SAAS;EAAQ,UAAQ,SAAA;CAAC,CAC7C,GAAC,CAGA,WAAU,OAAA,KAAO,KAACA,YAAA,OAAa,IAAI,MAAM,kBAAkB,MAAM,GAAC,CAAA,OAAA,KAAA,CAAA,GAAgBA,YAAA,YAAA;EAAA,aAEtE;EAAK,MACZ,eAAe;EAAU,iBAAA,OAAA,OAAA,OAAA,KACd,EAAE,MAAM,YAAsB,SAAA,QAAW,UAAU,OAAO,EAAG;EAAC,OAAA;CAAA,GAAA;EAAA,eAAA,CAAAA,YAAA,aAGvE,eAAc,QAAA,OAAA,aAAA,OAA6C;GAC7D,IAAI,QAAA,MAAQ;GAEZ,UAAQ,SAAA;GACR,SAAO,QAAA;GACP,mBAAiB,WAAA;GACjB,cAAc,WAAA,QAAa,KAAA,IAAS,MAAA;GACpC,QAAM,OAAA;EACR,CAAC,GAAC,IAAA,CAAA;EAAA,SAAA;CAAA,CAAA,CAAA,CAAA;AAKZ,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH"}
1
+ {"version":3,"file":"ListPopover.js","names":["_vtp_readonlyProp","_vue_shallowRef","_createVNode"],"sources":["../../src/input/ListPopover.tsx"],"sourcesContent":["/**\n * 选项弹出层(div popover=\"auto\"):Select、Combobox、TagsInput 共用。锚定的浮层面板、浮层滚动条,\n * 里面是虚拟滚动的选项列表(ListboxView,滚动容器就是这里的 ScrollArea 视口)。\n *\n * const { onToggle } = useAnchoredPopover(…, panel, …);\n * <ListPopover panelRef={_toRef(panel)} onToggle={onToggle} size={size} label={…}\n * listbox={{ list, id, empty, renderOption }} propsListbox={propsListbox} onPick={pick} />\n *\n * 开关与定位由父组件的 useAnchoredPopover 管(它要拿到面板元素);这里只负责渲染。\n * 弹层渲染在顶层、不是输入框外壳的后代,不继承外壳的字号:按同一个 size 设置。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { Ref, VNodeChild } from 'vue';\nimport { ScrollArea } from '../layout/ScrollArea';\nimport { anchoredPanelSx, floatingStyles } from '../utils/dom/floating';\nimport { toElement } from '../utils/dom/element';\nimport { hasContent, mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport type { TextSize } from '../utils/style/typography';\nimport { ListboxView, type ListboxViewProps } from './Listbox';\n\n/** 弹层的属性由组件管理 */\nexport type ListPopoverManaged = 'popover';\n\n/** ListPopover 的属性 */\nexport interface ListPopoverProps<T> {\n /** 面板元素(父组件里 _toRef(panel)):交给 useAnchoredPopover 定位 */\n panelRef: Ref<HTMLElement | null>;\n /** 面板的 toggle 事件:交给 useAnchoredPopover,同步开关状态 */\n onToggle: (event: ToggleEvent) => void;\n /** 字号档位:同输入框外壳 */\n size?: TextSize;\n /** 列表的名称:外部标签的 id(有它时优先) */\n labelledBy?: string;\n /** 列表的名称:没有外部标签时用这段文字(aria-label) */\n label?: string;\n /** 加载中:列表显示骨架或顶部进度条 */\n loading?: boolean;\n /** 点选了一项 */\n onPick?: (value: string) => void;\n /** 列表的组件自己给的属性(list、id、渲染方式…),使用方的 propsListbox 可以覆盖 */\n listbox: ListboxViewProps<T>;\n /** 列表上方、不随列表滚动的内容(Select 的搜索框) */\n header?: VNodeChild;\n /** 使用方给列表的部件属性 */\n propsListbox?: Partial<ListboxViewProps<T>>;\n /** 使用方给弹层面板的部件属性 */\n propsPopover?: PartProps<'div', ListPopoverManaged>;\n}\n\n/** ListPopover 的样式:panel、header */\nexport const listPopoverStyles = css.create({\n panel: { maxWidth: 'calc(100vw - 2em)' },\n header: {\n flexShrink: 0,\n padding: '_xs',\n borderBlockEndWidth: '_xs',\n borderBlockEndStyle: 'solid',\n borderBlockEndColor: '_borderMuted',\n },\n});\n\n/** 选项弹出层:锚定的面板、浮层滚动条与选项列表 */\nexport const ListPopover = _component(\n <T,>({\n panelRef,\n onToggle,\n size,\n labelledBy,\n label,\n loading,\n onPick,\n listbox,\n header,\n propsListbox,\n propsPopover,\n }: ListPopoverProps<T>) => {\n let scroller = _state.raw<HTMLElement | null>(null);\n return () => (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [anchoredPanelSx(size), floatingStyles.scrollPanel, listPopoverStyles.panel],\n },\n propsPopover,\n { ref: panelRef, popover: 'auto', onToggle },\n )}\n >\n {/* 使用方常写 cond && <…/>:false 同 undefined,不渲染带分隔线的空头部 */}\n {hasContent(header) && <div {...css.attrs(listPopoverStyles.header)}>{header}</div>}\n <ScrollArea\n focusable={false}\n sx={floatingStyles.scrollArea}\n propsViewport={{ ref: (element: unknown) => (scroller = toElement(element)) }}\n >\n <ListboxView\n {...mergePartProps<ListboxViewProps<T>>(listbox, propsListbox, {\n id: listbox.id,\n // 这里的 ScrollArea 视口是滚动容器:选项虚拟滚动\n scroller,\n loading,\n 'aria-labelledby': labelledBy,\n 'aria-label': labelledBy ? undefined : label,\n onPick,\n })}\n />\n </ScrollArea>\n </div>\n );\n },\n);\n"],"mappings":";;;;;;;;;;;;AAmDA,IAAa,oBAAoB,IAAI,OAAO;CAC1C,OAAO,EAAE,UAAU,oBAAoB;CACvC,QAAQ;EACN,YAAY;EACZ,SAAS;EACT,qBAAqB;EACrB,qBAAqB;EACrB,qBAAqB;CACvB;AACF,CAAC;;AAGD,IAAa,cAAc,0BACzB,QAAA,SAY2B;CAAA,MAAA,SAAA,CAAA;CAAA,MAAA,WAAAA,aAAA,QAAA,UAAA;CAAA,MAAA,WAAAA,aAAA,QAAA,UAAA;CAAA,MAAA,OAAAA,aAAA,QAAA,MAAA;CAAA,MAAA,aAAAA,aAAA,QAAA,YAAA;CAAA,MAAA,QAAAA,aAAA,QAAA,OAAA;CAAA,MAAA,UAAAA,aAAA,QAAA,SAAA;CAAA,MAAA,SAAAA,aAAA,QAAA,QAAA;CAAA,MAAA,UAAAA,aAAA,QAAA,SAAA;CAAA,MAAA,SAAAA,aAAA,QAAA,QAAA;CAAA,MAAA,eAAAA,aAAA,QAAA,cAAA;CAAA,MAAA,eAAAA,aAAA,QAAA,cAAA;CACzB,IAAI,WAAQC,WAAkC,IAAI;CAClD,aAAOC,YAAA,OAEC,WACF,EACE,IAAI;EAAC,gBAAe,KAAA,KAAK;EAAG,eAAe;EAAa,kBAAkB;CAAK,EACjF,GAAC,aAAA,OAED;EAAE,KAAG,SAAA;EAAY,SAAS;EAAQ,UAAQ,SAAA;CAAC,CAC7C,GAAC,CAGA,WAAU,OAAA,KAAO,KAACA,YAAA,OAAa,IAAI,MAAM,kBAAkB,MAAM,GAAC,CAAA,OAAA,KAAA,CAAA,GAAgBA,YAAA,YAAA;EAAA,aAEtE;EAAK,MACZ,eAAe;EAAU,iBAAA,OAAA,OAAA,OAAA,KACd,EAAE,MAAM,YAAsB,SAAA,QAAW,UAAU,OAAO,EAAG;EAAC,OAAA;CAAA,GAAA;EAAA,eAAA,CAAAA,YAAA,aAGvE,eAAc,QAAA,OAAA,aAAA,OAA6C;GAC7D,IAAI,QAAA,MAAQ;GAEZ,UAAQ,SAAA;GACR,SAAO,QAAA;GACP,mBAAiB,WAAA;GACjB,cAAc,WAAA,QAAa,KAAA,IAAS,MAAA;GACpC,QAAM,OAAA;EACR,CAAC,GAAC,IAAA,CAAA;EAAA,SAAA;CAAA,CAAA,CAAA,CAAA;AAKZ,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;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 IconProps } from '../base/Icon';
4
4
  import { type TextProps } from '../base/Text';
@@ -17,7 +17,7 @@ import { defaultRangeExtractor } from "../utils/virtual/virtualizer.js";
17
17
  import { useVirtualizer } from "../utils/virtual/use-virtualizer.js";
18
18
  import { Fragment, computed, createVNode, isVNode, shallowRef, useId, watch, withMemo } from "vue";
19
19
  import { _component, bindable, childrenProp, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
20
- import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
20
+ import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
21
21
  import { Check } from "@lucide/icons";
22
22
  //#region src/input/Listbox.tsx
23
23
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"Listbox.js","names":["_isVNode","_vtp_readonlyProp","_vtp_restProps","_vue_shallowRef","_vue_computed","_createVNode","_mergeProps","_Fragment","Text","_vtp_bindable","_vtp_childrenProp"],"sources":["../../src/input/Listbox.tsx"],"sourcesContent":["/**\n * 列表框(role=\"listbox\"):在一列选项里单选或多选。数据驱动,始终虚拟滚动(上万个选项也只渲染看得见的几十个):\n *\n * <Listbox items={cities} _value={city} aria-label=\"城市\" />\n * <Listbox items={tags} selectionMode=\"multiple\" _value={picked}>{(tag) => <Badge>{tag.label}</Badge>}</Listbox>\n * <Listbox items={users} toOption={(user) => ({ value: user.id, label: user.name })} _value={id} aria-label=\"成员\" />\n *\n * 选项是 { value, label, disabled?, description?, icon?, group? }(ListboxOption);别的形状的数据用 toOption 转换,\n * 自定义内容的渲染函数拿到的仍是原始数据。\n * 焦点在列表上,高亮项经 aria-activedescendant 告诉读屏:↑↓、Home / End、Page Up / Down 移动,\n * Enter / 空格选中,按字母跳到以它开头的项。状态与键盘见 list-state.ts;Select、Combobox 用同一个 ListboxView 渲染。\n *\n * 虚拟滚动(useVirtualizer):高亮项总在渲染范围里(aria-activedescendant 才指得到),键盘移动时滚进可见范围;\n * 选项带 aria-setsize / aria-posinset,读屏知道总数与位置。分组标题只是视觉上的一行(各行独立定位,没法用\n * role=\"group\" 包住组里的选项),组名经 aria-describedby 交给组里的每个选项。\n * loading:没有选项时显示骨架行;已有选项(刷新中)时顶部显示一条进度条;列表带 aria-busy。\n *\n * 部件:Root(div,role=\"listbox\")、GroupLabel、Option(div,role=\"option\")、Check(已选标记)、Skeleton(加载中的占位行)。\n */\nimport { Check } 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, withMemo, type VNode, type VNodeChild } from 'vue';\nimport { Icon, type IconProps } from '../base/Icon';\nimport { Text, type TextProps } from '../base/Text';\nimport { useDelayedLoading } from '../utils/motion/delayed-loading';\nimport { useLang } from '../config/context';\nimport { Empty, type EmptyProps } from '../feedback/Empty';\nimport { Progress } from '../feedback/Progress';\nimport { Skeleton, type SkeletonProps, type SkeletonShapeProps } from '../feedback/Skeleton';\nimport { SHIMMER_STAGGER } from '../utils/style/shimmer';\nimport { itemStyles } from '../utils/style/item-styles';\nimport {\n defaultLabelledBy,\n elementProps,\n mergeAttrs,\n mergePartProps,\n mergeProps,\n type PartProps,\n} from '../utils/props';\nimport { ScrollArea } from '../layout/ScrollArea';\nimport { selectedValues, type SelectionProps } from '../utils/data/selection';\nimport { focusRingStyles } from '../utils/style/styles';\nimport { useVirtualizer } from '../utils/virtual/use-virtualizer';\nimport { defaultRangeExtractor } from '../utils/virtual/virtualizer';\nimport { useFieldControl } from '../form/Field';\nimport {\n handleListKeydown,\n useListState,\n type ListboxOption,\n type ListStateEntry,\n type ListState,\n type OptionMapping,\n toListboxOption,\n} from './list-state';\n\n/** 选项的渲染状态:渲染函数据此画高亮、已选的样子 */\nexport interface OptionRenderState {\n /** 已选 */\n selected: boolean;\n /** 高亮(键盘或指针所在) */\n active: boolean;\n}\n\n/** 选项的部件属性:可以按选项(items 里的原始数据)计算 */\ntype OptionProps<T> =\n | PartProps<'div', 'role' | 'id' | 'aria-selected' | 'aria-disabled'>\n | ((item: T, state: OptionRenderState) => PartProps<'div'>);\n\n/** ListboxView 的属性:Listbox、Select、Combobox 共用的渲染层 */\nexport interface ListboxViewProps<T> extends PartProps<'div', 'role'> {\n /** 列表状态(useListState) */\n list: ListState<T>;\n /** 列表的 id;选项的 id 是 `${id}-${序号}`(aria-activedescendant 指向它) */\n id: string;\n /** 多选:aria-multiselectable */\n multiple?: boolean;\n /** 滚动容器:Select、Combobox 的弹出层;不给时列表自己滚动(ScrollArea 的浮层滚动条,最高 20em,用 sx 改) */\n scroller?: HTMLElement | null;\n /** 加载中:没有选项时显示骨架行,有选项时顶部显示进度条 */\n loading?: boolean;\n /** 选项的估计高度(px),默认 36;渲染后以实际高度为准 */\n estimateSize?: number;\n /** 自定义选项内容:拿到 items 里的原始数据 */\n renderOption?: (item: T, state: OptionRenderState) => VNodeChild;\n /** 没有选项时显示的内容;默认是 Empty(文案取语言包) */\n empty?: VNodeChild;\n /** 点选了一项(点击或 Enter,再选已选的那项也会调用):Select、弹层里的列表据此关闭 */\n onPick?: (value: string) => void;\n /** 选项的部件属性 */\n propsOption?: OptionProps<T>;\n /** 分组标题的部件属性 */\n propsGroupLabel?: Partial<TextProps>;\n /** 已选标记的部件属性 */\n propsCheck?: Partial<IconProps>;\n /** 空状态的部件属性 */\n propsEmpty?: Partial<EmptyProps>;\n /** 加载中占位行的部件属性 */\n propsSkeleton?: SkeletonShapeProps;\n}\n\n/** 渲染用的一行:分组标题或选项 */\ntype Row<T> =\n | { kind: 'group'; key: string; label: string; id: string }\n | {\n kind: 'option';\n key: string;\n option: ListStateEntry<T>;\n index: number;\n groupId: string | undefined;\n };\n\n/** 加载中显示几行骨架 */\nconst SKELETON_ROWS = 4;\n\n/** Listbox 的样式:root、scroll、sizer、row、groupLabel、content 等 */\nexport const listboxStyles = css.create({\n root: { position: 'relative', padding: '_xs', lineHeight: '_normal', outlineStyle: 'none' },\n // 自己是滚动容器时(单独使用的 Listbox):限制高度,滚动不传给页面\n scroll: { maxHeight: '20em', overflowY: 'auto', overscrollBehavior: 'contain' },\n sizer: { position: 'relative', width: '_full' },\n row: { position: 'absolute', top: 0, insetInline: 0 },\n groupLabel: {\n display: 'block',\n paddingTop: '_sm',\n paddingBottom: '_xs',\n paddingInline: '_sm',\n fontWeight: '_semibold',\n },\n content: { display: 'flex', flexDirection: 'column', flexGrow: 1, minWidth: 0 },\n description: { color: '_textMuted' },\n check: { flexShrink: 0 },\n hidden: { visibility: 'hidden' },\n // 刷新中的进度条贴在列表顶部,不占位\n progress: { position: 'absolute', top: 0, insetInline: 0, zIndex: 1 },\n skeleton: { display: 'block', height: '1em', marginBlock: '0.625em', marginInline: '_sm' },\n});\n\n// 行的位置是任意值,用动态样式;单独一个 create,见 COMPONENTS.md §4\n/** Listbox 的样式:y、height、width */\nexport const listboxPositionStyles = css.create({\n y: (px: number) => ({ transform: `translateY(${px}px)` }),\n height: (px: number) => ({ height: px }),\n width: (percent: string) => ({ width: percent }),\n});\n\n/** 列表的渲染层:虚拟滚动的选项、分组标题、已选标记、空状态与加载中;不管焦点,指针悬停高亮、点击选中 */\nexport const ListboxView = _component(\n <T,>({\n list,\n id,\n multiple = false,\n scroller,\n loading = false,\n estimateSize = 36,\n renderOption,\n empty,\n onPick,\n propsOption,\n propsGroupLabel,\n propsCheck,\n propsEmpty,\n propsSkeleton,\n ...rest\n }: ListboxViewProps<T>) => {\n const lang = useLang();\n // 骨架、进度条防闪烁;aria-busy 按真实的 loading\n const indicator = useDelayedLoading(() => loading);\n let root = _state.raw<HTMLElement | null>(null);\n let sizer = _state.raw<HTMLElement | null>(null);\n\n /** 选项按分组排好后展开成行:每组前插一行标题 */\n const rows = _derived.by<Row<T>[]>(() => {\n const result: Row<T>[] = [];\n let group: string | undefined;\n let headerId: string | undefined;\n list.options.forEach((option, index) => {\n if (option.group != null && option.group !== group) {\n headerId = `${id}-group-${result.length}`;\n result.push({\n kind: 'group',\n key: `group:${option.group}`,\n label: option.group,\n id: headerId,\n });\n }\n group = option.group;\n result.push({\n kind: 'option',\n key: option.value,\n option,\n index,\n groupId: option.group != null ? headerId : undefined,\n });\n });\n return result;\n });\n\n /** 值 → 行号:高亮项的行号一次查到,不在每次渲染时扫一遍 */\n const rowOf = _derived.by(() => {\n const map = new Map<string, number>();\n rows.forEach((row, index) => {\n if (row.kind === 'option') map.set(row.option.value, index);\n });\n return map;\n });\n const activeRow = () => (list.active === undefined ? -1 : (rowOf.get(list.active) ?? -1));\n\n const virtual = useVirtualizer(() => {\n const current = rows;\n // 读一下高亮项:它变了要重新算渲染范围(高亮项总要渲染)\n const active = activeRow();\n // 先读出来:每一项都要调用一次估计高度,不要每次都经过 props 的响应式读取\n const size = estimateSize;\n return {\n count: current.length,\n scrollElement: scroller === undefined ? root : scroller,\n list: sizer,\n estimateSize: (index: number) => (current[index]?.kind === 'group' ? 30 : size),\n getItemKey: (index: number) => current[index]!.key,\n overscan: 6,\n rangeExtractor: (range) => {\n const indices = defaultRangeExtractor(range);\n if (active >= 0 && !indices.includes(active)) {\n indices.push(active);\n indices.sort((a, b) => a - b);\n }\n return indices;\n },\n };\n });\n\n // 高亮项变了(键盘移动)时滚进可见范围;已经完整可见就不动(指针悬停触发的不会滚)。\n // 高亮的是第一项、上面是组名时滚到最顶上:组名不被挡住(搜索过滤后高亮第一个匹配的)\n watch(\n () => list.active,\n () => {\n const index = activeRow();\n if (index < 0) return;\n virtual.scrollToIndex(index === 1 && rows[0]?.kind === 'group' ? 0 : index, {\n align: 'auto',\n });\n },\n { flush: 'post' },\n );\n\n /**\n * 选项行按“会影响它的值”缓存(Vue 的 withMemo,同模板的 v-memo):方向键移动高亮时只重建前后两行,\n * 不再重建全部可见行与其中的图标。自定义了 renderOption 或按项计算的 propsOption 时不缓存:\n * 使用方的函数可能读别的状态,缓存了会显示旧内容\n */\n const memoCache: VNode[] = [];\n function optionRow(row: Extract<Row<T>, { kind: 'option' }>) {\n if (renderOption || typeof propsOption === 'function') return renderOptionRow(row);\n const { option } = row;\n return withMemo(\n [\n option,\n row.index,\n row.groupId,\n list.isSelected(option.value),\n list.active === option.value,\n list.options.length,\n propsOption,\n propsCheck,\n ],\n () => renderOptionRow(row),\n memoCache,\n row.index,\n );\n }\n\n function renderOptionRow(row: Extract<Row<T>, { kind: 'option' }>) {\n const { option, index } = row;\n const state = {\n selected: list.isSelected(option.value),\n active: list.active === option.value,\n };\n const own = typeof propsOption === 'function' ? propsOption(option.item, state) : propsOption;\n return (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n itemStyles.row,\n state.active && itemStyles.highlighted,\n state.selected && itemStyles.selected,\n option.disabled && itemStyles.disabled,\n ],\n },\n own,\n {\n id: `${id}-${index}`,\n role: 'option',\n 'aria-selected': state.selected,\n 'aria-disabled': option.disabled || undefined,\n 'aria-setsize': list.options.length,\n 'aria-posinset': index + 1,\n 'aria-describedby': row.groupId,\n // 焦点留在列表、触发按钮或输入框上\n onPointerdown: (event: PointerEvent) => event.preventDefault(),\n onPointermove: () => {\n if (!option.disabled && list.active !== option.value) list.setActive(option.value);\n },\n onClick: () => {\n if (option.disabled) return;\n list.select(option.value);\n onPick?.(option.value);\n },\n },\n )}\n data-state={state.selected ? 'checked' : 'unchecked'}\n data-active={state.active || undefined}\n data-disabled={option.disabled || undefined}\n >\n {renderOption ? (\n renderOption(option.item, state)\n ) : (\n <>\n {option.icon && <Icon icon={option.icon} />}\n <span {...css.attrs(listboxStyles.content)}>\n <span {...css.attrs(itemStyles.label)}>{option.label}</span>\n {option.description && (\n <Text size=\"sm\" sx={listboxStyles.description}>\n {option.description}\n </Text>\n )}\n </span>\n </>\n )}\n <Icon\n {...mergePartProps<IconProps>(\n { icon: Check, sx: [listboxStyles.check, !state.selected && listboxStyles.hidden] },\n propsCheck,\n )}\n />\n </div>\n );\n }\n\n function renderBody() {\n if (rows.length === 0) {\n if (loading) {\n if (!indicator.value) return null;\n return Array.from({ length: SKELETON_ROWS }, (_, index) => (\n <Skeleton\n key={index}\n {...mergePartProps<SkeletonProps>(\n {\n sx: [listboxStyles.skeleton, listboxPositionStyles.width(`${85 - index * 15}%`)],\n delay: index * SHIMMER_STAGGER,\n },\n propsSkeleton,\n )}\n />\n ));\n }\n return (\n empty ?? (\n <Empty\n {...mergePartProps<EmptyProps>(\n { size: 'sm', icon: false, description: lang.selectEmpty },\n propsEmpty,\n )}\n />\n )\n );\n }\n return (\n <div\n ref={_toRef(sizer)}\n role=\"presentation\"\n {...css.attrs(listboxStyles.sizer, listboxPositionStyles.height(virtual.total))}\n >\n {virtual.items.map((item) => {\n const row = rows[item.index]!;\n return (\n <div\n key={item.key}\n ref={virtual.measure}\n data-index={item.index}\n role=\"presentation\"\n {...css.attrs(listboxStyles.row, listboxPositionStyles.y(item.start))}\n >\n {row.kind === 'group' ? (\n <Text\n {...mergePartProps<TextProps>(\n { tone: 'muted', size: 'sm', sx: listboxStyles.groupLabel },\n propsGroupLabel,\n // 只是视觉上的标题:组名经各选项的 aria-describedby 念出\n { id: row.id, 'aria-hidden': true },\n )}\n >\n {row.label}\n </Text>\n ) : (\n optionRow(row)\n )}\n </div>\n );\n })}\n </div>\n );\n }\n\n return () => {\n const own = scroller === undefined;\n // 先不编译 sx:自己滚动时这些属性交给 ScrollArea 的视口,和视口自己的样式一次合并\n const props = mergeProps<'div'>(\n { sx: [listboxStyles.root, own && listboxStyles.scroll, focusRingStyles.visible] },\n rest,\n {\n ref: _toRef(root),\n id,\n role: 'listbox',\n 'aria-multiselectable': multiple || undefined,\n 'aria-busy': loading || undefined,\n },\n );\n const body = [\n indicator.value && rows.length > 0 && (\n <div aria-hidden=\"true\" {...css.attrs(listboxStyles.progress)}>\n <Progress size=\"xs\" aria-label={lang.loading} />\n </div>\n ),\n renderBody(),\n ];\n // 别处滚动(Select、Combobox 的弹出层):只渲染列表本身\n if (!own) return <div {...elementProps(props)}>{body}</div>;\n // 自己滚动:列表元素就是 ScrollArea 的视口,焦点与 aria-activedescendant 仍在它上面,滚动条换成浮层的\n return (\n <ScrollArea focusable={false} propsViewport={props as PartProps<'div'>}>\n {body}\n </ScrollArea>\n );\n };\n },\n { name: 'ListboxView' },\n);\n\n/** 高亮项的 id(给 aria-activedescendant);没有高亮时 undefined */\nexport function activeOptionId<T>(list: ListState<T>, id: string): string | undefined {\n const index = list.active === undefined ? -1 : list.indexOf(list.active);\n return index < 0 ? undefined : `${id}-${index}`;\n}\n\n/** 列表框共有的属性;未声明的属性落到 role=\"listbox\" 的 div 上 */\nexport interface ListboxBaseProps<T> extends Omit<\n ListboxViewProps<T>,\n 'list' | 'id' | 'multiple' | 'renderOption'\n> {\n /** 列表的 id;在 Field 里时默认用 Field 给的 */\n id?: string;\n /** 数据:ListboxOption、字符串,或任意数据加 toOption */\n items: readonly T[];\n /** 必须有选中项:单选时再点已选项不取消;在必填的 Field 里默认开启 */\n required?: boolean;\n /** 不可用 */\n disabled?: boolean;\n /** 自定义选项内容:`{(item, { selected, active }) => …}`,拿到 items 里的原始数据 */\n children?: (item: T, state: OptionRenderState) => VNodeChild;\n}\n\n/** 单选或多选;items 不是 ListboxOption 或字符串时要给 toOption */\nexport type ListboxProps<T = ListboxOption> = ListboxBaseProps<T> &\n SelectionProps &\n OptionMapping<T>;\n\n/** 列表框:焦点在列表上,方向键移动高亮、Enter / 空格选中 */\nexport const Listbox = _component(\n <T,>({\n items,\n toOption,\n selectionMode = 'single',\n _value: value = _bindable<string | string[] | null>(null),\n required,\n disabled,\n id,\n children,\n onPick,\n ...rest\n }: ListboxProps<T>) => {\n const generatedId = useId();\n const control = useFieldControl(() => ({ id, disabled, required }));\n const list = useListState({\n items: () => items,\n toOption: (item) => toListboxOption(item, toOption),\n selected: () => selectedValues(value),\n mode: () => selectionMode,\n required: () => control().required,\n onChange: (next) => (value = selectionMode === 'multiple' ? [...next] : (next[0] ?? null)),\n });\n\n function onKeydown(event: KeyboardEvent) {\n if (control().disabled) return;\n if (handleListKeydown(list, event, { space: true, typeahead: true }, onPick)) {\n event.preventDefault();\n }\n }\n\n return () => {\n const state = control();\n const prefix = state.id ?? generatedId;\n return (\n <ListboxView\n {...mergePartProps<ListboxViewProps<T>>(\n {\n list,\n id: prefix,\n multiple: selectionMode === 'multiple',\n renderOption: children,\n onPick,\n },\n rest as Partial<ListboxViewProps<T>>,\n {\n id: prefix,\n tabindex: state.disabled ? -1 : 0,\n 'aria-labelledby': defaultLabelledBy(rest, state.labelledBy),\n 'aria-describedby': state.describedBy,\n 'aria-disabled': state.disabled || undefined,\n 'aria-required': state.required || undefined,\n 'aria-activedescendant': activeOptionId(list, prefix),\n onFocus: () => {\n if (list.active === undefined) list.activateDefault();\n },\n onKeydown,\n },\n )}\n />\n );\n };\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"Listbox.js","names":["_isVNode","_vtp_readonlyProp","_vtp_restProps","_vue_shallowRef","_vue_computed","_createVNode","_mergeProps","_Fragment","Text","_vtp_bindable","_vtp_childrenProp"],"sources":["../../src/input/Listbox.tsx"],"sourcesContent":["/**\n * 列表框(role=\"listbox\"):在一列选项里单选或多选。数据驱动,始终虚拟滚动(上万个选项也只渲染看得见的几十个):\n *\n * <Listbox items={cities} _value={city} aria-label=\"城市\" />\n * <Listbox items={tags} selectionMode=\"multiple\" _value={picked}>{(tag) => <Badge>{tag.label}</Badge>}</Listbox>\n * <Listbox items={users} toOption={(user) => ({ value: user.id, label: user.name })} _value={id} aria-label=\"成员\" />\n *\n * 选项是 { value, label, disabled?, description?, icon?, group? }(ListboxOption);别的形状的数据用 toOption 转换,\n * 自定义内容的渲染函数拿到的仍是原始数据。\n * 焦点在列表上,高亮项经 aria-activedescendant 告诉读屏:↑↓、Home / End、Page Up / Down 移动,\n * Enter / 空格选中,按字母跳到以它开头的项。状态与键盘见 list-state.ts;Select、Combobox 用同一个 ListboxView 渲染。\n *\n * 虚拟滚动(useVirtualizer):高亮项总在渲染范围里(aria-activedescendant 才指得到),键盘移动时滚进可见范围;\n * 选项带 aria-setsize / aria-posinset,读屏知道总数与位置。分组标题只是视觉上的一行(各行独立定位,没法用\n * role=\"group\" 包住组里的选项),组名经 aria-describedby 交给组里的每个选项。\n * loading:没有选项时显示骨架行;已有选项(刷新中)时顶部显示一条进度条;列表带 aria-busy。\n *\n * 部件:Root(div,role=\"listbox\")、GroupLabel、Option(div,role=\"option\")、Check(已选标记)、Skeleton(加载中的占位行)。\n */\nimport { Check } 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, withMemo, type VNode, type VNodeChild } from 'vue';\nimport { Icon, type IconProps } from '../base/Icon';\nimport { Text, type TextProps } from '../base/Text';\nimport { useDelayedLoading } from '../utils/motion/delayed-loading';\nimport { useLang } from '../config/context';\nimport { Empty, type EmptyProps } from '../feedback/Empty';\nimport { Progress } from '../feedback/Progress';\nimport { Skeleton, type SkeletonProps, type SkeletonShapeProps } from '../feedback/Skeleton';\nimport { SHIMMER_STAGGER } from '../utils/style/shimmer';\nimport { itemStyles } from '../utils/style/item-styles';\nimport {\n defaultLabelledBy,\n elementProps,\n mergeAttrs,\n mergePartProps,\n mergeProps,\n type PartProps,\n} from '../utils/props';\nimport { ScrollArea } from '../layout/ScrollArea';\nimport { selectedValues, type SelectionProps } from '../utils/data/selection';\nimport { focusRingStyles } from '../utils/style/styles';\nimport { useVirtualizer } from '../utils/virtual/use-virtualizer';\nimport { defaultRangeExtractor } from '../utils/virtual/virtualizer';\nimport { useFieldControl } from '../form/Field';\nimport {\n handleListKeydown,\n useListState,\n type ListboxOption,\n type ListStateEntry,\n type ListState,\n type OptionMapping,\n toListboxOption,\n} from './list-state';\n\n/** 选项的渲染状态:渲染函数据此画高亮、已选的样子 */\nexport interface OptionRenderState {\n /** 已选 */\n selected: boolean;\n /** 高亮(键盘或指针所在) */\n active: boolean;\n}\n\n/** 选项的部件属性:可以按选项(items 里的原始数据)计算 */\ntype OptionProps<T> =\n | PartProps<'div', 'role' | 'id' | 'aria-selected' | 'aria-disabled'>\n | ((item: T, state: OptionRenderState) => PartProps<'div'>);\n\n/** ListboxView 的属性:Listbox、Select、Combobox 共用的渲染层 */\nexport interface ListboxViewProps<T> extends PartProps<'div', 'role'> {\n /** 列表状态(useListState) */\n list: ListState<T>;\n /** 列表的 id;选项的 id 是 `${id}-${序号}`(aria-activedescendant 指向它) */\n id: string;\n /** 多选:aria-multiselectable */\n multiple?: boolean;\n /** 滚动容器:Select、Combobox 的弹出层;不给时列表自己滚动(ScrollArea 的浮层滚动条,最高 20em,用 sx 改) */\n scroller?: HTMLElement | null;\n /** 加载中:没有选项时显示骨架行,有选项时顶部显示进度条 */\n loading?: boolean;\n /** 选项的估计高度(px),默认 36;渲染后以实际高度为准 */\n estimateSize?: number;\n /** 自定义选项内容:拿到 items 里的原始数据 */\n renderOption?: (item: T, state: OptionRenderState) => VNodeChild;\n /** 没有选项时显示的内容;默认是 Empty(文案取语言包) */\n empty?: VNodeChild;\n /** 点选了一项(点击或 Enter,再选已选的那项也会调用):Select、弹层里的列表据此关闭 */\n onPick?: (value: string) => void;\n /** 选项的部件属性 */\n propsOption?: OptionProps<T>;\n /** 分组标题的部件属性 */\n propsGroupLabel?: Partial<TextProps>;\n /** 已选标记的部件属性 */\n propsCheck?: Partial<IconProps>;\n /** 空状态的部件属性 */\n propsEmpty?: Partial<EmptyProps>;\n /** 加载中占位行的部件属性 */\n propsSkeleton?: SkeletonShapeProps;\n}\n\n/** 渲染用的一行:分组标题或选项 */\ntype Row<T> =\n | { kind: 'group'; key: string; label: string; id: string }\n | {\n kind: 'option';\n key: string;\n option: ListStateEntry<T>;\n index: number;\n groupId: string | undefined;\n };\n\n/** 加载中显示几行骨架 */\nconst SKELETON_ROWS = 4;\n\n/** Listbox 的样式:root、scroll、sizer、row、groupLabel、content 等 */\nexport const listboxStyles = css.create({\n root: { position: 'relative', padding: '_xs', lineHeight: '_normal', outlineStyle: 'none' },\n // 自己是滚动容器时(单独使用的 Listbox):限制高度,滚动不传给页面\n scroll: { maxHeight: '20em', overflowY: 'auto', overscrollBehavior: 'contain' },\n sizer: { position: 'relative', width: '_full' },\n row: { position: 'absolute', top: 0, insetInline: 0 },\n groupLabel: {\n display: 'block',\n paddingTop: '_sm',\n paddingBottom: '_xs',\n paddingInline: '_sm',\n fontWeight: '_semibold',\n },\n content: { display: 'flex', flexDirection: 'column', flexGrow: 1, minWidth: 0 },\n description: { color: '_textMuted' },\n check: { flexShrink: 0 },\n hidden: { visibility: 'hidden' },\n // 刷新中的进度条贴在列表顶部,不占位\n progress: { position: 'absolute', top: 0, insetInline: 0, zIndex: 1 },\n skeleton: { display: 'block', height: '1em', marginBlock: '0.625em', marginInline: '_sm' },\n});\n\n// 行的位置是任意值,用动态样式;单独一个 create,见 COMPONENTS.md §4\n/** Listbox 的样式:y、height、width */\nexport const listboxPositionStyles = css.create({\n y: (px: number) => ({ transform: `translateY(${px}px)` }),\n height: (px: number) => ({ height: px }),\n width: (percent: string) => ({ width: percent }),\n});\n\n/** 列表的渲染层:虚拟滚动的选项、分组标题、已选标记、空状态与加载中;不管焦点,指针悬停高亮、点击选中 */\nexport const ListboxView = _component(\n <T,>({\n list,\n id,\n multiple = false,\n scroller,\n loading = false,\n estimateSize = 36,\n renderOption,\n empty,\n onPick,\n propsOption,\n propsGroupLabel,\n propsCheck,\n propsEmpty,\n propsSkeleton,\n ...rest\n }: ListboxViewProps<T>) => {\n const lang = useLang();\n // 骨架、进度条防闪烁;aria-busy 按真实的 loading\n const indicator = useDelayedLoading(() => loading);\n let root = _state.raw<HTMLElement | null>(null);\n let sizer = _state.raw<HTMLElement | null>(null);\n\n /** 选项按分组排好后展开成行:每组前插一行标题 */\n const rows = _derived.by<Row<T>[]>(() => {\n const result: Row<T>[] = [];\n let group: string | undefined;\n let headerId: string | undefined;\n list.options.forEach((option, index) => {\n if (option.group != null && option.group !== group) {\n headerId = `${id}-group-${result.length}`;\n result.push({\n kind: 'group',\n key: `group:${option.group}`,\n label: option.group,\n id: headerId,\n });\n }\n group = option.group;\n result.push({\n kind: 'option',\n key: option.value,\n option,\n index,\n groupId: option.group != null ? headerId : undefined,\n });\n });\n return result;\n });\n\n /** 值 → 行号:高亮项的行号一次查到,不在每次渲染时扫一遍 */\n const rowOf = _derived.by(() => {\n const map = new Map<string, number>();\n rows.forEach((row, index) => {\n if (row.kind === 'option') map.set(row.option.value, index);\n });\n return map;\n });\n const activeRow = () => (list.active === undefined ? -1 : (rowOf.get(list.active) ?? -1));\n\n const virtual = useVirtualizer(() => {\n const current = rows;\n // 读一下高亮项:它变了要重新算渲染范围(高亮项总要渲染)\n const active = activeRow();\n // 先读出来:每一项都要调用一次估计高度,不要每次都经过 props 的响应式读取\n const size = estimateSize;\n return {\n count: current.length,\n scrollElement: scroller === undefined ? root : scroller,\n list: sizer,\n estimateSize: (index: number) => (current[index]?.kind === 'group' ? 30 : size),\n getItemKey: (index: number) => current[index]!.key,\n overscan: 6,\n rangeExtractor: (range) => {\n const indices = defaultRangeExtractor(range);\n if (active >= 0 && !indices.includes(active)) {\n indices.push(active);\n indices.sort((a, b) => a - b);\n }\n return indices;\n },\n };\n });\n\n // 高亮项变了(键盘移动)时滚进可见范围;已经完整可见就不动(指针悬停触发的不会滚)。\n // 高亮的是第一项、上面是组名时滚到最顶上:组名不被挡住(搜索过滤后高亮第一个匹配的)\n watch(\n () => list.active,\n () => {\n const index = activeRow();\n if (index < 0) return;\n virtual.scrollToIndex(index === 1 && rows[0]?.kind === 'group' ? 0 : index, {\n align: 'auto',\n });\n },\n { flush: 'post' },\n );\n\n /**\n * 选项行按“会影响它的值”缓存(Vue 的 withMemo,同模板的 v-memo):方向键移动高亮时只重建前后两行,\n * 不再重建全部可见行与其中的图标。自定义了 renderOption 或按项计算的 propsOption 时不缓存:\n * 使用方的函数可能读别的状态,缓存了会显示旧内容\n */\n const memoCache: VNode[] = [];\n function optionRow(row: Extract<Row<T>, { kind: 'option' }>) {\n if (renderOption || typeof propsOption === 'function') return renderOptionRow(row);\n const { option } = row;\n return withMemo(\n [\n option,\n row.index,\n row.groupId,\n list.isSelected(option.value),\n list.active === option.value,\n list.options.length,\n propsOption,\n propsCheck,\n ],\n () => renderOptionRow(row),\n memoCache,\n row.index,\n );\n }\n\n function renderOptionRow(row: Extract<Row<T>, { kind: 'option' }>) {\n const { option, index } = row;\n const state = {\n selected: list.isSelected(option.value),\n active: list.active === option.value,\n };\n const own = typeof propsOption === 'function' ? propsOption(option.item, state) : propsOption;\n return (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n itemStyles.row,\n state.active && itemStyles.highlighted,\n state.selected && itemStyles.selected,\n option.disabled && itemStyles.disabled,\n ],\n },\n own,\n {\n id: `${id}-${index}`,\n role: 'option',\n 'aria-selected': state.selected,\n 'aria-disabled': option.disabled || undefined,\n 'aria-setsize': list.options.length,\n 'aria-posinset': index + 1,\n 'aria-describedby': row.groupId,\n // 焦点留在列表、触发按钮或输入框上\n onPointerdown: (event: PointerEvent) => event.preventDefault(),\n onPointermove: () => {\n if (!option.disabled && list.active !== option.value) list.setActive(option.value);\n },\n onClick: () => {\n if (option.disabled) return;\n list.select(option.value);\n onPick?.(option.value);\n },\n },\n )}\n data-state={state.selected ? 'checked' : 'unchecked'}\n data-active={state.active || undefined}\n data-disabled={option.disabled || undefined}\n >\n {renderOption ? (\n renderOption(option.item, state)\n ) : (\n <>\n {option.icon && <Icon icon={option.icon} />}\n <span {...css.attrs(listboxStyles.content)}>\n <span {...css.attrs(itemStyles.label)}>{option.label}</span>\n {option.description && (\n <Text size=\"sm\" sx={listboxStyles.description}>\n {option.description}\n </Text>\n )}\n </span>\n </>\n )}\n <Icon\n {...mergePartProps<IconProps>(\n { icon: Check, sx: [listboxStyles.check, !state.selected && listboxStyles.hidden] },\n propsCheck,\n )}\n />\n </div>\n );\n }\n\n function renderBody() {\n if (rows.length === 0) {\n if (loading) {\n if (!indicator.value) return null;\n return Array.from({ length: SKELETON_ROWS }, (_, index) => (\n <Skeleton\n key={index}\n {...mergePartProps<SkeletonProps>(\n {\n sx: [listboxStyles.skeleton, listboxPositionStyles.width(`${85 - index * 15}%`)],\n delay: index * SHIMMER_STAGGER,\n },\n propsSkeleton,\n )}\n />\n ));\n }\n return (\n empty ?? (\n <Empty\n {...mergePartProps<EmptyProps>(\n { size: 'sm', icon: false, description: lang.selectEmpty },\n propsEmpty,\n )}\n />\n )\n );\n }\n return (\n <div\n ref={_toRef(sizer)}\n role=\"presentation\"\n {...css.attrs(listboxStyles.sizer, listboxPositionStyles.height(virtual.total))}\n >\n {virtual.items.map((item) => {\n const row = rows[item.index]!;\n return (\n <div\n key={item.key}\n ref={virtual.measure}\n data-index={item.index}\n role=\"presentation\"\n {...css.attrs(listboxStyles.row, listboxPositionStyles.y(item.start))}\n >\n {row.kind === 'group' ? (\n <Text\n {...mergePartProps<TextProps>(\n { tone: 'muted', size: 'sm', sx: listboxStyles.groupLabel },\n propsGroupLabel,\n // 只是视觉上的标题:组名经各选项的 aria-describedby 念出\n { id: row.id, 'aria-hidden': true },\n )}\n >\n {row.label}\n </Text>\n ) : (\n optionRow(row)\n )}\n </div>\n );\n })}\n </div>\n );\n }\n\n return () => {\n const own = scroller === undefined;\n // 先不编译 sx:自己滚动时这些属性交给 ScrollArea 的视口,和视口自己的样式一次合并\n const props = mergeProps<'div'>(\n { sx: [listboxStyles.root, own && listboxStyles.scroll, focusRingStyles.visible] },\n rest,\n {\n ref: _toRef(root),\n id,\n role: 'listbox',\n 'aria-multiselectable': multiple || undefined,\n 'aria-busy': loading || undefined,\n },\n );\n const body = [\n indicator.value && rows.length > 0 && (\n <div aria-hidden=\"true\" {...css.attrs(listboxStyles.progress)}>\n <Progress size=\"xs\" aria-label={lang.loading} />\n </div>\n ),\n renderBody(),\n ];\n // 别处滚动(Select、Combobox 的弹出层):只渲染列表本身\n if (!own) return <div {...elementProps(props)}>{body}</div>;\n // 自己滚动:列表元素就是 ScrollArea 的视口,焦点与 aria-activedescendant 仍在它上面,滚动条换成浮层的\n return (\n <ScrollArea focusable={false} propsViewport={props as PartProps<'div'>}>\n {body}\n </ScrollArea>\n );\n };\n },\n { name: 'ListboxView' },\n);\n\n/** 高亮项的 id(给 aria-activedescendant);没有高亮时 undefined */\nexport function activeOptionId<T>(list: ListState<T>, id: string): string | undefined {\n const index = list.active === undefined ? -1 : list.indexOf(list.active);\n return index < 0 ? undefined : `${id}-${index}`;\n}\n\n/** 列表框共有的属性;未声明的属性落到 role=\"listbox\" 的 div 上 */\nexport interface ListboxBaseProps<T> extends Omit<\n ListboxViewProps<T>,\n 'list' | 'id' | 'multiple' | 'renderOption'\n> {\n /** 列表的 id;在 Field 里时默认用 Field 给的 */\n id?: string;\n /** 数据:ListboxOption、字符串,或任意数据加 toOption */\n items: readonly T[];\n /** 必须有选中项:单选时再点已选项不取消;在必填的 Field 里默认开启 */\n required?: boolean;\n /** 不可用 */\n disabled?: boolean;\n /** 自定义选项内容:`{(item, { selected, active }) => …}`,拿到 items 里的原始数据 */\n children?: (item: T, state: OptionRenderState) => VNodeChild;\n}\n\n/** 单选或多选;items 不是 ListboxOption 或字符串时要给 toOption */\nexport type ListboxProps<T = ListboxOption> = ListboxBaseProps<T> &\n SelectionProps &\n OptionMapping<T>;\n\n/** 列表框:焦点在列表上,方向键移动高亮、Enter / 空格选中 */\nexport const Listbox = _component(\n <T,>({\n items,\n toOption,\n selectionMode = 'single',\n _value: value = _bindable<string | string[] | null>(null),\n required,\n disabled,\n id,\n children,\n onPick,\n ...rest\n }: ListboxProps<T>) => {\n const generatedId = useId();\n const control = useFieldControl(() => ({ id, disabled, required }));\n const list = useListState({\n items: () => items,\n toOption: (item) => toListboxOption(item, toOption),\n selected: () => selectedValues(value),\n mode: () => selectionMode,\n required: () => control().required,\n onChange: (next) => (value = selectionMode === 'multiple' ? [...next] : (next[0] ?? null)),\n });\n\n function onKeydown(event: KeyboardEvent) {\n if (control().disabled) return;\n if (handleListKeydown(list, event, { space: true, typeahead: true }, onPick)) {\n event.preventDefault();\n }\n }\n\n return () => {\n const state = control();\n const prefix = state.id ?? generatedId;\n return (\n <ListboxView\n {...mergePartProps<ListboxViewProps<T>>(\n {\n list,\n id: prefix,\n multiple: selectionMode === 'multiple',\n renderOption: children,\n onPick,\n },\n rest as Partial<ListboxViewProps<T>>,\n {\n id: prefix,\n tabindex: state.disabled ? -1 : 0,\n 'aria-labelledby': defaultLabelledBy(rest, state.labelledBy),\n 'aria-describedby': state.describedBy,\n 'aria-disabled': state.disabled || undefined,\n 'aria-required': state.required || undefined,\n 'aria-activedescendant': activeOptionId(list, prefix),\n onFocus: () => {\n if (list.active === undefined) list.activateDefault();\n },\n onKeydown,\n },\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 VNodeChild } from 'vue';
3
3
  import { type OpenChangeProps } from '../utils/dom/open-change';
4
4
  import { type PartProps } from '../utils/props';
@@ -11,7 +11,7 @@ import { useRemoteItems } from "./remote-items.js";
11
11
  import { caretAnchor } from "../utils/dom/caret.js";
12
12
  import { Fragment, createVNode, nextTick, ref, shallowRef, useId, watch } from "vue";
13
13
  import { _component, bindable, childrenProp, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
14
- import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
14
+ import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
15
15
  //#region src/input/Mentions.tsx
16
16
  /** 提及的弹出列表由组件管理 */
17
17
  /** Mentions 除 toOption 外的属性;未声明的属性落到 textarea 上(同 Textarea) */