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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (470) hide show
  1. package/dist/base/Badge.js +3 -3
  2. package/dist/base/Badge.js.map +1 -1
  3. package/dist/base/Can.d.ts +12 -0
  4. package/dist/base/Can.js +20 -0
  5. package/dist/base/Can.js.map +1 -0
  6. package/dist/base/ClientOnly.d.ts +10 -0
  7. package/dist/base/ClientOnly.js +18 -0
  8. package/dist/base/ClientOnly.js.map +1 -0
  9. package/dist/base/CloseButton.js +3 -3
  10. package/dist/base/CloseButton.js.map +1 -1
  11. package/dist/base/CodeBlock.js +5 -5
  12. package/dist/base/CodeBlock.js.map +1 -1
  13. package/dist/base/CopyButton.js +3 -3
  14. package/dist/base/CopyButton.js.map +1 -1
  15. package/dist/base/Icon.js +3 -3
  16. package/dist/base/Icon.js.map +1 -1
  17. package/dist/base/Indicator.js +3 -3
  18. package/dist/base/Indicator.js.map +1 -1
  19. package/dist/base/StatusDot.js +3 -3
  20. package/dist/base/StatusDot.js.map +1 -1
  21. package/dist/base/Tag.js +5 -5
  22. package/dist/base/Tag.js.map +1 -1
  23. package/dist/base/button-core.js +4 -4
  24. package/dist/base/button-core.js.map +1 -1
  25. package/dist/charts/AreaChart.js +3 -3
  26. package/dist/charts/AreaChart.js.map +1 -1
  27. package/dist/charts/BarChart.js +3 -3
  28. package/dist/charts/BarChart.js.map +1 -1
  29. package/dist/charts/ChordChart.js +3 -3
  30. package/dist/charts/ChordChart.js.map +1 -1
  31. package/dist/charts/ComboChart.js +3 -3
  32. package/dist/charts/ComboChart.js.map +1 -1
  33. package/dist/charts/DonutChart.js +3 -3
  34. package/dist/charts/DonutChart.js.map +1 -1
  35. package/dist/charts/FunnelChart.js +5 -5
  36. package/dist/charts/FunnelChart.js.map +1 -1
  37. package/dist/charts/GraphChart.js +3 -3
  38. package/dist/charts/GraphChart.js.map +1 -1
  39. package/dist/charts/LineChart.js +3 -3
  40. package/dist/charts/LineChart.js.map +1 -1
  41. package/dist/charts/MapChart.js +7 -7
  42. package/dist/charts/MapChart.js.map +1 -1
  43. package/dist/charts/RadarChart.js +16 -15
  44. package/dist/charts/RadarChart.js.map +1 -1
  45. package/dist/charts/SankeyChart.js +3 -3
  46. package/dist/charts/SankeyChart.js.map +1 -1
  47. package/dist/charts/ScatterChart.js +3 -3
  48. package/dist/charts/ScatterChart.js.map +1 -1
  49. package/dist/charts/TimelineChart.js +6 -5
  50. package/dist/charts/TimelineChart.js.map +1 -1
  51. package/dist/charts/TreemapChart.js +3 -3
  52. package/dist/charts/TreemapChart.js.map +1 -1
  53. package/dist/charts/WaterfallChart.js +3 -3
  54. package/dist/charts/WaterfallChart.js.map +1 -1
  55. package/dist/charts/XYChart.js +9 -7
  56. package/dist/charts/XYChart.js.map +1 -1
  57. package/dist/charts/frame.js +10 -8
  58. package/dist/charts/frame.js.map +1 -1
  59. package/dist/charts/single.js +4 -3
  60. package/dist/charts/single.js.map +1 -1
  61. package/dist/code-editor/CodeEditor.d.ts +18 -0
  62. package/dist/code-editor/CodeEditor.js +57 -0
  63. package/dist/code-editor/CodeEditor.js.map +1 -0
  64. package/dist/code-editor/editor.d.ts +52 -0
  65. package/dist/code-editor/editor.js +225 -0
  66. package/dist/code-editor/editor.js.map +1 -0
  67. package/dist/code-editor/index.d.ts +9 -0
  68. package/dist/code-editor/index.js +3 -0
  69. package/dist/config/Provider.d.ts +3 -1
  70. package/dist/config/Provider.js +9 -4
  71. package/dist/config/Provider.js.map +1 -1
  72. package/dist/config/context.d.ts +18 -0
  73. package/dist/config/context.js +16 -1
  74. package/dist/config/context.js.map +1 -1
  75. package/dist/config/createUi.d.ts +20 -3
  76. package/dist/config/createUi.js +80 -49
  77. package/dist/config/createUi.js.map +1 -1
  78. package/dist/config/lang/en-US.js +21 -3
  79. package/dist/config/lang/en-US.js.map +1 -1
  80. package/dist/config/lang/format.d.ts +2 -1
  81. package/dist/config/lang/format.js +9 -2
  82. package/dist/config/lang/format.js.map +1 -1
  83. package/dist/config/lang/lang.d.ts +19 -6
  84. package/dist/config/lang/lang.js +11 -2
  85. package/dist/config/lang/lang.js.map +1 -1
  86. package/dist/config/lang/zh-CN.js +21 -3
  87. package/dist/config/lang/zh-CN.js.map +1 -1
  88. package/dist/config/layout/preference.d.ts +43 -0
  89. package/dist/config/layout/preference.js +108 -0
  90. package/dist/config/layout/preference.js.map +1 -0
  91. package/dist/date/Calendar.js +3 -3
  92. package/dist/date/Calendar.js.map +1 -1
  93. package/dist/date/CalendarBoard.js +9 -9
  94. package/dist/date/CalendarBoard.js.map +1 -1
  95. package/dist/date/CalendarView.js +7 -7
  96. package/dist/date/CalendarView.js.map +1 -1
  97. package/dist/date/DateField.js +3 -3
  98. package/dist/date/DateField.js.map +1 -1
  99. package/dist/date/DatePicker.js +5 -5
  100. package/dist/date/DatePicker.js.map +1 -1
  101. package/dist/date/DateRangePicker.js +5 -5
  102. package/dist/date/DateRangePicker.js.map +1 -1
  103. package/dist/date/DateSegmentGroup.js +5 -5
  104. package/dist/date/DateSegmentGroup.js.map +1 -1
  105. package/dist/date/QuarterCalendar.js +6 -6
  106. package/dist/date/QuarterCalendar.js.map +1 -1
  107. package/dist/date/RangeCalendar.js +3 -3
  108. package/dist/date/RangeCalendar.js.map +1 -1
  109. package/dist/date/SegmentedField.js +3 -3
  110. package/dist/date/SegmentedField.js.map +1 -1
  111. package/dist/date/TimeField.js +3 -3
  112. package/dist/date/TimeField.js.map +1 -1
  113. package/dist/date/TimePicker.js +4 -4
  114. package/dist/date/TimePicker.js.map +1 -1
  115. package/dist/date/date-segments.js +1 -1
  116. package/dist/date/date-segments.js.map +1 -1
  117. package/dist/date/picker-popover.js +3 -2
  118. package/dist/date/picker-popover.js.map +1 -1
  119. package/dist/diagram/Diagram.js +12 -12
  120. package/dist/diagram/Diagram.js.map +1 -1
  121. package/dist/diagram/DiagramLanes.js +3 -3
  122. package/dist/diagram/DiagramLanes.js.map +1 -1
  123. package/dist/diagram/DiagramMinimap.js +4 -4
  124. package/dist/diagram/DiagramMinimap.js.map +1 -1
  125. package/dist/diagram/index.d.ts +2 -1
  126. package/dist/diagram/index.js +2 -1
  127. package/dist/diagram/layout.d.ts +57 -0
  128. package/dist/diagram/layout.js +50 -0
  129. package/dist/diagram/layout.js.map +1 -0
  130. package/dist/display/Accordion.js +6 -6
  131. package/dist/display/Accordion.js.map +1 -1
  132. package/dist/display/AnimatedNumber.js +4 -4
  133. package/dist/display/AnimatedNumber.js.map +1 -1
  134. package/dist/display/Avatar.js +4 -4
  135. package/dist/display/Avatar.js.map +1 -1
  136. package/dist/display/Checklist.js +7 -7
  137. package/dist/display/Checklist.js.map +1 -1
  138. package/dist/display/Collapse.js +8 -5
  139. package/dist/display/Collapse.js.map +1 -1
  140. package/dist/display/Collapsible.js +3 -3
  141. package/dist/display/Collapsible.js.map +1 -1
  142. package/dist/display/Descriptions.js +5 -5
  143. package/dist/display/Descriptions.js.map +1 -1
  144. package/dist/display/Ellipsis.js +3 -3
  145. package/dist/display/Ellipsis.js.map +1 -1
  146. package/dist/display/FieldCompare.js +4 -4
  147. package/dist/display/FieldCompare.js.map +1 -1
  148. package/dist/display/Gauge.js +11 -11
  149. package/dist/display/Gauge.js.map +1 -1
  150. package/dist/display/Image.js +4 -4
  151. package/dist/display/Image.js.map +1 -1
  152. package/dist/display/Marquee.js +3 -3
  153. package/dist/display/Marquee.js.map +1 -1
  154. package/dist/display/ProportionBar.js +4 -4
  155. package/dist/display/ProportionBar.js.map +1 -1
  156. package/dist/display/Sortable.js +4 -4
  157. package/dist/display/Sortable.js.map +1 -1
  158. package/dist/display/Sparkline.js +6 -6
  159. package/dist/display/Sparkline.js.map +1 -1
  160. package/dist/display/Stat.js +3 -3
  161. package/dist/display/Stat.js.map +1 -1
  162. package/dist/display/Timeline.js +7 -7
  163. package/dist/display/Timeline.js.map +1 -1
  164. package/dist/display/Tree.js +10 -10
  165. package/dist/display/Tree.js.map +1 -1
  166. package/dist/display/VirtualList.js +7 -7
  167. package/dist/display/VirtualList.js.map +1 -1
  168. package/dist/display/Watermark.js +3 -3
  169. package/dist/display/Watermark.js.map +1 -1
  170. package/dist/docs-kit/CodeGroup.js +5 -5
  171. package/dist/docs-kit/CodeGroup.js.map +1 -1
  172. package/dist/docs-kit/CodePreview.js +6 -6
  173. package/dist/docs-kit/CodePreview.js.map +1 -1
  174. package/dist/docs-kit/PropsTable.js +4 -4
  175. package/dist/docs-kit/PropsTable.js.map +1 -1
  176. package/dist/feedback/Alert.js +5 -5
  177. package/dist/feedback/Alert.js.map +1 -1
  178. package/dist/feedback/Banner.js +5 -5
  179. package/dist/feedback/Banner.js.map +1 -1
  180. package/dist/feedback/Empty.js +4 -4
  181. package/dist/feedback/Empty.js.map +1 -1
  182. package/dist/feedback/LoadingBar.js +20 -13
  183. package/dist/feedback/LoadingBar.js.map +1 -1
  184. package/dist/feedback/LoadingOverlay.js +3 -3
  185. package/dist/feedback/LoadingOverlay.js.map +1 -1
  186. package/dist/feedback/Progress.js +14 -14
  187. package/dist/feedback/Progress.js.map +1 -1
  188. package/dist/feedback/Result.js +4 -4
  189. package/dist/feedback/Result.js.map +1 -1
  190. package/dist/feedback/SkeletonText.js +3 -3
  191. package/dist/feedback/SkeletonText.js.map +1 -1
  192. package/dist/feedback/Toast.js +6 -6
  193. package/dist/feedback/Toast.js.map +1 -1
  194. package/dist/form/Field.d.ts +7 -0
  195. package/dist/form/Field.js +20 -9
  196. package/dist/form/Field.js.map +1 -1
  197. package/dist/form/Form.js +3 -3
  198. package/dist/form/Form.js.map +1 -1
  199. package/dist/form/FormErrorSummary.js +3 -3
  200. package/dist/form/FormErrorSummary.js.map +1 -1
  201. package/dist/form/FormSection.js +6 -6
  202. package/dist/form/FormSection.js.map +1 -1
  203. package/dist/form/useForm.d.ts +4 -1
  204. package/dist/form/useForm.js +35 -13
  205. package/dist/form/useForm.js.map +1 -1
  206. package/dist/index.d.ts +18 -10
  207. package/dist/index.js +17 -9
  208. package/dist/input/Autocomplete.js +3 -3
  209. package/dist/input/Autocomplete.js.map +1 -1
  210. package/dist/input/Cascader.js +7 -7
  211. package/dist/input/Cascader.js.map +1 -1
  212. package/dist/input/CharacterCount.js +3 -3
  213. package/dist/input/CharacterCount.js.map +1 -1
  214. package/dist/input/Checkbox.js +5 -5
  215. package/dist/input/Checkbox.js.map +1 -1
  216. package/dist/input/ColorField.js +4 -4
  217. package/dist/input/ColorField.js.map +1 -1
  218. package/dist/input/Combobox.js +5 -5
  219. package/dist/input/Combobox.js.map +1 -1
  220. package/dist/input/ConditionBuilder.js +15 -14
  221. package/dist/input/ConditionBuilder.js.map +1 -1
  222. package/dist/input/FileDrop.js +3 -3
  223. package/dist/input/FileDrop.js.map +1 -1
  224. package/dist/input/Listbox.js +9 -9
  225. package/dist/input/Listbox.js.map +1 -1
  226. package/dist/input/Mentions.js +4 -4
  227. package/dist/input/Mentions.js.map +1 -1
  228. package/dist/input/NumberField.js +3 -3
  229. package/dist/input/NumberField.js.map +1 -1
  230. package/dist/input/NumberRangeField.js +5 -5
  231. package/dist/input/NumberRangeField.js.map +1 -1
  232. package/dist/input/OtpField.js +5 -5
  233. package/dist/input/OtpField.js.map +1 -1
  234. package/dist/input/PeoplePicker.js +6 -6
  235. package/dist/input/PeoplePicker.js.map +1 -1
  236. package/dist/input/PeoplePickerPanel.js +15 -15
  237. package/dist/input/PeoplePickerPanel.js.map +1 -1
  238. package/dist/input/Radio.js +4 -4
  239. package/dist/input/Radio.js.map +1 -1
  240. package/dist/input/Rating.js +5 -5
  241. package/dist/input/Rating.js.map +1 -1
  242. package/dist/input/Select.js +5 -5
  243. package/dist/input/Select.js.map +1 -1
  244. package/dist/input/SelectedTags.js +4 -4
  245. package/dist/input/SelectedTags.js.map +1 -1
  246. package/dist/input/Slider.js +6 -6
  247. package/dist/input/Slider.js.map +1 -1
  248. package/dist/input/Switch.js +3 -3
  249. package/dist/input/Switch.js.map +1 -1
  250. package/dist/input/TagsInput.js +5 -5
  251. package/dist/input/TagsInput.js.map +1 -1
  252. package/dist/input/TextField.js +5 -5
  253. package/dist/input/TextField.js.map +1 -1
  254. package/dist/input/Textarea.js +4 -4
  255. package/dist/input/Textarea.js.map +1 -1
  256. package/dist/input/ToggleGroup.js +4 -4
  257. package/dist/input/ToggleGroup.js.map +1 -1
  258. package/dist/input/Transfer.js +8 -8
  259. package/dist/input/Transfer.js.map +1 -1
  260. package/dist/input/TreeSelect.js +7 -7
  261. package/dist/input/TreeSelect.js.map +1 -1
  262. package/dist/input/Upload.js +10 -9
  263. package/dist/input/Upload.js.map +1 -1
  264. package/dist/input/condition.d.ts +1 -1
  265. package/dist/input/condition.js +32 -14
  266. package/dist/input/condition.js.map +1 -1
  267. package/dist/input/people.d.ts +15 -14
  268. package/dist/input/people.js +5 -5
  269. package/dist/input/people.js.map +1 -1
  270. package/dist/input/remote-items.d.ts +4 -2
  271. package/dist/input/remote-items.js +7 -2
  272. package/dist/input/remote-items.js.map +1 -1
  273. package/dist/layout/Affix.js +4 -4
  274. package/dist/layout/Affix.js.map +1 -1
  275. package/dist/layout/ResizeHandle.d.ts +6 -2
  276. package/dist/layout/ResizeHandle.js +32 -9
  277. package/dist/layout/ResizeHandle.js.map +1 -1
  278. package/dist/layout/ScrollArea.js +3 -3
  279. package/dist/layout/ScrollArea.js.map +1 -1
  280. package/dist/layout/Separator.js +3 -3
  281. package/dist/layout/Separator.js.map +1 -1
  282. package/dist/layout/Splitter.js +3 -3
  283. package/dist/layout/Splitter.js.map +1 -1
  284. package/dist/layout/ViewportFill.d.ts +2 -2
  285. package/dist/layout/ViewportFill.js +4 -4
  286. package/dist/layout/ViewportFill.js.map +1 -1
  287. package/dist/navigation/Breadcrumbs.js +4 -4
  288. package/dist/navigation/Breadcrumbs.js.map +1 -1
  289. package/dist/navigation/NavBar.js +6 -6
  290. package/dist/navigation/NavBar.js.map +1 -1
  291. package/dist/navigation/NavList.d.ts +1 -0
  292. package/dist/navigation/NavList.js +20 -12
  293. package/dist/navigation/NavList.js.map +1 -1
  294. package/dist/navigation/NavMenu.d.ts +27 -0
  295. package/dist/navigation/NavMenu.js +54 -0
  296. package/dist/navigation/NavMenu.js.map +1 -0
  297. package/dist/navigation/PageJump.js +3 -3
  298. package/dist/navigation/PageJump.js.map +1 -1
  299. package/dist/navigation/PageSizeSelect.js +4 -4
  300. package/dist/navigation/PageSizeSelect.js.map +1 -1
  301. package/dist/navigation/Pagination.js +6 -6
  302. package/dist/navigation/Pagination.js.map +1 -1
  303. package/dist/navigation/PaginationBar.js +5 -5
  304. package/dist/navigation/PaginationBar.js.map +1 -1
  305. package/dist/navigation/Steps.js +4 -4
  306. package/dist/navigation/Steps.js.map +1 -1
  307. package/dist/navigation/TableOfContents.js +5 -5
  308. package/dist/navigation/TableOfContents.js.map +1 -1
  309. package/dist/navigation/Tabs.js +7 -7
  310. package/dist/navigation/Tabs.js.map +1 -1
  311. package/dist/navigation/Toolbar.js +3 -3
  312. package/dist/navigation/Toolbar.js.map +1 -1
  313. package/dist/overlay/AlertDialog.js +4 -4
  314. package/dist/overlay/AlertDialog.js.map +1 -1
  315. package/dist/overlay/CommandPalette.js +4 -4
  316. package/dist/overlay/CommandPalette.js.map +1 -1
  317. package/dist/overlay/ContextMenu.js +3 -3
  318. package/dist/overlay/ContextMenu.js.map +1 -1
  319. package/dist/overlay/Dialog.js +4 -4
  320. package/dist/overlay/Dialog.js.map +1 -1
  321. package/dist/overlay/Drawer.js +5 -5
  322. package/dist/overlay/Drawer.js.map +1 -1
  323. package/dist/overlay/HoverCard.js +5 -3
  324. package/dist/overlay/HoverCard.js.map +1 -1
  325. package/dist/overlay/Lightbox.js +5 -5
  326. package/dist/overlay/Lightbox.js.map +1 -1
  327. package/dist/overlay/Menu.js +7 -7
  328. package/dist/overlay/Menu.js.map +1 -1
  329. package/dist/overlay/ModalCore.js +9 -9
  330. package/dist/overlay/ModalCore.js.map +1 -1
  331. package/dist/overlay/Popconfirm.js +6 -6
  332. package/dist/overlay/Popconfirm.js.map +1 -1
  333. package/dist/overlay/Popover.js +5 -3
  334. package/dist/overlay/Popover.js.map +1 -1
  335. package/dist/overlay/Tooltip.js +5 -3
  336. package/dist/overlay/Tooltip.js.map +1 -1
  337. package/dist/overlay/Tour.js +8 -8
  338. package/dist/overlay/Tour.js.map +1 -1
  339. package/dist/overlay/detached.d.ts +2 -0
  340. package/dist/overlay/detached.js +73 -42
  341. package/dist/overlay/detached.js.map +1 -1
  342. package/dist/patterns/ActionBar.js +3 -3
  343. package/dist/patterns/ActionBar.js.map +1 -1
  344. package/dist/patterns/AppShell.d.ts +28 -1
  345. package/dist/patterns/AppShell.js +158 -52
  346. package/dist/patterns/AppShell.js.map +1 -1
  347. package/dist/patterns/AuthLayout.d.ts +28 -0
  348. package/dist/patterns/AuthLayout.js +77 -0
  349. package/dist/patterns/AuthLayout.js.map +1 -0
  350. package/dist/patterns/CommentThread.js +9 -9
  351. package/dist/patterns/CommentThread.js.map +1 -1
  352. package/dist/patterns/DataImport.js +4 -4
  353. package/dist/patterns/DataImport.js.map +1 -1
  354. package/dist/patterns/DeadlineBadge.js +3 -3
  355. package/dist/patterns/DeadlineBadge.js.map +1 -1
  356. package/dist/patterns/FilterBar.d.ts +11 -1
  357. package/dist/patterns/FilterBar.js +39 -10
  358. package/dist/patterns/FilterBar.js.map +1 -1
  359. package/dist/patterns/FormDialog.d.ts +18 -0
  360. package/dist/patterns/FormDialog.js +46 -0
  361. package/dist/patterns/FormDialog.js.map +1 -0
  362. package/dist/patterns/KanbanBoard.js +8 -8
  363. package/dist/patterns/KanbanBoard.js.map +1 -1
  364. package/dist/patterns/LayoutSwitcher.d.ts +12 -0
  365. package/dist/patterns/LayoutSwitcher.js +79 -0
  366. package/dist/patterns/LayoutSwitcher.js.map +1 -0
  367. package/dist/patterns/NotificationCenter.js +8 -8
  368. package/dist/patterns/NotificationCenter.js.map +1 -1
  369. package/dist/patterns/PageTabs.d.ts +12 -7
  370. package/dist/patterns/PageTabs.js +41 -29
  371. package/dist/patterns/PageTabs.js.map +1 -1
  372. package/dist/patterns/QueryTable.d.ts +10 -1
  373. package/dist/patterns/QueryTable.js +128 -68
  374. package/dist/patterns/QueryTable.js.map +1 -1
  375. package/dist/patterns/SlideCaptcha.d.ts +80 -0
  376. package/dist/patterns/SlideCaptcha.js +354 -0
  377. package/dist/patterns/SlideCaptcha.js.map +1 -0
  378. package/dist/patterns/StepsForm.js +7 -7
  379. package/dist/patterns/StepsForm.js.map +1 -1
  380. package/dist/patterns/ThemeSwitcher.js +3 -3
  381. package/dist/patterns/ThemeSwitcher.js.map +1 -1
  382. package/dist/patterns/index.d.ts +7 -3
  383. package/dist/patterns/index.js +5 -1
  384. package/dist/patterns/messages.d.ts +39 -1
  385. package/dist/patterns/messages.js +40 -2
  386. package/dist/patterns/messages.js.map +1 -1
  387. package/dist/table/ColumnHeaderActions.js +3 -3
  388. package/dist/table/ColumnHeaderActions.js.map +1 -1
  389. package/dist/table/ColumnResizer.js +3 -3
  390. package/dist/table/ColumnResizer.js.map +1 -1
  391. package/dist/table/ColumnSettings.js +5 -5
  392. package/dist/table/ColumnSettings.js.map +1 -1
  393. package/dist/table/ColumnTable.js +8 -8
  394. package/dist/table/ColumnTable.js.map +1 -1
  395. package/dist/table/DataTable.js +8 -8
  396. package/dist/table/DataTable.js.map +1 -1
  397. package/dist/table/DataTableView.js +21 -21
  398. package/dist/table/DataTableView.js.map +1 -1
  399. package/dist/table/PivotTable.js +3 -3
  400. package/dist/table/PivotTable.js.map +1 -1
  401. package/dist/table/SelectionBar.js +4 -4
  402. package/dist/table/SelectionBar.js.map +1 -1
  403. package/dist/table/TreeDataTable.js +5 -5
  404. package/dist/table/TreeDataTable.js.map +1 -1
  405. package/dist/theme-customize/ThemeCustomizer.js +7 -6
  406. package/dist/theme-customize/ThemeCustomizer.js.map +1 -1
  407. package/dist/theme-customize/ThemeThumbnail.js +3 -3
  408. package/dist/theme-customize/ThemeThumbnail.js.map +1 -1
  409. package/dist/three/background/AuroraBackground.js +3 -3
  410. package/dist/three/background/AuroraBackground.js.map +1 -1
  411. package/dist/three/background/MeshGradient.js +3 -3
  412. package/dist/three/background/MeshGradient.js.map +1 -1
  413. package/dist/three/background/ShaderBackground.js +3 -3
  414. package/dist/three/background/ShaderBackground.js.map +1 -1
  415. package/dist/three/core/EffectSurface.js +3 -3
  416. package/dist/three/core/EffectSurface.js.map +1 -1
  417. package/dist/three/core/ThreeCanvas.js +4 -4
  418. package/dist/three/core/ThreeCanvas.js.map +1 -1
  419. package/dist/three/effects/Confetti.js +3 -3
  420. package/dist/three/effects/Confetti.js.map +1 -1
  421. package/dist/three/effects/ParticleField.js +3 -3
  422. package/dist/three/effects/ParticleField.js.map +1 -1
  423. package/dist/three/effects/WaveGrid.js +3 -3
  424. package/dist/three/effects/WaveGrid.js.map +1 -1
  425. package/dist/three/globe/Globe.js +3 -3
  426. package/dist/three/globe/Globe.js.map +1 -1
  427. package/dist/three/model/ModelViewer.js +3 -3
  428. package/dist/three/model/ModelViewer.js.map +1 -1
  429. package/dist/utils/data/clone.d.ts +8 -0
  430. package/dist/utils/data/clone.js +21 -0
  431. package/dist/utils/data/clone.js.map +1 -0
  432. package/dist/utils/data/date.d.ts +10 -0
  433. package/dist/utils/data/date.js +13 -1
  434. package/dist/utils/data/date.js.map +1 -1
  435. package/dist/utils/data/number.d.ts +5 -0
  436. package/dist/utils/data/number.js +8 -1
  437. package/dist/utils/data/number.js.map +1 -1
  438. package/dist/utils/data/numeric.d.ts +7 -0
  439. package/dist/utils/data/numeric.js +46 -1
  440. package/dist/utils/data/numeric.js.map +1 -1
  441. package/dist/utils/dom/download.d.ts +8 -1
  442. package/dist/utils/dom/download.js +19 -2
  443. package/dist/utils/dom/download.js.map +1 -1
  444. package/dist/utils/dom/element.d.ts +3 -1
  445. package/dist/utils/dom/element.js +8 -4
  446. package/dist/utils/dom/element.js.map +1 -1
  447. package/dist/utils/dom/fullscreen.d.ts +1 -1
  448. package/dist/utils/dom/fullscreen.js +12 -8
  449. package/dist/utils/dom/fullscreen.js.map +1 -1
  450. package/dist/utils/dom/mounted.d.ts +7 -0
  451. package/dist/utils/dom/mounted.js +16 -0
  452. package/dist/utils/dom/mounted.js.map +1 -0
  453. package/dist/utils/dom/overflow.js +2 -1
  454. package/dist/utils/dom/overflow.js.map +1 -1
  455. package/dist/utils/dom/pan-zoom.js +2 -1
  456. package/dist/utils/dom/pan-zoom.js.map +1 -1
  457. package/dist/utils/props.js +3 -13
  458. package/dist/utils/props.js.map +1 -1
  459. package/dist/utils/request/error-message.d.ts +17 -0
  460. package/dist/utils/request/error-message.js +50 -0
  461. package/dist/utils/request/error-message.js.map +1 -0
  462. package/dist/utils/request/http.d.ts +80 -4
  463. package/dist/utils/request/http.js +121 -24
  464. package/dist/utils/request/http.js.map +1 -1
  465. package/dist/utils/request/use-autosave.d.ts +35 -0
  466. package/dist/utils/request/use-autosave.js +69 -0
  467. package/dist/utils/request/use-autosave.js.map +1 -0
  468. package/dist/utils/request/use-request.js +4 -2
  469. package/dist/utils/request/use-request.js.map +1 -1
  470. package/package.json +57 -4
@@ -5,8 +5,8 @@ import { useRecipe } from "../config/styles.js";
5
5
  import { ResizeHandle } from "../layout/ResizeHandle.js";
6
6
  import { useDetachedOverlay } from "./detached.js";
7
7
  import { ModalCore, modalPartStyles } from "./ModalCore.js";
8
- import { createVNode, isVNode, mergeProps } from "vue";
9
- import { _component, bindable, readonlyProp, restProps, untrack } from "@zerodep-dev/vue-tsx-pro-tsx";
8
+ import { createVNode, isVNode } from "vue";
9
+ import { _component, bindable, mergeJsxProps, readonlyProp, restProps, untrack } from "@zerodep-dev/vue-tsx-pro-tsx";
10
10
  import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
11
11
  //#region src/overlay/Drawer.tsx
12
12
  /** 抽屉从哪一侧滑入;start / end 是逻辑方向,从右到左排版下左右互换 */
@@ -163,13 +163,13 @@ var Drawer = /*#__PURE__*/ _component((_props, _ctx) => {
163
163
  size: inline && width.value == null ? appearance().size : void 0,
164
164
  resizable: resizing
165
165
  });
166
- return createVNode(ModalCore, mergeProps(rest, {
166
+ return createVNode(ModalCore, mergeJsxProps(rest, {
167
167
  "_open": open.value,
168
168
  "onUpdate:_open": _cache[0] || (_cache[0] = ($event) => open.value = $event),
169
169
  "parts": s,
170
170
  "style": inline && width.value != null ? { width: `${width.value}px` } : void 0,
171
171
  "data-side": side.value,
172
- "edge": resizing && createVNode(ResizeHandle, mergeProps({
172
+ "edge": resizing && createVNode(ResizeHandle, mergeJsxProps({
173
173
  "aria-label": messages.drawerResize,
174
174
  "minWidth": minWidth.value,
175
175
  "maxWidth": typeof window === "undefined" ? void 0 : window.innerWidth - 48,
@@ -203,7 +203,7 @@ var Drawer = /*#__PURE__*/ _component((_props, _ctx) => {
203
203
  * drawer.open({ title: `订单 ${row.id}`, size: 'md', content: (handle) => <OrderForm id={row.id} onSaved={handle.close} /> });
204
204
  */
205
205
  function useDrawer() {
206
- return { open: useDetachedOverlay((props, host, children) => createVNode(Drawer, mergeProps(props, {
206
+ return { open: useDetachedOverlay((props, host, children) => createVNode(Drawer, mergeJsxProps(props, {
207
207
  "_open": host.open,
208
208
  "onUpdate:_open": ($event) => host.open = $event
209
209
  }), _isSlot(children) ? children : { default: () => [children] })) };
@@ -1 +1 @@
1
- {"version":3,"file":"Drawer.js","names":["_isVNode","_vtp_bindable","_vtp_readonlyProp","_vtp_restProps","_vtp_untrack","_createVNode","_mergeProps"],"sources":["../../src/overlay/Drawer.tsx"],"sourcesContent":["/**\n * 抽屉:贴着视口一侧滑入的模态面板。内核见 Modal.tsx(与 Dialog、AlertDialog 共用)。\n *\n * <Drawer _open={filtering} side=\"end\" title=\"筛选\">…</Drawer>\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 { useLang } from '../config/context';\nimport { useDefaults } from '../config/defaults';\nimport { useRecipe } from '../config/styles';\nimport { ResizeHandle, type ResizeHandleProps } from '../layout/ResizeHandle';\nimport {\n useDetachedOverlay,\n type DetachedOverlayHandle,\n type DetachedOverlayOptions,\n} from './detached';\nimport { ModalCore, modalPartStyles, type ModalProps } from './ModalCore';\nimport { t } from '../config/theme/tokens';\n\n/** 抽屉从哪一侧滑入;start / end 是逻辑方向,从右到左排版下左右互换 */\nexport interface DrawerSides {\n /** 起始边(从左到右排版时是左侧):导航菜单 */\n start: unknown;\n /** 结束边(默认,从左到右排版时是右侧):详情、筛选、表单 */\n end: unknown;\n /** 顶部 */\n top: unknown;\n /** 底部:手机上的操作面板 */\n bottom: unknown;\n}\n\n/** 抽屉的外观选项;可以用 createUi / Provider 的 defaults.Drawer 统一改默认值 */\nexport interface DrawerOptions {\n /** 宽度(左右两侧)档位,与 Container 相同,默认 xs(30rem);上下两侧时高度由内容决定,最多到视口高度 */\n size?: keyof ContainerSizes;\n /**\n * 靠正文的一边可以拖动调整宽度(也能聚焦后用 ← / →,双击回到初始宽度),能一直拖到只剩一窄条、\n * 让出后面的页面;只用于左右两侧\n * @default true\n */\n resizable?: boolean;\n}\n\n/** 未声明的属性落到 dialog 上 */\nexport interface DrawerProps extends ModalProps, DrawerOptions {\n /** 从哪一侧滑入,默认 end */\n side?: keyof DrawerSides;\n /** 宽度(px,左右两侧):写了就不按 size 的档位;父级写 _width={x} 记住拖动后的宽度 */\n _width?: number | null;\n /**\n * 拖动时的最小宽度(px):默认只留一窄条(几乎关上,还能拖回来);比内容窄时内容被裁掉,不挤成一列\n * @default 48\n */\n minWidth?: number;\n /** 宽度调整手柄的部件属性 */\n propsResizeHandle?: Partial<ResizeHandleProps>;\n}\n\n/**\n * 抽屉的配方:部件同 ModalCore(base 并进了 modalPartStyles);root 是 dialog 元素(去掉居中、按所在一侧定位与滑入),\n * 能拖动调整宽度时标题行、说明、正文、页脚保持最小宽度\n */\nexport const drawerRecipe = css.recipe({\n name: 'Drawer',\n parts: ['root', 'header', 'title', 'close', 'description', 'body', 'bodyContent', 'footer'],\n base: {\n ...modalPartStyles,\n root: {\n ...modalPartStyles.root,\n margin: 0,\n // 给了 width 时宽度写在行内,最多到视口宽\n maxWidth: '100vw',\n maxHeight: '100dvh',\n borderRadius: 0,\n // 进场从所在一侧滑入(@starting-style),离场滑回去(allow-discrete,离场过渡目前只有 Chromium);\n // “减少动态效果”时时长为 0。打开时 translate 是 none 而不是 0 0:否则抽屉会成为 fixed 子元素\n // (移进来的 Toaster)的包含块;关闭时不显示,移到所在一侧之外没有这个问题\n transition: {\n default: `translate ${t.durations.md} ${t.easings.exit}, display ${t.durations.md} allow-discrete, overlay ${t.durations.md} allow-discrete`,\n ':modal': `translate ${t.durations.lg} ${t.easings.enter}, display ${t.durations.lg} allow-discrete, overlay ${t.durations.lg} allow-discrete`,\n },\n },\n },\n variants: {\n // 左右两侧占满视口高度、宽度看档位,上下两侧占满视口宽度、高度由内容决定。\n // 位置用逻辑属性,从右到左排版自动换边;translate 是物理方向,用 :dir() 区分\n side: {\n start: {\n root: {\n insetBlock: 0,\n width: '_full',\n height: '100dvh',\n overflow: 'hidden',\n insetInlineStart: 0,\n insetInlineEnd: 'auto',\n borderInlineStartWidth: 0,\n translate: {\n default: '-100% 0',\n ':dir(rtl)': '100% 0',\n ':modal': {\n default: 'none',\n '@starting-style': { default: '-100% 0', ':dir(rtl)': '100% 0' },\n },\n },\n },\n },\n end: {\n root: {\n insetBlock: 0,\n width: '_full',\n height: '100dvh',\n overflow: 'hidden',\n insetInlineStart: 'auto',\n insetInlineEnd: 0,\n borderInlineEndWidth: 0,\n translate: {\n default: '100% 0',\n ':dir(rtl)': '-100% 0',\n ':modal': {\n default: 'none',\n '@starting-style': { default: '100% 0', ':dir(rtl)': '-100% 0' },\n },\n },\n },\n },\n top: {\n root: {\n insetInline: 0,\n width: '100vw',\n height: 'auto',\n top: 0,\n bottom: 'auto',\n borderBlockStartWidth: 0,\n translate: {\n default: '0 -100%',\n ':modal': { default: 'none', '@starting-style': '0 -100%' },\n },\n },\n },\n bottom: {\n root: {\n insetInline: 0,\n width: '100vw',\n height: 'auto',\n top: 'auto',\n bottom: 0,\n borderBlockEndWidth: 0,\n translate: {\n default: '0 100%',\n ':modal': { default: 'none', '@starting-style': '0 100%' },\n },\n },\n },\n },\n // 左右两侧、没给 width 时的宽度档位\n size: {\n xs: { root: { maxWidth: `min(${t.sizes.xs}, 100vw)` } },\n sm: { root: { maxWidth: `min(${t.sizes.sm}, 100vw)` } },\n md: { root: { maxWidth: `min(${t.sizes.md}, 100vw)` } },\n lg: { root: { maxWidth: `min(${t.sizes.lg}, 100vw)` } },\n xl: { root: { maxWidth: `min(${t.sizes.xl}, 100vw)` } },\n },\n // 能拖动调整宽度(左右两侧):拖窄以后内容保持能读的最小宽度,多出来的被面板裁掉\n resizable: {\n true: {\n header: { minWidth: 'min(20rem, 100vw - 3rem)' },\n description: { minWidth: 'min(20rem, 100vw - 3rem)' },\n body: { minWidth: 'min(20rem, 100vw - 3rem)' },\n footer: { minWidth: 'min(20rem, 100vw - 3rem)' },\n },\n },\n },\n});\n\n/** 抽屉的部件(createUi / Provider 的 styles.Drawer 按它定制) */\nexport type DrawerPart = (typeof drawerRecipe.parts)[number];\n\n/** 抽屉:贴着视口一侧滑入的模态面板 */\nexport const Drawer = _component(\n ({\n _open: open = _bindable(false),\n side = 'end',\n size,\n _width: width = _bindable<number | null>(null),\n resizable,\n minWidth = 48,\n propsResizeHandle,\n ...rest\n }: DrawerProps) => {\n const appearance = useDefaults('Drawer', () => ({ size, resizable }), {\n size: 'xs',\n resizable: true,\n });\n const messages = useLang();\n const recipe = useRecipe(drawerRecipe);\n // 双击回到打开时的宽度\n const initialWidth = _untrack(width);\n return () => {\n const inline = side === 'start' || side === 'end';\n const resizing = inline && appearance().resizable;\n const s = recipe({\n side,\n size: inline && width == null ? appearance().size : undefined,\n resizable: resizing,\n });\n return (\n <ModalCore\n {...rest}\n _open={open}\n parts={s}\n style={inline && width != null ? { width: `${width}px` } : undefined}\n data-side={side}\n edge={\n resizing && (\n <ResizeHandle\n aria-label={messages.drawerResize}\n minWidth={minWidth}\n maxWidth={typeof window === 'undefined' ? undefined : window.innerWidth - 48}\n defaultWidth={initialWidth ?? undefined}\n {...propsResizeHandle}\n edge={side === 'end' ? 'start' : 'end'}\n width={width ?? undefined}\n onWidthChange={(next: number) => (width = next)}\n />\n )\n }\n />\n );\n };\n },\n);\n\n/** useDrawer 返回的:open 打开一个抽屉 */\nexport interface DrawerApi {\n /** 打开抽屉:属性同 Drawer(open 由句柄管理),content 是正文;返回句柄 */\n open(options: DetachedOverlayOptions<DrawerProps>): DetachedOverlayHandle<DrawerProps>;\n}\n\n/**\n * 命令式抽屉:在组件 setup 里调用,用法同 useDialog。从表格的一行打开详情、编辑时不必在页面里放一个 Drawer 再管 open:\n *\n * const drawer = useDrawer();\n * drawer.open({ title: `订单 ${row.id}`, size: 'md', content: (handle) => <OrderForm id={row.id} onSaved={handle.close} /> });\n */\nexport function useDrawer(): DrawerApi {\n const open = useDetachedOverlay<DrawerProps>((props, host, children) => (\n <Drawer {...props} _open={host.open}>\n {children}\n </Drawer>\n ));\n return { open };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"Drawer.js","names":["_isVNode","_vtp_bindable","_vtp_readonlyProp","_vtp_restProps","_vtp_untrack","_createVNode","_mergeProps"],"sources":["../../src/overlay/Drawer.tsx"],"sourcesContent":["/**\n * 抽屉:贴着视口一侧滑入的模态面板。内核见 Modal.tsx(与 Dialog、AlertDialog 共用)。\n *\n * <Drawer _open={filtering} side=\"end\" title=\"筛选\">…</Drawer>\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 { useLang } from '../config/context';\nimport { useDefaults } from '../config/defaults';\nimport { useRecipe } from '../config/styles';\nimport { ResizeHandle, type ResizeHandleProps } from '../layout/ResizeHandle';\nimport {\n useDetachedOverlay,\n type DetachedOverlayHandle,\n type DetachedOverlayOptions,\n} from './detached';\nimport { ModalCore, modalPartStyles, type ModalProps } from './ModalCore';\nimport { t } from '../config/theme/tokens';\n\n/** 抽屉从哪一侧滑入;start / end 是逻辑方向,从右到左排版下左右互换 */\nexport interface DrawerSides {\n /** 起始边(从左到右排版时是左侧):导航菜单 */\n start: unknown;\n /** 结束边(默认,从左到右排版时是右侧):详情、筛选、表单 */\n end: unknown;\n /** 顶部 */\n top: unknown;\n /** 底部:手机上的操作面板 */\n bottom: unknown;\n}\n\n/** 抽屉的外观选项;可以用 createUi / Provider 的 defaults.Drawer 统一改默认值 */\nexport interface DrawerOptions {\n /** 宽度(左右两侧)档位,与 Container 相同,默认 xs(30rem);上下两侧时高度由内容决定,最多到视口高度 */\n size?: keyof ContainerSizes;\n /**\n * 靠正文的一边可以拖动调整宽度(也能聚焦后用 ← / →,双击回到初始宽度),能一直拖到只剩一窄条、\n * 让出后面的页面;只用于左右两侧\n * @default true\n */\n resizable?: boolean;\n}\n\n/** 未声明的属性落到 dialog 上 */\nexport interface DrawerProps extends ModalProps, DrawerOptions {\n /** 从哪一侧滑入,默认 end */\n side?: keyof DrawerSides;\n /** 宽度(px,左右两侧):写了就不按 size 的档位;父级写 _width={x} 记住拖动后的宽度 */\n _width?: number | null;\n /**\n * 拖动时的最小宽度(px):默认只留一窄条(几乎关上,还能拖回来);比内容窄时内容被裁掉,不挤成一列\n * @default 48\n */\n minWidth?: number;\n /** 宽度调整手柄的部件属性 */\n propsResizeHandle?: Partial<ResizeHandleProps>;\n}\n\n/**\n * 抽屉的配方:部件同 ModalCore(base 并进了 modalPartStyles);root 是 dialog 元素(去掉居中、按所在一侧定位与滑入),\n * 能拖动调整宽度时标题行、说明、正文、页脚保持最小宽度\n */\nexport const drawerRecipe = css.recipe({\n name: 'Drawer',\n parts: ['root', 'header', 'title', 'close', 'description', 'body', 'bodyContent', 'footer'],\n base: {\n ...modalPartStyles,\n root: {\n ...modalPartStyles.root,\n margin: 0,\n // 给了 width 时宽度写在行内,最多到视口宽\n maxWidth: '100vw',\n maxHeight: '100dvh',\n borderRadius: 0,\n // 进场从所在一侧滑入(@starting-style),离场滑回去(allow-discrete,离场过渡目前只有 Chromium);\n // “减少动态效果”时时长为 0。打开时 translate 是 none 而不是 0 0:否则抽屉会成为 fixed 子元素\n // (移进来的 Toaster)的包含块;关闭时不显示,移到所在一侧之外没有这个问题\n transition: {\n default: `translate ${t.durations.md} ${t.easings.exit}, display ${t.durations.md} allow-discrete, overlay ${t.durations.md} allow-discrete`,\n ':modal': `translate ${t.durations.lg} ${t.easings.enter}, display ${t.durations.lg} allow-discrete, overlay ${t.durations.lg} allow-discrete`,\n },\n },\n },\n variants: {\n // 左右两侧占满视口高度、宽度看档位,上下两侧占满视口宽度、高度由内容决定。\n // 位置用逻辑属性,从右到左排版自动换边;translate 是物理方向,用 :dir() 区分\n side: {\n start: {\n root: {\n insetBlock: 0,\n width: '_full',\n height: '100dvh',\n overflow: 'hidden',\n insetInlineStart: 0,\n insetInlineEnd: 'auto',\n borderInlineStartWidth: 0,\n translate: {\n default: '-100% 0',\n ':dir(rtl)': '100% 0',\n ':modal': {\n default: 'none',\n '@starting-style': { default: '-100% 0', ':dir(rtl)': '100% 0' },\n },\n },\n },\n },\n end: {\n root: {\n insetBlock: 0,\n width: '_full',\n height: '100dvh',\n overflow: 'hidden',\n insetInlineStart: 'auto',\n insetInlineEnd: 0,\n borderInlineEndWidth: 0,\n translate: {\n default: '100% 0',\n ':dir(rtl)': '-100% 0',\n ':modal': {\n default: 'none',\n '@starting-style': { default: '100% 0', ':dir(rtl)': '-100% 0' },\n },\n },\n },\n },\n top: {\n root: {\n insetInline: 0,\n width: '100vw',\n height: 'auto',\n top: 0,\n bottom: 'auto',\n borderBlockStartWidth: 0,\n translate: {\n default: '0 -100%',\n ':modal': { default: 'none', '@starting-style': '0 -100%' },\n },\n },\n },\n bottom: {\n root: {\n insetInline: 0,\n width: '100vw',\n height: 'auto',\n top: 'auto',\n bottom: 0,\n borderBlockEndWidth: 0,\n translate: {\n default: '0 100%',\n ':modal': { default: 'none', '@starting-style': '0 100%' },\n },\n },\n },\n },\n // 左右两侧、没给 width 时的宽度档位\n size: {\n xs: { root: { maxWidth: `min(${t.sizes.xs}, 100vw)` } },\n sm: { root: { maxWidth: `min(${t.sizes.sm}, 100vw)` } },\n md: { root: { maxWidth: `min(${t.sizes.md}, 100vw)` } },\n lg: { root: { maxWidth: `min(${t.sizes.lg}, 100vw)` } },\n xl: { root: { maxWidth: `min(${t.sizes.xl}, 100vw)` } },\n },\n // 能拖动调整宽度(左右两侧):拖窄以后内容保持能读的最小宽度,多出来的被面板裁掉\n resizable: {\n true: {\n header: { minWidth: 'min(20rem, 100vw - 3rem)' },\n description: { minWidth: 'min(20rem, 100vw - 3rem)' },\n body: { minWidth: 'min(20rem, 100vw - 3rem)' },\n footer: { minWidth: 'min(20rem, 100vw - 3rem)' },\n },\n },\n },\n});\n\n/** 抽屉的部件(createUi / Provider 的 styles.Drawer 按它定制) */\nexport type DrawerPart = (typeof drawerRecipe.parts)[number];\n\n/** 抽屉:贴着视口一侧滑入的模态面板 */\nexport const Drawer = _component(\n ({\n _open: open = _bindable(false),\n side = 'end',\n size,\n _width: width = _bindable<number | null>(null),\n resizable,\n minWidth = 48,\n propsResizeHandle,\n ...rest\n }: DrawerProps) => {\n const appearance = useDefaults('Drawer', () => ({ size, resizable }), {\n size: 'xs',\n resizable: true,\n });\n const messages = useLang();\n const recipe = useRecipe(drawerRecipe);\n // 双击回到打开时的宽度\n const initialWidth = _untrack(width);\n return () => {\n const inline = side === 'start' || side === 'end';\n const resizing = inline && appearance().resizable;\n const s = recipe({\n side,\n size: inline && width == null ? appearance().size : undefined,\n resizable: resizing,\n });\n return (\n <ModalCore\n {...rest}\n _open={open}\n parts={s}\n style={inline && width != null ? { width: `${width}px` } : undefined}\n data-side={side}\n edge={\n resizing && (\n <ResizeHandle\n aria-label={messages.drawerResize}\n minWidth={minWidth}\n maxWidth={typeof window === 'undefined' ? undefined : window.innerWidth - 48}\n defaultWidth={initialWidth ?? undefined}\n {...propsResizeHandle}\n edge={side === 'end' ? 'start' : 'end'}\n width={width ?? undefined}\n onWidthChange={(next: number) => (width = next)}\n />\n )\n }\n />\n );\n };\n },\n);\n\n/** useDrawer 返回的:open 打开一个抽屉 */\nexport interface DrawerApi {\n /** 打开抽屉:属性同 Drawer(open 由句柄管理),content 是正文;返回句柄 */\n open(options: DetachedOverlayOptions<DrawerProps>): DetachedOverlayHandle<DrawerProps>;\n}\n\n/**\n * 命令式抽屉:在组件 setup 里调用,用法同 useDialog。从表格的一行打开详情、编辑时不必在页面里放一个 Drawer 再管 open:\n *\n * const drawer = useDrawer();\n * drawer.open({ title: `订单 ${row.id}`, size: 'md', content: (handle) => <OrderForm id={row.id} onSaved={handle.close} /> });\n */\nexport function useDrawer(): DrawerApi {\n const open = useDetachedOverlay<DrawerProps>((props, host, children) => (\n <Drawer {...props} _open={host.open}>\n {children}\n </Drawer>\n ));\n return { open };\n}\n"],"mappings":"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"}
@@ -1,12 +1,13 @@
1
1
  import { mergeAttrs } from "../utils/props.js";
2
2
  import { transitions } from "../utils/style/transitions.js";
3
+ import { useMounted } from "../utils/dom/mounted.js";
3
4
  import { useLazyContent } from "../utils/motion/presence.js";
4
5
  import { floatingStyles } from "../utils/dom/floating.js";
5
6
  import { createHoverGroup } from "../utils/dom/hover-intent.js";
6
7
  import { openSetter } from "../utils/dom/open-change.js";
7
8
  import { useHoverLayer } from "../utils/dom/hover-layer.js";
8
- import { Fragment, createVNode, mergeProps } from "vue";
9
- import { _component, bindable, childrenProp, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
9
+ import { Fragment, createVNode } from "vue";
10
+ import { _component, bindable, childrenProp, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
10
11
  import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
11
12
  //#region src/overlay/HoverCard.tsx
12
13
  /** 交给触发器的属性:展开到触发元素上(`{...props}`) */
@@ -33,6 +34,7 @@ var HoverCard = /*#__PURE__*/ _component((_props, _ctx) => {
33
34
  const lazy = readonlyProp(_props, "lazy", true);
34
35
  const children = childrenProp(_props);
35
36
  const rest = restProps(_props, _ctx, false);
37
+ const mounted = useMounted();
36
38
  const showContent = useLazyContent(() => open.value, () => lazy.value);
37
39
  const layer = useHoverLayer(hoverCards, () => ({
38
40
  open: open.value,
@@ -48,7 +50,7 @@ var HoverCard = /*#__PURE__*/ _component((_props, _ctx) => {
48
50
  onBlur: (event) => {
49
51
  if (!layer.contains(event.relatedTarget)) layer.hover.closeNow("focus", event);
50
52
  }
51
- }), createVNode("div", mergeProps(mergeAttrs({ sx: [
53
+ }), mounted.value && createVNode("div", mergeJsxProps(mergeAttrs({ sx: [
52
54
  floatingStyles.anchored,
53
55
  floatingStyles.surface,
54
56
  hoverCardStyles.panel,
@@ -1 +1 @@
1
- {"version":3,"file":"HoverCard.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_createVNode","_Fragment","_mergeProps"],"sources":["../../src/overlay/HoverCard.tsx"],"sourcesContent":["/**\n * 悬停卡片:指针停在触发器(通常是链接、用户名)上、或用键盘聚焦它时,弹出一张富内容卡片(用户资料、链接预览)。\n * 开关时机同 Tooltip(useHoverIntent:停留后打开、可以移到卡片上、同组只开一个、刚关掉一个时下一个直接打开),\n * 定位同 Popover(floating-ui,可选箭头)。参考 Radix HoverCard。\n *\n * <HoverCard trigger={(props) => <Link {...props} href=\"/u/ada\">@ada</Link>}>\n * <Avatar name=\"Ada Lovelace\" /> …\n * </HoverCard>\n *\n * 卡片只是预览:里面的信息要在别处也能拿到(触屏没有悬停)。卡片里可以有链接、按钮:\n * 键盘聚焦触发器打开后按 Tab 进入卡片,焦点离开触发器与卡片时关闭;Esc 关闭。\n * 用 popover=\"manual\" 渲染在顶层,不会关掉正打开的菜单或弹出框。开关、定位、Esc 见 useHoverLayer(与 Tooltip 共用)。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { VNodeChild } from 'vue';\nimport {\n floatingStyles,\n type FloatingOptions,\n type FloatingPlacement,\n} from '../utils/dom/floating';\nimport { createHoverGroup } from '../utils/dom/hover-intent';\nimport { openSetter, type OpenChangeProps } from '../utils/dom/open-change';\nimport { useHoverLayer } from '../utils/dom/hover-layer';\nimport { useLazyContent, type LazyContentOptions } from '../utils/motion/presence';\nimport { mergeAttrs, type PartProps } from '../utils/props';\nimport { transitions } from '../utils/style/transitions';\n\n/** 交给触发器的属性:展开到触发元素上(`{...props}`) */\nexport interface HoverCardTriggerProps {\n /** 取得触发器元素:定位的参照 */\n ref: (element: unknown) => void;\n /** 指针进入:等 delay 后打开 */\n onPointerenter: (event: PointerEvent) => void;\n /** 指针离开:稍后关闭(可以移到卡片上) */\n onPointerleave: (event: PointerEvent) => void;\n /** 按下(点击)触发器时关闭 */\n onPointerdown: (event: PointerEvent) => void;\n /** 键盘聚焦时立即打开 */\n onFocus: (event: FocusEvent) => void;\n /** 焦点离开(不是移进卡片)时关闭 */\n onBlur: (event: FocusEvent) => void;\n}\n\n/** 未声明的属性落到卡片的 div 上 */\nexport interface HoverCardProps\n extends\n PartProps<'div', 'id' | 'popover'>,\n Pick<FloatingOptions, 'offset'>,\n LazyContentOptions,\n OpenChangeProps {\n /** 是否打开:父级可以写 _open={x} 控制或得知 */\n _open?: boolean;\n /** 弹出位置,默认 bottom;空间不够时自动翻转 */\n placement?: FloatingPlacement;\n /** 指针停留多久后打开(毫秒),默认 700 */\n delay?: number;\n /** 指针离开多久后关闭(毫秒),默认 300 */\n closeDelay?: number;\n /** 不打开(触发器照常渲染) */\n disabled?: boolean;\n /** 显示指向触发器的箭头 */\n arrow?: boolean;\n /** 触发器:`(props) => <Link {...props} … />` */\n trigger: (props: HoverCardTriggerProps) => VNodeChild;\n /** 箭头的部件属性 */\n propsArrow?: PartProps<'span'>;\n /** 卡片内容 */\n children?: VNodeChild;\n}\n\n/** HoverCard 的样式:panel */\nexport const hoverCardStyles = css.create({\n panel: { padding: '_md', maxWidth: 'min(22em, calc(100vw - 2em))' },\n});\n\n/** 所有悬停卡片一组:同一时间只开一个 */\nconst hoverCards = createHoverGroup();\n\n/** 悬停卡片:悬停或键盘聚焦时在触发器旁边显示富内容 */\nexport const HoverCard = _component(\n ({\n _open: open = _bindable(false),\n onOpenChange,\n placement = 'bottom',\n offset,\n delay = 700,\n closeDelay = 300,\n disabled = false,\n arrow = false,\n trigger,\n propsArrow,\n lazy = true,\n children,\n ...rest\n }: HoverCardProps) => {\n const showContent = useLazyContent(\n () => open,\n () => lazy,\n );\n const layer = useHoverLayer(\n hoverCards,\n () => ({ open, disabled, placement, offset, delay, closeDelay }),\n openSetter(\n () => open,\n (next) => (open = next),\n () => onOpenChange,\n ),\n );\n\n return () => (\n <>\n {trigger({\n ref: layer.anchorRef,\n ...layer.hover.trigger,\n // Tab 进卡片(下一个可聚焦元素)时不关\n onBlur: (event: FocusEvent) => {\n if (!layer.contains(event.relatedTarget)) layer.hover.closeNow('focus', event);\n },\n })}\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n floatingStyles.anchored,\n floatingStyles.surface,\n hoverCardStyles.panel,\n transitions.scale,\n arrow && floatingStyles.withArrow,\n ],\n },\n rest,\n {\n ref: layer.panelRef,\n id: layer.id,\n popover: 'manual',\n ...layer.hover.panel,\n onFocusout: (event: FocusEvent) => {\n if (!layer.contains(event.relatedTarget)) layer.hover.closeNow('focus', event);\n },\n },\n )}\n data-state={open && !disabled ? 'open' : 'closed'}\n >\n {showContent() && children}\n {arrow && <span {...layer.arrowProps(propsArrow)} />}\n </div>\n </>\n );\n },\n);\n"],"mappings":";;;;;;;;;;;;;;AAwEA,IAAa,kBAAkB,IAAI,OAAO,EACxC,OAAO;CAAE,SAAS;CAAO,UAAU;AAA+B,EACpE,CAAC;;AAGD,IAAM,aAAa,iBAAiB;;AAGpC,IAAa,YAAY,0BACvB,QAAA,SAcsB;CAAA,MAAA,OAAAA,SAAA,QAAA,eAbI,OAAK,KAAA,IAAA;CAAA,MAAA,eAAAC,aAAA,QAAA,cAAA;CAAA,MAAA,YAAAA,aAAA,QAAA,aAEjB,QAAQ;CAAA,MAAA,SAAAA,aAAA,QAAA,QAAA;CAAA,MAAA,QAAAA,aAAA,QAAA,SAEZ,GAAG;CAAA,MAAA,aAAAA,aAAA,QAAA,cACE,GAAG;CAAA,MAAA,WAAAA,aAAA,QAAA,YACL,KAAK;CAAA,MAAA,QAAAA,aAAA,QAAA,SACR,KAAK;CAAA,MAAA,UAAAA,aAAA,QAAA,SAAA;CAAA,MAAA,aAAAA,aAAA,QAAA,YAAA;CAAA,MAAA,OAAAA,aAAA,QAAA,QAGN,IAAI;CAAA,MAAA,WAAAC,aAAA,MAAA;CAAA,MAER,OAAIC,UAAA,QAAA,MAAA,KAAA;CAEP,MAAM,cAAc,qBAClB,KAAA,aACA,KAAA,KACF;CACA,MAAM,QAAQ,cACZ,mBACO;EAAE,MAAI,KAAA;EAAE,UAAQ,SAAA;EAAE,WAAS,UAAA;EAAE,QAAM,OAAA;EAAE,OAAK,MAAA;EAAE,YAAU,WAAA;CAAC,IAC9D,iBACE,KAAA,QACC,SAAU,KAAA,QAAO,YAClB,aAAA,KACF,CACF;CAEA,aAAOC,YAAAC,UAAA,MAAA,CAEF,QAAA,MAAQ;EACP,KAAK,MAAM;EACX,GAAG,MAAM,MAAM;EAEf,SAAS,UAAsB;GAC7B,IAAI,CAAC,MAAM,SAAS,MAAM,aAAa,GAAG,MAAM,MAAM,SAAS,SAAS,KAAK;EAC/E;CACF,CAAC,GAACD,YAAA,OAAAE,WAEI,WACF,EACE,IAAI;EACF,eAAe;EACf,eAAe;EACf,gBAAgB;EAChB,YAAY;EACZ,MAAA,SAAS,eAAe;CAAS,EAErC,GACA,MACA;EACE,KAAK,MAAM;EACX,IAAI,MAAM;EACV,SAAS;EACT,GAAG,MAAM,MAAM;EACf,aAAa,UAAsB;GACjC,IAAI,CAAC,MAAM,SAAS,MAAM,aAAa,GAAG,MAAM,MAAM,SAAS,SAAS,KAAK;EAC/E;CACF,CACF,GAAC,EAAA,cACW,KAAA,SAAQ,CAAA,SAAA,QAAY,SAAS,SAAQ,CAAA,GAAA,CAEhD,YAAY,KAAC,SAAA,OACb,MAAA,SAAAF,YAAA,QAAmB,MAAM,WAAU,WAAA,KAAW,GAAC,IAAA,CAAI,CAAA,CAAA,CAAA;AAI5D,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH"}
1
+ {"version":3,"file":"HoverCard.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_childrenProp","_vtp_restProps","_createVNode","_Fragment","_mergeProps"],"sources":["../../src/overlay/HoverCard.tsx"],"sourcesContent":["/**\n * 悬停卡片:指针停在触发器(通常是链接、用户名)上、或用键盘聚焦它时,弹出一张富内容卡片(用户资料、链接预览)。\n * 开关时机同 Tooltip(useHoverIntent:停留后打开、可以移到卡片上、同组只开一个、刚关掉一个时下一个直接打开),\n * 定位同 Popover(floating-ui,可选箭头)。参考 Radix HoverCard。\n *\n * <HoverCard trigger={(props) => <Link {...props} href=\"/u/ada\">@ada</Link>}>\n * <Avatar name=\"Ada Lovelace\" /> …\n * </HoverCard>\n *\n * 卡片只是预览:里面的信息要在别处也能拿到(触屏没有悬停)。卡片里可以有链接、按钮:\n * 键盘聚焦触发器打开后按 Tab 进入卡片,焦点离开触发器与卡片时关闭;Esc 关闭。\n * 用 popover=\"manual\" 渲染在顶层,不会关掉正打开的菜单或弹出框。开关、定位、Esc 见 useHoverLayer(与 Tooltip 共用)。\n */\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport type { VNodeChild } from 'vue';\nimport {\n floatingStyles,\n type FloatingOptions,\n type FloatingPlacement,\n} from '../utils/dom/floating';\nimport { createHoverGroup } from '../utils/dom/hover-intent';\nimport { openSetter, type OpenChangeProps } from '../utils/dom/open-change';\nimport { useHoverLayer } from '../utils/dom/hover-layer';\nimport { useLazyContent, type LazyContentOptions } from '../utils/motion/presence';\nimport { mergeAttrs, type PartProps } from '../utils/props';\nimport { transitions } from '../utils/style/transitions';\nimport { useMounted } from '../utils/dom/mounted';\n\n/** 交给触发器的属性:展开到触发元素上(`{...props}`) */\nexport interface HoverCardTriggerProps {\n /** 取得触发器元素:定位的参照 */\n ref: (element: unknown) => void;\n /** 指针进入:等 delay 后打开 */\n onPointerenter: (event: PointerEvent) => void;\n /** 指针离开:稍后关闭(可以移到卡片上) */\n onPointerleave: (event: PointerEvent) => void;\n /** 按下(点击)触发器时关闭 */\n onPointerdown: (event: PointerEvent) => void;\n /** 键盘聚焦时立即打开 */\n onFocus: (event: FocusEvent) => void;\n /** 焦点离开(不是移进卡片)时关闭 */\n onBlur: (event: FocusEvent) => void;\n}\n\n/** 未声明的属性落到卡片的 div 上 */\nexport interface HoverCardProps\n extends\n PartProps<'div', 'id' | 'popover'>,\n Pick<FloatingOptions, 'offset'>,\n LazyContentOptions,\n OpenChangeProps {\n /** 是否打开:父级可以写 _open={x} 控制或得知 */\n _open?: boolean;\n /** 弹出位置,默认 bottom;空间不够时自动翻转 */\n placement?: FloatingPlacement;\n /** 指针停留多久后打开(毫秒),默认 700 */\n delay?: number;\n /** 指针离开多久后关闭(毫秒),默认 300 */\n closeDelay?: number;\n /** 不打开(触发器照常渲染) */\n disabled?: boolean;\n /** 显示指向触发器的箭头 */\n arrow?: boolean;\n /** 触发器:`(props) => <Link {...props} … />` */\n trigger: (props: HoverCardTriggerProps) => VNodeChild;\n /** 箭头的部件属性 */\n propsArrow?: PartProps<'span'>;\n /** 卡片内容 */\n children?: VNodeChild;\n}\n\n/** HoverCard 的样式:panel */\nexport const hoverCardStyles = css.create({\n panel: { padding: '_md', maxWidth: 'min(22em, calc(100vw - 2em))' },\n});\n\n/** 所有悬停卡片一组:同一时间只开一个 */\nconst hoverCards = createHoverGroup();\n\n/** 悬停卡片:悬停或键盘聚焦时在触发器旁边显示富内容 */\nexport const HoverCard = _component(\n ({\n _open: open = _bindable(false),\n onOpenChange,\n placement = 'bottom',\n offset,\n delay = 700,\n closeDelay = 300,\n disabled = false,\n arrow = false,\n trigger,\n propsArrow,\n lazy = true,\n children,\n ...rest\n }: HoverCardProps) => {\n // 面板挂载后才渲染:关着时本来就看不见;服务端渲染时也不输出,触发器在 <p> 里时 <div> 不会把段落提前截断,水合对得上\n const mounted = useMounted();\n const showContent = useLazyContent(\n () => open,\n () => lazy,\n );\n const layer = useHoverLayer(\n hoverCards,\n () => ({ open, disabled, placement, offset, delay, closeDelay }),\n openSetter(\n () => open,\n (next) => (open = next),\n () => onOpenChange,\n ),\n );\n\n return () => (\n <>\n {trigger({\n ref: layer.anchorRef,\n ...layer.hover.trigger,\n // Tab 进卡片(下一个可聚焦元素)时不关\n onBlur: (event: FocusEvent) => {\n if (!layer.contains(event.relatedTarget)) layer.hover.closeNow('focus', event);\n },\n })}\n {mounted.value && (\n <div\n {...mergeAttrs<'div'>(\n {\n sx: [\n floatingStyles.anchored,\n floatingStyles.surface,\n hoverCardStyles.panel,\n transitions.scale,\n arrow && floatingStyles.withArrow,\n ],\n },\n rest,\n {\n ref: layer.panelRef,\n id: layer.id,\n popover: 'manual',\n ...layer.hover.panel,\n onFocusout: (event: FocusEvent) => {\n if (!layer.contains(event.relatedTarget)) layer.hover.closeNow('focus', event);\n },\n },\n )}\n data-state={open && !disabled ? 'open' : 'closed'}\n >\n {showContent() && children}\n {arrow && <span {...layer.arrowProps(propsArrow)} />}\n </div>\n )}\n </>\n );\n },\n);\n"],"mappings":";;;;;;;;;;;;;;;AAyEA,IAAa,kBAAkB,IAAI,OAAO,EACxC,OAAO;CAAE,SAAS;CAAO,UAAU;AAA+B,EACpE,CAAC;;AAGD,IAAM,aAAa,iBAAiB;;AAGpC,IAAa,YAAY,0BACvB,QAAA,SAcsB;CAAA,MAAA,OAAAA,SAAA,QAAA,eAbI,OAAK,KAAA,IAAA;CAAA,MAAA,eAAAC,aAAA,QAAA,cAAA;CAAA,MAAA,YAAAA,aAAA,QAAA,aAEjB,QAAQ;CAAA,MAAA,SAAAA,aAAA,QAAA,QAAA;CAAA,MAAA,QAAAA,aAAA,QAAA,SAEZ,GAAG;CAAA,MAAA,aAAAA,aAAA,QAAA,cACE,GAAG;CAAA,MAAA,WAAAA,aAAA,QAAA,YACL,KAAK;CAAA,MAAA,QAAAA,aAAA,QAAA,SACR,KAAK;CAAA,MAAA,UAAAA,aAAA,QAAA,SAAA;CAAA,MAAA,aAAAA,aAAA,QAAA,YAAA;CAAA,MAAA,OAAAA,aAAA,QAAA,QAGN,IAAI;CAAA,MAAA,WAAAC,aAAA,MAAA;CAAA,MAER,OAAIC,UAAA,QAAA,MAAA,KAAA;CAGP,MAAM,UAAU,WAAW;CAC3B,MAAM,cAAc,qBAClB,KAAA,aACA,KAAA,KACF;CACA,MAAM,QAAQ,cACZ,mBACO;EAAE,MAAI,KAAA;EAAE,UAAQ,SAAA;EAAE,WAAS,UAAA;EAAE,QAAM,OAAA;EAAE,OAAK,MAAA;EAAE,YAAU,WAAA;CAAC,IAC9D,iBACE,KAAA,QACC,SAAU,KAAA,QAAO,YAClB,aAAA,KACF,CACF;CAEA,aAAOC,YAAAC,UAAA,MAAA,CAEF,QAAA,MAAQ;EACP,KAAK,MAAM;EACX,GAAG,MAAM,MAAM;EAEf,SAAS,UAAsB;GAC7B,IAAI,CAAC,MAAM,SAAS,MAAM,aAAa,GAAG,MAAM,MAAM,SAAS,SAAS,KAAK;EAC/E;CACF,CAAC,GACA,QAAQ,SAAKD,YAAA,OAAAE,cAEN,WACF,EACE,IAAI;EACF,eAAe;EACf,eAAe;EACf,gBAAgB;EAChB,YAAY;EACZ,MAAA,SAAS,eAAe;CAAS,EAErC,GACA,MACA;EACE,KAAK,MAAM;EACX,IAAI,MAAM;EACV,SAAS;EACT,GAAG,MAAM,MAAM;EACf,aAAa,UAAsB;GACjC,IAAI,CAAC,MAAM,SAAS,MAAM,aAAa,GAAG,MAAM,MAAM,SAAS,SAAS,KAAK;EAC/E;CACF,CACF,GAAC,EAAA,cACW,KAAA,SAAQ,CAAA,SAAA,QAAY,SAAS,SAAQ,CAAA,GAAA,CAEhD,YAAY,KAAC,SAAA,OACb,MAAA,SAAAF,YAAA,QAAmB,MAAM,WAAU,WAAA,KAAW,GAAC,IAAA,CAAI,CAAA,CAEvD,CAAA;AAGP,GAAC;CAAA,MAAA;CAAA,OAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;EAAA;CAAA;AAAA,CACH"}
@@ -7,8 +7,8 @@ import { openModalDialog } from "../utils/dom/overlay.js";
7
7
  import { IconLinkButton } from "../base/IconLinkButton.js";
8
8
  import { openSetter } from "../utils/dom/open-change.js";
9
9
  import { usePanZoom } from "../utils/dom/pan-zoom.js";
10
- import { createTextVNode, createVNode, mergeProps, nextTick, onBeforeUnmount, ref, shallowRef } from "vue";
11
- import { _component, bindable, effect, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
10
+ import { createTextVNode, createVNode, nextTick, onBeforeUnmount, ref, shallowRef } from "vue";
11
+ import { _component, bindable, effect, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
12
12
  import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
13
13
  import { ChevronLeft, ChevronRight, Download, RotateCcw, RotateCw, Undo2, X, ZoomIn, ZoomOut } from "@lucide/icons";
14
14
  //#region src/overlay/Lightbox.tsx
@@ -268,13 +268,13 @@ var Lightbox = /*#__PURE__*/ _component((_props, _ctx) => {
268
268
  onKeydown
269
269
  }), [
270
270
  createVNode("div", css.attrs(lightboxStyles.toolbar), [
271
- createVNode("span", mergeProps(css.attrs(lightboxStyles.counter), { "aria-live": "polite" }), [total > 1 ? lang.lightboxCounter(index.value + 1, total) : ""]),
271
+ createVNode("span", mergeJsxProps(css.attrs(lightboxStyles.counter), { "aria-live": "polite" }), [total > 1 ? lang.lightboxCounter(index.value + 1, total) : ""]),
272
272
  createVNode(IconButton, button({
273
273
  icon: ZoomOut,
274
274
  "aria-label": lang.lightboxZoomOut,
275
275
  onClick: () => view.zoomOut()
276
276
  }), null),
277
- createVNode("span", mergeProps(css.attrs(lightboxStyles.zoom), { "aria-hidden": "true" }), [Math.round(view.scale * 100), createTextVNode("%")]),
277
+ createVNode("span", mergeJsxProps(css.attrs(lightboxStyles.zoom), { "aria-hidden": "true" }), [Math.round(view.scale * 100), createTextVNode("%")]),
278
278
  createVNode(IconButton, button({
279
279
  icon: ZoomIn,
280
280
  "aria-label": lang.lightboxZoomIn,
@@ -315,7 +315,7 @@ var Lightbox = /*#__PURE__*/ _component((_props, _ctx) => {
315
315
  tabindex: 0,
316
316
  role: "img",
317
317
  "aria-label": item?.alt
318
- }), [item && createVNode("div", css.attrs(lightboxStyles.content, css.select(() => !view.interacting && lightboxStyles.smooth, true), css.bind(lightboxDynamicStyles.transform, () => [view.transform], true), css.bind(lightboxDynamicStyles.box, () => [width, height])), [createVNode("img", mergeProps({
318
+ }), [item && createVNode("div", css.attrs(lightboxStyles.content, css.select(() => !view.interacting && lightboxStyles.smooth, true), css.bind(lightboxDynamicStyles.transform, () => [view.transform], true), css.bind(lightboxDynamicStyles.box, () => [width, height])), [createVNode("img", mergeJsxProps({
319
319
  "key": item.src,
320
320
  "src": item.src,
321
321
  "alt": "",
@@ -1 +1 @@
1
- {"version":3,"file":"Lightbox.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_restProps","_vue_shallowRef","_vue_ref","_createVNode","_mergeProps","_createTextVNode"],"sources":["../../src/overlay/Lightbox.tsx"],"sourcesContent":["/**\n * 图片预览(全屏的模态 dialog):深色背景上看大图——缩放、拖动、旋转、还原、下载,几张图时左右切换。\n * Image 的 preview 打开它(同一个 ImageGroup 里的图共用一个),也可以单独用。参考 Ant Design Image 的预览、Element Plus 的 image-viewer。\n *\n * <Lightbox _open={viewing} _index={at} items={[{ src: '/photos/1.jpg', alt: '支架正面' }, …]} />\n *\n * - 平移与缩放建在 usePanZoom 上:拖动平移,滚轮、触控板、捏合以指针为中心缩放,双击放大 / 还原;\n * 打开或换一张时整张图放进视口(不超过原大)。旋转以 90° 为一档,转完重新放进视口。\n * - 键盘:← / → 上一张、下一张,+ / − 缩放,0 还原,R 向右旋转,Esc 关闭;焦点在工具栏与图片区之间循环(模态)。\n * - 读屏:dialog 的名称是“图片预览”,图片区是 role=\"img\"、名称是图片的 alt;换一张时念出“第 2 张,共 5 张”。\n *\n * 部件:Root(dialog)、Toolbar(div)、Counter(span)、Viewport(div)、Image(img)、Previous、Next(IconButton)、Caption(div)。\n */\nimport {\n ChevronLeft,\n ChevronRight,\n Download,\n RotateCcw,\n RotateCw,\n Undo2,\n X,\n ZoomIn,\n ZoomOut,\n} from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { nextTick, onBeforeUnmount, type VNodeChild } from 'vue';\nimport { IconButton, type IconButtonProps } from '../base/IconButton';\nimport { IconLinkButton, type IconLinkButtonProps } from '../base/IconLinkButton';\nimport { useLang } from '../config/context';\nimport { clamp } from '../utils/data/number';\nimport { openSetter, type OpenChangeProps, type OpenChangeReasons } from '../utils/dom/open-change';\nimport { openModalDialog } from '../utils/dom/overlay';\nimport { usePanZoom } from '../utils/dom/pan-zoom';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { transitions } from '../utils/style/transitions';\n\n/** 一张图 */\nexport interface LightboxItem {\n /** 大图的地址 */\n src: string;\n /** 图片的说明(读屏念它) */\n alt: string;\n /** 图片下方的说明文字 */\n caption?: VNodeChild;\n /** 下载时的文件名;false 不显示下载按钮 */\n download?: string | false;\n}\n\n/** 打开、关联由组件管理;未声明的属性落到 dialog 上 */\nexport interface LightboxProps\n extends PartProps<'dialog', 'open' | 'aria-label' | 'aria-labelledby'>, OpenChangeProps {\n /** 是否打开:父级写 _open={x};Esc、关闭按钮会关上并写回 */\n _open?: boolean;\n /** 图片 */\n items: readonly LightboxItem[];\n /** 当前第几张,从 0 开始:父级可以写 _index={x} */\n _index?: number;\n /** 到头之后从另一头继续,默认 false */\n loop?: boolean;\n /** 工具栏按钮的部件属性 */\n propsButton?: Partial<IconButtonProps>;\n /** 图片区(视口)的部件属性 */\n propsViewport?: PartProps<'div'>;\n /** 说明文字的部件属性 */\n propsCaption?: PartProps<'div'>;\n}\n\n/** Lightbox 的样式:root、toolbar、counter、viewport、content、image、side、previous、next、caption、button */\nexport const lightboxStyles = css.create({\n root: {\n // 占满视口:原生 dialog 默认有最大宽高与边框\n boxSizing: 'border-box',\n width: '100vw',\n height: '100dvh',\n maxWidth: 'none',\n maxHeight: 'none',\n margin: 0,\n padding: 0,\n borderWidth: 0,\n display: { default: 'none', ':modal': 'flex' },\n flexDirection: 'column',\n // 图片预览总是深色背景:不跟主题变(看图片本身的颜色)\n backgroundColor: 'rgb(0 0 0 / 0.86)',\n color: 'white',\n colorScheme: 'dark',\n },\n toolbar: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'flex-end',\n gap: '_xs',\n paddingBlock: '_sm',\n paddingInline: '_md',\n flexShrink: 0,\n },\n counter: {\n marginInlineEnd: 'auto',\n fontVariantNumeric: 'tabular-nums',\n fontSize: '_sm',\n opacity: 0.8,\n },\n zoom: {\n minWidth: '3.5em',\n textAlign: 'center',\n fontSize: '_sm',\n fontVariantNumeric: 'tabular-nums',\n },\n viewport: {\n position: 'relative',\n flexGrow: 1,\n minHeight: 0,\n overflow: 'hidden',\n cursor: { default: 'grab', ':active': 'grabbing' },\n outline: 'none',\n },\n // 平移与缩放作用在它上面(transform-origin 左上角);它的大小是旋转之后图片占的框\n content: { position: 'absolute', top: 0, left: 0, transformOrigin: '0 0' },\n // 图片以框的中心旋转\n image: {\n position: 'absolute',\n top: '50%',\n left: '50%',\n maxWidth: 'none',\n userSelect: 'none',\n pointerEvents: 'none',\n },\n smooth: { transitionProperty: 'transform', transitionDuration: '_md' },\n side: {\n position: 'absolute',\n top: '50%',\n translate: '0 -50%',\n zIndex: 1,\n },\n previous: { insetInlineStart: '_md' },\n next: { insetInlineEnd: '_md' },\n caption: {\n flexShrink: 0,\n paddingBlock: '_md',\n paddingInline: '_xl',\n textAlign: 'center',\n fontSize: '_sm',\n opacity: 0.9,\n },\n // 深色背景上的按钮:文字白色,悬停时浅一点的底\n button: {\n color: 'white',\n backgroundColor: { default: 'transparent', ':hover': 'rgb(255 255 255 / 0.12)' },\n },\n});\n\n/** Lightbox 的动态样式:平移缩放、框的大小、图片的大小与旋转 */\nexport const lightboxDynamicStyles = css.create({\n transform: (transform: string) => ({ transform }),\n box: (width: number, height: number) => ({ width: `${width}px`, height: `${height}px` }),\n image: (width: number, height: number, degrees: number) => ({\n width: `${width}px`,\n height: `${height}px`,\n transform: `translate(-50%, -50%) rotate(${degrees}deg)`,\n }),\n});\n\n/** 图片预览:全屏 dialog,缩放、拖动、旋转、左右切换 */\nexport const Lightbox = _component(\n ({\n _open: open = _bindable(false),\n onOpenChange,\n items,\n _index: index = _bindable(0),\n loop = false,\n propsButton,\n propsViewport,\n propsCaption,\n ...rest\n }: LightboxProps) => {\n const lang = useLang();\n let dialog = _state.raw<HTMLDialogElement | null>(null);\n let viewport = _state.raw<HTMLElement | null>(null);\n // 当前图片的原始大小(加载后知道)与旋转(0、90、180、270)\n let natural = _state<{ width: number; height: number } | null>(null);\n let rotation = _state(0);\n let release: (() => void) | undefined;\n let closing: keyof OpenChangeReasons | undefined;\n const setOpen = openSetter(\n () => open,\n (next) => (open = next),\n () => onOpenChange,\n );\n\n const current = () => items[clamp(index, 0, Math.max(0, items.length - 1))];\n /** 旋转之后图片占的框 */\n const box = () => {\n if (!natural) return { width: 0, height: 0 };\n const sideways = rotation % 180 !== 0;\n return sideways\n ? { width: natural.height, height: natural.width }\n : { width: natural.width, height: natural.height };\n };\n\n const view = usePanZoom({\n viewport: () => viewport,\n min: 0.05,\n max: 8,\n bounds: () => (natural ? box() : undefined),\n initial: () => ({ x: 0, y: 0, scale: 1 }),\n });\n\n /** 整张图放进视口(不超过原大):打开、换一张、旋转之后 */\n function fitImage() {\n if (!natural) return;\n view.fit(box(), 24);\n }\n\n function go(step: 1 | -1) {\n if (items.length < 2) return;\n const next = index + step;\n if (next < 0 || next >= items.length) {\n if (!loop) return;\n index = (next + items.length) % items.length;\n } else index = next;\n }\n\n function rotate(step: 1 | -1) {\n rotation = (rotation + step * 90 + 360) % 360;\n void nextTick(fitImage);\n }\n\n function reset() {\n rotation = 0;\n void nextTick(fitImage);\n }\n\n function onLoad(event: Event) {\n const image = event.currentTarget as HTMLImageElement;\n natural = { width: image.naturalWidth, height: image.naturalHeight };\n void nextTick(fitImage);\n }\n\n function onKeydown(event: KeyboardEvent) {\n if (event.altKey || event.ctrlKey || event.metaKey) return;\n if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {\n // 从右到左排版时左右对调\n const rtl = dialog ? getComputedStyle(dialog).direction === 'rtl' : false;\n go((event.key === 'ArrowRight') !== rtl ? 1 : -1);\n event.preventDefault();\n } else if (event.key === 'r' || event.key === 'R') {\n rotate(1);\n event.preventDefault();\n }\n }\n\n function close() {\n closing = 'close';\n dialog?.close();\n }\n\n // 不论怎么关上(Esc、关闭按钮、open 改成 false),原生 close 事件都会来\n function onClose() {\n release?.();\n release = undefined;\n const reason = closing ?? 'escape';\n closing = undefined;\n setOpen(false, reason);\n }\n\n // 换一张:原图大小重新量,方向回正\n _effect(() => {\n void current()?.src;\n natural = null;\n rotation = 0;\n });\n _effect(() => {\n if (open && dialog && !dialog.open) {\n release = openModalDialog(dialog);\n void nextTick(() => viewport?.focus());\n } else if (!open && dialog?.open) dialog.close();\n });\n // 预先加载前后两张:切换时不闪\n _effect(() => {\n if (!open) return;\n for (const step of [-1, 1]) {\n const neighbour = items[index + step];\n if (neighbour) new Image().src = neighbour.src;\n }\n });\n onBeforeUnmount(() => release?.());\n\n const button = (props: Partial<IconButtonProps>) =>\n mergePartProps<IconButtonProps>(\n {\n icon: X,\n variant: 'ghost',\n tone: 'neutral',\n sx: lightboxStyles.button,\n 'aria-label': '',\n },\n propsButton,\n props,\n );\n\n return () => {\n const item = current();\n const total = items.length;\n const { width, height } = box();\n const canDownload = item && item.download !== false;\n return (\n <dialog\n {...mergeAttrs<'dialog'>({ sx: [lightboxStyles.root, transitions.backdrop] }, rest, {\n ref: _toRef(dialog),\n 'aria-label': lang.lightboxLabel,\n onClose,\n onKeydown,\n })}\n >\n <div {...css.attrs(lightboxStyles.toolbar)}>\n <span {...css.attrs(lightboxStyles.counter)} aria-live=\"polite\">\n {total > 1 ? lang.lightboxCounter(index + 1, total) : ''}\n </span>\n <IconButton\n {...button({\n icon: ZoomOut,\n 'aria-label': lang.lightboxZoomOut,\n onClick: () => view.zoomOut(),\n })}\n />\n <span {...css.attrs(lightboxStyles.zoom)} aria-hidden=\"true\">\n {Math.round(view.scale * 100)}%\n </span>\n <IconButton\n {...button({\n icon: ZoomIn,\n 'aria-label': lang.lightboxZoomIn,\n onClick: () => view.zoomIn(),\n })}\n />\n <IconButton\n {...button({\n icon: RotateCcw,\n 'aria-label': lang.lightboxRotateLeft,\n onClick: () => rotate(-1),\n })}\n />\n <IconButton\n {...button({\n icon: RotateCw,\n 'aria-label': lang.lightboxRotateRight,\n onClick: () => rotate(1),\n })}\n />\n <IconButton\n {...button({ icon: Undo2, 'aria-label': lang.lightboxReset, onClick: reset })}\n />\n {canDownload && (\n <IconLinkButton\n {...mergePartProps<IconLinkButtonProps>(\n {\n icon: Download,\n variant: 'ghost',\n tone: 'neutral',\n sx: lightboxStyles.button,\n 'aria-label': lang.lightboxDownload,\n href: item.src,\n },\n // 下载而不是打开:download 是文件名,空字符串时用地址里的名字\n { download: item.download ?? '' } as Partial<IconLinkButtonProps>,\n )}\n />\n )}\n <IconButton\n {...button({\n icon: X,\n 'aria-label': lang.close,\n onClick: close,\n })}\n />\n </div>\n <div\n {...mergeAttrs<'div'>({ sx: lightboxStyles.viewport }, propsViewport, {\n ...view.viewportProps,\n ref: _toRef(viewport),\n tabindex: 0,\n role: 'img',\n 'aria-label': item?.alt,\n })}\n >\n {item && (\n <div\n {...css.attrs(\n lightboxStyles.content,\n !view.interacting && lightboxStyles.smooth,\n lightboxDynamicStyles.transform(view.transform),\n lightboxDynamicStyles.box(width, height),\n )}\n >\n <img\n key={item.src}\n src={item.src}\n alt=\"\"\n draggable={false}\n onLoad={onLoad}\n {...css.attrs(\n lightboxStyles.image,\n natural && lightboxDynamicStyles.image(natural.width, natural.height, rotation),\n )}\n />\n </div>\n )}\n </div>\n {total > 1 && (loop || index > 0) && (\n <IconButton\n {...button({\n icon: ChevronLeft,\n propsIcon: { flipInRtl: true },\n radius: 'full',\n sx: [lightboxStyles.button, lightboxStyles.side, lightboxStyles.previous],\n 'aria-label': lang.lightboxPrevious,\n onClick: () => go(-1),\n })}\n />\n )}\n {total > 1 && (loop || index < total - 1) && (\n <IconButton\n {...button({\n icon: ChevronRight,\n propsIcon: { flipInRtl: true },\n radius: 'full',\n sx: [lightboxStyles.button, lightboxStyles.side, lightboxStyles.next],\n 'aria-label': lang.lightboxNext,\n onClick: () => go(1),\n })}\n />\n )}\n {item?.caption != null && (\n <div {...mergeAttrs<'div'>({ sx: lightboxStyles.caption }, propsCaption)}>\n {item.caption}\n </div>\n )}\n </dialog>\n );\n };\n },\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"Lightbox.js","names":["_vtp_bindable","_vtp_readonlyProp","_vtp_restProps","_vue_shallowRef","_vue_ref","_createVNode","_mergeProps","_createTextVNode"],"sources":["../../src/overlay/Lightbox.tsx"],"sourcesContent":["/**\n * 图片预览(全屏的模态 dialog):深色背景上看大图——缩放、拖动、旋转、还原、下载,几张图时左右切换。\n * Image 的 preview 打开它(同一个 ImageGroup 里的图共用一个),也可以单独用。参考 Ant Design Image 的预览、Element Plus 的 image-viewer。\n *\n * <Lightbox _open={viewing} _index={at} items={[{ src: '/photos/1.jpg', alt: '支架正面' }, …]} />\n *\n * - 平移与缩放建在 usePanZoom 上:拖动平移,滚轮、触控板、捏合以指针为中心缩放,双击放大 / 还原;\n * 打开或换一张时整张图放进视口(不超过原大)。旋转以 90° 为一档,转完重新放进视口。\n * - 键盘:← / → 上一张、下一张,+ / − 缩放,0 还原,R 向右旋转,Esc 关闭;焦点在工具栏与图片区之间循环(模态)。\n * - 读屏:dialog 的名称是“图片预览”,图片区是 role=\"img\"、名称是图片的 alt;换一张时念出“第 2 张,共 5 张”。\n *\n * 部件:Root(dialog)、Toolbar(div)、Counter(span)、Viewport(div)、Image(img)、Previous、Next(IconButton)、Caption(div)。\n */\nimport {\n ChevronLeft,\n ChevronRight,\n Download,\n RotateCcw,\n RotateCw,\n Undo2,\n X,\n ZoomIn,\n ZoomOut,\n} from '@lucide/icons';\nimport { _component } from '@zerodep-dev/vue-tsx-pro-tsx';\nimport * as css from '@zerodep-dev/vue-tsx-pro-tsx/styles';\nimport { nextTick, onBeforeUnmount, type VNodeChild } from 'vue';\nimport { IconButton, type IconButtonProps } from '../base/IconButton';\nimport { IconLinkButton, type IconLinkButtonProps } from '../base/IconLinkButton';\nimport { useLang } from '../config/context';\nimport { clamp } from '../utils/data/number';\nimport { openSetter, type OpenChangeProps, type OpenChangeReasons } from '../utils/dom/open-change';\nimport { openModalDialog } from '../utils/dom/overlay';\nimport { usePanZoom } from '../utils/dom/pan-zoom';\nimport { mergeAttrs, mergePartProps, type PartProps } from '../utils/props';\nimport { transitions } from '../utils/style/transitions';\n\n/** 一张图 */\nexport interface LightboxItem {\n /** 大图的地址 */\n src: string;\n /** 图片的说明(读屏念它) */\n alt: string;\n /** 图片下方的说明文字 */\n caption?: VNodeChild;\n /** 下载时的文件名;false 不显示下载按钮 */\n download?: string | false;\n}\n\n/** 打开、关联由组件管理;未声明的属性落到 dialog 上 */\nexport interface LightboxProps\n extends PartProps<'dialog', 'open' | 'aria-label' | 'aria-labelledby'>, OpenChangeProps {\n /** 是否打开:父级写 _open={x};Esc、关闭按钮会关上并写回 */\n _open?: boolean;\n /** 图片 */\n items: readonly LightboxItem[];\n /** 当前第几张,从 0 开始:父级可以写 _index={x} */\n _index?: number;\n /** 到头之后从另一头继续,默认 false */\n loop?: boolean;\n /** 工具栏按钮的部件属性 */\n propsButton?: Partial<IconButtonProps>;\n /** 图片区(视口)的部件属性 */\n propsViewport?: PartProps<'div'>;\n /** 说明文字的部件属性 */\n propsCaption?: PartProps<'div'>;\n}\n\n/** Lightbox 的样式:root、toolbar、counter、viewport、content、image、side、previous、next、caption、button */\nexport const lightboxStyles = css.create({\n root: {\n // 占满视口:原生 dialog 默认有最大宽高与边框\n boxSizing: 'border-box',\n width: '100vw',\n height: '100dvh',\n maxWidth: 'none',\n maxHeight: 'none',\n margin: 0,\n padding: 0,\n borderWidth: 0,\n display: { default: 'none', ':modal': 'flex' },\n flexDirection: 'column',\n // 图片预览总是深色背景:不跟主题变(看图片本身的颜色)\n backgroundColor: 'rgb(0 0 0 / 0.86)',\n color: 'white',\n colorScheme: 'dark',\n },\n toolbar: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'flex-end',\n gap: '_xs',\n paddingBlock: '_sm',\n paddingInline: '_md',\n flexShrink: 0,\n },\n counter: {\n marginInlineEnd: 'auto',\n fontVariantNumeric: 'tabular-nums',\n fontSize: '_sm',\n opacity: 0.8,\n },\n zoom: {\n minWidth: '3.5em',\n textAlign: 'center',\n fontSize: '_sm',\n fontVariantNumeric: 'tabular-nums',\n },\n viewport: {\n position: 'relative',\n flexGrow: 1,\n minHeight: 0,\n overflow: 'hidden',\n cursor: { default: 'grab', ':active': 'grabbing' },\n outline: 'none',\n },\n // 平移与缩放作用在它上面(transform-origin 左上角);它的大小是旋转之后图片占的框\n content: { position: 'absolute', top: 0, left: 0, transformOrigin: '0 0' },\n // 图片以框的中心旋转\n image: {\n position: 'absolute',\n top: '50%',\n left: '50%',\n maxWidth: 'none',\n userSelect: 'none',\n pointerEvents: 'none',\n },\n smooth: { transitionProperty: 'transform', transitionDuration: '_md' },\n side: {\n position: 'absolute',\n top: '50%',\n translate: '0 -50%',\n zIndex: 1,\n },\n previous: { insetInlineStart: '_md' },\n next: { insetInlineEnd: '_md' },\n caption: {\n flexShrink: 0,\n paddingBlock: '_md',\n paddingInline: '_xl',\n textAlign: 'center',\n fontSize: '_sm',\n opacity: 0.9,\n },\n // 深色背景上的按钮:文字白色,悬停时浅一点的底\n button: {\n color: 'white',\n backgroundColor: { default: 'transparent', ':hover': 'rgb(255 255 255 / 0.12)' },\n },\n});\n\n/** Lightbox 的动态样式:平移缩放、框的大小、图片的大小与旋转 */\nexport const lightboxDynamicStyles = css.create({\n transform: (transform: string) => ({ transform }),\n box: (width: number, height: number) => ({ width: `${width}px`, height: `${height}px` }),\n image: (width: number, height: number, degrees: number) => ({\n width: `${width}px`,\n height: `${height}px`,\n transform: `translate(-50%, -50%) rotate(${degrees}deg)`,\n }),\n});\n\n/** 图片预览:全屏 dialog,缩放、拖动、旋转、左右切换 */\nexport const Lightbox = _component(\n ({\n _open: open = _bindable(false),\n onOpenChange,\n items,\n _index: index = _bindable(0),\n loop = false,\n propsButton,\n propsViewport,\n propsCaption,\n ...rest\n }: LightboxProps) => {\n const lang = useLang();\n let dialog = _state.raw<HTMLDialogElement | null>(null);\n let viewport = _state.raw<HTMLElement | null>(null);\n // 当前图片的原始大小(加载后知道)与旋转(0、90、180、270)\n let natural = _state<{ width: number; height: number } | null>(null);\n let rotation = _state(0);\n let release: (() => void) | undefined;\n let closing: keyof OpenChangeReasons | undefined;\n const setOpen = openSetter(\n () => open,\n (next) => (open = next),\n () => onOpenChange,\n );\n\n const current = () => items[clamp(index, 0, Math.max(0, items.length - 1))];\n /** 旋转之后图片占的框 */\n const box = () => {\n if (!natural) return { width: 0, height: 0 };\n const sideways = rotation % 180 !== 0;\n return sideways\n ? { width: natural.height, height: natural.width }\n : { width: natural.width, height: natural.height };\n };\n\n const view = usePanZoom({\n viewport: () => viewport,\n min: 0.05,\n max: 8,\n bounds: () => (natural ? box() : undefined),\n initial: () => ({ x: 0, y: 0, scale: 1 }),\n });\n\n /** 整张图放进视口(不超过原大):打开、换一张、旋转之后 */\n function fitImage() {\n if (!natural) return;\n view.fit(box(), 24);\n }\n\n function go(step: 1 | -1) {\n if (items.length < 2) return;\n const next = index + step;\n if (next < 0 || next >= items.length) {\n if (!loop) return;\n index = (next + items.length) % items.length;\n } else index = next;\n }\n\n function rotate(step: 1 | -1) {\n rotation = (rotation + step * 90 + 360) % 360;\n void nextTick(fitImage);\n }\n\n function reset() {\n rotation = 0;\n void nextTick(fitImage);\n }\n\n function onLoad(event: Event) {\n const image = event.currentTarget as HTMLImageElement;\n natural = { width: image.naturalWidth, height: image.naturalHeight };\n void nextTick(fitImage);\n }\n\n function onKeydown(event: KeyboardEvent) {\n if (event.altKey || event.ctrlKey || event.metaKey) return;\n if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {\n // 从右到左排版时左右对调\n const rtl = dialog ? getComputedStyle(dialog).direction === 'rtl' : false;\n go((event.key === 'ArrowRight') !== rtl ? 1 : -1);\n event.preventDefault();\n } else if (event.key === 'r' || event.key === 'R') {\n rotate(1);\n event.preventDefault();\n }\n }\n\n function close() {\n closing = 'close';\n dialog?.close();\n }\n\n // 不论怎么关上(Esc、关闭按钮、open 改成 false),原生 close 事件都会来\n function onClose() {\n release?.();\n release = undefined;\n const reason = closing ?? 'escape';\n closing = undefined;\n setOpen(false, reason);\n }\n\n // 换一张:原图大小重新量,方向回正\n _effect(() => {\n void current()?.src;\n natural = null;\n rotation = 0;\n });\n _effect(() => {\n if (open && dialog && !dialog.open) {\n release = openModalDialog(dialog);\n void nextTick(() => viewport?.focus());\n } else if (!open && dialog?.open) dialog.close();\n });\n // 预先加载前后两张:切换时不闪\n _effect(() => {\n if (!open) return;\n for (const step of [-1, 1]) {\n const neighbour = items[index + step];\n if (neighbour) new Image().src = neighbour.src;\n }\n });\n onBeforeUnmount(() => release?.());\n\n const button = (props: Partial<IconButtonProps>) =>\n mergePartProps<IconButtonProps>(\n {\n icon: X,\n variant: 'ghost',\n tone: 'neutral',\n sx: lightboxStyles.button,\n 'aria-label': '',\n },\n propsButton,\n props,\n );\n\n return () => {\n const item = current();\n const total = items.length;\n const { width, height } = box();\n const canDownload = item && item.download !== false;\n return (\n <dialog\n {...mergeAttrs<'dialog'>({ sx: [lightboxStyles.root, transitions.backdrop] }, rest, {\n ref: _toRef(dialog),\n 'aria-label': lang.lightboxLabel,\n onClose,\n onKeydown,\n })}\n >\n <div {...css.attrs(lightboxStyles.toolbar)}>\n <span {...css.attrs(lightboxStyles.counter)} aria-live=\"polite\">\n {total > 1 ? lang.lightboxCounter(index + 1, total) : ''}\n </span>\n <IconButton\n {...button({\n icon: ZoomOut,\n 'aria-label': lang.lightboxZoomOut,\n onClick: () => view.zoomOut(),\n })}\n />\n <span {...css.attrs(lightboxStyles.zoom)} aria-hidden=\"true\">\n {Math.round(view.scale * 100)}%\n </span>\n <IconButton\n {...button({\n icon: ZoomIn,\n 'aria-label': lang.lightboxZoomIn,\n onClick: () => view.zoomIn(),\n })}\n />\n <IconButton\n {...button({\n icon: RotateCcw,\n 'aria-label': lang.lightboxRotateLeft,\n onClick: () => rotate(-1),\n })}\n />\n <IconButton\n {...button({\n icon: RotateCw,\n 'aria-label': lang.lightboxRotateRight,\n onClick: () => rotate(1),\n })}\n />\n <IconButton\n {...button({ icon: Undo2, 'aria-label': lang.lightboxReset, onClick: reset })}\n />\n {canDownload && (\n <IconLinkButton\n {...mergePartProps<IconLinkButtonProps>(\n {\n icon: Download,\n variant: 'ghost',\n tone: 'neutral',\n sx: lightboxStyles.button,\n 'aria-label': lang.lightboxDownload,\n href: item.src,\n },\n // 下载而不是打开:download 是文件名,空字符串时用地址里的名字\n { download: item.download ?? '' } as Partial<IconLinkButtonProps>,\n )}\n />\n )}\n <IconButton\n {...button({\n icon: X,\n 'aria-label': lang.close,\n onClick: close,\n })}\n />\n </div>\n <div\n {...mergeAttrs<'div'>({ sx: lightboxStyles.viewport }, propsViewport, {\n ...view.viewportProps,\n ref: _toRef(viewport),\n tabindex: 0,\n role: 'img',\n 'aria-label': item?.alt,\n })}\n >\n {item && (\n <div\n {...css.attrs(\n lightboxStyles.content,\n !view.interacting && lightboxStyles.smooth,\n lightboxDynamicStyles.transform(view.transform),\n lightboxDynamicStyles.box(width, height),\n )}\n >\n <img\n key={item.src}\n src={item.src}\n alt=\"\"\n draggable={false}\n onLoad={onLoad}\n {...css.attrs(\n lightboxStyles.image,\n natural && lightboxDynamicStyles.image(natural.width, natural.height, rotation),\n )}\n />\n </div>\n )}\n </div>\n {total > 1 && (loop || index > 0) && (\n <IconButton\n {...button({\n icon: ChevronLeft,\n propsIcon: { flipInRtl: true },\n radius: 'full',\n sx: [lightboxStyles.button, lightboxStyles.side, lightboxStyles.previous],\n 'aria-label': lang.lightboxPrevious,\n onClick: () => go(-1),\n })}\n />\n )}\n {total > 1 && (loop || index < total - 1) && (\n <IconButton\n {...button({\n icon: ChevronRight,\n propsIcon: { flipInRtl: true },\n radius: 'full',\n sx: [lightboxStyles.button, lightboxStyles.side, lightboxStyles.next],\n 'aria-label': lang.lightboxNext,\n onClick: () => go(1),\n })}\n />\n )}\n {item?.caption != null && (\n <div {...mergeAttrs<'div'>({ sx: lightboxStyles.caption }, propsCaption)}>\n {item.caption}\n </div>\n )}\n </dialog>\n );\n };\n },\n);\n"],"mappings":"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"}
@@ -17,8 +17,8 @@ import { openSetter } from "../utils/dom/open-change.js";
17
17
  import { ariaKeyShortcut, formatHotkey, useHotkeys } from "../utils/dom/hotkeys.js";
18
18
  import { itemStyles } from "../utils/style/item-styles.js";
19
19
  import { rovingFocus } from "../utils/dom/roving-focus.js";
20
- import { Fragment, createVNode, isVNode, mergeProps, onBeforeUnmount, shallowRef, useId } from "vue";
21
- import { _component, bindable, childrenProp, childrenStable, createContext, effect, forwardChildren, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
20
+ import { Fragment, createVNode, isVNode, onBeforeUnmount, shallowRef, useId } from "vue";
21
+ import { _component, bindable, childrenProp, childrenStable, createContext, effect, forwardChildren, mergeJsxProps, readonlyProp, restProps } from "@zerodep-dev/vue-tsx-pro-tsx";
22
22
  import * as css from "@zerodep-dev/vue-tsx-pro-tsx/styles";
23
23
  import { Check, ChevronRight, Dot } from "@lucide/icons";
24
24
  //#region src/overlay/Menu.tsx
@@ -175,7 +175,7 @@ var Menu$1 = /*#__PURE__*/ _component((_props, _ctx) => {
175
175
  "aria-haspopup": "menu",
176
176
  "aria-expanded": open.value,
177
177
  "aria-controls": id
178
- }), createVNode("div", mergeProps(mergeAttrs({
178
+ }), createVNode("div", mergeJsxProps(mergeAttrs({
179
179
  sx: [
180
180
  floatingStyles.anchored,
181
181
  floatingStyles.surface,
@@ -296,7 +296,7 @@ function useButtonItem(read, run) {
296
296
  useItemShortcut(read, run);
297
297
  return ({ role, tone = "neutral", disabled, closeOnSelect, checked, indicator, content, attrs }) => {
298
298
  let _slot2;
299
- return createVNode(ButtonBase, mergeProps(mergePartProps({
299
+ return createVNode(ButtonBase, mergeJsxProps(mergePartProps({
300
300
  sx: menuItemSx(tone, disabled),
301
301
  ripple: item.menu.ripple
302
302
  }, attrs, {
@@ -383,7 +383,7 @@ var MenuLinkItem = /*#__PURE__*/ _component((_props3, _ctx3) => {
383
383
  const item = useMenuItem();
384
384
  const ids = useMenuItemContentIds();
385
385
  const router = useRouterLink();
386
- return () => createVNode("a", mergeProps(mergeAttrs({ sx: menuItemSx("neutral", disabled.value) }, rest, {
386
+ return () => createVNode("a", mergeJsxProps(mergeAttrs({ sx: menuItemSx("neutral", disabled.value) }, rest, {
387
387
  role: "menuitem",
388
388
  href: disabled.value ? void 0 : router.href(href.value),
389
389
  "aria-keyshortcuts": keyShortcuts(shortcut.value),
@@ -731,7 +731,7 @@ var MenuSub = /*#__PURE__*/ _component((_props8, _ctx8) => {
731
731
  }
732
732
  return () => {
733
733
  let _slot3;
734
- return createVNode(Fragment, null, [createVNode(ButtonBase, mergeProps(mergePartProps({
734
+ return createVNode(Fragment, null, [createVNode(ButtonBase, mergeJsxProps(mergePartProps({
735
735
  sx: menuItemSx("neutral", disabled.value),
736
736
  ripple: parent.ripple
737
737
  }, rest, {
@@ -761,7 +761,7 @@ var MenuSub = /*#__PURE__*/ _component((_props8, _ctx8) => {
761
761
  sx: menuStyles.shortcut
762
762
  }, propsChevron.value), null)],
763
763
  $stable: true
764
- }), createVNode("div", mergeProps(mergeAttrs({
764
+ }), createVNode("div", mergeJsxProps(mergeAttrs({
765
765
  sx: [
766
766
  floatingStyles.anchored,
767
767
  floatingStyles.surface,