@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 VNodeChild } from 'vue';
3
3
  import { type TextProps } from '../base/Text';
4
4
  import { type FlexProps } from '../layout/Flex';
@@ -9,7 +9,7 @@ import { useScrollSpy } from "../utils/dom/scroll-spy.js";
9
9
  import { useActiveIndicator } from "../utils/motion/active-indicator.js";
10
10
  import { createVNode, shallowRef, useId } from "vue";
11
11
  import { _component, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
12
- import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
12
+ import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
13
13
  //#region src/navigation/TableOfContents.tsx
14
14
  /** 未声明的属性落到 nav 上;原生的 title 属性(悬停提示)让给目录的标题 */
15
15
  /** TableOfContents 的样式:title、list、indicator、link、current */
@@ -1 +1 @@
1
- {"version":3,"file":"TableOfContents.js","names":["_vtp_readonlyProp","_vtp_restProps","_vue_shallowRef","_createVNode","Text","_mergeProps"],"sources":["../../src/navigation/TableOfContents.tsx"],"sourcesContent":["/**\n * 本页目录:列出页面的各节标题,滚动时高亮正在读的一节(useScrollSpy),侧边的指示条滑过去(useActiveIndicator)。\n *\n * <TableOfContents items={[{ id: 'install', label: '安装', level: 2 }, …]} />\n *\n * 目录项可以手写,也可以在页面渲染后用 collectHeadings(article) 从带 id 的标题收集。\n * 链接是普通的页内锚点(#install):标题的 scroll-margin 让开粘性顶栏(layoutVars.stickyOffset)。\n * 当前节的链接带 aria-current=\"location\"。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { useId, type VNodeChild } from 'vue';\nimport { Text, type TextProps } from '../base/Text';\nimport { useLang } from '../config/context';\nimport { FlexList, type FlexProps } from '../layout/Flex';\nimport { toElement } from '../utils/dom/element';\nimport { useScrollSpy, type HeadingEntry } from '../utils/dom/scroll-spy';\nimport { useActiveIndicator } from '../utils/motion/active-indicator';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { focusRingStyles } from '../utils/style/styles';\nimport { t } from '../config/theme/tokens';\n\n/** 未声明的属性落到 nav 上;原生的 title 属性(悬停提示)让给目录的标题 */\nexport interface TableOfContentsProps extends PartProps<'nav', 'aria-labelledby' | 'title'> {\n /** 目录项:标题的 id、文字与级别(2 级起,每深一级多缩进一档) */\n items: readonly HeadingEntry[];\n /** 目录的标题,同时是导航的名称;默认取语言包(本页目录) */\n title?: VNodeChild;\n /** 页面在哪个容器里滚动;不写时是窗口 */\n scrollRoot?: HTMLElement | null;\n /** 标题的部件属性 */\n propsTitle?: Partial<TextProps>;\n /** 列表(ul)的部件属性 */\n propsList?: Partial<FlexProps<'ul'>>;\n /** 链接的部件属性 */\n propsLink?: PartProps<'a'>;\n}\n\n/** TableOfContents 的样式:title、list、indicator、link、current */\nexport const tableOfContentsStyles = css.create({\n title: { display: 'block', marginBlockEnd: '_sm' },\n // 指示条按链接的 offsetTop 定位:列表是它的定位容器\n list: {\n position: 'relative',\n borderInlineStartWidth: '_xs',\n borderInlineStartStyle: 'solid',\n borderInlineStartColor: '_border',\n },\n indicator: {\n position: 'absolute',\n insetBlockStart: 0,\n insetInlineStart: 0,\n // 盖住列表左边的细线\n marginInlineStart: `calc(-1 * ${t.borderWidths.xs})`,\n width: '_borderWidths.sm',\n borderRadius: '_full',\n backgroundColor: '_accent',\n },\n link: {\n display: 'block',\n paddingBlock: '_xs',\n paddingInlineEnd: '_xs',\n borderRadius: '_xs',\n color: { default: '_textMuted', ':hover': '_text' },\n fontSize: '_sm',\n lineHeight: '_snug',\n textDecoration: 'none',\n transition: `color ${t.durations.sm} ${t.easings.standard}`,\n },\n current: { color: { default: '_accentText', ':hover': '_accentText' } },\n // 按级别缩进:2 级贴着细线留一档,往下每级多一档\n indent: (level: number) => ({ paddingInlineStart: `calc(${Math.max(level - 1, 1)} * 0.75em)` }),\n});\n\n/** 本页目录(nav):滚动时高亮当前节 */\nexport const TableOfContents = _component(\n ({\n items,\n title,\n scrollRoot,\n propsTitle,\n propsList,\n propsLink,\n ...rest\n }: TableOfContentsProps) => {\n const lang = useLang();\n const titleId = useId();\n let list = _state.raw<HTMLElement | null>(null);\n let indicator = _state.raw<HTMLElement | null>(null);\n const current = useScrollSpy(() => ({\n ids: items.map((item) => item.id),\n root: scrollRoot,\n }));\n useActiveIndicator(() => ({\n container: list,\n indicator,\n active: '[aria-current=\"location\"]',\n axis: 'vertical',\n value: current.value,\n }));\n\n return () => (\n <nav {...mergeAttrs<'nav'>({}, rest, { 'aria-labelledby': titleId })}>\n <Text\n {...mergePartProps<TextProps>(\n { sx: tableOfContentsStyles.title, size: 'sm', weight: 'semibold' },\n propsTitle,\n { id: titleId },\n )}\n >\n {title ?? lang.tableOfContents}\n </Text>\n <FlexList\n {...mergePartProps<FlexProps<'ul'>>(\n { sx: tableOfContentsStyles.list, direction: 'column' },\n propsList,\n { ref: (value: unknown) => (list = toElement(value)) },\n )}\n >\n {current.value !== undefined && (\n <span\n {...mergeAttrs<'span'>({ sx: tableOfContentsStyles.indicator })}\n ref={_toRef(indicator)}\n aria-hidden=\"true\"\n />\n )}\n {items.map((item) => (\n <li key={item.id}>\n <a\n {...mergeAttrs<'a'>(\n {\n sx: [\n tableOfContentsStyles.link,\n tableOfContentsStyles.indent(item.level),\n current.value === item.id && tableOfContentsStyles.current,\n focusRingStyles.visible,\n ],\n },\n propsLink,\n {\n href: `#${item.id}`,\n 'aria-current': current.value === item.id ? 'location' : undefined,\n },\n )}\n >\n {item.label}\n </a>\n </li>\n ))}\n </FlexList>\n </nav>\n );\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"TableOfContents.js","names":["_vtp_readonlyProp","_vtp_restProps","_vue_shallowRef","_createVNode","Text","_mergeProps"],"sources":["../../src/navigation/TableOfContents.tsx"],"sourcesContent":["/**\n * 本页目录:列出页面的各节标题,滚动时高亮正在读的一节(useScrollSpy),侧边的指示条滑过去(useActiveIndicator)。\n *\n * <TableOfContents items={[{ id: 'install', label: '安装', level: 2 }, …]} />\n *\n * 目录项可以手写,也可以在页面渲染后用 collectHeadings(article) 从带 id 的标题收集。\n * 链接是普通的页内锚点(#install):标题的 scroll-margin 让开粘性顶栏(layoutVars.stickyOffset)。\n * 当前节的链接带 aria-current=\"location\"。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { useId, type VNodeChild } from 'vue';\nimport { Text, type TextProps } from '../base/Text';\nimport { useLang } from '../config/context';\nimport { FlexList, type FlexProps } from '../layout/Flex';\nimport { toElement } from '../utils/dom/element';\nimport { useScrollSpy, type HeadingEntry } from '../utils/dom/scroll-spy';\nimport { useActiveIndicator } from '../utils/motion/active-indicator';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { focusRingStyles } from '../utils/style/styles';\nimport { t } from '../config/theme/tokens';\n\n/** 未声明的属性落到 nav 上;原生的 title 属性(悬停提示)让给目录的标题 */\nexport interface TableOfContentsProps extends PartProps<'nav', 'aria-labelledby' | 'title'> {\n /** 目录项:标题的 id、文字与级别(2 级起,每深一级多缩进一档) */\n items: readonly HeadingEntry[];\n /** 目录的标题,同时是导航的名称;默认取语言包(本页目录) */\n title?: VNodeChild;\n /** 页面在哪个容器里滚动;不写时是窗口 */\n scrollRoot?: HTMLElement | null;\n /** 标题的部件属性 */\n propsTitle?: Partial<TextProps>;\n /** 列表(ul)的部件属性 */\n propsList?: Partial<FlexProps<'ul'>>;\n /** 链接的部件属性 */\n propsLink?: PartProps<'a'>;\n}\n\n/** TableOfContents 的样式:title、list、indicator、link、current */\nexport const tableOfContentsStyles = css.create({\n title: { display: 'block', marginBlockEnd: '_sm' },\n // 指示条按链接的 offsetTop 定位:列表是它的定位容器\n list: {\n position: 'relative',\n borderInlineStartWidth: '_xs',\n borderInlineStartStyle: 'solid',\n borderInlineStartColor: '_border',\n },\n indicator: {\n position: 'absolute',\n insetBlockStart: 0,\n insetInlineStart: 0,\n // 盖住列表左边的细线\n marginInlineStart: `calc(-1 * ${t.borderWidths.xs})`,\n width: '_borderWidths.sm',\n borderRadius: '_full',\n backgroundColor: '_accent',\n },\n link: {\n display: 'block',\n paddingBlock: '_xs',\n paddingInlineEnd: '_xs',\n borderRadius: '_xs',\n color: { default: '_textMuted', ':hover': '_text' },\n fontSize: '_sm',\n lineHeight: '_snug',\n textDecoration: 'none',\n transition: `color ${t.durations.sm} ${t.easings.standard}`,\n },\n current: { color: { default: '_accentText', ':hover': '_accentText' } },\n // 按级别缩进:2 级贴着细线留一档,往下每级多一档\n indent: (level: number) => ({ paddingInlineStart: `calc(${Math.max(level - 1, 1)} * 0.75em)` }),\n});\n\n/** 本页目录(nav):滚动时高亮当前节 */\nexport const TableOfContents = _component(\n ({\n items,\n title,\n scrollRoot,\n propsTitle,\n propsList,\n propsLink,\n ...rest\n }: TableOfContentsProps) => {\n const lang = useLang();\n const titleId = useId();\n let list = _state.raw<HTMLElement | null>(null);\n let indicator = _state.raw<HTMLElement | null>(null);\n const current = useScrollSpy(() => ({\n ids: items.map((item) => item.id),\n root: scrollRoot,\n }));\n useActiveIndicator(() => ({\n container: list,\n indicator,\n active: '[aria-current=\"location\"]',\n axis: 'vertical',\n value: current.value,\n }));\n\n return () => (\n <nav {...mergeAttrs<'nav'>({}, rest, { 'aria-labelledby': titleId })}>\n <Text\n {...mergePartProps<TextProps>(\n { sx: tableOfContentsStyles.title, size: 'sm', weight: 'semibold' },\n propsTitle,\n { id: titleId },\n )}\n >\n {title ?? lang.tableOfContents}\n </Text>\n <FlexList\n {...mergePartProps<FlexProps<'ul'>>(\n { sx: tableOfContentsStyles.list, direction: 'column' },\n propsList,\n { ref: (value: unknown) => (list = toElement(value)) },\n )}\n >\n {current.value !== undefined && (\n <span\n {...mergeAttrs<'span'>({ sx: tableOfContentsStyles.indicator })}\n ref={_toRef(indicator)}\n aria-hidden=\"true\"\n />\n )}\n {items.map((item) => (\n <li key={item.id}>\n <a\n {...mergeAttrs<'a'>(\n {\n sx: [\n tableOfContentsStyles.link,\n tableOfContentsStyles.indent(item.level),\n current.value === item.id && tableOfContentsStyles.current,\n focusRingStyles.visible,\n ],\n },\n propsLink,\n {\n href: `#${item.id}`,\n 'aria-current': current.value === item.id ? 'location' : undefined,\n },\n )}\n >\n {item.label}\n </a>\n </li>\n ))}\n </FlexList>\n </nav>\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 IconButtonProps } from '../base/IconButton';
4
4
  import { type PartProps } from '../utils/props';
@@ -19,7 +19,7 @@ import { Menu as Menu$1, MenuRadioGroup, MenuRadioItem } from "../overlay/Menu.j
19
19
  import { useActiveIndicator } from "../utils/motion/active-indicator.js";
20
20
  import { computed, createVNode, isVNode, nextTick, onBeforeUnmount, ref, shallowRef, useId, watch } from "vue";
21
21
  import { _component, bindable, childrenProp, createContext, effect, forwardChildren, mergeJsxProps, readonlyProp, restProps, untrack } from "@zerodep-dev/vue-tsx-pro-tsx";
22
- import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
22
+ import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
23
23
  import { ChevronDown, ChevronLeft, ChevronRight, Plus, X } from "@lucide/icons";
24
24
  //#region src/navigation/Tabs.tsx
25
25
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"Tabs.js","names":["_isVNode","_vtp_bindable","_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_vue_shallowRef","_vue_ref","_vue_computed","_createVNode","_mergeProps","Menu","_vtp_untrack","_vtp_forwardChildren"],"sources":["../../src/navigation/Tabs.tsx"],"sourcesContent":["/**\n * 标签页(WAI-ARIA 的 Tabs 模式),复合组件:Tabs(状态)> TabList(role=\"tablist\")> Tab(role=\"tab\"),\n * 加上与每个 Tab 对应的 TabPanel(role=\"tabpanel\")。各层都是独立的组件,可以自由排版、各自加属性。\n *\n * <Tabs _value={tab}>\n * <TabList aria-label=\"订单\">\n * <Tab value=\"all\">全部</Tab>\n * <Tab value=\"paid\">已付款</Tab>\n * </TabList>\n * <TabPanel value=\"all\">…</TabPanel>\n * <TabPanel value=\"paid\">…</TabPanel>\n * </Tabs>\n *\n * 键盘:标签之间用方向键移动(漫游焦点,整组一个 Tab 位置),Home / End 到两端;\n * activation=\"automatic\"(默认)时焦点移到哪个标签就切换到哪个,\"manual\" 时按 Enter / 空格才切换。\n *\n * line 样式的下划线是 TabList 里的一个指示条(Indicator):跟着当前标签走(useActiveIndicator:\n * 切换时用 Anime.js 滑过去,时长取主题,减少动态效果时直接到位;尺寸变化时直接对齐)。\n */\nimport { ChevronDown, ChevronLeft, ChevronRight, Plus, X } from '@lucide/icons';\nimport { createContext, _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { nextTick, onBeforeUnmount, useId, watch, type VNodeChild } from 'vue';\nimport { ButtonBase, type ButtonBaseProps } from '../base/ButtonBase';\nimport { IconButton, type IconButtonProps } from '../base/IconButton';\nimport { useLang } from '../config/context';\nimport { useDefaults } from '../config/defaults';\nimport { useRecipe } from '../config/styles';\nimport { useActiveIndicator } from '../utils/motion/active-indicator';\nimport { useLazyContent } from '../utils/motion/presence';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { Menu, MenuRadioGroup, MenuRadioItem } from '../overlay/Menu';\nimport { plainText } from '../utils/data/text';\nimport { announce } from '../utils/dom/announcer';\nimport { inlineArrows, isRtl } from '../utils/dom/direction';\nimport { batchLayout } from '../utils/dom/layout-batch';\nimport { startMove } from '../utils/dom/move';\nimport { useResizeObserver } from '../utils/dom/resize';\nimport { rovingFocus } from '../utils/dom/roving-focus';\nimport { focusRingStyles } from '../utils/style/styles';\nimport { fontSizeStyles, type TextSize } from '../utils/style/typography';\nimport { t } from '../config/theme/tokens';\n\n/** 标签的排列方向 */\nexport interface TabsOrientations {\n /** 横排(默认),左右键切换 */\n horizontal: unknown;\n /** 竖排(标签在左侧),上下键切换 */\n vertical: unknown;\n}\n\n/** 焦点移动时是否同时切换 */\nexport interface TabsActivations {\n /** 焦点移到哪个标签就显示哪个面板(默认):面板内容轻量时用 */\n automatic: unknown;\n /** 方向键只移动焦点,按 Enter / 空格才切换:切换面板代价大(要请求数据)时用 */\n manual: unknown;\n}\n\n/** 标签的样式 */\nexport interface TabsVariants {\n /** 下划线(默认):当前标签下方一条品牌色的线 */\n line: unknown;\n /** 浅色底:当前标签有浅色底,像分段控件 */\n soft: unknown;\n}\n\n/** Tabs 的外观选项;可以用 createUi / Provider 的 defaults.Tabs 统一改默认值 */\nexport interface TabsOptions {\n /** 样式,默认 line */\n variant?: keyof TabsVariants;\n /** 字号档位,不写时继承 */\n size?: TextSize;\n}\n\n/** Tabs 交给 TabList、Tab、TabPanel 的状态 */\nexport interface TabsState {\n /** 当前标签的值 */\n readonly value: string | undefined;\n /** 横排或竖排 */\n readonly orientation: keyof TabsOrientations;\n /** 方向键移动焦点时是否同时切换 */\n readonly activation: keyof TabsActivations;\n /** 样式 */\n readonly variant: keyof TabsVariants;\n /** 面板第一次显示时才渲染 */\n readonly lazy: boolean;\n /** 波纹;不写时沿用配置 */\n readonly ripple: boolean | undefined;\n /** 切换到某个标签 */\n select(value: string): void;\n /** 标签与面板的 id,互相引用 */\n id(part: 'tab' | 'panel', value: string): string;\n /**\n * 登记标签(按渲染顺序)与它的文字,没有选中值时选第一个;返回注销函数\n * (参数是注销时各标签显示的顺序,关掉当前标签时按它选旁边的)\n */\n register(value: string, label: () => string): (order?: readonly string[]) => void;\n /** 标签的文字(“全部标签页”菜单用) */\n label(value: string): string;\n /** 登记面板;返回注销函数 */\n registerPanel(value: string): () => void;\n /** 这个标签有没有对应的面板:只当导航用的标签(没有 TabPanel)不写 aria-controls */\n hasPanel(value: string): boolean;\n /** 登记了的标签,按渲染顺序 */\n readonly values: readonly string[];\n /** 正在拖动的标签 */\n readonly dragging: string | undefined;\n /** 开始、结束拖动 */\n setDragging(value: string | undefined): void;\n /** 关闭了有焦点的标签:等选中的标签换好之后,把焦点交给它 */\n refocus(): void;\n}\n\n/** Tabs 的上下文:自定义的标签或面板可以 inject 它 */\nexport const TabsContext = createContext<TabsState>('Tabs');\n\n/** 值里的空格等字符不能出现在 id 里 */\nconst idSafe = (value: string) => value.replace(/[^\\w-]/g, '_');\n\n// ─────────────── Tabs ───────────────\n\n/** 未声明的属性落到外层 div 上 */\nexport interface TabsProps extends PartProps<'div'>, TabsOptions {\n /** 当前标签的 value:父级写 _value={x};不写时默认第一个标签 */\n _value?: string;\n /** 方向,默认 horizontal */\n orientation?: keyof TabsOrientations;\n /** 焦点移动时是否同时切换,默认 automatic */\n activation?: keyof TabsActivations;\n /** 面板第一次显示时才渲染,之后切走也保留(面板内容重时用) */\n lazy?: boolean;\n /** 标签按下时的波纹;不写时沿用全局配置 */\n ripple?: boolean;\n children?: VNodeChild;\n}\n\n/** Tabs 的样式:root、vertical */\nexport const tabsStyles = css.create({\n // 能收缩:放在顶栏这类一行里时,列表放不下就在列表里滚动\n root: { display: 'flex', flexDirection: 'column', gap: '_md', minWidth: 0 },\n vertical: { flexDirection: 'row', alignItems: 'flex-start' },\n});\n\n/** 标签页的状态容器:管理当前值,并把它交给 TabList、Tab、TabPanel */\nexport const Tabs = _component(\n ({\n _value: value = _bindable<string | undefined>(undefined),\n orientation = 'horizontal',\n activation = 'automatic',\n variant,\n size,\n lazy = false,\n ripple,\n children,\n ...rest\n }: TabsProps) => {\n const appearance = useDefaults('Tabs', () => ({ variant, size }), { variant: 'line' });\n const baseId = useId();\n let registered = _state.raw<string[]>([]);\n let panels = _state.raw<string[]>([]);\n let dragging = _state<string | undefined>(undefined);\n // 各标签的文字:读的是 Tab 的子内容,跟着它变\n const labels = new Map<string, () => string>();\n const current = _derived(value ?? registered[0]);\n const tabId = (tab: string) => `${baseId}-tab-${idSafe(tab)}`;\n\n TabsContext.provide({\n get value() {\n return current;\n },\n get orientation() {\n return orientation;\n },\n get activation() {\n return activation;\n },\n get variant() {\n return appearance().variant;\n },\n get lazy() {\n return lazy;\n },\n get ripple() {\n return ripple;\n },\n select: (next) => (value = next),\n id: (part, tab) => (part === 'tab' ? tabId(tab) : `${baseId}-${part}-${idSafe(tab)}`),\n register(tab, label) {\n registered = [...registered, tab];\n labels.set(tab, label);\n return (order = registered) => {\n registered = registered.filter((item) => item !== tab);\n labels.delete(tab);\n if (current !== tab) return;\n // 关掉的是当前标签(使用方没有另选):按显示的顺序选它后面的一个,没有时选前面的一个\n const index = order.indexOf(tab);\n const rest = order.filter((item) => item !== tab && registered.includes(item));\n value = rest[Math.min(Math.max(index, 0), rest.length - 1)];\n };\n },\n registerPanel(tab) {\n panels = [...panels, tab];\n return () => (panels = panels.filter((item) => item !== tab));\n },\n hasPanel: (tab) => panels.includes(tab),\n label: (tab) => labels.get(tab)?.() ?? tab,\n get values() {\n return registered;\n },\n get dragging() {\n return dragging;\n },\n setDragging: (next) => (dragging = next),\n refocus: () =>\n void nextTick(() => {\n if (current !== undefined) document.getElementById(tabId(current))?.focus();\n }),\n });\n\n return () => (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n tabsStyles.root,\n orientation === 'vertical' && tabsStyles.vertical,\n appearance().size && fontSizeStyles[appearance().size!],\n ],\n },\n rest,\n )}\n data-orientation={orientation}\n >\n {children}\n </div>\n );\n },\n);\n\n// ─────────────── TabList ───────────────\n\n/** 角色、方向由组件管理 */\nexport type TabListManaged = 'role' | 'aria-orientation';\n\n/** 未声明的属性落到 role=\"tablist\" 的 div 上;aria-label 是这组标签的名称 */\nexport interface TabListProps extends PartProps<'div', TabListManaged> {\n /** 到两端后是否从另一端继续,默认 true */\n loop?: boolean;\n /** 列表末尾的“新建标签页”按钮:点了调用 */\n onAdd?: () => void;\n /**\n * 拖动标签(或在标签上按 Alt + ←→)改变顺序:参数是新的顺序(各标签的 value),使用方按它重排;\n * 不写时不能拖\n */\n onReorder?: (values: string[]) => void;\n /** 标签栏右边“全部标签页”的菜单(标签多、放不下时一眼找到并切过去) */\n showAllMenu?: boolean;\n /** line 样式的下划线指示条的部件属性 */\n propsIndicator?: PartProps<'span'>;\n /** 横排时包着标签列表与右边按钮的那一层的部件属性 */\n propsBar?: PartProps<'div'>;\n /** “新建标签页”按钮的部件属性 */\n propsAdd?: Partial<IconButtonProps>;\n children?: VNodeChild;\n}\n\n/** TabList 的样式:bar、barLine、root、scrollable、line、lineVertical、soft、softVertical、indicator、indicatorVertical */\nexport const tabListStyles = css.create({\n // 横排时包着标签列表与右边的按钮(滚动、全部标签页、新建):列表按内容宽,放不下时收缩并滚动\n bar: { display: 'flex', alignItems: 'center', gap: '_xs', minWidth: 0 },\n // 横排 line 的分隔线画在整行上:标签少时也铺满(页签区、页面顶部的标签)\n barLine: {\n borderBottomWidth: '_xs',\n borderBottomStyle: 'solid',\n borderBottomColor: '_borderMuted',\n },\n root: { display: 'flex', flexShrink: 0 },\n // 横排放不下时(顶栏、窄屏)在列表里横向滚动,不盖到旁边的内容上;滚动条藏起来,触控板、拖动照样能滚\n scrollable: {\n flexShrink: 1,\n minWidth: 0,\n overflowX: 'auto',\n overflowY: 'hidden',\n scrollbarWidth: 'none',\n },\n // 指示条按标签的 offsetLeft / offsetTop 定位,列表要是它的定位容器\n line: { position: 'relative', gap: '_md' },\n lineVertical: {\n flexDirection: 'column',\n gap: '_xs',\n borderInlineEndWidth: '_xs',\n borderInlineEndStyle: 'solid',\n borderInlineEndColor: '_borderMuted',\n },\n soft: { gap: '_xs', padding: '_xs', borderRadius: '_md', backgroundColor: '_fill' },\n softVertical: { flexDirection: 'column' },\n // 一条 2px 的品牌色线,压在列表的分隔线上;位置与长度由脚本写(transform 与 width/height)\n indicator: {\n position: 'absolute',\n left: 0,\n // 压在列表底边的分隔线上(滚动的列表会裁掉伸出去的部分,所以放在边框内侧)\n bottom: 0,\n width: 0,\n height: '_borderWidths.sm',\n borderRadius: '_sm',\n backgroundColor: '_accent',\n pointerEvents: 'none',\n },\n indicatorVertical: {\n left: 'auto',\n bottom: 'auto',\n top: 0,\n insetInlineEnd: `calc(-1 * ${t.borderWidths.xs})`,\n width: '_borderWidths.sm',\n height: 0,\n },\n});\n\n/** 列表里各标签的 value,按显示的顺序(拖动排序后组件的登记顺序不再是显示顺序) */\nconst tabOrder = (list: Element | null | undefined) =>\n [...(list?.querySelectorAll<HTMLElement>('[role=\"tab\"]') ?? [])].map((tab) => tab.dataset.value!);\n\n/** 标签列表(role=\"tablist\"):方向键在标签之间移动;横排放不下时有滚动按钮,可以拖动排序、新建 */\nexport const TabList = _component(\n ({\n loop = true,\n onAdd,\n onReorder,\n showAllMenu = false,\n propsIndicator,\n propsBar,\n propsAdd,\n children,\n ...rest\n }: TabListProps) => {\n const lang = useLang();\n const tabs = TabsContext.inject();\n let list = _state.raw<HTMLElement | null>(null);\n let indicator = _state.raw<HTMLElement | null>(null);\n // 横排放不下时:能不能往前、往后滚(滚动按钮)\n let overflow = _state.raw({ overflowing: false, start: false, end: false });\n _effect(() =>\n list\n ? rovingFocus(list, { items: '[role=\"tab\"]', orientation: tabs.orientation, loop })\n : undefined,\n );\n\n useActiveIndicator(() => ({\n container: list,\n indicator,\n active: '[role=\"tab\"][aria-selected=\"true\"]',\n axis: tabs.orientation,\n value: tabs.value,\n }));\n\n function measure() {\n batchLayout(() => {\n if (!list || tabs.orientation === 'vertical') return;\n // 从右到左排版时 scrollLeft 是负的:取绝对值就是离起始端多远\n const scrolled = Math.abs(list.scrollLeft);\n const max = list.scrollWidth - list.clientWidth;\n const next = { overflowing: max > 1, start: scrolled > 1, end: scrolled < max - 1 };\n return () => {\n if (Object.entries(next).some(([key, value]) => overflow[key as 'start'] !== value))\n overflow = next;\n };\n });\n }\n useResizeObserver(\n () => (list ? [list, ...list.querySelectorAll<HTMLElement>('[role=\"tab\"]')] : []),\n measure,\n );\n watch(() => tabs.values.length, measure, { flush: 'post' });\n\n // 切到一个滚到外面的标签(方向键、菜单、程序):把它滚进来\n watch(\n () => tabs.value,\n (value) => {\n const tab = value === undefined ? null : document.getElementById(tabs.id('tab', value));\n if (!list || !tab || list.scrollWidth <= list.clientWidth) return;\n const outer = list.getBoundingClientRect();\n const inner = tab.getBoundingClientRect();\n if (inner.left < outer.left) list.scrollBy({ left: inner.left - outer.left - 16 });\n else if (inner.right > outer.right) list.scrollBy({ left: inner.right - outer.right + 16 });\n },\n { flush: 'post' },\n );\n\n /** 滚动按钮:往前(-1)或往后(1)滚大半屏 */\n function scrollBy(direction: 1 | -1) {\n if (!list) return;\n const sign = isRtl(list) ? -direction : direction;\n list.scrollBy({ left: sign * list.clientWidth * 0.8, behavior: 'smooth' });\n }\n\n /** 把 value 移到 to(按显示的顺序),交给使用方重排;键盘移动时告诉读屏 */\n function moveTab(value: string, to: number, announceMove: boolean) {\n const order = tabOrder(list);\n const from = order.indexOf(value);\n if (!onReorder || from < 0 || to < 0 || to >= order.length || to === from) return;\n const next = order.filter((item) => item !== value);\n next.splice(to, 0, value);\n onReorder(next);\n if (!announceMove) return;\n const label = document.getElementById(tabs.id('tab', value))?.textContent ?? value;\n announce(lang.tabMoved(label, to + 1, order.length));\n // 标签的元素被移动过:焦点放回它上面\n void nextTick(() => document.getElementById(tabs.id('tab', value))?.focus());\n }\n\n // 拖动排序:越过别的标签的中线就换位(同 Sortable);触摸时照常横向滚动\n function onPointerdown(event: PointerEvent) {\n const target = event.target as Element;\n const tab = target.closest<HTMLElement>('[role=\"tab\"]');\n if (!onReorder || !tab || !list || event.pointerType === 'touch') return;\n const value = tab.dataset.value!;\n startMove(event, {\n threshold: 4,\n // 标签的元素会被重排:捕获在不动的列表上\n captureTarget: list,\n onMove: ({ clientX }) => {\n tabs.setDragging(value);\n const order = tabOrder(list);\n const from = order.indexOf(value);\n const over = [...list!.querySelectorAll<HTMLElement>('[role=\"tab\"]')].find((item) => {\n const rect = item.getBoundingClientRect();\n return clientX >= rect.left && clientX <= rect.right;\n });\n const to = over ? order.indexOf(over.dataset.value!) : -1;\n if (!over || to === from) return;\n const rect = over.getBoundingClientRect();\n const center = rect.left + rect.width / 2;\n // 按书写方向“越过中线”:往后挪时要过了它的中线,往前挪时要回到中线之前\n const past = isRtl(list!) ? clientX < center : clientX > center;\n if (to > from === past) moveTab(value, to, false);\n },\n onEnd: () => tabs.setDragging(undefined),\n });\n }\n\n // 键盘替代拖动:在标签上按 Alt + ←→ 往前、往后挪一位(从右到左排版时反过来)\n function onKeydown(event: KeyboardEvent) {\n if (!onReorder || !event.altKey || event.ctrlKey || event.metaKey || !list) return;\n const tab = (event.target as Element).closest<HTMLElement>('[role=\"tab\"]');\n const { forward, backward } = inlineArrows(isRtl(list));\n if (!tab || (event.key !== forward && event.key !== backward)) return;\n event.preventDefault();\n const value = tab.dataset.value!;\n const from = tabOrder(list).indexOf(value);\n moveTab(value, from + (event.key === forward ? 1 : -1), true);\n }\n\n /** “全部标签页”菜单:按显示的顺序(刚加上、还没渲染出来的排在最后)列出标签的文字 */\n function renderAllMenu() {\n const shown = tabOrder(list).filter((value) => tabs.values.includes(value));\n const order = [...shown, ...tabs.values.filter((value) => !shown.includes(value))];\n const items = order.map((value) => ({ value, label: tabs.label(value) }));\n return (\n <Menu\n trigger={(props) => (\n <IconButton\n {...props}\n icon={ChevronDown}\n size=\"sm\"\n variant=\"ghost\"\n aria-label={lang.tabList}\n />\n )}\n placement=\"bottom-end\"\n >\n <MenuRadioGroup\n label={lang.tabList}\n _value={tabs.value ?? ''}\n onUpdate:_value={(next: string) => tabs.select(next)}\n >\n {items.map((item) => (\n <MenuRadioItem key={item.value} value={item.value}>\n {item.label}\n </MenuRadioItem>\n ))}\n </MenuRadioGroup>\n </Menu>\n );\n }\n\n return () => {\n const vertical = tabs.orientation === 'vertical';\n const tablist = (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n tabListStyles.root,\n !vertical && tabListStyles.scrollable,\n tabs.variant === 'line'\n ? [tabListStyles.line, vertical && tabListStyles.lineVertical]\n : [tabListStyles.soft, vertical && tabListStyles.softVertical],\n ],\n },\n rest,\n {\n ref: _toRef(list),\n role: 'tablist',\n 'aria-orientation': tabs.orientation,\n onScroll: measure,\n onPointerdown,\n onKeydown,\n },\n )}\n >\n {children}\n {tabs.variant === 'line' && (\n <span\n {...mergeAttrs<'span'>(\n { sx: [tabListStyles.indicator, vertical && tabListStyles.indicatorVertical] },\n propsIndicator,\n { ref: _toRef(indicator), 'aria-hidden': true },\n )}\n />\n )}\n </div>\n );\n if (vertical) return tablist;\n // 滚动按钮只给指针用:键盘在标签之间移动时,当前标签会自己滚进来\n const scrollButton = (direction: 1 | -1) =>\n overflow.overflowing && (\n <IconButton\n icon={direction === 1 ? ChevronRight : ChevronLeft}\n propsIcon={{ flipInRtl: true }}\n size=\"sm\"\n variant=\"ghost\"\n tabindex={-1}\n aria-label={direction === 1 ? lang.tabScrollNext : lang.tabScrollPrevious}\n disabled={direction === 1 ? !overflow.end : !overflow.start}\n onClick={() => scrollBy(direction)}\n />\n );\n return (\n <div\n {...mergeAttrs<'div'>(\n { sx: [tabListStyles.bar, tabs.variant === 'line' && tabListStyles.barLine] },\n propsBar,\n )}\n >\n {scrollButton(-1)}\n {tablist}\n {scrollButton(1)}\n {showAllMenu && renderAllMenu()}\n {onAdd && (\n <IconButton\n {...mergePartProps<IconButtonProps>(\n { icon: Plus, size: 'sm', variant: 'ghost', 'aria-label': lang.tabAdd },\n propsAdd,\n { onClick: onAdd },\n )}\n />\n )}\n </div>\n );\n };\n },\n);\n\n// ─────────────── Tab ───────────────\n\n/** 角色、选中、关联与可聚焦由组件管理 */\nexport type TabManaged =\n 'role' | 'aria-selected' | 'aria-controls' | 'id' | 'tabindex' | 'disabled';\n\n/** 未声明的属性落到 role=\"tab\" 的 button 上 */\nexport interface TabProps extends PartProps<'button', TabManaged> {\n /** 这个标签的值,与对应 TabPanel 的 value 相同 */\n value: string;\n /** 不可用:方向键跳过它 */\n disabled?: boolean;\n /**\n * 可以关闭:标签末尾有关闭按钮,标签上按 Delete、鼠标中键点也关闭。使用方移除这个标签;\n * 关掉的是当前标签时 Tabs 选它后面(没有时前面)的一个,焦点也跟过去\n */\n onClose?: () => void;\n /** 关闭按钮的部件属性 */\n propsClose?: Partial<IconButtonProps>;\n children?: VNodeChild;\n}\n\n/** Tabs 的样式:root、hover、line、lineVertical、lineActive、soft 等 */\n/**\n * 标签的配方:状态(选中、禁用、拖动中)由 DOM 上的 aria-selected、disabled、data-dragging 决定,\n * 样式、方向、可关闭是档位\n */\nexport const tabRecipe = css.recipe({\n name: 'Tab',\n parts: ['root', 'closeWrapper', 'close'],\n base: {\n // 去掉按钮默认外观、焦点环、波纹、颜色过渡由 ButtonBase 给出\n root: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '_sm',\n minHeight: `max(${t.sizes.control}, ${t.sizes.minTarget})`,\n paddingInline: '_md',\n color: { default: '_textMuted', _hover: '_text', _selected: '_text' },\n fontWeight: '_medium',\n whiteSpace: 'nowrap',\n borderRadius: '_sm',\n opacity: { default: null, _dragging: 0.6, _disabled: '_disabled' },\n },\n closeWrapper: { display: 'inline-grid', flexShrink: 0 },\n close: { gridArea: '1 / 1', justifySelf: 'end', alignSelf: 'center', marginInlineEnd: '_xs' },\n },\n variants: {\n variant: {\n // 下划线:当前标签的底边(竖排时是结束边)一条 2px 的品牌色线,压在列表的分隔线上;\n // 线由 TabList 的指示条画(切换时滑过去),标签自己只变文字颜色\n line: {\n root: {\n marginBottom: `calc(-1 * ${t.borderWidths.xs})`,\n borderBottomWidth: '_sm',\n borderBottomStyle: 'solid',\n borderBottomColor: 'transparent',\n },\n },\n soft: {\n root: {\n // 未选中时同 ButtonBase 的透明底:条件对象按属性整体覆盖前面的值,default 写 null 会露出原生按钮底色\n backgroundColor: { default: 'transparent', _selected: '_surface' },\n boxShadow: { default: null, _selected: '_xs' },\n },\n },\n },\n orientation: { horizontal: {}, vertical: {} },\n // 可关闭:标签与关闭按钮叠在同一个网格格子里,关闭按钮靠结束端,标签给它留出位置。\n // 不用定位:标签的 offsetParent 还得是列表,下划线指示条按它的 offsetLeft 对齐\n closable: {\n true: { root: { gridArea: '1 / 1', paddingInlineEnd: `calc(${t.space.md} + 1.25em)` } },\n },\n },\n compound: [\n {\n when: { variant: 'line', orientation: 'vertical' },\n root: {\n justifyContent: 'flex-start',\n marginBottom: 0,\n marginInlineEnd: `calc(-1 * ${t.borderWidths.xs})`,\n borderBottomWidth: 0,\n borderInlineEndWidth: '_sm',\n borderInlineEndStyle: 'solid',\n borderInlineEndColor: 'transparent',\n },\n },\n ],\n});\n\n/** 标签的部件(createUi / Provider 的 styles.Tab 按它定制) */\nexport type TabPart = (typeof tabRecipe.parts)[number];\n\n/** 标签(role=\"tab\" 的 button) */\nexport const Tab = _component(\n ({ value, disabled = false, onClose, propsClose, children, ...rest }: TabProps) => {\n const lang = useLang();\n const tabs = TabsContext.inject();\n const recipe = useRecipe(tabRecipe);\n const unregister = tabs.register(_untrack(value), () => plainText(children) || value);\n onBeforeUnmount(() => {\n const element = document.getElementById(tabs.id('tab', value));\n // 关掉的标签有焦点:等 Tabs 选好旁边的标签再把焦点交过去(元素一移除焦点就丢到 body 上了)\n if (element && element === document.activeElement) tabs.refocus();\n unregister(tabOrder(element?.closest('[role=\"tablist\"]')));\n });\n\n function onKeydown(event: KeyboardEvent) {\n if (event.key === 'Delete' && onClose && !disabled) {\n event.preventDefault();\n onClose();\n }\n }\n\n return () => {\n const selected = tabs.value === value;\n const styles = recipe({\n variant: tabs.variant,\n orientation: tabs.orientation,\n closable: !!onClose,\n });\n const tab = (\n <ButtonBase\n {...mergePartProps<ButtonBaseProps>(\n {\n ...styles.root,\n ripple: tabs.ripple,\n },\n rest as Partial<ButtonBaseProps>,\n {\n role: 'tab',\n id: tabs.id('tab', value),\n 'aria-selected': selected,\n 'aria-controls': tabs.hasPanel(value) ? tabs.id('panel', value) : undefined,\n disabled,\n // 使用方的 onClick / onFocus 先执行(mergeProps 的规则),onClick 里 preventDefault 可以拦下切换\n onClick: () => tabs.select(value),\n onFocus: () => {\n if (tabs.activation === 'automatic') tabs.select(value);\n },\n onKeydown,\n 'aria-keyshortcuts': onClose ? 'Delete' : undefined,\n // 鼠标中键关闭(同浏览器的标签页)\n onAuxclick: (event: MouseEvent) => {\n if (event.button === 1 && onClose && !disabled) onClose();\n },\n },\n )}\n data-state={selected ? 'active' : 'inactive'}\n data-value={value}\n data-dragging={tabs.dragging === value || undefined}\n >\n {children}\n </ButtonBase>\n );\n if (!onClose) return tab;\n // 关闭按钮不能放进标签按钮里(按钮里不能有按钮):一起包在 role=\"presentation\" 里,按钮本身只给指针用(对读屏隐藏)\n return (\n <span role=\"presentation\" {...mergeAttrs<'span'>(styles.closeWrapper)}>\n {tab}\n <IconButton\n {...mergePartProps<IconButtonProps>(\n {\n icon: X,\n size: 'xs',\n variant: 'ghost',\n radius: 'full',\n ...styles.close,\n 'aria-label': lang.tabClose(plainText(children) || value),\n },\n propsClose,\n {\n tabindex: -1,\n // 只给指针用:tablist 里只能有标签;键盘、读屏用标签上的 Delete(aria-keyshortcuts)\n 'aria-hidden': true,\n disabled,\n // 按下时不把焦点挪到关闭按钮上\n onPointerdown: (event: PointerEvent) => event.preventDefault(),\n onClick: (event: MouseEvent) => {\n event.stopPropagation();\n onClose();\n },\n },\n )}\n />\n </span>\n );\n };\n },\n);\n\n// ─────────────── TabPanel ───────────────\n\n/** 角色、关联与显示由组件管理 */\nexport type TabPanelManaged = 'role' | 'id' | 'aria-labelledby' | 'hidden';\n\n/** 未声明的属性落到 role=\"tabpanel\" 的 div 上 */\nexport interface TabPanelProps extends PartProps<'div', TabPanelManaged> {\n /** 对应标签的 value */\n value: string;\n children?: VNodeChild;\n}\n\n/** Tabs 的样式:root */\nexport const tabPanelStyles = css.create({\n root: { flexGrow: 1, minWidth: 0, borderRadius: '_sm' },\n});\n\n/** 标签面板(role=\"tabpanel\"):只显示当前标签的那一个 */\nexport const TabPanel = _component(({ value, children, ...rest }: TabPanelProps) => {\n const tabs = TabsContext.inject();\n onBeforeUnmount(tabs.registerPanel(_untrack(value)));\n // 显示过:lazy 时从这以后一直渲染内容\n const showContent = useLazyContent(\n () => tabs.value === value,\n () => tabs.lazy,\n );\n\n return () => {\n const selected = tabs.value === value;\n return (\n <div\n {...mergeAttrs<'div'>(\n { sx: [tabPanelStyles.root, focusRingStyles.visible], tabindex: 0 },\n rest,\n {\n role: 'tabpanel',\n id: tabs.id('panel', value),\n 'aria-labelledby': tabs.id('tab', value),\n hidden: !selected,\n },\n )}\n data-state={selected ? 'active' : 'inactive'}\n >\n {showContent() && children}\n </div>\n );\n };\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"Tabs.js","names":["_isVNode","_vtp_bindable","_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_vue_shallowRef","_vue_ref","_vue_computed","_createVNode","_mergeProps","Menu","_vtp_untrack","_vtp_forwardChildren"],"sources":["../../src/navigation/Tabs.tsx"],"sourcesContent":["/**\n * 标签页(WAI-ARIA 的 Tabs 模式),复合组件:Tabs(状态)> TabList(role=\"tablist\")> Tab(role=\"tab\"),\n * 加上与每个 Tab 对应的 TabPanel(role=\"tabpanel\")。各层都是独立的组件,可以自由排版、各自加属性。\n *\n * <Tabs _value={tab}>\n * <TabList aria-label=\"订单\">\n * <Tab value=\"all\">全部</Tab>\n * <Tab value=\"paid\">已付款</Tab>\n * </TabList>\n * <TabPanel value=\"all\">…</TabPanel>\n * <TabPanel value=\"paid\">…</TabPanel>\n * </Tabs>\n *\n * 键盘:标签之间用方向键移动(漫游焦点,整组一个 Tab 位置),Home / End 到两端;\n * activation=\"automatic\"(默认)时焦点移到哪个标签就切换到哪个,\"manual\" 时按 Enter / 空格才切换。\n *\n * line 样式的下划线是 TabList 里的一个指示条(Indicator):跟着当前标签走(useActiveIndicator:\n * 切换时用 Anime.js 滑过去,时长取主题,减少动态效果时直接到位;尺寸变化时直接对齐)。\n */\nimport { ChevronDown, ChevronLeft, ChevronRight, Plus, X } from '@lucide/icons';\nimport { createContext, _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { nextTick, onBeforeUnmount, useId, watch, type VNodeChild } from 'vue';\nimport { ButtonBase, type ButtonBaseProps } from '../base/ButtonBase';\nimport { IconButton, type IconButtonProps } from '../base/IconButton';\nimport { useLang } from '../config/context';\nimport { useDefaults } from '../config/defaults';\nimport { useRecipe } from '../config/styles';\nimport { useActiveIndicator } from '../utils/motion/active-indicator';\nimport { useLazyContent } from '../utils/motion/presence';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { Menu, MenuRadioGroup, MenuRadioItem } from '../overlay/Menu';\nimport { plainText } from '../utils/data/text';\nimport { announce } from '../utils/dom/announcer';\nimport { inlineArrows, isRtl } from '../utils/dom/direction';\nimport { batchLayout } from '../utils/dom/layout-batch';\nimport { startMove } from '../utils/dom/move';\nimport { useResizeObserver } from '../utils/dom/resize';\nimport { rovingFocus } from '../utils/dom/roving-focus';\nimport { focusRingStyles } from '../utils/style/styles';\nimport { fontSizeStyles, type TextSize } from '../utils/style/typography';\nimport { t } from '../config/theme/tokens';\n\n/** 标签的排列方向 */\nexport interface TabsOrientations {\n /** 横排(默认),左右键切换 */\n horizontal: unknown;\n /** 竖排(标签在左侧),上下键切换 */\n vertical: unknown;\n}\n\n/** 焦点移动时是否同时切换 */\nexport interface TabsActivations {\n /** 焦点移到哪个标签就显示哪个面板(默认):面板内容轻量时用 */\n automatic: unknown;\n /** 方向键只移动焦点,按 Enter / 空格才切换:切换面板代价大(要请求数据)时用 */\n manual: unknown;\n}\n\n/** 标签的样式 */\nexport interface TabsVariants {\n /** 下划线(默认):当前标签下方一条品牌色的线 */\n line: unknown;\n /** 浅色底:当前标签有浅色底,像分段控件 */\n soft: unknown;\n}\n\n/** Tabs 的外观选项;可以用 createUi / Provider 的 defaults.Tabs 统一改默认值 */\nexport interface TabsOptions {\n /** 样式,默认 line */\n variant?: keyof TabsVariants;\n /** 字号档位,不写时继承 */\n size?: TextSize;\n}\n\n/** Tabs 交给 TabList、Tab、TabPanel 的状态 */\nexport interface TabsState {\n /** 当前标签的值 */\n readonly value: string | undefined;\n /** 横排或竖排 */\n readonly orientation: keyof TabsOrientations;\n /** 方向键移动焦点时是否同时切换 */\n readonly activation: keyof TabsActivations;\n /** 样式 */\n readonly variant: keyof TabsVariants;\n /** 面板第一次显示时才渲染 */\n readonly lazy: boolean;\n /** 波纹;不写时沿用配置 */\n readonly ripple: boolean | undefined;\n /** 切换到某个标签 */\n select(value: string): void;\n /** 标签与面板的 id,互相引用 */\n id(part: 'tab' | 'panel', value: string): string;\n /**\n * 登记标签(按渲染顺序)与它的文字,没有选中值时选第一个;返回注销函数\n * (参数是注销时各标签显示的顺序,关掉当前标签时按它选旁边的)\n */\n register(value: string, label: () => string): (order?: readonly string[]) => void;\n /** 标签的文字(“全部标签页”菜单用) */\n label(value: string): string;\n /** 登记面板;返回注销函数 */\n registerPanel(value: string): () => void;\n /** 这个标签有没有对应的面板:只当导航用的标签(没有 TabPanel)不写 aria-controls */\n hasPanel(value: string): boolean;\n /** 登记了的标签,按渲染顺序 */\n readonly values: readonly string[];\n /** 正在拖动的标签 */\n readonly dragging: string | undefined;\n /** 开始、结束拖动 */\n setDragging(value: string | undefined): void;\n /** 关闭了有焦点的标签:等选中的标签换好之后,把焦点交给它 */\n refocus(): void;\n}\n\n/** Tabs 的上下文:自定义的标签或面板可以 inject 它 */\nexport const TabsContext = createContext<TabsState>('Tabs');\n\n/** 值里的空格等字符不能出现在 id 里 */\nconst idSafe = (value: string) => value.replace(/[^\\w-]/g, '_');\n\n// ─────────────── Tabs ───────────────\n\n/** 未声明的属性落到外层 div 上 */\nexport interface TabsProps extends PartProps<'div'>, TabsOptions {\n /** 当前标签的 value:父级写 _value={x};不写时默认第一个标签 */\n _value?: string;\n /** 方向,默认 horizontal */\n orientation?: keyof TabsOrientations;\n /** 焦点移动时是否同时切换,默认 automatic */\n activation?: keyof TabsActivations;\n /** 面板第一次显示时才渲染,之后切走也保留(面板内容重时用) */\n lazy?: boolean;\n /** 标签按下时的波纹;不写时沿用全局配置 */\n ripple?: boolean;\n children?: VNodeChild;\n}\n\n/** Tabs 的样式:root、vertical */\nexport const tabsStyles = css.create({\n // 能收缩:放在顶栏这类一行里时,列表放不下就在列表里滚动\n root: { display: 'flex', flexDirection: 'column', gap: '_md', minWidth: 0 },\n vertical: { flexDirection: 'row', alignItems: 'flex-start' },\n});\n\n/** 标签页的状态容器:管理当前值,并把它交给 TabList、Tab、TabPanel */\nexport const Tabs = _component(\n ({\n _value: value = _bindable<string | undefined>(undefined),\n orientation = 'horizontal',\n activation = 'automatic',\n variant,\n size,\n lazy = false,\n ripple,\n children,\n ...rest\n }: TabsProps) => {\n const appearance = useDefaults('Tabs', () => ({ variant, size }), { variant: 'line' });\n const baseId = useId();\n let registered = _state.raw<string[]>([]);\n let panels = _state.raw<string[]>([]);\n let dragging = _state<string | undefined>(undefined);\n // 各标签的文字:读的是 Tab 的子内容,跟着它变\n const labels = new Map<string, () => string>();\n const current = _derived(value ?? registered[0]);\n const tabId = (tab: string) => `${baseId}-tab-${idSafe(tab)}`;\n\n TabsContext.provide({\n get value() {\n return current;\n },\n get orientation() {\n return orientation;\n },\n get activation() {\n return activation;\n },\n get variant() {\n return appearance().variant;\n },\n get lazy() {\n return lazy;\n },\n get ripple() {\n return ripple;\n },\n select: (next) => (value = next),\n id: (part, tab) => (part === 'tab' ? tabId(tab) : `${baseId}-${part}-${idSafe(tab)}`),\n register(tab, label) {\n registered = [...registered, tab];\n labels.set(tab, label);\n return (order = registered) => {\n registered = registered.filter((item) => item !== tab);\n labels.delete(tab);\n if (current !== tab) return;\n // 关掉的是当前标签(使用方没有另选):按显示的顺序选它后面的一个,没有时选前面的一个\n const index = order.indexOf(tab);\n const rest = order.filter((item) => item !== tab && registered.includes(item));\n value = rest[Math.min(Math.max(index, 0), rest.length - 1)];\n };\n },\n registerPanel(tab) {\n panels = [...panels, tab];\n return () => (panels = panels.filter((item) => item !== tab));\n },\n hasPanel: (tab) => panels.includes(tab),\n label: (tab) => labels.get(tab)?.() ?? tab,\n get values() {\n return registered;\n },\n get dragging() {\n return dragging;\n },\n setDragging: (next) => (dragging = next),\n refocus: () =>\n void nextTick(() => {\n if (current !== undefined) document.getElementById(tabId(current))?.focus();\n }),\n });\n\n return () => (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n tabsStyles.root,\n orientation === 'vertical' && tabsStyles.vertical,\n appearance().size && fontSizeStyles[appearance().size!],\n ],\n },\n rest,\n )}\n data-orientation={orientation}\n >\n {children}\n </div>\n );\n },\n);\n\n// ─────────────── TabList ───────────────\n\n/** 角色、方向由组件管理 */\nexport type TabListManaged = 'role' | 'aria-orientation';\n\n/** 未声明的属性落到 role=\"tablist\" 的 div 上;aria-label 是这组标签的名称 */\nexport interface TabListProps extends PartProps<'div', TabListManaged> {\n /** 到两端后是否从另一端继续,默认 true */\n loop?: boolean;\n /** 列表末尾的“新建标签页”按钮:点了调用 */\n onAdd?: () => void;\n /**\n * 拖动标签(或在标签上按 Alt + ←→)改变顺序:参数是新的顺序(各标签的 value),使用方按它重排;\n * 不写时不能拖\n */\n onReorder?: (values: string[]) => void;\n /** 标签栏右边“全部标签页”的菜单(标签多、放不下时一眼找到并切过去) */\n showAllMenu?: boolean;\n /** line 样式的下划线指示条的部件属性 */\n propsIndicator?: PartProps<'span'>;\n /** 横排时包着标签列表与右边按钮的那一层的部件属性 */\n propsBar?: PartProps<'div'>;\n /** “新建标签页”按钮的部件属性 */\n propsAdd?: Partial<IconButtonProps>;\n children?: VNodeChild;\n}\n\n/** TabList 的样式:bar、barLine、root、scrollable、line、lineVertical、soft、softVertical、indicator、indicatorVertical */\nexport const tabListStyles = css.create({\n // 横排时包着标签列表与右边的按钮(滚动、全部标签页、新建):列表按内容宽,放不下时收缩并滚动\n bar: { display: 'flex', alignItems: 'center', gap: '_xs', minWidth: 0 },\n // 横排 line 的分隔线画在整行上:标签少时也铺满(页签区、页面顶部的标签)\n barLine: {\n borderBottomWidth: '_xs',\n borderBottomStyle: 'solid',\n borderBottomColor: '_borderMuted',\n },\n root: { display: 'flex', flexShrink: 0 },\n // 横排放不下时(顶栏、窄屏)在列表里横向滚动,不盖到旁边的内容上;滚动条藏起来,触控板、拖动照样能滚\n scrollable: {\n flexShrink: 1,\n minWidth: 0,\n overflowX: 'auto',\n overflowY: 'hidden',\n scrollbarWidth: 'none',\n },\n // 指示条按标签的 offsetLeft / offsetTop 定位,列表要是它的定位容器\n line: { position: 'relative', gap: '_md' },\n lineVertical: {\n flexDirection: 'column',\n gap: '_xs',\n borderInlineEndWidth: '_xs',\n borderInlineEndStyle: 'solid',\n borderInlineEndColor: '_borderMuted',\n },\n soft: { gap: '_xs', padding: '_xs', borderRadius: '_md', backgroundColor: '_fill' },\n softVertical: { flexDirection: 'column' },\n // 一条 2px 的品牌色线,压在列表的分隔线上;位置与长度由脚本写(transform 与 width/height)\n indicator: {\n position: 'absolute',\n left: 0,\n // 压在列表底边的分隔线上(滚动的列表会裁掉伸出去的部分,所以放在边框内侧)\n bottom: 0,\n width: 0,\n height: '_borderWidths.sm',\n borderRadius: '_sm',\n backgroundColor: '_accent',\n pointerEvents: 'none',\n },\n indicatorVertical: {\n left: 'auto',\n bottom: 'auto',\n top: 0,\n insetInlineEnd: `calc(-1 * ${t.borderWidths.xs})`,\n width: '_borderWidths.sm',\n height: 0,\n },\n});\n\n/** 列表里各标签的 value,按显示的顺序(拖动排序后组件的登记顺序不再是显示顺序) */\nconst tabOrder = (list: Element | null | undefined) =>\n [...(list?.querySelectorAll<HTMLElement>('[role=\"tab\"]') ?? [])].map((tab) => tab.dataset.value!);\n\n/** 标签列表(role=\"tablist\"):方向键在标签之间移动;横排放不下时有滚动按钮,可以拖动排序、新建 */\nexport const TabList = _component(\n ({\n loop = true,\n onAdd,\n onReorder,\n showAllMenu = false,\n propsIndicator,\n propsBar,\n propsAdd,\n children,\n ...rest\n }: TabListProps) => {\n const lang = useLang();\n const tabs = TabsContext.inject();\n let list = _state.raw<HTMLElement | null>(null);\n let indicator = _state.raw<HTMLElement | null>(null);\n // 横排放不下时:能不能往前、往后滚(滚动按钮)\n let overflow = _state.raw({ overflowing: false, start: false, end: false });\n _effect(() =>\n list\n ? rovingFocus(list, { items: '[role=\"tab\"]', orientation: tabs.orientation, loop })\n : undefined,\n );\n\n useActiveIndicator(() => ({\n container: list,\n indicator,\n active: '[role=\"tab\"][aria-selected=\"true\"]',\n axis: tabs.orientation,\n value: tabs.value,\n }));\n\n function measure() {\n batchLayout(() => {\n if (!list || tabs.orientation === 'vertical') return;\n // 从右到左排版时 scrollLeft 是负的:取绝对值就是离起始端多远\n const scrolled = Math.abs(list.scrollLeft);\n const max = list.scrollWidth - list.clientWidth;\n const next = { overflowing: max > 1, start: scrolled > 1, end: scrolled < max - 1 };\n return () => {\n if (Object.entries(next).some(([key, value]) => overflow[key as 'start'] !== value))\n overflow = next;\n };\n });\n }\n useResizeObserver(\n () => (list ? [list, ...list.querySelectorAll<HTMLElement>('[role=\"tab\"]')] : []),\n measure,\n );\n watch(() => tabs.values.length, measure, { flush: 'post' });\n\n // 切到一个滚到外面的标签(方向键、菜单、程序):把它滚进来\n watch(\n () => tabs.value,\n (value) => {\n const tab = value === undefined ? null : document.getElementById(tabs.id('tab', value));\n if (!list || !tab || list.scrollWidth <= list.clientWidth) return;\n const outer = list.getBoundingClientRect();\n const inner = tab.getBoundingClientRect();\n if (inner.left < outer.left) list.scrollBy({ left: inner.left - outer.left - 16 });\n else if (inner.right > outer.right) list.scrollBy({ left: inner.right - outer.right + 16 });\n },\n { flush: 'post' },\n );\n\n /** 滚动按钮:往前(-1)或往后(1)滚大半屏 */\n function scrollBy(direction: 1 | -1) {\n if (!list) return;\n const sign = isRtl(list) ? -direction : direction;\n list.scrollBy({ left: sign * list.clientWidth * 0.8, behavior: 'smooth' });\n }\n\n /** 把 value 移到 to(按显示的顺序),交给使用方重排;键盘移动时告诉读屏 */\n function moveTab(value: string, to: number, announceMove: boolean) {\n const order = tabOrder(list);\n const from = order.indexOf(value);\n if (!onReorder || from < 0 || to < 0 || to >= order.length || to === from) return;\n const next = order.filter((item) => item !== value);\n next.splice(to, 0, value);\n onReorder(next);\n if (!announceMove) return;\n const label = document.getElementById(tabs.id('tab', value))?.textContent ?? value;\n announce(lang.tabMoved(label, to + 1, order.length));\n // 标签的元素被移动过:焦点放回它上面\n void nextTick(() => document.getElementById(tabs.id('tab', value))?.focus());\n }\n\n // 拖动排序:越过别的标签的中线就换位(同 Sortable);触摸时照常横向滚动\n function onPointerdown(event: PointerEvent) {\n const target = event.target as Element;\n const tab = target.closest<HTMLElement>('[role=\"tab\"]');\n if (!onReorder || !tab || !list || event.pointerType === 'touch') return;\n const value = tab.dataset.value!;\n startMove(event, {\n threshold: 4,\n // 标签的元素会被重排:捕获在不动的列表上\n captureTarget: list,\n onMove: ({ clientX }) => {\n tabs.setDragging(value);\n const order = tabOrder(list);\n const from = order.indexOf(value);\n const over = [...list!.querySelectorAll<HTMLElement>('[role=\"tab\"]')].find((item) => {\n const rect = item.getBoundingClientRect();\n return clientX >= rect.left && clientX <= rect.right;\n });\n const to = over ? order.indexOf(over.dataset.value!) : -1;\n if (!over || to === from) return;\n const rect = over.getBoundingClientRect();\n const center = rect.left + rect.width / 2;\n // 按书写方向“越过中线”:往后挪时要过了它的中线,往前挪时要回到中线之前\n const past = isRtl(list!) ? clientX < center : clientX > center;\n if (to > from === past) moveTab(value, to, false);\n },\n onEnd: () => tabs.setDragging(undefined),\n });\n }\n\n // 键盘替代拖动:在标签上按 Alt + ←→ 往前、往后挪一位(从右到左排版时反过来)\n function onKeydown(event: KeyboardEvent) {\n if (!onReorder || !event.altKey || event.ctrlKey || event.metaKey || !list) return;\n const tab = (event.target as Element).closest<HTMLElement>('[role=\"tab\"]');\n const { forward, backward } = inlineArrows(isRtl(list));\n if (!tab || (event.key !== forward && event.key !== backward)) return;\n event.preventDefault();\n const value = tab.dataset.value!;\n const from = tabOrder(list).indexOf(value);\n moveTab(value, from + (event.key === forward ? 1 : -1), true);\n }\n\n /** “全部标签页”菜单:按显示的顺序(刚加上、还没渲染出来的排在最后)列出标签的文字 */\n function renderAllMenu() {\n const shown = tabOrder(list).filter((value) => tabs.values.includes(value));\n const order = [...shown, ...tabs.values.filter((value) => !shown.includes(value))];\n const items = order.map((value) => ({ value, label: tabs.label(value) }));\n return (\n <Menu\n trigger={(props) => (\n <IconButton\n {...props}\n icon={ChevronDown}\n size=\"sm\"\n variant=\"ghost\"\n aria-label={lang.tabList}\n />\n )}\n placement=\"bottom-end\"\n >\n <MenuRadioGroup\n label={lang.tabList}\n _value={tabs.value ?? ''}\n onUpdate:_value={(next: string) => tabs.select(next)}\n >\n {items.map((item) => (\n <MenuRadioItem key={item.value} value={item.value}>\n {item.label}\n </MenuRadioItem>\n ))}\n </MenuRadioGroup>\n </Menu>\n );\n }\n\n return () => {\n const vertical = tabs.orientation === 'vertical';\n const tablist = (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n tabListStyles.root,\n !vertical && tabListStyles.scrollable,\n tabs.variant === 'line'\n ? [tabListStyles.line, vertical && tabListStyles.lineVertical]\n : [tabListStyles.soft, vertical && tabListStyles.softVertical],\n ],\n },\n rest,\n {\n ref: _toRef(list),\n role: 'tablist',\n 'aria-orientation': tabs.orientation,\n onScroll: measure,\n onPointerdown,\n onKeydown,\n },\n )}\n >\n {children}\n {tabs.variant === 'line' && (\n <span\n {...mergeAttrs<'span'>(\n { sx: [tabListStyles.indicator, vertical && tabListStyles.indicatorVertical] },\n propsIndicator,\n { ref: _toRef(indicator), 'aria-hidden': true },\n )}\n />\n )}\n </div>\n );\n if (vertical) return tablist;\n // 滚动按钮只给指针用:键盘在标签之间移动时,当前标签会自己滚进来\n const scrollButton = (direction: 1 | -1) =>\n overflow.overflowing && (\n <IconButton\n icon={direction === 1 ? ChevronRight : ChevronLeft}\n propsIcon={{ flipInRtl: true }}\n size=\"sm\"\n variant=\"ghost\"\n tabindex={-1}\n aria-label={direction === 1 ? lang.tabScrollNext : lang.tabScrollPrevious}\n disabled={direction === 1 ? !overflow.end : !overflow.start}\n onClick={() => scrollBy(direction)}\n />\n );\n return (\n <div\n {...mergeAttrs<'div'>(\n { sx: [tabListStyles.bar, tabs.variant === 'line' && tabListStyles.barLine] },\n propsBar,\n )}\n >\n {scrollButton(-1)}\n {tablist}\n {scrollButton(1)}\n {showAllMenu && renderAllMenu()}\n {onAdd && (\n <IconButton\n {...mergePartProps<IconButtonProps>(\n { icon: Plus, size: 'sm', variant: 'ghost', 'aria-label': lang.tabAdd },\n propsAdd,\n { onClick: onAdd },\n )}\n />\n )}\n </div>\n );\n };\n },\n);\n\n// ─────────────── Tab ───────────────\n\n/** 角色、选中、关联与可聚焦由组件管理 */\nexport type TabManaged =\n 'role' | 'aria-selected' | 'aria-controls' | 'id' | 'tabindex' | 'disabled';\n\n/** 未声明的属性落到 role=\"tab\" 的 button 上 */\nexport interface TabProps extends PartProps<'button', TabManaged> {\n /** 这个标签的值,与对应 TabPanel 的 value 相同 */\n value: string;\n /** 不可用:方向键跳过它 */\n disabled?: boolean;\n /**\n * 可以关闭:标签末尾有关闭按钮,标签上按 Delete、鼠标中键点也关闭。使用方移除这个标签;\n * 关掉的是当前标签时 Tabs 选它后面(没有时前面)的一个,焦点也跟过去\n */\n onClose?: () => void;\n /** 关闭按钮的部件属性 */\n propsClose?: Partial<IconButtonProps>;\n children?: VNodeChild;\n}\n\n/** Tabs 的样式:root、hover、line、lineVertical、lineActive、soft 等 */\n/**\n * 标签的配方:状态(选中、禁用、拖动中)由 DOM 上的 aria-selected、disabled、data-dragging 决定,\n * 样式、方向、可关闭是档位\n */\nexport const tabRecipe = css.recipe({\n name: 'Tab',\n parts: ['root', 'closeWrapper', 'close'],\n base: {\n // 去掉按钮默认外观、焦点环、波纹、颜色过渡由 ButtonBase 给出\n root: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '_sm',\n minHeight: `max(${t.sizes.control}, ${t.sizes.minTarget})`,\n paddingInline: '_md',\n color: { default: '_textMuted', _hover: '_text', _selected: '_text' },\n fontWeight: '_medium',\n whiteSpace: 'nowrap',\n borderRadius: '_sm',\n opacity: { default: null, _dragging: 0.6, _disabled: '_disabled' },\n },\n closeWrapper: { display: 'inline-grid', flexShrink: 0 },\n close: { gridArea: '1 / 1', justifySelf: 'end', alignSelf: 'center', marginInlineEnd: '_xs' },\n },\n variants: {\n variant: {\n // 下划线:当前标签的底边(竖排时是结束边)一条 2px 的品牌色线,压在列表的分隔线上;\n // 线由 TabList 的指示条画(切换时滑过去),标签自己只变文字颜色\n line: {\n root: {\n marginBottom: `calc(-1 * ${t.borderWidths.xs})`,\n borderBottomWidth: '_sm',\n borderBottomStyle: 'solid',\n borderBottomColor: 'transparent',\n },\n },\n soft: {\n root: {\n // 未选中时同 ButtonBase 的透明底:条件对象按属性整体覆盖前面的值,default 写 null 会露出原生按钮底色\n backgroundColor: { default: 'transparent', _selected: '_surface' },\n boxShadow: { default: null, _selected: '_xs' },\n },\n },\n },\n orientation: { horizontal: {}, vertical: {} },\n // 可关闭:标签与关闭按钮叠在同一个网格格子里,关闭按钮靠结束端,标签给它留出位置。\n // 不用定位:标签的 offsetParent 还得是列表,下划线指示条按它的 offsetLeft 对齐\n closable: {\n true: { root: { gridArea: '1 / 1', paddingInlineEnd: `calc(${t.space.md} + 1.25em)` } },\n },\n },\n compound: [\n {\n when: { variant: 'line', orientation: 'vertical' },\n root: {\n justifyContent: 'flex-start',\n marginBottom: 0,\n marginInlineEnd: `calc(-1 * ${t.borderWidths.xs})`,\n borderBottomWidth: 0,\n borderInlineEndWidth: '_sm',\n borderInlineEndStyle: 'solid',\n borderInlineEndColor: 'transparent',\n },\n },\n ],\n});\n\n/** 标签的部件(createUi / Provider 的 styles.Tab 按它定制) */\nexport type TabPart = (typeof tabRecipe.parts)[number];\n\n/** 标签(role=\"tab\" 的 button) */\nexport const Tab = _component(\n ({ value, disabled = false, onClose, propsClose, children, ...rest }: TabProps) => {\n const lang = useLang();\n const tabs = TabsContext.inject();\n const recipe = useRecipe(tabRecipe);\n const unregister = tabs.register(_untrack(value), () => plainText(children) || value);\n onBeforeUnmount(() => {\n const element = document.getElementById(tabs.id('tab', value));\n // 关掉的标签有焦点:等 Tabs 选好旁边的标签再把焦点交过去(元素一移除焦点就丢到 body 上了)\n if (element && element === document.activeElement) tabs.refocus();\n unregister(tabOrder(element?.closest('[role=\"tablist\"]')));\n });\n\n function onKeydown(event: KeyboardEvent) {\n if (event.key === 'Delete' && onClose && !disabled) {\n event.preventDefault();\n onClose();\n }\n }\n\n return () => {\n const selected = tabs.value === value;\n const styles = recipe({\n variant: tabs.variant,\n orientation: tabs.orientation,\n closable: !!onClose,\n });\n const tab = (\n <ButtonBase\n {...mergePartProps<ButtonBaseProps>(\n {\n ...styles.root,\n ripple: tabs.ripple,\n },\n rest as Partial<ButtonBaseProps>,\n {\n role: 'tab',\n id: tabs.id('tab', value),\n 'aria-selected': selected,\n 'aria-controls': tabs.hasPanel(value) ? tabs.id('panel', value) : undefined,\n disabled,\n // 使用方的 onClick / onFocus 先执行(mergeProps 的规则),onClick 里 preventDefault 可以拦下切换\n onClick: () => tabs.select(value),\n onFocus: () => {\n if (tabs.activation === 'automatic') tabs.select(value);\n },\n onKeydown,\n 'aria-keyshortcuts': onClose ? 'Delete' : undefined,\n // 鼠标中键关闭(同浏览器的标签页)\n onAuxclick: (event: MouseEvent) => {\n if (event.button === 1 && onClose && !disabled) onClose();\n },\n },\n )}\n data-state={selected ? 'active' : 'inactive'}\n data-value={value}\n data-dragging={tabs.dragging === value || undefined}\n >\n {children}\n </ButtonBase>\n );\n if (!onClose) return tab;\n // 关闭按钮不能放进标签按钮里(按钮里不能有按钮):一起包在 role=\"presentation\" 里,按钮本身只给指针用(对读屏隐藏)\n return (\n <span role=\"presentation\" {...mergeAttrs<'span'>(styles.closeWrapper)}>\n {tab}\n <IconButton\n {...mergePartProps<IconButtonProps>(\n {\n icon: X,\n size: 'xs',\n variant: 'ghost',\n radius: 'full',\n ...styles.close,\n 'aria-label': lang.tabClose(plainText(children) || value),\n },\n propsClose,\n {\n tabindex: -1,\n // 只给指针用:tablist 里只能有标签;键盘、读屏用标签上的 Delete(aria-keyshortcuts)\n 'aria-hidden': true,\n disabled,\n // 按下时不把焦点挪到关闭按钮上\n onPointerdown: (event: PointerEvent) => event.preventDefault(),\n onClick: (event: MouseEvent) => {\n event.stopPropagation();\n onClose();\n },\n },\n )}\n />\n </span>\n );\n };\n },\n);\n\n// ─────────────── TabPanel ───────────────\n\n/** 角色、关联与显示由组件管理 */\nexport type TabPanelManaged = 'role' | 'id' | 'aria-labelledby' | 'hidden';\n\n/** 未声明的属性落到 role=\"tabpanel\" 的 div 上 */\nexport interface TabPanelProps extends PartProps<'div', TabPanelManaged> {\n /** 对应标签的 value */\n value: string;\n children?: VNodeChild;\n}\n\n/** Tabs 的样式:root */\nexport const tabPanelStyles = css.create({\n root: { flexGrow: 1, minWidth: 0, borderRadius: '_sm' },\n});\n\n/** 标签面板(role=\"tabpanel\"):只显示当前标签的那一个 */\nexport const TabPanel = _component(({ value, children, ...rest }: TabPanelProps) => {\n const tabs = TabsContext.inject();\n onBeforeUnmount(tabs.registerPanel(_untrack(value)));\n // 显示过:lazy 时从这以后一直渲染内容\n const showContent = useLazyContent(\n () => tabs.value === value,\n () => tabs.lazy,\n );\n\n return () => {\n const selected = tabs.value === value;\n return (\n <div\n {...mergeAttrs<'div'>(\n { sx: [tabPanelStyles.root, focusRingStyles.visible], tabindex: 0 },\n rest,\n {\n role: 'tabpanel',\n id: tabs.id('panel', value),\n 'aria-labelledby': tabs.id('tab', value),\n hidden: !selected,\n },\n )}\n data-state={selected ? 'active' : 'inactive'}\n >\n {showContent() && children}\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 Space } from '../utils/style/styles';
@@ -3,7 +3,7 @@ import { gapStyles } from "../utils/style/styles.js";
3
3
  import { rovingFocus } from "../utils/dom/roving-focus.js";
4
4
  import { createVNode, shallowRef } from "vue";
5
5
  import { _component, childrenProp, createContext, effect, mergeJsxProps, 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/navigation/Toolbar.tsx
8
8
  /** 工具栏方向 */
9
9
  /** 角色与方向由组件管理 */
@@ -1 +1 @@
1
- {"version":3,"file":"Toolbar.js","names":["_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_vue_shallowRef","_createVNode","_mergeProps"],"sources":["../../src/navigation/Toolbar.tsx"],"sourcesContent":["/**\n * 工具栏(role=\"toolbar\"):一组相关的按钮、链接。整组只占一个 Tab 位置,组内用方向键移动(漫游焦点),\n * 键盘用户不必一个个 Tab 过去(WAI-ARIA 的 Toolbar 模式)。名称写 aria-label。\n *\n * <Toolbar aria-label=\"文字格式\">\n * <IconButton icon={Bold} aria-label=\"加粗\" />\n * <IconButton icon={Italic} aria-label=\"斜体\" />\n * </Toolbar>\n *\n * 里面的输入框不参与方向键移动(左右键要用来移动光标),用 Tab 进出。\n * 里面的 ToggleGroup 不再自己管焦点,它的按钮和其他按钮一起用方向键移动(同 WAI-ARIA 的文字格式工具栏示例)。\n */\nimport { createContext, _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 { mergeAttrs, type PartProps } from '../utils/props';\nimport { rovingFocus } from '../utils/dom/roving-focus';\nimport { gapStyles, type Space } from '../utils/style/styles';\n\n/** 工具栏方向 */\nexport interface ToolbarOrientations {\n /** 横排(默认),左右键移动 */\n horizontal: unknown;\n /** 竖排,上下键移动 */\n vertical: unknown;\n}\n\n/** 角色与方向由组件管理 */\nexport type ToolbarManaged = 'role' | 'aria-orientation';\n\n/** 未声明的属性落到 div 上;aria-label 是工具栏的名称 */\nexport interface ToolbarProps extends PartProps<'div', ToolbarManaged> {\n /** 方向,默认 horizontal */\n orientation?: keyof ToolbarOrientations;\n /** 到两端后是否从另一端继续,默认 true */\n loop?: boolean;\n /** 项之间的间距档位,默认 xs */\n gap?: Space;\n /** 参与方向键移动的项的选择器,默认按钮与链接 */\n items?: string;\n children?: VNodeChild;\n}\n\n/** Toolbar 的样式:root、vertical */\nexport const toolbarStyles = css.create({\n root: { display: 'flex', alignItems: 'center', flexWrap: 'wrap' },\n vertical: { flexDirection: 'column', alignItems: 'stretch' },\n});\n\n/** 默认参与方向键移动的项:按钮、链接、自定义的 role=\"button\" */\nconst DEFAULT_ITEMS = 'button, a[href], [role=\"button\"]';\n\n/** 工具栏交给里面的组件的状态 */\nexport interface ToolbarState {\n /** 方向 */\n readonly orientation: keyof ToolbarOrientations;\n}\n\n/** 工具栏的上下文:里面自带漫游焦点的组件(ToggleGroup)据此把焦点交给工具栏统一管理 */\nexport const ToolbarContext = createContext<ToolbarState>('Toolbar');\n\n/** 工具栏:一个 Tab 位置,组内方向键移动 */\nexport const Toolbar = _component(\n ({\n orientation = 'horizontal',\n loop = true,\n gap = 'xs',\n items = DEFAULT_ITEMS,\n children,\n ...rest\n }: ToolbarProps) => {\n let root = _state.raw<HTMLElement | null>(null);\n // Tab 进入时落在上次聚焦的项,没有就是第一项:不跳到按下的切换按钮上(那是标签页的习惯)\n _effect(() =>\n root\n ? rovingFocus(root, { items, orientation, loop, initial: (enabled) => enabled[0] })\n : undefined,\n );\n ToolbarContext.provide({\n get orientation() {\n return orientation;\n },\n });\n\n return () => (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n toolbarStyles.root,\n orientation === 'vertical' && toolbarStyles.vertical,\n gapStyles[gap],\n ],\n },\n rest,\n { ref: _toRef(root), role: 'toolbar', 'aria-orientation': orientation },\n )}\n data-orientation={orientation}\n >\n {children}\n </div>\n );\n },\n);\n"],"mappings":";;;;;;;;;;;AA4CA,IAAa,gBAAgB,IAAI,OAAO;CACtC,MAAM;EAAE,SAAS;EAAQ,YAAY;EAAU,UAAU;CAAO;CAChE,UAAU;EAAE,eAAe;EAAU,YAAY;CAAU;AAC7D,CAAC;;AAGD,IAAM,gBAAgB;;;AAStB,IAAa,iBAAiB,cAA4B,SAAS;;AAGnE,IAAa,UAAU,0BACrB,QAAA,SAOoB;CAAA,MAAA,cAAAA,aAAA,QAAA,eANJ,YAAY;CAAA,MAAA,OAAAA,aAAA,QAAA,QACnB,IAAI;CAAA,MAAA,MAAAA,aAAA,QAAA,OACL,IAAI;CAAA,MAAA,QAAAA,aAAA,QAAA,eACF,aAAa;CAAA,MAAA,WAAAC,aAAA,MAAA;CAAA,MAElB,OAAIC,UAAA,QAAA,MAAA,KAAA;CAEP,IAAI,OAAIC,WAAkC,IAAI;CAE9C,aACE,KAAA,QACI,YAAW,KAAA,OAAO;EAAE,OAAK,MAAA;EAAE,aAAW,YAAA;EAAE,MAAI,KAAA;EAAE,UAAU,YAAY,QAAQ;CAAG,CAAC,IAChF,KAAA,CAAS;CAEf,eAAe,QAAQ,EACrB,IAAI,cAAc;EAChB,OAAA,YAAA;CACF,EACF,CAAC;CAED,aAAOC,YAAA,OAAAC,cAEC,WACF,EACE,IAAI;EACF,cAAc;EACd,YAAA,UAAgB,cAAc,cAAc;EAC5C,UAAS,IAAA;CAAK,EAElB,GACA,MACA;EAAE,KAAG;EAAgB,MAAM;EAAW,oBAAkB,YAAA;CAAc,CACxE,GAAC,EAAA,oBAAA,YAAA,MAAA,CAAA,GAAA,CAAA,SAAA,KAAA,CAAA;AAMP,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH"}
1
+ {"version":3,"file":"Toolbar.js","names":["_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_vue_shallowRef","_createVNode","_mergeProps"],"sources":["../../src/navigation/Toolbar.tsx"],"sourcesContent":["/**\n * 工具栏(role=\"toolbar\"):一组相关的按钮、链接。整组只占一个 Tab 位置,组内用方向键移动(漫游焦点),\n * 键盘用户不必一个个 Tab 过去(WAI-ARIA 的 Toolbar 模式)。名称写 aria-label。\n *\n * <Toolbar aria-label=\"文字格式\">\n * <IconButton icon={Bold} aria-label=\"加粗\" />\n * <IconButton icon={Italic} aria-label=\"斜体\" />\n * </Toolbar>\n *\n * 里面的输入框不参与方向键移动(左右键要用来移动光标),用 Tab 进出。\n * 里面的 ToggleGroup 不再自己管焦点,它的按钮和其他按钮一起用方向键移动(同 WAI-ARIA 的文字格式工具栏示例)。\n */\nimport { createContext, _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { VNodeChild } from 'vue';\nimport { mergeAttrs, type PartProps } from '../utils/props';\nimport { rovingFocus } from '../utils/dom/roving-focus';\nimport { gapStyles, type Space } from '../utils/style/styles';\n\n/** 工具栏方向 */\nexport interface ToolbarOrientations {\n /** 横排(默认),左右键移动 */\n horizontal: unknown;\n /** 竖排,上下键移动 */\n vertical: unknown;\n}\n\n/** 角色与方向由组件管理 */\nexport type ToolbarManaged = 'role' | 'aria-orientation';\n\n/** 未声明的属性落到 div 上;aria-label 是工具栏的名称 */\nexport interface ToolbarProps extends PartProps<'div', ToolbarManaged> {\n /** 方向,默认 horizontal */\n orientation?: keyof ToolbarOrientations;\n /** 到两端后是否从另一端继续,默认 true */\n loop?: boolean;\n /** 项之间的间距档位,默认 xs */\n gap?: Space;\n /** 参与方向键移动的项的选择器,默认按钮与链接 */\n items?: string;\n children?: VNodeChild;\n}\n\n/** Toolbar 的样式:root、vertical */\nexport const toolbarStyles = css.create({\n root: { display: 'flex', alignItems: 'center', flexWrap: 'wrap' },\n vertical: { flexDirection: 'column', alignItems: 'stretch' },\n});\n\n/** 默认参与方向键移动的项:按钮、链接、自定义的 role=\"button\" */\nconst DEFAULT_ITEMS = 'button, a[href], [role=\"button\"]';\n\n/** 工具栏交给里面的组件的状态 */\nexport interface ToolbarState {\n /** 方向 */\n readonly orientation: keyof ToolbarOrientations;\n}\n\n/** 工具栏的上下文:里面自带漫游焦点的组件(ToggleGroup)据此把焦点交给工具栏统一管理 */\nexport const ToolbarContext = createContext<ToolbarState>('Toolbar');\n\n/** 工具栏:一个 Tab 位置,组内方向键移动 */\nexport const Toolbar = _component(\n ({\n orientation = 'horizontal',\n loop = true,\n gap = 'xs',\n items = DEFAULT_ITEMS,\n children,\n ...rest\n }: ToolbarProps) => {\n let root = _state.raw<HTMLElement | null>(null);\n // Tab 进入时落在上次聚焦的项,没有就是第一项:不跳到按下的切换按钮上(那是标签页的习惯)\n _effect(() =>\n root\n ? rovingFocus(root, { items, orientation, loop, initial: (enabled) => enabled[0] })\n : undefined,\n );\n ToolbarContext.provide({\n get orientation() {\n return orientation;\n },\n });\n\n return () => (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n toolbarStyles.root,\n orientation === 'vertical' && toolbarStyles.vertical,\n gapStyles[gap],\n ],\n },\n rest,\n { ref: _toRef(root), role: 'toolbar', 'aria-orientation': orientation },\n )}\n data-orientation={orientation}\n >\n {children}\n </div>\n );\n },\n);\n"],"mappings":";;;;;;;;;;;AA4CA,IAAa,gBAAgB,IAAI,OAAO;CACtC,MAAM;EAAE,SAAS;EAAQ,YAAY;EAAU,UAAU;CAAO;CAChE,UAAU;EAAE,eAAe;EAAU,YAAY;CAAU;AAC7D,CAAC;;AAGD,IAAM,gBAAgB;;;AAStB,IAAa,iBAAiB,cAA4B,SAAS;;AAGnE,IAAa,UAAU,0BACrB,QAAA,SAOoB;CAAA,MAAA,cAAAA,aAAA,QAAA,eANJ,YAAY;CAAA,MAAA,OAAAA,aAAA,QAAA,QACnB,IAAI;CAAA,MAAA,MAAAA,aAAA,QAAA,OACL,IAAI;CAAA,MAAA,QAAAA,aAAA,QAAA,eACF,aAAa;CAAA,MAAA,WAAAC,aAAA,MAAA;CAAA,MAElB,OAAIC,UAAA,QAAA,MAAA,KAAA;CAEP,IAAI,OAAIC,WAAkC,IAAI;CAE9C,aACE,KAAA,QACI,YAAW,KAAA,OAAO;EAAE,OAAK,MAAA;EAAE,aAAW,YAAA;EAAE,MAAI,KAAA;EAAE,UAAU,YAAY,QAAQ;CAAG,CAAC,IAChF,KAAA,CAAS;CAEf,eAAe,QAAQ,EACrB,IAAI,cAAc;EAChB,OAAA,YAAA;CACF,EACF,CAAC;CAED,aAAOC,YAAA,OAAAC,cAEC,WACF,EACE,IAAI;EACF,cAAc;EACd,YAAA,UAAgB,cAAc,cAAc;EAC5C,UAAS,IAAA;CAAK,EAElB,GACA,MACA;EAAE,KAAG;EAAgB,MAAM;EAAW,oBAAkB,YAAA;CAAc,CACxE,GAAC,EAAA,oBAAA,YAAA,MAAA,CAAA,GAAA,CAAA,SAAA,KAAA,CAAA;AAMP,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH"}
@@ -1,4 +1,4 @@
1
- import * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';
1
+ import { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';
2
2
  import { type VNodeChild } from 'vue';
3
3
  import { type ButtonBaseProps } from '../base/ButtonBase';
4
4
  import { type ListboxViewProps, type OptionRenderState } from '../input/Listbox';
@@ -13,7 +13,7 @@ import { Dialog } from "./Dialog.js";
13
13
  import { ListboxView, activeOptionId } from "../input/Listbox.js";
14
14
  import { Fragment, createVNode, useId, vModelText, watch, withDirectives } from "vue";
15
15
  import { _component, bindable, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
16
- import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
16
+ import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
17
17
  import { Search } from "@lucide/icons";
18
18
  //#region src/overlay/CommandPalette.tsx
19
19
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"CommandPalette.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_restProps","_createVNode","_Fragment","_mergeProps","_withDirectives","_vModelText"],"sources":["../../src/overlay/CommandPalette.tsx"],"sourcesContent":["/**\n * 命令面板:Mod+K(macOS 上 ⌘K,其他系统 Ctrl+K)或点触发按钮打开的搜索对话框,边输入边过滤,回车打开。\n * 文档站的站内搜索、后台的“跳转到…”都用它;数据由使用方给,选中后做什么也由使用方决定。\n *\n * <CommandPalette\n * items={pages}\n * toOption={(page) => ({ value: page.path, label: page.title, description: page.summary, group: page.section })}\n * onAction={(page) => router.push(page.path)}\n * />\n *\n * 结构是 Dialog(模态、焦点循环、Esc 关闭)里放一个 combobox 输入框与 ListboxView:\n * 焦点一直在输入框上,↑↓ / Page Up / Page Down 移动高亮(aria-activedescendant),Enter 选中;\n * 数据层与 Select、Combobox 相同(useListState),选项多时虚拟滚动。\n * 远程搜索与 Combobox 一样:_inputValue={keyword} 拿到输入,filter={false} 不再本地过滤,取数据时给 loading。\n */\nimport { Search } from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { useId, watch, type VNodeChild } from 'vue';\nimport { ButtonBase, type ButtonBaseProps } from '../base/ButtonBase';\nimport { Icon } from '../base/Icon';\nimport { Kbd } from '../base/Kbd';\nimport { visuallyHiddenStyles } from '../base/VisuallyHidden';\nimport { useLang, useTextMatcher } from '../config/context';\nimport { controlParts, useControlAppearance, type ControlParts } from '../input/control';\nimport {\n ListboxView,\n activeOptionId,\n type ListboxViewProps,\n type OptionRenderState,\n} from '../input/Listbox';\nimport {\n handleListKeydown,\n useListState,\n type ListboxOption,\n type OptionMapping,\n toListboxOption,\n} from '../input/list-state';\nimport { ariaKeyShortcut, formatHotkey, useHotkeys } from '../utils/dom/hotkeys';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { breakpoints } from '../config/theme/tokens';\nimport { openSetter } from '../utils/dom/open-change';\nimport { Dialog, type DialogProps } from './Dialog';\n\n/** 交给触发器的属性:展开到按钮上 */\nexport interface CommandPaletteTriggerProps {\n /** 打开面板 */\n onClick: (event: MouseEvent) => void;\n /** 告诉读屏这个按钮会打开对话框 */\n 'aria-haspopup': 'dialog';\n /** 面板是否打开 */\n 'aria-expanded': boolean;\n}\n\n/** 与数据类型无关的属性;未声明的属性落到对话框(dialog)上 */\nexport interface CommandPaletteBaseProps<T> extends Omit<\n DialogProps,\n 'open' | 'title' | 'description' | 'footer' | 'children' | 'onSelect'\n> {\n /** 是否打开:父级可以写 _open={x};快捷键、触发按钮、选中、Esc 都会改它 */\n _open?: boolean;\n /** 数据:ListboxOption、字符串,或任意数据加 toOption */\n items: readonly T[];\n /** 执行了一项(回车或点击):面板随即关闭 */\n onAction: (item: T) => void;\n /** 输入框里的文字:父级可以写 _inputValue={x}(远程搜索时据此取数据);每次打开清空 */\n _inputValue?: string;\n /** 过滤:默认按选项文字与说明匹配(忽略大小写与重音);函数自定义;false 不过滤(远程搜索,items 就是结果) */\n filter?: false | ((item: T, query: string) => boolean);\n /** 正在取结果(远程搜索):没有结果时列表里是骨架行,已有结果时顶部显示进度条 */\n loading?: boolean;\n /** 打开面板的快捷键,默认 'Mod+K';false 不注册 */\n hotkey?: string | false;\n /** 输入框的占位文字,默认取语言包(搜索文档) */\n placeholder?: string;\n /** 面板的名称(读屏念的),默认取语言包(搜索) */\n label?: string;\n /** 触发器:`(props) => <IconButton {...props} icon={Search} aria-label=\"搜索\" />`;默认是一个像搜索框的按钮,false 不渲染 */\n trigger?: ((props: CommandPaletteTriggerProps) => VNodeChild) | false;\n /** 自定义选项内容 */\n renderOption?: (item: T, state: OptionRenderState) => VNodeChild;\n /** 没有匹配时显示的内容;默认是 Empty(文案取语言包) */\n empty?: VNodeChild;\n /** 默认触发器的部件属性 */\n propsTrigger?: Partial<ButtonBaseProps>;\n /** 输入框的部件属性 */\n propsInput?: PartProps<'input'>;\n /** 列表的部件属性 */\n propsListbox?: Partial<ListboxViewProps<T>>;\n}\n\n/** 命令面板的属性;items 不是 ListboxOption 或字符串时要给 toOption */\nexport type CommandPaletteProps<T = ListboxOption> = CommandPaletteBaseProps<T> & OptionMapping<T>;\n\n/** CommandPalette 的样式:dialog、search、input、listbox、trigger、triggerText、triggerLabel */\nexport const commandPaletteStyles = css.create({\n // 停在视口上部而不是正中:结果变多变少时输入框不跳\n dialog: { marginBlockStart: '12dvh' },\n search: {\n display: 'flex',\n alignItems: 'center',\n gap: '_sm',\n paddingBlock: '_sm',\n paddingInline: '_md',\n borderBlockEndWidth: '_xs',\n borderBlockEndStyle: 'solid',\n borderBlockEndColor: '_border',\n fontSize: '_lg',\n },\n input: { paddingBlock: '_sm' },\n listbox: { maxHeight: 'min(24rem, 50dvh)' },\n body: { padding: 0 },\n // 窄屏(40rem 以下,sizes.sm)只留放大镜图标,不挤占顶栏\n trigger: {\n gap: '_sm',\n minWidth: { default: null, [breakpoints.sm]: '12rem' },\n color: '_textMuted',\n cursor: 'pointer',\n },\n triggerText: { display: { default: 'none', [breakpoints.sm]: 'initial' } },\n // 按钮的名称来自这段文字(与看得见的一致,WCAG 2.5.3):窄屏只留图标时视觉上隐藏,读屏仍念得到\n triggerLabel: {\n flexGrow: 1,\n textAlign: 'start',\n whiteSpace: 'nowrap',\n position: { default: 'absolute', [breakpoints.sm]: 'static' },\n width: { default: 1, [breakpoints.sm]: 'auto' },\n height: { default: 1, [breakpoints.sm]: 'auto' },\n overflow: { default: 'hidden', [breakpoints.sm]: 'visible' },\n clipPath: { default: 'inset(50%)', [breakpoints.sm]: 'none' },\n },\n});\n\n/** 命令面板:快捷键打开的搜索对话框 */\nexport const CommandPalette = _component(\n <T,>({\n _open: open = _bindable(false),\n onOpenChange,\n _inputValue: inputValue = _bindable(''),\n items,\n toOption,\n onAction,\n filter,\n loading = false,\n hotkey = 'Mod+K',\n placeholder,\n label,\n trigger,\n renderOption,\n empty,\n propsTrigger,\n propsInput,\n propsListbox,\n ...rest\n }: CommandPaletteProps<T>) => {\n const lang = useLang();\n const textMatcher = useTextMatcher();\n const listId = useId();\n const appearance = useControlAppearance(() => ({}));\n const optionOf = (item: T) => toListboxOption(item, toOption);\n const setOpen = openSetter(\n () => open,\n (next) => (open = next),\n () => onOpenChange,\n );\n\n function matches(item: T, text: string) {\n if (filter === false) return true;\n if (filter) return filter(item, text);\n const match = textMatcher();\n const option = optionOf(item);\n return match(option.label, text) || match(option.description ?? '', text);\n }\n\n const list = useListState({\n items: () => (inputValue ? items.filter((item) => matches(item, inputValue)) : items),\n toOption: optionOf,\n // 面板不记选择:选中就是执行\n selected: () => [],\n mode: () => 'single',\n onChange: () => {},\n });\n\n // 每次打开从空白开始;输入变了高亮第一个结果\n watch(\n () => open,\n (isOpen) => {\n if (isOpen) inputValue = '';\n },\n );\n // 远程搜索时结果晚到:结果变了也高亮第一个\n watch([() => inputValue, () => open, () => list.options.length], () => list.move('first'), {\n flush: 'post',\n });\n\n useHotkeys(() => (hotkey ? { [hotkey]: (event) => setOpen(!open, 'imperative', event) } : {}), {\n inInputs: true,\n });\n\n function pick(value: string, event?: Event) {\n const entry = list.options[list.indexOf(value)];\n if (!entry || entry.disabled) return;\n setOpen(false, 'select', event);\n onAction(entry.item);\n }\n\n function onKeydown(event: KeyboardEvent) {\n if (handleListKeydown(list, event, { homeEnd: false }, (value) => pick(value, event)))\n event.preventDefault();\n }\n\n const triggerProps = (): CommandPaletteTriggerProps => ({\n onClick: (event: MouseEvent) => setOpen(true, 'trigger', event),\n 'aria-haspopup': 'dialog',\n 'aria-expanded': open,\n });\n\n /** 默认的触发按钮:画成输入框外壳(只取样式,部件标记归面板自己) */\n function renderTrigger(shell: ControlParts) {\n if (trigger === false) return null;\n if (trigger) return trigger(triggerProps());\n const text = placeholder ?? lang.searchPlaceholder;\n return (\n <ButtonBase\n {...mergePartProps<ButtonBaseProps>(\n {\n sx: [shell.root.sx, commandPaletteStyles.trigger],\n // 快捷键由 aria-keyshortcuts 告诉读屏,显示它的 Kbd 不算进名称\n 'aria-keyshortcuts': hotkey ? ariaKeyShortcut(hotkey) : undefined,\n },\n propsTrigger,\n triggerProps(),\n )}\n >\n <Icon icon={Search} sx={shell.icon.sx} />\n <span {...mergeAttrs<'span'>({ sx: commandPaletteStyles.triggerLabel })}>{text}</span>\n {hotkey && (\n <Kbd\n sx={commandPaletteStyles.triggerText}\n aria-hidden={ariaKeyShortcut(hotkey) ? 'true' : undefined}\n >\n {formatHotkey(hotkey)}\n </Kbd>\n )}\n </ButtonBase>\n );\n }\n\n return () => {\n const shell = controlParts(appearance(), {});\n return (\n <>\n {renderTrigger(shell)}\n <Dialog\n {...mergePartProps<DialogProps>(\n {\n title: label ?? lang.searchLabel,\n sx: commandPaletteStyles.dialog,\n size: 'sm',\n closable: false,\n // 标题只给读屏:面板的名称\n propsHeader: { sx: visuallyHiddenStyles.hidden },\n propsBody: { propsContent: { sx: commandPaletteStyles.body } },\n },\n rest as Partial<DialogProps>,\n )}\n _open={open}\n onOpenChange={onOpenChange}\n >\n <div {...mergeAttrs<'div'>({ sx: commandPaletteStyles.search })}>\n <Icon icon={Search} sx={shell.icon.sx} />\n {/* _bind 编译为 v-model:输入法组合期间不过滤 */}\n <input\n {...mergeAttrs<'input'>(\n { sx: [shell.input.sx, commandPaletteStyles.input] },\n propsInput,\n {\n role: 'combobox',\n type: 'search',\n autofocus: true,\n autocomplete: 'off',\n enterkeyhint: 'go',\n placeholder: placeholder ?? lang.searchPlaceholder,\n 'aria-label': label ?? lang.searchLabel,\n 'aria-autocomplete': 'list',\n 'aria-expanded': true,\n 'aria-controls': listId,\n 'aria-activedescendant': activeOptionId(list, listId),\n onKeydown,\n },\n )}\n _value={inputValue}\n />\n </div>\n <ListboxView\n {...mergePartProps<ListboxViewProps<T>>(\n {\n sx: commandPaletteStyles.listbox,\n list,\n id: listId,\n renderOption,\n empty,\n loading,\n propsEmpty: { description: lang.searchEmpty },\n },\n propsListbox,\n { id: listId, 'aria-label': label ?? lang.searchLabel, onPick: pick },\n )}\n />\n </Dialog>\n </>\n );\n };\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"CommandPalette.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_restProps","_createVNode","_Fragment","_mergeProps","_withDirectives","_vModelText"],"sources":["../../src/overlay/CommandPalette.tsx"],"sourcesContent":["/**\n * 命令面板:Mod+K(macOS 上 ⌘K,其他系统 Ctrl+K)或点触发按钮打开的搜索对话框,边输入边过滤,回车打开。\n * 文档站的站内搜索、后台的“跳转到…”都用它;数据由使用方给,选中后做什么也由使用方决定。\n *\n * <CommandPalette\n * items={pages}\n * toOption={(page) => ({ value: page.path, label: page.title, description: page.summary, group: page.section })}\n * onAction={(page) => router.push(page.path)}\n * />\n *\n * 结构是 Dialog(模态、焦点循环、Esc 关闭)里放一个 combobox 输入框与 ListboxView:\n * 焦点一直在输入框上,↑↓ / Page Up / Page Down 移动高亮(aria-activedescendant),Enter 选中;\n * 数据层与 Select、Combobox 相同(useListState),选项多时虚拟滚动。\n * 远程搜索与 Combobox 一样:_inputValue={keyword} 拿到输入,filter={false} 不再本地过滤,取数据时给 loading。\n */\nimport { Search } from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { useId, watch, type VNodeChild } from 'vue';\nimport { ButtonBase, type ButtonBaseProps } from '../base/ButtonBase';\nimport { Icon } from '../base/Icon';\nimport { Kbd } from '../base/Kbd';\nimport { visuallyHiddenStyles } from '../base/VisuallyHidden';\nimport { useLang, useTextMatcher } from '../config/context';\nimport { controlParts, useControlAppearance, type ControlParts } from '../input/control';\nimport {\n ListboxView,\n activeOptionId,\n type ListboxViewProps,\n type OptionRenderState,\n} from '../input/Listbox';\nimport {\n handleListKeydown,\n useListState,\n type ListboxOption,\n type OptionMapping,\n toListboxOption,\n} from '../input/list-state';\nimport { ariaKeyShortcut, formatHotkey, useHotkeys } from '../utils/dom/hotkeys';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { breakpoints } from '../config/theme/tokens';\nimport { openSetter } from '../utils/dom/open-change';\nimport { Dialog, type DialogProps } from './Dialog';\n\n/** 交给触发器的属性:展开到按钮上 */\nexport interface CommandPaletteTriggerProps {\n /** 打开面板 */\n onClick: (event: MouseEvent) => void;\n /** 告诉读屏这个按钮会打开对话框 */\n 'aria-haspopup': 'dialog';\n /** 面板是否打开 */\n 'aria-expanded': boolean;\n}\n\n/** 与数据类型无关的属性;未声明的属性落到对话框(dialog)上 */\nexport interface CommandPaletteBaseProps<T> extends Omit<\n DialogProps,\n 'open' | 'title' | 'description' | 'footer' | 'children' | 'onSelect'\n> {\n /** 是否打开:父级可以写 _open={x};快捷键、触发按钮、选中、Esc 都会改它 */\n _open?: boolean;\n /** 数据:ListboxOption、字符串,或任意数据加 toOption */\n items: readonly T[];\n /** 执行了一项(回车或点击):面板随即关闭 */\n onAction: (item: T) => void;\n /** 输入框里的文字:父级可以写 _inputValue={x}(远程搜索时据此取数据);每次打开清空 */\n _inputValue?: string;\n /** 过滤:默认按选项文字与说明匹配(忽略大小写与重音);函数自定义;false 不过滤(远程搜索,items 就是结果) */\n filter?: false | ((item: T, query: string) => boolean);\n /** 正在取结果(远程搜索):没有结果时列表里是骨架行,已有结果时顶部显示进度条 */\n loading?: boolean;\n /** 打开面板的快捷键,默认 'Mod+K';false 不注册 */\n hotkey?: string | false;\n /** 输入框的占位文字,默认取语言包(搜索文档) */\n placeholder?: string;\n /** 面板的名称(读屏念的),默认取语言包(搜索) */\n label?: string;\n /** 触发器:`(props) => <IconButton {...props} icon={Search} aria-label=\"搜索\" />`;默认是一个像搜索框的按钮,false 不渲染 */\n trigger?: ((props: CommandPaletteTriggerProps) => VNodeChild) | false;\n /** 自定义选项内容 */\n renderOption?: (item: T, state: OptionRenderState) => VNodeChild;\n /** 没有匹配时显示的内容;默认是 Empty(文案取语言包) */\n empty?: VNodeChild;\n /** 默认触发器的部件属性 */\n propsTrigger?: Partial<ButtonBaseProps>;\n /** 输入框的部件属性 */\n propsInput?: PartProps<'input'>;\n /** 列表的部件属性 */\n propsListbox?: Partial<ListboxViewProps<T>>;\n}\n\n/** 命令面板的属性;items 不是 ListboxOption 或字符串时要给 toOption */\nexport type CommandPaletteProps<T = ListboxOption> = CommandPaletteBaseProps<T> & OptionMapping<T>;\n\n/** CommandPalette 的样式:dialog、search、input、listbox、trigger、triggerText、triggerLabel */\nexport const commandPaletteStyles = css.create({\n // 停在视口上部而不是正中:结果变多变少时输入框不跳\n dialog: { marginBlockStart: '12dvh' },\n search: {\n display: 'flex',\n alignItems: 'center',\n gap: '_sm',\n paddingBlock: '_sm',\n paddingInline: '_md',\n borderBlockEndWidth: '_xs',\n borderBlockEndStyle: 'solid',\n borderBlockEndColor: '_border',\n fontSize: '_lg',\n },\n input: { paddingBlock: '_sm' },\n listbox: { maxHeight: 'min(24rem, 50dvh)' },\n body: { padding: 0 },\n // 窄屏(40rem 以下,sizes.sm)只留放大镜图标,不挤占顶栏\n trigger: {\n gap: '_sm',\n minWidth: { default: null, [breakpoints.sm]: '12rem' },\n color: '_textMuted',\n cursor: 'pointer',\n },\n triggerText: { display: { default: 'none', [breakpoints.sm]: 'initial' } },\n // 按钮的名称来自这段文字(与看得见的一致,WCAG 2.5.3):窄屏只留图标时视觉上隐藏,读屏仍念得到\n triggerLabel: {\n flexGrow: 1,\n textAlign: 'start',\n whiteSpace: 'nowrap',\n position: { default: 'absolute', [breakpoints.sm]: 'static' },\n width: { default: 1, [breakpoints.sm]: 'auto' },\n height: { default: 1, [breakpoints.sm]: 'auto' },\n overflow: { default: 'hidden', [breakpoints.sm]: 'visible' },\n clipPath: { default: 'inset(50%)', [breakpoints.sm]: 'none' },\n },\n});\n\n/** 命令面板:快捷键打开的搜索对话框 */\nexport const CommandPalette = _component(\n <T,>({\n _open: open = _bindable(false),\n onOpenChange,\n _inputValue: inputValue = _bindable(''),\n items,\n toOption,\n onAction,\n filter,\n loading = false,\n hotkey = 'Mod+K',\n placeholder,\n label,\n trigger,\n renderOption,\n empty,\n propsTrigger,\n propsInput,\n propsListbox,\n ...rest\n }: CommandPaletteProps<T>) => {\n const lang = useLang();\n const textMatcher = useTextMatcher();\n const listId = useId();\n const appearance = useControlAppearance(() => ({}));\n const optionOf = (item: T) => toListboxOption(item, toOption);\n const setOpen = openSetter(\n () => open,\n (next) => (open = next),\n () => onOpenChange,\n );\n\n function matches(item: T, text: string) {\n if (filter === false) return true;\n if (filter) return filter(item, text);\n const match = textMatcher();\n const option = optionOf(item);\n return match(option.label, text) || match(option.description ?? '', text);\n }\n\n const list = useListState({\n items: () => (inputValue ? items.filter((item) => matches(item, inputValue)) : items),\n toOption: optionOf,\n // 面板不记选择:选中就是执行\n selected: () => [],\n mode: () => 'single',\n onChange: () => {},\n });\n\n // 每次打开从空白开始;输入变了高亮第一个结果\n watch(\n () => open,\n (isOpen) => {\n if (isOpen) inputValue = '';\n },\n );\n // 远程搜索时结果晚到:结果变了也高亮第一个\n watch([() => inputValue, () => open, () => list.options.length], () => list.move('first'), {\n flush: 'post',\n });\n\n useHotkeys(() => (hotkey ? { [hotkey]: (event) => setOpen(!open, 'imperative', event) } : {}), {\n inInputs: true,\n });\n\n function pick(value: string, event?: Event) {\n const entry = list.options[list.indexOf(value)];\n if (!entry || entry.disabled) return;\n setOpen(false, 'select', event);\n onAction(entry.item);\n }\n\n function onKeydown(event: KeyboardEvent) {\n if (handleListKeydown(list, event, { homeEnd: false }, (value) => pick(value, event)))\n event.preventDefault();\n }\n\n const triggerProps = (): CommandPaletteTriggerProps => ({\n onClick: (event: MouseEvent) => setOpen(true, 'trigger', event),\n 'aria-haspopup': 'dialog',\n 'aria-expanded': open,\n });\n\n /** 默认的触发按钮:画成输入框外壳(只取样式,部件标记归面板自己) */\n function renderTrigger(shell: ControlParts) {\n if (trigger === false) return null;\n if (trigger) return trigger(triggerProps());\n const text = placeholder ?? lang.searchPlaceholder;\n return (\n <ButtonBase\n {...mergePartProps<ButtonBaseProps>(\n {\n sx: [shell.root.sx, commandPaletteStyles.trigger],\n // 快捷键由 aria-keyshortcuts 告诉读屏,显示它的 Kbd 不算进名称\n 'aria-keyshortcuts': hotkey ? ariaKeyShortcut(hotkey) : undefined,\n },\n propsTrigger,\n triggerProps(),\n )}\n >\n <Icon icon={Search} sx={shell.icon.sx} />\n <span {...mergeAttrs<'span'>({ sx: commandPaletteStyles.triggerLabel })}>{text}</span>\n {hotkey && (\n <Kbd\n sx={commandPaletteStyles.triggerText}\n aria-hidden={ariaKeyShortcut(hotkey) ? 'true' : undefined}\n >\n {formatHotkey(hotkey)}\n </Kbd>\n )}\n </ButtonBase>\n );\n }\n\n return () => {\n const shell = controlParts(appearance(), {});\n return (\n <>\n {renderTrigger(shell)}\n <Dialog\n {...mergePartProps<DialogProps>(\n {\n title: label ?? lang.searchLabel,\n sx: commandPaletteStyles.dialog,\n size: 'sm',\n closable: false,\n // 标题只给读屏:面板的名称\n propsHeader: { sx: visuallyHiddenStyles.hidden },\n propsBody: { propsContent: { sx: commandPaletteStyles.body } },\n },\n rest as Partial<DialogProps>,\n )}\n _open={open}\n onOpenChange={onOpenChange}\n >\n <div {...mergeAttrs<'div'>({ sx: commandPaletteStyles.search })}>\n <Icon icon={Search} sx={shell.icon.sx} />\n {/* _bind 编译为 v-model:输入法组合期间不过滤 */}\n <input\n {...mergeAttrs<'input'>(\n { sx: [shell.input.sx, commandPaletteStyles.input] },\n propsInput,\n {\n role: 'combobox',\n type: 'search',\n autofocus: true,\n autocomplete: 'off',\n enterkeyhint: 'go',\n placeholder: placeholder ?? lang.searchPlaceholder,\n 'aria-label': label ?? lang.searchLabel,\n 'aria-autocomplete': 'list',\n 'aria-expanded': true,\n 'aria-controls': listId,\n 'aria-activedescendant': activeOptionId(list, listId),\n onKeydown,\n },\n )}\n _value={inputValue}\n />\n </div>\n <ListboxView\n {...mergePartProps<ListboxViewProps<T>>(\n {\n sx: commandPaletteStyles.listbox,\n list,\n id: listId,\n renderOption,\n empty,\n loading,\n propsEmpty: { description: lang.searchEmpty },\n },\n propsListbox,\n { id: listId, 'aria-label': label ?? lang.searchLabel, onPick: pick },\n )}\n />\n </Dialog>\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 { ContainerSizes } from '../layout/Container';
3
3
  import { type DetachedOverlayHandle, type DetachedOverlayOptions } from './detached';
4
4
  import { type ModalProps } from './ModalCore';
@@ -6,7 +6,7 @@ import { useDetachedOverlay } from "./detached.js";
6
6
  import { ModalCore, modalPartStyles } from "./ModalCore.js";
7
7
  import { createVNode, isVNode } from "vue";
8
8
  import { _component, bindable, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
9
- import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
9
+ import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
10
10
  //#region src/overlay/Dialog.tsx
11
11
  /** 对话框的宽度档位,与 Container 相同(30–80rem),另加 full 占满视口 */
12
12
  /** 对话框的外观选项;可以用 createUi / Provider 的 defaults.Dialog 统一改默认值(AlertDialog 也用它) */
@@ -1 +1 @@
1
- {"version":3,"file":"Dialog.js","names":["_isVNode","_vtp_bindable","_vtp_readonlyProp","_vtp_restProps","_createVNode","_mergeProps"],"sources":["../../src/overlay/Dialog.tsx"],"sourcesContent":["/**\n * 模态对话框:居中显示,淡入放大。内核见 ModalCore.tsx,贴着视口一侧滑入的见 Drawer。\n *\n * <Dialog _open={editing} title=\"编辑资料\" footer={<Button onClick={save}>保存</Button>}>…</Dialog>\n *\n * 不想自己管 open(从表格的一行打开详情、在回调里弹出)时用命令式的 useDialog:\n *\n * const dialog = useDialog(); // setup 里\n * const handle = dialog.open({ title: '订单详情', size: 'md', content: () => <OrderDetail id={id} /> });\n * handle.update({ title: '订单详情(已发货)' }); handle.close(); await handle.closed;\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { ContainerSizes } from '../layout/Container';\nimport {\n useDetachedOverlay,\n type DetachedOverlayHandle,\n type DetachedOverlayOptions,\n} from './detached';\nimport { useDefaults } from '../config/defaults';\nimport { useRecipe } from '../config/styles';\nimport { transitions } from '../utils/style/transitions';\nimport { ModalCore, modalPartStyles, type ModalProps } from './ModalCore';\nimport { t } from '../config/theme/tokens';\n\n/** 对话框的宽度档位,与 Container 相同(30–80rem),另加 full 占满视口 */\nexport interface DialogSizes extends ContainerSizes {\n /** 占满视口(四周留出 1em) */\n full: unknown;\n}\n\n/** 对话框的外观选项;可以用 createUi / Provider 的 defaults.Dialog 统一改默认值(AlertDialog 也用它) */\nexport interface DialogOptions {\n /** 宽度档位,默认 xs(30rem);窄屏时不超出视口 */\n size?: keyof DialogSizes;\n}\n\n/** 未声明的属性落到 dialog 上 */\nexport interface DialogProps extends ModalProps, DialogOptions {}\n\n/**\n * 对话框的配方(Dialog、AlertDialog 共用):部件同 ModalCore(base 并进了 modalPartStyles);\n * root 是 dialog 元素,宽度占满可用空间、高度上限、圆角,宽度档位不超出视口,full 占满视口\n */\nexport const dialogRecipe = css.recipe({\n name: 'Dialog',\n parts: ['root', 'header', 'title', 'close', 'description', 'body', 'bodyContent', 'footer'],\n base: {\n ...modalPartStyles,\n root: {\n ...modalPartStyles.root,\n width: '_full',\n // 原生 dialog 已限制 max-width / max-height 不超出视口;这里只把高度上限放到四周各留 1em\n maxHeight: 'calc(100dvh - 2em)',\n borderRadius: '_xl',\n },\n },\n variants: {\n size: {\n xs: { root: { maxWidth: `min(${t.sizes.xs}, calc(100vw - 2em))` } },\n sm: { root: { maxWidth: `min(${t.sizes.sm}, calc(100vw - 2em))` } },\n md: { root: { maxWidth: `min(${t.sizes.md}, calc(100vw - 2em))` } },\n lg: { root: { maxWidth: `min(${t.sizes.lg}, calc(100vw - 2em))` } },\n xl: { root: { maxWidth: `min(${t.sizes.xl}, calc(100vw - 2em))` } },\n full: { root: { maxWidth: 'calc(100vw - 2em)', height: 'calc(100dvh - 2em)' } },\n },\n },\n});\n\n/** 对话框的部件(createUi / Provider 的 styles.Dialog 按它定制,AlertDialog 也用它) */\nexport type DialogPart = (typeof dialogRecipe.parts)[number];\n\n/** 模态对话框:居中显示,淡入放大 */\nexport const Dialog = _component(\n ({ _open: open = _bindable(false), size, ...rest }: DialogProps) => {\n const appearance = useDefaults('Dialog', () => ({ size }), { size: 'xs' });\n const recipe = useRecipe(dialogRecipe);\n return () => (\n <ModalCore\n {...rest}\n parts={recipe({ size: appearance().size })}\n panelSx={transitions.scale}\n _open={open}\n />\n );\n },\n);\n\n/** useDialog 返回的:open 打开一个对话框 */\nexport interface DialogApi {\n /** 打开对话框:属性同 Dialog(open 由句柄管理),content 是正文;返回句柄 */\n open(options: DetachedOverlayOptions<DialogProps>): DetachedOverlayHandle<DialogProps>;\n}\n\n/**\n * 命令式对话框:在组件 setup 里调用。对话框渲染到 body 末尾,沿用调用处的主题、语言等配置,关上后自动卸载。\n * 句柄的 closed 得到关上的原因(确认是 confirm);只想问一句“确定吗”用 useConfirm。\n */\nexport function useDialog(): DialogApi {\n const open = useDetachedOverlay<DialogProps>((props, host, children) => (\n <Dialog {...props} _open={host.open}>\n {children}\n </Dialog>\n ));\n return { open };\n}\n"],"mappings":";;;;;;;;;;;;;AAqCA,SAAA,QAAA,GAAA;CAAA,OAAA,OAAA,MAAA,cAAA,OAAA,UAAA,SAAA,KAAA,CAAA,MAAA,qBAAA,CAAAA,QAAA,CAAA;AAAA;;;;;AAOA,IAAa,eAAe,IAAI,OAAO;CACrC,MAAM;CACN,OAAO;EAAC;EAAQ;EAAU;EAAS;EAAS;EAAe;EAAQ;EAAe;CAAQ;CAC1F,MAAM;EACJ,GAAG;EACH,MAAM;GACJ,GAAG,gBAAgB;GACnB,OAAO;GAEP,WAAW;GACX,cAAc;EAChB;CACF;CACA,UAAU,EACR,MAAM;EACJ,IAAI,EAAE,MAAM,EAAE,UAAU,OAAO,EAAE,MAAM,GAAE,sBAAuB,EAAE;EAClE,IAAI,EAAE,MAAM,EAAE,UAAU,OAAO,EAAE,MAAM,GAAE,sBAAuB,EAAE;EAClE,IAAI,EAAE,MAAM,EAAE,UAAU,OAAO,EAAE,MAAM,GAAE,sBAAuB,EAAE;EAClE,IAAI,EAAE,MAAM,EAAE,UAAU,OAAO,EAAE,MAAM,GAAE,sBAAuB,EAAE;EAClE,IAAI,EAAE,MAAM,EAAE,UAAU,OAAO,EAAE,MAAM,GAAE,sBAAuB,EAAE;EAClE,MAAM,EAAE,MAAM;GAAE,UAAU;GAAqB,QAAQ;EAAqB,EAAE;CAChF,EACF;AACF,CAAC;;;AAMD,IAAa,SAAS,0BACpB,QAAA,SAAoE;CAAA,MAAA,SAAA,CAAA;CAAA,MAAA,OAAAC,SAAA,QAAA,eAAzC,OAAK,KAAA,IAAA;CAAA,MAAA,OAAAC,aAAA,QAAA,MAAA;CAAA,MAAY,OAAIC,UAAA,QAAA,MAAA,IAAA;CAC9C,MAAM,aAAa,YAAY,iBAAiB,EAAE,MAAI,KAAA,MAAC,IAAI,EAAE,MAAM,KAAK,CAAC;CACzE,MAAM,SAAS,UAAU,YAAY;CACrC,aAAOC,YAAA,WAAAC,cAEC,MAAI;EAAA,SACD,OAAO,EAAE,MAAM,WAAW,CAAC,CAAC,KAAK,CAAC;EAAC,WACjC,YAAY;EAAK,SAAA,KAAA;EAAA,kBAAA,OAAA,OAAA,OAAA,MAAA,WAAA,KAAA,QAAA;CAAA,CAAA,GAAA,IAAA;AAIhC,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH;;;;;;AAYA,SAAgB,YAAuB;CAMrC,OAAO,EAAE,MALI,oBAAiC,OAAO,MAAM,aAAQD,YAAA,QAAAC,cACrD,OAAK;EAAA,SAAS,KAAK;EAAI,mBAAA,WAAT,KAAK,OAAI;CAAA,CAAA,GAAA,QAChC,QAAQ,IAAR,WAAQ,EAAA,eAAA,CAAR,QAAQ,EAAA,CAAA,CAGJ,EAAK;AAChB"}
1
+ {"version":3,"file":"Dialog.js","names":["_isVNode","_vtp_bindable","_vtp_readonlyProp","_vtp_restProps","_createVNode","_mergeProps"],"sources":["../../src/overlay/Dialog.tsx"],"sourcesContent":["/**\n * 模态对话框:居中显示,淡入放大。内核见 ModalCore.tsx,贴着视口一侧滑入的见 Drawer。\n *\n * <Dialog _open={editing} title=\"编辑资料\" footer={<Button onClick={save}>保存</Button>}>…</Dialog>\n *\n * 不想自己管 open(从表格的一行打开详情、在回调里弹出)时用命令式的 useDialog:\n *\n * const dialog = useDialog(); // setup 里\n * const handle = dialog.open({ title: '订单详情', size: 'md', content: () => <OrderDetail id={id} /> });\n * handle.update({ title: '订单详情(已发货)' }); handle.close(); await handle.closed;\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport { css } from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { ContainerSizes } from '../layout/Container';\nimport {\n useDetachedOverlay,\n type DetachedOverlayHandle,\n type DetachedOverlayOptions,\n} from './detached';\nimport { useDefaults } from '../config/defaults';\nimport { useRecipe } from '../config/styles';\nimport { transitions } from '../utils/style/transitions';\nimport { ModalCore, modalPartStyles, type ModalProps } from './ModalCore';\nimport { t } from '../config/theme/tokens';\n\n/** 对话框的宽度档位,与 Container 相同(30–80rem),另加 full 占满视口 */\nexport interface DialogSizes extends ContainerSizes {\n /** 占满视口(四周留出 1em) */\n full: unknown;\n}\n\n/** 对话框的外观选项;可以用 createUi / Provider 的 defaults.Dialog 统一改默认值(AlertDialog 也用它) */\nexport interface DialogOptions {\n /** 宽度档位,默认 xs(30rem);窄屏时不超出视口 */\n size?: keyof DialogSizes;\n}\n\n/** 未声明的属性落到 dialog 上 */\nexport interface DialogProps extends ModalProps, DialogOptions {}\n\n/**\n * 对话框的配方(Dialog、AlertDialog 共用):部件同 ModalCore(base 并进了 modalPartStyles);\n * root 是 dialog 元素,宽度占满可用空间、高度上限、圆角,宽度档位不超出视口,full 占满视口\n */\nexport const dialogRecipe = css.recipe({\n name: 'Dialog',\n parts: ['root', 'header', 'title', 'close', 'description', 'body', 'bodyContent', 'footer'],\n base: {\n ...modalPartStyles,\n root: {\n ...modalPartStyles.root,\n width: '_full',\n // 原生 dialog 已限制 max-width / max-height 不超出视口;这里只把高度上限放到四周各留 1em\n maxHeight: 'calc(100dvh - 2em)',\n borderRadius: '_xl',\n },\n },\n variants: {\n size: {\n xs: { root: { maxWidth: `min(${t.sizes.xs}, calc(100vw - 2em))` } },\n sm: { root: { maxWidth: `min(${t.sizes.sm}, calc(100vw - 2em))` } },\n md: { root: { maxWidth: `min(${t.sizes.md}, calc(100vw - 2em))` } },\n lg: { root: { maxWidth: `min(${t.sizes.lg}, calc(100vw - 2em))` } },\n xl: { root: { maxWidth: `min(${t.sizes.xl}, calc(100vw - 2em))` } },\n full: { root: { maxWidth: 'calc(100vw - 2em)', height: 'calc(100dvh - 2em)' } },\n },\n },\n});\n\n/** 对话框的部件(createUi / Provider 的 styles.Dialog 按它定制,AlertDialog 也用它) */\nexport type DialogPart = (typeof dialogRecipe.parts)[number];\n\n/** 模态对话框:居中显示,淡入放大 */\nexport const Dialog = _component(\n ({ _open: open = _bindable(false), size, ...rest }: DialogProps) => {\n const appearance = useDefaults('Dialog', () => ({ size }), { size: 'xs' });\n const recipe = useRecipe(dialogRecipe);\n return () => (\n <ModalCore\n {...rest}\n parts={recipe({ size: appearance().size })}\n panelSx={transitions.scale}\n _open={open}\n />\n );\n },\n);\n\n/** useDialog 返回的:open 打开一个对话框 */\nexport interface DialogApi {\n /** 打开对话框:属性同 Dialog(open 由句柄管理),content 是正文;返回句柄 */\n open(options: DetachedOverlayOptions<DialogProps>): DetachedOverlayHandle<DialogProps>;\n}\n\n/**\n * 命令式对话框:在组件 setup 里调用。对话框渲染到 body 末尾,沿用调用处的主题、语言等配置,关上后自动卸载。\n * 句柄的 closed 得到关上的原因(确认是 confirm);只想问一句“确定吗”用 useConfirm。\n */\nexport function useDialog(): DialogApi {\n const open = useDetachedOverlay<DialogProps>((props, host, children) => (\n <Dialog {...props} _open={host.open}>\n {children}\n </Dialog>\n ));\n return { open };\n}\n"],"mappings":";;;;;;;;;;;;;AAqCA,SAAA,QAAA,GAAA;CAAA,OAAA,OAAA,MAAA,cAAA,OAAA,UAAA,SAAA,KAAA,CAAA,MAAA,qBAAA,CAAAA,QAAA,CAAA;AAAA;;;;;AAOA,IAAa,eAAe,IAAI,OAAO;CACrC,MAAM;CACN,OAAO;EAAC;EAAQ;EAAU;EAAS;EAAS;EAAe;EAAQ;EAAe;CAAQ;CAC1F,MAAM;EACJ,GAAG;EACH,MAAM;GACJ,GAAG,gBAAgB;GACnB,OAAO;GAEP,WAAW;GACX,cAAc;EAChB;CACF;CACA,UAAU,EACR,MAAM;EACJ,IAAI,EAAE,MAAM,EAAE,UAAU,OAAO,EAAE,MAAM,GAAE,sBAAuB,EAAE;EAClE,IAAI,EAAE,MAAM,EAAE,UAAU,OAAO,EAAE,MAAM,GAAE,sBAAuB,EAAE;EAClE,IAAI,EAAE,MAAM,EAAE,UAAU,OAAO,EAAE,MAAM,GAAE,sBAAuB,EAAE;EAClE,IAAI,EAAE,MAAM,EAAE,UAAU,OAAO,EAAE,MAAM,GAAE,sBAAuB,EAAE;EAClE,IAAI,EAAE,MAAM,EAAE,UAAU,OAAO,EAAE,MAAM,GAAE,sBAAuB,EAAE;EAClE,MAAM,EAAE,MAAM;GAAE,UAAU;GAAqB,QAAQ;EAAqB,EAAE;CAChF,EACF;AACF,CAAC;;;AAMD,IAAa,SAAS,0BACpB,QAAA,SAAoE;CAAA,MAAA,SAAA,CAAA;CAAA,MAAA,OAAAC,SAAA,QAAA,eAAzC,OAAK,KAAA,IAAA;CAAA,MAAA,OAAAC,aAAA,QAAA,MAAA;CAAA,MAAY,OAAIC,UAAA,QAAA,MAAA,IAAA;CAC9C,MAAM,aAAa,YAAY,iBAAiB,EAAE,MAAI,KAAA,MAAC,IAAI,EAAE,MAAM,KAAK,CAAC;CACzE,MAAM,SAAS,UAAU,YAAY;CACrC,aAAOC,YAAA,WAAAC,cAEC,MAAI;EAAA,SACD,OAAO,EAAE,MAAM,WAAW,CAAC,CAAC,KAAK,CAAC;EAAC,WACjC,YAAY;EAAK,SAAA,KAAA;EAAA,kBAAA,OAAA,OAAA,OAAA,MAAA,WAAA,KAAA,QAAA;CAAA,CAAA,GAAA,IAAA;AAIhC,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH;;;;;;AAYA,SAAgB,YAAuB;CAMrC,OAAO,EAAE,MALI,oBAAiC,OAAO,MAAM,aAAQD,YAAA,QAAAC,cACrD,OAAK;EAAA,SAAS,KAAK;EAAI,mBAAA,WAAT,KAAK,OAAI;CAAA,CAAA,GAAA,QAChC,QAAQ,IAAR,WAAQ,EAAA,eAAA,CAAR,QAAQ,EAAA,CAAA,CAGJ,EAAK;AAChB"}
@@ -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 { ContainerSizes } from '../layout/Container';
3
3
  import { type ResizeHandleProps } from '../layout/ResizeHandle';
4
4
  import { type DetachedOverlayHandle, type DetachedOverlayOptions } from './detached';
@@ -7,7 +7,7 @@ import { useDetachedOverlay } from "./detached.js";
7
7
  import { ModalCore, modalPartStyles } from "./ModalCore.js";
8
8
  import { createVNode, isVNode } from "vue";
9
9
  import { _component, bindable, mergeJsxProps, readonlyProp, restProps, untrack } from "@zerodep-dev/vue-tsx-pro-tsx";
10
- import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
10
+ import { css } from "@zerodep-dev/vue-tsx-pro-tsx/styles";
11
11
  //#region src/overlay/Drawer.tsx
12
12
  /** 抽屉从哪一侧滑入;start / end 是逻辑方向,从右到左排版下左右互换 */
13
13
  /** 抽屉的外观选项;可以用 createUi / Provider 的 defaults.Drawer 统一改默认值 */