@miaixz/ui 0.5.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 (690) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +7 -0
  3. package/README.md +190 -0
  4. package/dist/accessibility/focus-scope.d.ts +57 -0
  5. package/dist/accessibility/focus-scope.d.ts.map +1 -0
  6. package/dist/accessibility/focus-scope.js +272 -0
  7. package/dist/accessibility/focus-scope.js.map +1 -0
  8. package/dist/accessibility/index.d.ts +2 -0
  9. package/dist/accessibility/index.d.ts.map +1 -0
  10. package/dist/accessibility/index.js +2 -0
  11. package/dist/accessibility/index.js.map +1 -0
  12. package/dist/components/alert/alert.d.ts +8 -0
  13. package/dist/components/alert/alert.d.ts.map +1 -0
  14. package/dist/components/alert/alert.js +24 -0
  15. package/dist/components/alert/alert.js.map +1 -0
  16. package/dist/components/alert/alert.types.d.ts +43 -0
  17. package/dist/components/alert/alert.types.d.ts.map +1 -0
  18. package/dist/components/alert/alert.types.js +2 -0
  19. package/dist/components/alert/alert.types.js.map +1 -0
  20. package/dist/components/alert/index.d.ts +4 -0
  21. package/dist/components/alert/index.d.ts.map +1 -0
  22. package/dist/components/alert/index.js +2 -0
  23. package/dist/components/alert/index.js.map +1 -0
  24. package/dist/components/avatar/avatar.d.ts +8 -0
  25. package/dist/components/avatar/avatar.d.ts.map +1 -0
  26. package/dist/components/avatar/avatar.js +29 -0
  27. package/dist/components/avatar/avatar.js.map +1 -0
  28. package/dist/components/avatar/avatar.types.d.ts +35 -0
  29. package/dist/components/avatar/avatar.types.d.ts.map +1 -0
  30. package/dist/components/avatar/avatar.types.js +2 -0
  31. package/dist/components/avatar/avatar.types.js.map +1 -0
  32. package/dist/components/avatar/index.d.ts +4 -0
  33. package/dist/components/avatar/index.d.ts.map +1 -0
  34. package/dist/components/avatar/index.js +2 -0
  35. package/dist/components/avatar/index.js.map +1 -0
  36. package/dist/components/badge/badge.d.ts +8 -0
  37. package/dist/components/badge/badge.d.ts.map +1 -0
  38. package/dist/components/badge/badge.js +12 -0
  39. package/dist/components/badge/badge.js.map +1 -0
  40. package/dist/components/badge/badge.types.d.ts +37 -0
  41. package/dist/components/badge/badge.types.d.ts.map +1 -0
  42. package/dist/components/badge/badge.types.js +2 -0
  43. package/dist/components/badge/badge.types.js.map +1 -0
  44. package/dist/components/badge/index.d.ts +3 -0
  45. package/dist/components/badge/index.d.ts.map +1 -0
  46. package/dist/components/badge/index.js +2 -0
  47. package/dist/components/badge/index.js.map +1 -0
  48. package/dist/components/breadcrumb/breadcrumb.d.ts +14 -0
  49. package/dist/components/breadcrumb/breadcrumb.d.ts.map +1 -0
  50. package/dist/components/breadcrumb/breadcrumb.js +22 -0
  51. package/dist/components/breadcrumb/breadcrumb.js.map +1 -0
  52. package/dist/components/breadcrumb/breadcrumb.types.d.ts +30 -0
  53. package/dist/components/breadcrumb/breadcrumb.types.d.ts.map +1 -0
  54. package/dist/components/breadcrumb/breadcrumb.types.js +2 -0
  55. package/dist/components/breadcrumb/breadcrumb.types.js.map +1 -0
  56. package/dist/components/breadcrumb/index.d.ts +3 -0
  57. package/dist/components/breadcrumb/index.d.ts.map +1 -0
  58. package/dist/components/breadcrumb/index.js +2 -0
  59. package/dist/components/breadcrumb/index.js.map +1 -0
  60. package/dist/components/button/button.d.ts +8 -0
  61. package/dist/components/button/button.d.ts.map +1 -0
  62. package/dist/components/button/button.js +16 -0
  63. package/dist/components/button/button.js.map +1 -0
  64. package/dist/components/button/button.types.d.ts +99 -0
  65. package/dist/components/button/button.types.d.ts.map +1 -0
  66. package/dist/components/button/button.types.js +2 -0
  67. package/dist/components/button/button.types.js.map +1 -0
  68. package/dist/components/button/index.d.ts +3 -0
  69. package/dist/components/button/index.d.ts.map +1 -0
  70. package/dist/components/button/index.js +2 -0
  71. package/dist/components/button/index.js.map +1 -0
  72. package/dist/components/checkbox/checkbox.d.ts +8 -0
  73. package/dist/components/checkbox/checkbox.d.ts.map +1 -0
  74. package/dist/components/checkbox/checkbox.js +18 -0
  75. package/dist/components/checkbox/checkbox.js.map +1 -0
  76. package/dist/components/checkbox/checkbox.types.d.ts +23 -0
  77. package/dist/components/checkbox/checkbox.types.d.ts.map +1 -0
  78. package/dist/components/checkbox/checkbox.types.js +2 -0
  79. package/dist/components/checkbox/checkbox.types.js.map +1 -0
  80. package/dist/components/checkbox/index.d.ts +3 -0
  81. package/dist/components/checkbox/index.d.ts.map +1 -0
  82. package/dist/components/checkbox/index.js +2 -0
  83. package/dist/components/checkbox/index.js.map +1 -0
  84. package/dist/components/combobox/combobox.d.ts +123 -0
  85. package/dist/components/combobox/combobox.d.ts.map +1 -0
  86. package/dist/components/combobox/combobox.js +378 -0
  87. package/dist/components/combobox/combobox.js.map +1 -0
  88. package/dist/components/combobox/combobox.types.d.ts +108 -0
  89. package/dist/components/combobox/combobox.types.d.ts.map +1 -0
  90. package/dist/components/combobox/combobox.types.js +2 -0
  91. package/dist/components/combobox/combobox.types.js.map +1 -0
  92. package/dist/components/combobox/index.d.ts +3 -0
  93. package/dist/components/combobox/index.d.ts.map +1 -0
  94. package/dist/components/combobox/index.js +2 -0
  95. package/dist/components/combobox/index.js.map +1 -0
  96. package/dist/components/confirm-dialog/confirm-dialog.d.ts +10 -0
  97. package/dist/components/confirm-dialog/confirm-dialog.d.ts.map +1 -0
  98. package/dist/components/confirm-dialog/confirm-dialog.js +70 -0
  99. package/dist/components/confirm-dialog/confirm-dialog.js.map +1 -0
  100. package/dist/components/confirm-dialog/confirm-dialog.types.d.ts +63 -0
  101. package/dist/components/confirm-dialog/confirm-dialog.types.d.ts.map +1 -0
  102. package/dist/components/confirm-dialog/confirm-dialog.types.js +2 -0
  103. package/dist/components/confirm-dialog/confirm-dialog.types.js.map +1 -0
  104. package/dist/components/confirm-dialog/index.d.ts +3 -0
  105. package/dist/components/confirm-dialog/index.d.ts.map +1 -0
  106. package/dist/components/confirm-dialog/index.js +2 -0
  107. package/dist/components/confirm-dialog/index.js.map +1 -0
  108. package/dist/components/data-table/data-table.d.ts +9 -0
  109. package/dist/components/data-table/data-table.d.ts.map +1 -0
  110. package/dist/components/data-table/data-table.js +198 -0
  111. package/dist/components/data-table/data-table.js.map +1 -0
  112. package/dist/components/data-table/data-table.types.d.ts +127 -0
  113. package/dist/components/data-table/data-table.types.d.ts.map +1 -0
  114. package/dist/components/data-table/data-table.types.js +2 -0
  115. package/dist/components/data-table/data-table.types.js.map +1 -0
  116. package/dist/components/data-table/index.d.ts +3 -0
  117. package/dist/components/data-table/index.d.ts.map +1 -0
  118. package/dist/components/data-table/index.js +2 -0
  119. package/dist/components/data-table/index.js.map +1 -0
  120. package/dist/components/dialog/dialog.d.ts +8 -0
  121. package/dist/components/dialog/dialog.d.ts.map +1 -0
  122. package/dist/components/dialog/dialog.js +45 -0
  123. package/dist/components/dialog/dialog.js.map +1 -0
  124. package/dist/components/dialog/dialog.types.d.ts +57 -0
  125. package/dist/components/dialog/dialog.types.d.ts.map +1 -0
  126. package/dist/components/dialog/dialog.types.js +2 -0
  127. package/dist/components/dialog/dialog.types.js.map +1 -0
  128. package/dist/components/dialog/index.d.ts +3 -0
  129. package/dist/components/dialog/index.d.ts.map +1 -0
  130. package/dist/components/dialog/index.js +2 -0
  131. package/dist/components/dialog/index.js.map +1 -0
  132. package/dist/components/divider/divider.d.ts +8 -0
  133. package/dist/components/divider/divider.d.ts.map +1 -0
  134. package/dist/components/divider/divider.js +12 -0
  135. package/dist/components/divider/divider.js.map +1 -0
  136. package/dist/components/divider/divider.types.d.ts +22 -0
  137. package/dist/components/divider/divider.types.d.ts.map +1 -0
  138. package/dist/components/divider/divider.types.js +2 -0
  139. package/dist/components/divider/divider.types.js.map +1 -0
  140. package/dist/components/divider/index.d.ts +3 -0
  141. package/dist/components/divider/index.d.ts.map +1 -0
  142. package/dist/components/divider/index.js +2 -0
  143. package/dist/components/divider/index.js.map +1 -0
  144. package/dist/components/drawer/drawer.d.ts +8 -0
  145. package/dist/components/drawer/drawer.d.ts.map +1 -0
  146. package/dist/components/drawer/drawer.js +45 -0
  147. package/dist/components/drawer/drawer.js.map +1 -0
  148. package/dist/components/drawer/drawer.types.d.ts +69 -0
  149. package/dist/components/drawer/drawer.types.d.ts.map +1 -0
  150. package/dist/components/drawer/drawer.types.js +2 -0
  151. package/dist/components/drawer/drawer.types.js.map +1 -0
  152. package/dist/components/drawer/index.d.ts +3 -0
  153. package/dist/components/drawer/index.d.ts.map +1 -0
  154. package/dist/components/drawer/index.js +2 -0
  155. package/dist/components/drawer/index.js.map +1 -0
  156. package/dist/components/dropdown/dropdown.d.ts +26 -0
  157. package/dist/components/dropdown/dropdown.d.ts.map +1 -0
  158. package/dist/components/dropdown/dropdown.js +70 -0
  159. package/dist/components/dropdown/dropdown.js.map +1 -0
  160. package/dist/components/dropdown/dropdown.types.d.ts +83 -0
  161. package/dist/components/dropdown/dropdown.types.d.ts.map +1 -0
  162. package/dist/components/dropdown/dropdown.types.js +2 -0
  163. package/dist/components/dropdown/dropdown.types.js.map +1 -0
  164. package/dist/components/dropdown/index.d.ts +3 -0
  165. package/dist/components/dropdown/index.d.ts.map +1 -0
  166. package/dist/components/dropdown/index.js +2 -0
  167. package/dist/components/dropdown/index.js.map +1 -0
  168. package/dist/components/dropzone/dropzone.d.ts +8 -0
  169. package/dist/components/dropzone/dropzone.d.ts.map +1 -0
  170. package/dist/components/dropzone/dropzone.js +98 -0
  171. package/dist/components/dropzone/dropzone.js.map +1 -0
  172. package/dist/components/dropzone/dropzone.types.d.ts +40 -0
  173. package/dist/components/dropzone/dropzone.types.d.ts.map +1 -0
  174. package/dist/components/dropzone/dropzone.types.js +2 -0
  175. package/dist/components/dropzone/dropzone.types.js.map +1 -0
  176. package/dist/components/dropzone/index.d.ts +3 -0
  177. package/dist/components/dropzone/index.d.ts.map +1 -0
  178. package/dist/components/dropzone/index.js +2 -0
  179. package/dist/components/dropzone/index.js.map +1 -0
  180. package/dist/components/empty-state/empty-state.d.ts +8 -0
  181. package/dist/components/empty-state/empty-state.d.ts.map +1 -0
  182. package/dist/components/empty-state/empty-state.js +13 -0
  183. package/dist/components/empty-state/empty-state.js.map +1 -0
  184. package/dist/components/empty-state/empty-state.types.d.ts +37 -0
  185. package/dist/components/empty-state/empty-state.types.d.ts.map +1 -0
  186. package/dist/components/empty-state/empty-state.types.js +2 -0
  187. package/dist/components/empty-state/empty-state.types.js.map +1 -0
  188. package/dist/components/empty-state/index.d.ts +3 -0
  189. package/dist/components/empty-state/index.d.ts.map +1 -0
  190. package/dist/components/empty-state/index.js +2 -0
  191. package/dist/components/empty-state/index.js.map +1 -0
  192. package/dist/components/file-upload/file-upload.d.ts +8 -0
  193. package/dist/components/file-upload/file-upload.d.ts.map +1 -0
  194. package/dist/components/file-upload/file-upload.js +359 -0
  195. package/dist/components/file-upload/file-upload.js.map +1 -0
  196. package/dist/components/file-upload/file-upload.types.d.ts +91 -0
  197. package/dist/components/file-upload/file-upload.types.d.ts.map +1 -0
  198. package/dist/components/file-upload/file-upload.types.js +2 -0
  199. package/dist/components/file-upload/file-upload.types.js.map +1 -0
  200. package/dist/components/file-upload/index.d.ts +3 -0
  201. package/dist/components/file-upload/index.d.ts.map +1 -0
  202. package/dist/components/file-upload/index.js +2 -0
  203. package/dist/components/file-upload/index.js.map +1 -0
  204. package/dist/components/form-field/form-field.d.ts +11 -0
  205. package/dist/components/form-field/form-field.d.ts.map +1 -0
  206. package/dist/components/form-field/form-field.js +41 -0
  207. package/dist/components/form-field/form-field.js.map +1 -0
  208. package/dist/components/form-field/form-field.types.d.ts +66 -0
  209. package/dist/components/form-field/form-field.types.d.ts.map +1 -0
  210. package/dist/components/form-field/form-field.types.js +2 -0
  211. package/dist/components/form-field/form-field.types.js.map +1 -0
  212. package/dist/components/form-field/index.d.ts +3 -0
  213. package/dist/components/form-field/index.d.ts.map +1 -0
  214. package/dist/components/form-field/index.js +2 -0
  215. package/dist/components/form-field/index.js.map +1 -0
  216. package/dist/components/icon/icon.d.ts +14 -0
  217. package/dist/components/icon/icon.d.ts.map +1 -0
  218. package/dist/components/icon/icon.js +48 -0
  219. package/dist/components/icon/icon.js.map +1 -0
  220. package/dist/components/icon/icon.types.d.ts +69 -0
  221. package/dist/components/icon/icon.types.d.ts.map +1 -0
  222. package/dist/components/icon/icon.types.js +2 -0
  223. package/dist/components/icon/icon.types.js.map +1 -0
  224. package/dist/components/icon/index.d.ts +3 -0
  225. package/dist/components/icon/index.d.ts.map +1 -0
  226. package/dist/components/icon/index.js +2 -0
  227. package/dist/components/icon/index.js.map +1 -0
  228. package/dist/components/index.d.ts +46 -0
  229. package/dist/components/index.d.ts.map +1 -0
  230. package/dist/components/index.js +45 -0
  231. package/dist/components/index.js.map +1 -0
  232. package/dist/components/inline-message/index.d.ts +4 -0
  233. package/dist/components/inline-message/index.d.ts.map +1 -0
  234. package/dist/components/inline-message/index.js +2 -0
  235. package/dist/components/inline-message/index.js.map +1 -0
  236. package/dist/components/inline-message/inline-message.d.ts +8 -0
  237. package/dist/components/inline-message/inline-message.d.ts.map +1 -0
  238. package/dist/components/inline-message/inline-message.js +20 -0
  239. package/dist/components/inline-message/inline-message.js.map +1 -0
  240. package/dist/components/inline-message/inline-message.types.d.ts +27 -0
  241. package/dist/components/inline-message/inline-message.types.d.ts.map +1 -0
  242. package/dist/components/inline-message/inline-message.types.js +2 -0
  243. package/dist/components/inline-message/inline-message.types.js.map +1 -0
  244. package/dist/components/input/index.d.ts +3 -0
  245. package/dist/components/input/index.d.ts.map +1 -0
  246. package/dist/components/input/index.js +2 -0
  247. package/dist/components/input/index.js.map +1 -0
  248. package/dist/components/input/input.d.ts +8 -0
  249. package/dist/components/input/input.d.ts.map +1 -0
  250. package/dist/components/input/input.js +13 -0
  251. package/dist/components/input/input.js.map +1 -0
  252. package/dist/components/input/input.types.d.ts +35 -0
  253. package/dist/components/input/input.types.d.ts.map +1 -0
  254. package/dist/components/input/input.types.js +2 -0
  255. package/dist/components/input/input.types.js.map +1 -0
  256. package/dist/components/list/index.d.ts +3 -0
  257. package/dist/components/list/index.d.ts.map +1 -0
  258. package/dist/components/list/index.js +2 -0
  259. package/dist/components/list/index.js.map +1 -0
  260. package/dist/components/list/list.d.ts +14 -0
  261. package/dist/components/list/list.d.ts.map +1 -0
  262. package/dist/components/list/list.js +21 -0
  263. package/dist/components/list/list.js.map +1 -0
  264. package/dist/components/list/list.types.d.ts +72 -0
  265. package/dist/components/list/list.types.d.ts.map +1 -0
  266. package/dist/components/list/list.types.js +2 -0
  267. package/dist/components/list/list.types.js.map +1 -0
  268. package/dist/components/loading-overlay/index.d.ts +3 -0
  269. package/dist/components/loading-overlay/index.d.ts.map +1 -0
  270. package/dist/components/loading-overlay/index.js +2 -0
  271. package/dist/components/loading-overlay/index.js.map +1 -0
  272. package/dist/components/loading-overlay/loading-overlay.d.ts +8 -0
  273. package/dist/components/loading-overlay/loading-overlay.d.ts.map +1 -0
  274. package/dist/components/loading-overlay/loading-overlay.js +13 -0
  275. package/dist/components/loading-overlay/loading-overlay.js.map +1 -0
  276. package/dist/components/loading-overlay/loading-overlay.types.d.ts +28 -0
  277. package/dist/components/loading-overlay/loading-overlay.types.d.ts.map +1 -0
  278. package/dist/components/loading-overlay/loading-overlay.types.js +2 -0
  279. package/dist/components/loading-overlay/loading-overlay.types.js.map +1 -0
  280. package/dist/components/multi-select/index.d.ts +3 -0
  281. package/dist/components/multi-select/index.d.ts.map +1 -0
  282. package/dist/components/multi-select/index.js +2 -0
  283. package/dist/components/multi-select/index.js.map +1 -0
  284. package/dist/components/multi-select/multi-select.d.ts +9 -0
  285. package/dist/components/multi-select/multi-select.d.ts.map +1 -0
  286. package/dist/components/multi-select/multi-select.js +74 -0
  287. package/dist/components/multi-select/multi-select.js.map +1 -0
  288. package/dist/components/multi-select/multi-select.types.d.ts +35 -0
  289. package/dist/components/multi-select/multi-select.types.d.ts.map +1 -0
  290. package/dist/components/multi-select/multi-select.types.js +2 -0
  291. package/dist/components/multi-select/multi-select.types.js.map +1 -0
  292. package/dist/components/navigation/index.d.ts +3 -0
  293. package/dist/components/navigation/index.d.ts.map +1 -0
  294. package/dist/components/navigation/index.js +2 -0
  295. package/dist/components/navigation/index.js.map +1 -0
  296. package/dist/components/navigation/navigation.d.ts +14 -0
  297. package/dist/components/navigation/navigation.d.ts.map +1 -0
  298. package/dist/components/navigation/navigation.js +29 -0
  299. package/dist/components/navigation/navigation.js.map +1 -0
  300. package/dist/components/navigation/navigation.types.d.ts +84 -0
  301. package/dist/components/navigation/navigation.types.d.ts.map +1 -0
  302. package/dist/components/navigation/navigation.types.js +2 -0
  303. package/dist/components/navigation/navigation.types.js.map +1 -0
  304. package/dist/components/page-layout/index.d.ts +3 -0
  305. package/dist/components/page-layout/index.d.ts.map +1 -0
  306. package/dist/components/page-layout/index.js +2 -0
  307. package/dist/components/page-layout/index.js.map +1 -0
  308. package/dist/components/page-layout/page-layout.d.ts +74 -0
  309. package/dist/components/page-layout/page-layout.d.ts.map +1 -0
  310. package/dist/components/page-layout/page-layout.js +103 -0
  311. package/dist/components/page-layout/page-layout.js.map +1 -0
  312. package/dist/components/page-layout/page-layout.types.d.ts +188 -0
  313. package/dist/components/page-layout/page-layout.types.d.ts.map +1 -0
  314. package/dist/components/page-layout/page-layout.types.js +2 -0
  315. package/dist/components/page-layout/page-layout.types.js.map +1 -0
  316. package/dist/components/pagination/index.d.ts +4 -0
  317. package/dist/components/pagination/index.d.ts.map +1 -0
  318. package/dist/components/pagination/index.js +2 -0
  319. package/dist/components/pagination/index.js.map +1 -0
  320. package/dist/components/pagination/pagination.d.ts +24 -0
  321. package/dist/components/pagination/pagination.d.ts.map +1 -0
  322. package/dist/components/pagination/pagination.js +48 -0
  323. package/dist/components/pagination/pagination.js.map +1 -0
  324. package/dist/components/pagination/pagination.types.d.ts +43 -0
  325. package/dist/components/pagination/pagination.types.d.ts.map +1 -0
  326. package/dist/components/pagination/pagination.types.js +2 -0
  327. package/dist/components/pagination/pagination.types.js.map +1 -0
  328. package/dist/components/panel/index.d.ts +3 -0
  329. package/dist/components/panel/index.d.ts.map +1 -0
  330. package/dist/components/panel/index.js +2 -0
  331. package/dist/components/panel/index.js.map +1 -0
  332. package/dist/components/panel/panel.d.ts +14 -0
  333. package/dist/components/panel/panel.d.ts.map +1 -0
  334. package/dist/components/panel/panel.js +22 -0
  335. package/dist/components/panel/panel.js.map +1 -0
  336. package/dist/components/panel/panel.types.d.ts +62 -0
  337. package/dist/components/panel/panel.types.d.ts.map +1 -0
  338. package/dist/components/panel/panel.types.js +2 -0
  339. package/dist/components/panel/panel.types.js.map +1 -0
  340. package/dist/components/popover/index.d.ts +3 -0
  341. package/dist/components/popover/index.d.ts.map +1 -0
  342. package/dist/components/popover/index.js +2 -0
  343. package/dist/components/popover/index.js.map +1 -0
  344. package/dist/components/popover/popover-context.d.ts +29 -0
  345. package/dist/components/popover/popover-context.d.ts.map +1 -0
  346. package/dist/components/popover/popover-context.js +14 -0
  347. package/dist/components/popover/popover-context.js.map +1 -0
  348. package/dist/components/popover/popover.d.ts +8 -0
  349. package/dist/components/popover/popover.d.ts.map +1 -0
  350. package/dist/components/popover/popover.js +60 -0
  351. package/dist/components/popover/popover.js.map +1 -0
  352. package/dist/components/popover/popover.types.d.ts +47 -0
  353. package/dist/components/popover/popover.types.d.ts.map +1 -0
  354. package/dist/components/popover/popover.types.js +2 -0
  355. package/dist/components/popover/popover.types.js.map +1 -0
  356. package/dist/components/progress/index.d.ts +3 -0
  357. package/dist/components/progress/index.d.ts.map +1 -0
  358. package/dist/components/progress/index.js +2 -0
  359. package/dist/components/progress/index.js.map +1 -0
  360. package/dist/components/progress/progress.d.ts +8 -0
  361. package/dist/components/progress/progress.d.ts.map +1 -0
  362. package/dist/components/progress/progress.js +32 -0
  363. package/dist/components/progress/progress.js.map +1 -0
  364. package/dist/components/progress/progress.types.d.ts +36 -0
  365. package/dist/components/progress/progress.types.d.ts.map +1 -0
  366. package/dist/components/progress/progress.types.js +2 -0
  367. package/dist/components/progress/progress.types.js.map +1 -0
  368. package/dist/components/radio/index.d.ts +3 -0
  369. package/dist/components/radio/index.d.ts.map +1 -0
  370. package/dist/components/radio/index.js +2 -0
  371. package/dist/components/radio/index.js.map +1 -0
  372. package/dist/components/radio/radio.d.ts +8 -0
  373. package/dist/components/radio/radio.d.ts.map +1 -0
  374. package/dist/components/radio/radio.js +12 -0
  375. package/dist/components/radio/radio.js.map +1 -0
  376. package/dist/components/radio/radio.types.d.ts +17 -0
  377. package/dist/components/radio/radio.types.d.ts.map +1 -0
  378. package/dist/components/radio/radio.types.js +2 -0
  379. package/dist/components/radio/radio.types.js.map +1 -0
  380. package/dist/components/search-input/index.d.ts +3 -0
  381. package/dist/components/search-input/index.d.ts.map +1 -0
  382. package/dist/components/search-input/index.js +2 -0
  383. package/dist/components/search-input/index.js.map +1 -0
  384. package/dist/components/search-input/search-input.d.ts +8 -0
  385. package/dist/components/search-input/search-input.d.ts.map +1 -0
  386. package/dist/components/search-input/search-input.js +35 -0
  387. package/dist/components/search-input/search-input.js.map +1 -0
  388. package/dist/components/search-input/search-input.types.d.ts +38 -0
  389. package/dist/components/search-input/search-input.types.d.ts.map +1 -0
  390. package/dist/components/search-input/search-input.types.js +2 -0
  391. package/dist/components/search-input/search-input.types.js.map +1 -0
  392. package/dist/components/select/index.d.ts +3 -0
  393. package/dist/components/select/index.d.ts.map +1 -0
  394. package/dist/components/select/index.js +2 -0
  395. package/dist/components/select/index.js.map +1 -0
  396. package/dist/components/select/select.d.ts +8 -0
  397. package/dist/components/select/select.d.ts.map +1 -0
  398. package/dist/components/select/select.js +14 -0
  399. package/dist/components/select/select.js.map +1 -0
  400. package/dist/components/select/select.types.d.ts +27 -0
  401. package/dist/components/select/select.types.d.ts.map +1 -0
  402. package/dist/components/select/select.types.js +2 -0
  403. package/dist/components/select/select.types.js.map +1 -0
  404. package/dist/components/shared.types.d.ts +13 -0
  405. package/dist/components/shared.types.d.ts.map +1 -0
  406. package/dist/components/shared.types.js +2 -0
  407. package/dist/components/shared.types.js.map +1 -0
  408. package/dist/components/skeleton/index.d.ts +3 -0
  409. package/dist/components/skeleton/index.d.ts.map +1 -0
  410. package/dist/components/skeleton/index.js +2 -0
  411. package/dist/components/skeleton/index.js.map +1 -0
  412. package/dist/components/skeleton/skeleton.d.ts +8 -0
  413. package/dist/components/skeleton/skeleton.d.ts.map +1 -0
  414. package/dist/components/skeleton/skeleton.js +12 -0
  415. package/dist/components/skeleton/skeleton.js.map +1 -0
  416. package/dist/components/skeleton/skeleton.types.d.ts +29 -0
  417. package/dist/components/skeleton/skeleton.types.d.ts.map +1 -0
  418. package/dist/components/skeleton/skeleton.types.js +2 -0
  419. package/dist/components/skeleton/skeleton.types.js.map +1 -0
  420. package/dist/components/spinner/index.d.ts +4 -0
  421. package/dist/components/spinner/index.d.ts.map +1 -0
  422. package/dist/components/spinner/index.js +2 -0
  423. package/dist/components/spinner/index.js.map +1 -0
  424. package/dist/components/spinner/spinner.d.ts +8 -0
  425. package/dist/components/spinner/spinner.d.ts.map +1 -0
  426. package/dist/components/spinner/spinner.js +19 -0
  427. package/dist/components/spinner/spinner.js.map +1 -0
  428. package/dist/components/spinner/spinner.types.d.ts +27 -0
  429. package/dist/components/spinner/spinner.types.d.ts.map +1 -0
  430. package/dist/components/spinner/spinner.types.js +2 -0
  431. package/dist/components/spinner/spinner.types.js.map +1 -0
  432. package/dist/components/status-indicator/index.d.ts +4 -0
  433. package/dist/components/status-indicator/index.d.ts.map +1 -0
  434. package/dist/components/status-indicator/index.js +2 -0
  435. package/dist/components/status-indicator/index.js.map +1 -0
  436. package/dist/components/status-indicator/status-indicator.d.ts +8 -0
  437. package/dist/components/status-indicator/status-indicator.d.ts.map +1 -0
  438. package/dist/components/status-indicator/status-indicator.js +12 -0
  439. package/dist/components/status-indicator/status-indicator.js.map +1 -0
  440. package/dist/components/status-indicator/status-indicator.types.d.ts +25 -0
  441. package/dist/components/status-indicator/status-indicator.types.d.ts.map +1 -0
  442. package/dist/components/status-indicator/status-indicator.types.js +2 -0
  443. package/dist/components/status-indicator/status-indicator.types.js.map +1 -0
  444. package/dist/components/switch/index.d.ts +3 -0
  445. package/dist/components/switch/index.d.ts.map +1 -0
  446. package/dist/components/switch/index.js +2 -0
  447. package/dist/components/switch/index.js.map +1 -0
  448. package/dist/components/switch/switch.d.ts +8 -0
  449. package/dist/components/switch/switch.d.ts.map +1 -0
  450. package/dist/components/switch/switch.js +12 -0
  451. package/dist/components/switch/switch.js.map +1 -0
  452. package/dist/components/switch/switch.types.d.ts +17 -0
  453. package/dist/components/switch/switch.types.d.ts.map +1 -0
  454. package/dist/components/switch/switch.types.js +2 -0
  455. package/dist/components/switch/switch.types.js.map +1 -0
  456. package/dist/components/table/index.d.ts +3 -0
  457. package/dist/components/table/index.d.ts.map +1 -0
  458. package/dist/components/table/index.js +2 -0
  459. package/dist/components/table/index.js.map +1 -0
  460. package/dist/components/table/table.d.ts +56 -0
  461. package/dist/components/table/table.d.ts.map +1 -0
  462. package/dist/components/table/table.js +76 -0
  463. package/dist/components/table/table.js.map +1 -0
  464. package/dist/components/table/table.types.d.ts +101 -0
  465. package/dist/components/table/table.types.d.ts.map +1 -0
  466. package/dist/components/table/table.types.js +2 -0
  467. package/dist/components/table/table.types.js.map +1 -0
  468. package/dist/components/tabs/index.d.ts +3 -0
  469. package/dist/components/tabs/index.d.ts.map +1 -0
  470. package/dist/components/tabs/index.js +2 -0
  471. package/dist/components/tabs/index.js.map +1 -0
  472. package/dist/components/tabs/tabs.d.ts +26 -0
  473. package/dist/components/tabs/tabs.d.ts.map +1 -0
  474. package/dist/components/tabs/tabs.js +122 -0
  475. package/dist/components/tabs/tabs.js.map +1 -0
  476. package/dist/components/tabs/tabs.types.d.ts +70 -0
  477. package/dist/components/tabs/tabs.types.d.ts.map +1 -0
  478. package/dist/components/tabs/tabs.types.js +2 -0
  479. package/dist/components/tabs/tabs.types.js.map +1 -0
  480. package/dist/components/textarea/index.d.ts +3 -0
  481. package/dist/components/textarea/index.d.ts.map +1 -0
  482. package/dist/components/textarea/index.js +2 -0
  483. package/dist/components/textarea/index.js.map +1 -0
  484. package/dist/components/textarea/textarea.d.ts +8 -0
  485. package/dist/components/textarea/textarea.d.ts.map +1 -0
  486. package/dist/components/textarea/textarea.js +13 -0
  487. package/dist/components/textarea/textarea.js.map +1 -0
  488. package/dist/components/textarea/textarea.types.d.ts +39 -0
  489. package/dist/components/textarea/textarea.types.d.ts.map +1 -0
  490. package/dist/components/textarea/textarea.types.js +2 -0
  491. package/dist/components/textarea/textarea.types.js.map +1 -0
  492. package/dist/components/toast/index.d.ts +3 -0
  493. package/dist/components/toast/index.d.ts.map +1 -0
  494. package/dist/components/toast/index.js +2 -0
  495. package/dist/components/toast/index.js.map +1 -0
  496. package/dist/components/toast/toast.d.ts +24 -0
  497. package/dist/components/toast/toast.d.ts.map +1 -0
  498. package/dist/components/toast/toast.js +111 -0
  499. package/dist/components/toast/toast.js.map +1 -0
  500. package/dist/components/toast/toast.types.d.ts +103 -0
  501. package/dist/components/toast/toast.types.d.ts.map +1 -0
  502. package/dist/components/toast/toast.types.js +2 -0
  503. package/dist/components/toast/toast.types.js.map +1 -0
  504. package/dist/components/toolbar/index.d.ts +3 -0
  505. package/dist/components/toolbar/index.d.ts.map +1 -0
  506. package/dist/components/toolbar/index.js +2 -0
  507. package/dist/components/toolbar/index.js.map +1 -0
  508. package/dist/components/toolbar/toolbar.d.ts +20 -0
  509. package/dist/components/toolbar/toolbar.d.ts.map +1 -0
  510. package/dist/components/toolbar/toolbar.js +28 -0
  511. package/dist/components/toolbar/toolbar.js.map +1 -0
  512. package/dist/components/toolbar/toolbar.types.d.ts +37 -0
  513. package/dist/components/toolbar/toolbar.types.d.ts.map +1 -0
  514. package/dist/components/toolbar/toolbar.types.js +2 -0
  515. package/dist/components/toolbar/toolbar.types.js.map +1 -0
  516. package/dist/components/tooltip/index.d.ts +3 -0
  517. package/dist/components/tooltip/index.d.ts.map +1 -0
  518. package/dist/components/tooltip/index.js +2 -0
  519. package/dist/components/tooltip/index.js.map +1 -0
  520. package/dist/components/tooltip/tooltip.d.ts +8 -0
  521. package/dist/components/tooltip/tooltip.d.ts.map +1 -0
  522. package/dist/components/tooltip/tooltip.js +84 -0
  523. package/dist/components/tooltip/tooltip.js.map +1 -0
  524. package/dist/components/tooltip/tooltip.types.d.ts +34 -0
  525. package/dist/components/tooltip/tooltip.types.d.ts.map +1 -0
  526. package/dist/components/tooltip/tooltip.types.js +2 -0
  527. package/dist/components/tooltip/tooltip.types.js.map +1 -0
  528. package/dist/components/tree-view/index.d.ts +3 -0
  529. package/dist/components/tree-view/index.d.ts.map +1 -0
  530. package/dist/components/tree-view/index.js +2 -0
  531. package/dist/components/tree-view/index.js.map +1 -0
  532. package/dist/components/tree-view/tree-view.d.ts +9 -0
  533. package/dist/components/tree-view/tree-view.d.ts.map +1 -0
  534. package/dist/components/tree-view/tree-view.js +573 -0
  535. package/dist/components/tree-view/tree-view.js.map +1 -0
  536. package/dist/components/tree-view/tree-view.types.d.ts +92 -0
  537. package/dist/components/tree-view/tree-view.types.d.ts.map +1 -0
  538. package/dist/components/tree-view/tree-view.types.js +2 -0
  539. package/dist/components/tree-view/tree-view.types.js.map +1 -0
  540. package/dist/components/visually-hidden/index.d.ts +3 -0
  541. package/dist/components/visually-hidden/index.d.ts.map +1 -0
  542. package/dist/components/visually-hidden/index.js +2 -0
  543. package/dist/components/visually-hidden/index.js.map +1 -0
  544. package/dist/components/visually-hidden/visually-hidden.d.ts +8 -0
  545. package/dist/components/visually-hidden/visually-hidden.d.ts.map +1 -0
  546. package/dist/components/visually-hidden/visually-hidden.js +12 -0
  547. package/dist/components/visually-hidden/visually-hidden.js.map +1 -0
  548. package/dist/components/visually-hidden/visually-hidden.types.d.ts +9 -0
  549. package/dist/components/visually-hidden/visually-hidden.types.d.ts.map +1 -0
  550. package/dist/components/visually-hidden/visually-hidden.types.js +2 -0
  551. package/dist/components/visually-hidden/visually-hidden.types.js.map +1 -0
  552. package/dist/errors/index.d.ts +2 -0
  553. package/dist/errors/index.d.ts.map +1 -0
  554. package/dist/errors/index.js +2 -0
  555. package/dist/errors/index.js.map +1 -0
  556. package/dist/errors/ui-error.d.ts +60 -0
  557. package/dist/errors/ui-error.d.ts.map +1 -0
  558. package/dist/errors/ui-error.js +219 -0
  559. package/dist/errors/ui-error.js.map +1 -0
  560. package/dist/i18n/i18n.d.ts +52 -0
  561. package/dist/i18n/i18n.d.ts.map +1 -0
  562. package/dist/i18n/i18n.js +156 -0
  563. package/dist/i18n/i18n.js.map +1 -0
  564. package/dist/i18n/index.d.ts +3 -0
  565. package/dist/i18n/index.d.ts.map +1 -0
  566. package/dist/i18n/index.js +3 -0
  567. package/dist/i18n/index.js.map +1 -0
  568. package/dist/icons/icon-names.d.ts +7 -0
  569. package/dist/icons/icon-names.d.ts.map +1 -0
  570. package/dist/icons/icon-names.js +2 -0
  571. package/dist/icons/icon-names.js.map +1 -0
  572. package/dist/icons/icon-registry.d.ts +30 -0
  573. package/dist/icons/icon-registry.d.ts.map +1 -0
  574. package/dist/icons/icon-registry.js +31 -0
  575. package/dist/icons/icon-registry.js.map +1 -0
  576. package/dist/icons/index.d.ts +4 -0
  577. package/dist/icons/index.d.ts.map +1 -0
  578. package/dist/icons/index.js +2 -0
  579. package/dist/icons/index.js.map +1 -0
  580. package/dist/index.d.ts +6 -0
  581. package/dist/index.d.ts.map +1 -0
  582. package/dist/index.js +5 -0
  583. package/dist/index.js.map +1 -0
  584. package/dist/internal/class-names.d.ts +8 -0
  585. package/dist/internal/class-names.d.ts.map +1 -0
  586. package/dist/internal/class-names.js +10 -0
  587. package/dist/internal/class-names.js.map +1 -0
  588. package/dist/internal/menu/index.d.ts +3 -0
  589. package/dist/internal/menu/index.d.ts.map +1 -0
  590. package/dist/internal/menu/index.js +2 -0
  591. package/dist/internal/menu/index.js.map +1 -0
  592. package/dist/internal/menu/menu.d.ts +33 -0
  593. package/dist/internal/menu/menu.d.ts.map +1 -0
  594. package/dist/internal/menu/menu.js +150 -0
  595. package/dist/internal/menu/menu.js.map +1 -0
  596. package/dist/internal/overlay/dismissible-layer.d.ts +38 -0
  597. package/dist/internal/overlay/dismissible-layer.d.ts.map +1 -0
  598. package/dist/internal/overlay/dismissible-layer.js +99 -0
  599. package/dist/internal/overlay/dismissible-layer.js.map +1 -0
  600. package/dist/internal/overlay/document-scroll-lock.d.ts +8 -0
  601. package/dist/internal/overlay/document-scroll-lock.d.ts.map +1 -0
  602. package/dist/internal/overlay/document-scroll-lock.js +58 -0
  603. package/dist/internal/overlay/document-scroll-lock.js.map +1 -0
  604. package/dist/internal/overlay/floating-position.d.ts +46 -0
  605. package/dist/internal/overlay/floating-position.d.ts.map +1 -0
  606. package/dist/internal/overlay/floating-position.js +137 -0
  607. package/dist/internal/overlay/floating-position.js.map +1 -0
  608. package/dist/internal/overlay/index.d.ts +8 -0
  609. package/dist/internal/overlay/index.d.ts.map +1 -0
  610. package/dist/internal/overlay/index.js +6 -0
  611. package/dist/internal/overlay/index.js.map +1 -0
  612. package/dist/internal/overlay/native-modal.d.ts +11 -0
  613. package/dist/internal/overlay/native-modal.d.ts.map +1 -0
  614. package/dist/internal/overlay/native-modal.js +160 -0
  615. package/dist/internal/overlay/native-modal.js.map +1 -0
  616. package/dist/internal/overlay/portal-target.d.ts +19 -0
  617. package/dist/internal/overlay/portal-target.d.ts.map +1 -0
  618. package/dist/internal/overlay/portal-target.js +113 -0
  619. package/dist/internal/overlay/portal-target.js.map +1 -0
  620. package/dist/internal/overlay/top-layer.d.ts +21 -0
  621. package/dist/internal/overlay/top-layer.d.ts.map +1 -0
  622. package/dist/internal/overlay/top-layer.js +51 -0
  623. package/dist/internal/overlay/top-layer.js.map +1 -0
  624. package/dist/internal/use-merged-ref.d.ts +11 -0
  625. package/dist/internal/use-merged-ref.d.ts.map +1 -0
  626. package/dist/internal/use-merged-ref.js +31 -0
  627. package/dist/internal/use-merged-ref.js.map +1 -0
  628. package/dist/internal/use-native-dialog.d.ts +9 -0
  629. package/dist/internal/use-native-dialog.d.ts.map +1 -0
  630. package/dist/internal/use-native-dialog.js +19 -0
  631. package/dist/internal/use-native-dialog.js.map +1 -0
  632. package/dist/runtime/appearance.d.ts +32 -0
  633. package/dist/runtime/appearance.d.ts.map +1 -0
  634. package/dist/runtime/appearance.js +123 -0
  635. package/dist/runtime/appearance.js.map +1 -0
  636. package/dist/styles/components/alert.css +99 -0
  637. package/dist/styles/components/avatar.css +70 -0
  638. package/dist/styles/components/badge.css +101 -0
  639. package/dist/styles/components/breadcrumb.css +65 -0
  640. package/dist/styles/components/button.css +136 -0
  641. package/dist/styles/components/choice.css +120 -0
  642. package/dist/styles/components/combobox.css +200 -0
  643. package/dist/styles/components/confirm-dialog.css +50 -0
  644. package/dist/styles/components/data-table.css +120 -0
  645. package/dist/styles/components/dialog.css +135 -0
  646. package/dist/styles/components/divider.css +27 -0
  647. package/dist/styles/components/drawer.css +160 -0
  648. package/dist/styles/components/dropdown.css +75 -0
  649. package/dist/styles/components/dropzone.css +94 -0
  650. package/dist/styles/components/empty-state.css +85 -0
  651. package/dist/styles/components/file-upload.css +145 -0
  652. package/dist/styles/components/form-field.css +49 -0
  653. package/dist/styles/components/icon.css +53 -0
  654. package/dist/styles/components/inline-message.css +33 -0
  655. package/dist/styles/components/input.css +77 -0
  656. package/dist/styles/components/list.css +132 -0
  657. package/dist/styles/components/loading-overlay.css +24 -0
  658. package/dist/styles/components/menu.css +6 -0
  659. package/dist/styles/components/multi-select.css +68 -0
  660. package/dist/styles/components/navigation.css +116 -0
  661. package/dist/styles/components/page-layout.css +279 -0
  662. package/dist/styles/components/pagination.css +99 -0
  663. package/dist/styles/components/panel.css +123 -0
  664. package/dist/styles/components/popover.css +41 -0
  665. package/dist/styles/components/progress.css +65 -0
  666. package/dist/styles/components/search-input.css +12 -0
  667. package/dist/styles/components/select.css +56 -0
  668. package/dist/styles/components/skeleton.css +93 -0
  669. package/dist/styles/components/spinner.css +27 -0
  670. package/dist/styles/components/status-indicator.css +54 -0
  671. package/dist/styles/components/switch.css +111 -0
  672. package/dist/styles/components/table.css +127 -0
  673. package/dist/styles/components/tabs.css +144 -0
  674. package/dist/styles/components/textarea.css +79 -0
  675. package/dist/styles/components/toast.css +134 -0
  676. package/dist/styles/components/toolbar.css +27 -0
  677. package/dist/styles/components/tooltip.css +32 -0
  678. package/dist/styles/components/tree-view.css +146 -0
  679. package/dist/styles/components.css +45 -0
  680. package/dist/styles/foundation/controls.css +91 -0
  681. package/dist/styles/foundation/density.css +76 -0
  682. package/dist/styles/foundation/icons.css +29 -0
  683. package/dist/styles/foundation/layout.css +150 -0
  684. package/dist/styles/foundation/motion.css +58 -0
  685. package/dist/styles/foundation/surface.css +60 -0
  686. package/dist/styles/foundation/theme.css +166 -0
  687. package/dist/styles/foundation/typography.css +84 -0
  688. package/dist/styles/foundation.css +10 -0
  689. package/dist/styles/miaixz.css +4 -0
  690. package/package.json +304 -0
@@ -0,0 +1,150 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useRef, } from "react";
3
+ import { classNames } from "../class-names.js";
4
+ /**
5
+ * Selects enabled items owned by the package-internal menu pattern.
6
+ */
7
+ const miaixzMenuItemSelector = [
8
+ '[role="menuitem"]',
9
+ '[role="menuitemcheckbox"]',
10
+ '[role="menuitemradio"]',
11
+ ].join(",");
12
+ /**
13
+ * Selects document-order focus targets when Tab leaves a Portal menu.
14
+ */
15
+ const miaixzDocumentTabStopSelector = [
16
+ "a[href]",
17
+ "button:not([disabled])",
18
+ "input:not([disabled]):not([type='hidden'])",
19
+ "select:not([disabled])",
20
+ "textarea:not([disabled])",
21
+ "[contenteditable='true']",
22
+ "[tabindex]:not([tabindex='-1'])",
23
+ ].join(",");
24
+ /**
25
+ * Renders the single package-internal menu pattern used by Dropdown and future composites.
26
+ *
27
+ * @param props - Native menu attributes and package-owned lifecycle controls.
28
+ * @param props.active - Whether the menu owns keyboard focus.
29
+ * @param props.triggerRef - Reference to the owning menu button.
30
+ * @param props.onRequestClose - Closure request with focus-restoration intent.
31
+ * @param props.className - Optional project class merged with the internal menu class.
32
+ * @param props.children - Menu item, label, and divider content.
33
+ * @param props.onClick - Optional native click observer.
34
+ * @param props.onKeyDown - Optional native keyboard observer.
35
+ * @returns A WAI-ARIA menu with roving focus and Portal-safe Tab behavior.
36
+ */
37
+ export function MiaixzMenu({ active, triggerRef, onRequestClose, className, children, onClick, onKeyDown, ...props }) {
38
+ const menuRef = useRef(null);
39
+ useEffect(() => {
40
+ if (!active)
41
+ return;
42
+ queueMicrotask(() => {
43
+ const items = getMiaixzMenuItems(menuRef.current);
44
+ for (const item of items)
45
+ item.tabIndex = -1;
46
+ items[0]?.focus({ preventScroll: true });
47
+ });
48
+ }, [active]);
49
+ return (_jsx("div", { ...props, ref: menuRef, role: "menu", className: classNames("miaixz-menu", className), onClick: (event) => {
50
+ onClick?.(event);
51
+ if (!event.defaultPrevented && getMiaixzMenuItemFromEvent(event) !== null) {
52
+ onRequestClose(true);
53
+ }
54
+ }, onKeyDown: (event) => {
55
+ onKeyDown?.(event);
56
+ if (!event.defaultPrevented) {
57
+ handleMiaixzMenuKeyDown(event, triggerRef.current, onRequestClose);
58
+ }
59
+ }, children: children }));
60
+ }
61
+ /**
62
+ * Applies the frozen menu keyboard table to one key event.
63
+ *
64
+ * @param event - Keyboard event dispatched by the menu.
65
+ * @param trigger - Owning menu button used for restoration and Tab order.
66
+ * @param onRequestClose - Closure request with focus-restoration intent.
67
+ */
68
+ function handleMiaixzMenuKeyDown(event, trigger, onRequestClose) {
69
+ const items = getMiaixzMenuItems(event.currentTarget);
70
+ const currentIndex = items.indexOf(event.currentTarget.ownerDocument.activeElement);
71
+ let nextIndex;
72
+ if (items.length > 0) {
73
+ if (event.key === "ArrowDown")
74
+ nextIndex = (currentIndex + 1) % items.length;
75
+ if (event.key === "ArrowUp")
76
+ nextIndex = (currentIndex - 1 + items.length) % items.length;
77
+ if (event.key === "Home")
78
+ nextIndex = 0;
79
+ if (event.key === "End")
80
+ nextIndex = items.length - 1;
81
+ }
82
+ const nextItem = nextIndex === undefined ? undefined : items[nextIndex];
83
+ if (nextItem !== undefined) {
84
+ event.preventDefault();
85
+ nextItem.focus({ preventScroll: true });
86
+ return;
87
+ }
88
+ if (event.key === "Escape") {
89
+ event.preventDefault();
90
+ onRequestClose(true);
91
+ return;
92
+ }
93
+ if (event.key === "Tab") {
94
+ event.preventDefault();
95
+ const tabTarget = getAdjacentMiaixzTabStop(trigger, event.shiftKey);
96
+ onRequestClose(false);
97
+ queueMicrotask(() => tabTarget?.focus({ preventScroll: true }));
98
+ }
99
+ }
100
+ /**
101
+ * Reads connected and enabled menu items in current DOM order.
102
+ *
103
+ * @param menu - Menu root whose items should be queried.
104
+ * @returns Enabled menu items in roving-focus order.
105
+ */
106
+ function getMiaixzMenuItems(menu) {
107
+ if (menu === null)
108
+ return [];
109
+ return Array.from(menu.querySelectorAll(miaixzMenuItemSelector)).filter((item) => item.isConnected &&
110
+ !item.hasAttribute("disabled") &&
111
+ item.getAttribute("aria-disabled") !== "true" &&
112
+ item.closest("[hidden], [inert], [aria-hidden='true']") === null);
113
+ }
114
+ /**
115
+ * Resolves an enabled menu item from a bubbling click event.
116
+ *
117
+ * @param event - Menu click event whose target should be inspected.
118
+ * @returns The selected enabled item, or null when the click is not a selection.
119
+ */
120
+ function getMiaixzMenuItemFromEvent(event) {
121
+ const target = event.target;
122
+ if (!(target instanceof Element))
123
+ return null;
124
+ const item = target.closest(miaixzMenuItemSelector);
125
+ if (item === null ||
126
+ !event.currentTarget.contains(item) ||
127
+ item.hasAttribute("disabled") ||
128
+ item.getAttribute("aria-disabled") === "true") {
129
+ return null;
130
+ }
131
+ return item;
132
+ }
133
+ /**
134
+ * Finds the document-order Tab stop adjacent to a Portal menu trigger.
135
+ *
136
+ * @param trigger - Owning menu button.
137
+ * @param reverse - Whether Shift+Tab requests the previous stop.
138
+ * @returns Adjacent connected focus target, or null at a document boundary.
139
+ */
140
+ function getAdjacentMiaixzTabStop(trigger, reverse) {
141
+ if (trigger === null)
142
+ return null;
143
+ const stops = Array.from(trigger.ownerDocument.querySelectorAll(miaixzDocumentTabStopSelector)).filter((element) => element.isConnected &&
144
+ element.closest("[hidden], [inert], [aria-hidden='true'], [role='menu']") === null);
145
+ const triggerIndex = stops.indexOf(trigger);
146
+ if (triggerIndex < 0)
147
+ return null;
148
+ return stops[triggerIndex + (reverse ? -1 : 1)] ?? null;
149
+ }
150
+ //# sourceMappingURL=menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menu.js","sourceRoot":"","sources":["../../../src/internal/menu/menu.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n useEffect,\n useRef,\n type HTMLAttributes,\n type KeyboardEvent,\n type MouseEvent,\n type RefObject,\n} from \"react\";\n\nimport { classNames } from \"../class-names.js\";\n\n/**\n * Selects enabled items owned by the package-internal menu pattern.\n */\nconst miaixzMenuItemSelector = [\n '[role=\"menuitem\"]',\n '[role=\"menuitemcheckbox\"]',\n '[role=\"menuitemradio\"]',\n].join(\",\");\n\n/**\n * Selects document-order focus targets when Tab leaves a Portal menu.\n */\nconst miaixzDocumentTabStopSelector = [\n \"a[href]\",\n \"button:not([disabled])\",\n \"input:not([disabled]):not([type='hidden'])\",\n \"select:not([disabled])\",\n \"textarea:not([disabled])\",\n \"[contenteditable='true']\",\n \"[tabindex]:not([tabindex='-1'])\",\n].join(\",\");\n\n/**\n * Configures the package-internal WAI-ARIA menu behavior.\n */\nexport interface MiaixzMenuProps extends HTMLAttributes<HTMLDivElement> {\n /**\n * Controls initial focus and active keyboard behavior.\n */\n readonly active: boolean;\n\n /**\n * References the menu button used for restoration and Tab ordering.\n */\n readonly triggerRef: RefObject<HTMLButtonElement | null>;\n\n /**\n * Requests closure and chooses whether trigger focus should be restored.\n */\n readonly onRequestClose: (restoreFocus: boolean) => void;\n}\n\n/**\n * Renders the single package-internal menu pattern used by Dropdown and future composites.\n *\n * @param props - Native menu attributes and package-owned lifecycle controls.\n * @param props.active - Whether the menu owns keyboard focus.\n * @param props.triggerRef - Reference to the owning menu button.\n * @param props.onRequestClose - Closure request with focus-restoration intent.\n * @param props.className - Optional project class merged with the internal menu class.\n * @param props.children - Menu item, label, and divider content.\n * @param props.onClick - Optional native click observer.\n * @param props.onKeyDown - Optional native keyboard observer.\n * @returns A WAI-ARIA menu with roving focus and Portal-safe Tab behavior.\n */\nexport function MiaixzMenu({\n active,\n triggerRef,\n onRequestClose,\n className,\n children,\n onClick,\n onKeyDown,\n ...props\n}: MiaixzMenuProps) {\n const menuRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (!active) return;\n queueMicrotask(() => {\n const items = getMiaixzMenuItems(menuRef.current);\n for (const item of items) item.tabIndex = -1;\n items[0]?.focus({ preventScroll: true });\n });\n }, [active]);\n\n return (\n <div\n {...props}\n ref={menuRef}\n role=\"menu\"\n className={classNames(\"miaixz-menu\", className)}\n onClick={(event) => {\n onClick?.(event);\n if (!event.defaultPrevented && getMiaixzMenuItemFromEvent(event) !== null) {\n onRequestClose(true);\n }\n }}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n if (!event.defaultPrevented) {\n handleMiaixzMenuKeyDown(event, triggerRef.current, onRequestClose);\n }\n }}\n >\n {children}\n </div>\n );\n}\n\n/**\n * Applies the frozen menu keyboard table to one key event.\n *\n * @param event - Keyboard event dispatched by the menu.\n * @param trigger - Owning menu button used for restoration and Tab order.\n * @param onRequestClose - Closure request with focus-restoration intent.\n */\nfunction handleMiaixzMenuKeyDown(\n event: KeyboardEvent<HTMLDivElement>,\n trigger: HTMLButtonElement | null,\n onRequestClose: (restoreFocus: boolean) => void,\n): void {\n const items = getMiaixzMenuItems(event.currentTarget);\n const currentIndex = items.indexOf(\n event.currentTarget.ownerDocument.activeElement as HTMLElement,\n );\n let nextIndex: number | undefined;\n\n if (items.length > 0) {\n if (event.key === \"ArrowDown\") nextIndex = (currentIndex + 1) % items.length;\n if (event.key === \"ArrowUp\") nextIndex = (currentIndex - 1 + items.length) % items.length;\n if (event.key === \"Home\") nextIndex = 0;\n if (event.key === \"End\") nextIndex = items.length - 1;\n }\n\n const nextItem = nextIndex === undefined ? undefined : items[nextIndex];\n if (nextItem !== undefined) {\n event.preventDefault();\n nextItem.focus({ preventScroll: true });\n return;\n }\n\n if (event.key === \"Escape\") {\n event.preventDefault();\n onRequestClose(true);\n return;\n }\n\n if (event.key === \"Tab\") {\n event.preventDefault();\n const tabTarget = getAdjacentMiaixzTabStop(trigger, event.shiftKey);\n onRequestClose(false);\n queueMicrotask(() => tabTarget?.focus({ preventScroll: true }));\n }\n}\n\n/**\n * Reads connected and enabled menu items in current DOM order.\n *\n * @param menu - Menu root whose items should be queried.\n * @returns Enabled menu items in roving-focus order.\n */\nfunction getMiaixzMenuItems(menu: HTMLDivElement | null): HTMLElement[] {\n if (menu === null) return [];\n return Array.from(menu.querySelectorAll<HTMLElement>(miaixzMenuItemSelector)).filter(\n (item) =>\n item.isConnected &&\n !item.hasAttribute(\"disabled\") &&\n item.getAttribute(\"aria-disabled\") !== \"true\" &&\n item.closest(\"[hidden], [inert], [aria-hidden='true']\") === null,\n );\n}\n\n/**\n * Resolves an enabled menu item from a bubbling click event.\n *\n * @param event - Menu click event whose target should be inspected.\n * @returns The selected enabled item, or null when the click is not a selection.\n */\nfunction getMiaixzMenuItemFromEvent(event: MouseEvent<HTMLDivElement>): HTMLElement | null {\n const target = event.target;\n if (!(target instanceof Element)) return null;\n const item = target.closest<HTMLElement>(miaixzMenuItemSelector);\n if (\n item === null ||\n !event.currentTarget.contains(item) ||\n item.hasAttribute(\"disabled\") ||\n item.getAttribute(\"aria-disabled\") === \"true\"\n ) {\n return null;\n }\n return item;\n}\n\n/**\n * Finds the document-order Tab stop adjacent to a Portal menu trigger.\n *\n * @param trigger - Owning menu button.\n * @param reverse - Whether Shift+Tab requests the previous stop.\n * @returns Adjacent connected focus target, or null at a document boundary.\n */\nfunction getAdjacentMiaixzTabStop(\n trigger: HTMLButtonElement | null,\n reverse: boolean,\n): HTMLElement | null {\n if (trigger === null) return null;\n const stops = Array.from(\n trigger.ownerDocument.querySelectorAll<HTMLElement>(miaixzDocumentTabStopSelector),\n ).filter(\n (element) =>\n element.isConnected &&\n element.closest(\"[hidden], [inert], [aria-hidden='true'], [role='menu']\") === null,\n );\n const triggerIndex = stops.indexOf(trigger);\n if (triggerIndex < 0) return null;\n return stops[triggerIndex + (reverse ? -1 : 1)] ?? null;\n}\n"]}
@@ -0,0 +1,38 @@
1
+ import { type RefObject } from "react";
2
+ /**
3
+ * Identifies the user interaction that dismissed an overlay layer.
4
+ */
5
+ export type MiaixzDismissReason = "escape" | "outside";
6
+ /**
7
+ * Configures one active package-owned dismissible layer.
8
+ */
9
+ interface MiaixzDismissibleLayerOptions {
10
+ /**
11
+ * Controls whether the layer participates in the document stack.
12
+ */
13
+ readonly active: boolean;
14
+ /**
15
+ * References the trigger or wrapper owned by the layer.
16
+ */
17
+ readonly triggerRef: RefObject<HTMLElement | null>;
18
+ /**
19
+ * References the Portal surface owned by the layer.
20
+ */
21
+ readonly contentRef: RefObject<HTMLElement | null>;
22
+ /**
23
+ * Receives a package-defined dismissal request.
24
+ */
25
+ readonly onDismiss: (reason: MiaixzDismissReason) => void;
26
+ /**
27
+ * Identifies the current Portal target and document realm.
28
+ */
29
+ readonly portalTarget: HTMLElement | null;
30
+ }
31
+ /**
32
+ * Registers Escape and external-pointer dismissal for one active overlay surface.
33
+ *
34
+ * @param options - Layer registration and dismissal configuration.
35
+ */
36
+ export declare function useMiaixzDismissibleLayer(options: MiaixzDismissibleLayerOptions): void;
37
+ export {};
38
+ //# sourceMappingURL=dismissible-layer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dismissible-layer.d.ts","sourceRoot":"","sources":["../../../src/internal/overlay/dismissible-layer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE1D;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEvD;;GAEG;AACH,UAAU,6BAA6B;IACrC;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAEnD;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAEnD;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAE1D;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,WAAW,GAAG,IAAI,CAAC;CAC3C;AA0CD;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,6BAA6B,GAAG,IAAI,CA0BtF"}
@@ -0,0 +1,99 @@
1
+ import { useEffect, useRef } from "react";
2
+ /**
3
+ * Isolates dismissible overlay branches between document realms.
4
+ */
5
+ const miaixzDismissibleLayerStores = new WeakMap();
6
+ /**
7
+ * Registers Escape and external-pointer dismissal for one active overlay surface.
8
+ *
9
+ * @param options - Layer registration and dismissal configuration.
10
+ */
11
+ export function useMiaixzDismissibleLayer(options) {
12
+ const dismissRef = useRef(options.onDismiss);
13
+ useEffect(() => {
14
+ dismissRef.current = options.onDismiss;
15
+ }, [options.onDismiss]);
16
+ useEffect(() => {
17
+ const ownerDocument = options.portalTarget?.ownerDocument;
18
+ if (!options.active || ownerDocument === undefined)
19
+ return undefined;
20
+ const entry = {
21
+ triggerRef: options.triggerRef,
22
+ contentRef: options.contentRef,
23
+ dismiss: (reason) => dismissRef.current(reason),
24
+ };
25
+ const store = getMiaixzDismissibleLayerStore(ownerDocument);
26
+ store.entries.push(entry);
27
+ return () => {
28
+ const index = store.entries.indexOf(entry);
29
+ if (index >= 0)
30
+ store.entries.splice(index, 1);
31
+ if (store.entries.length === 0) {
32
+ store.removeListeners();
33
+ miaixzDismissibleLayerStores.delete(ownerDocument);
34
+ }
35
+ };
36
+ }, [options.active, options.contentRef, options.portalTarget, options.triggerRef]);
37
+ }
38
+ /**
39
+ * Returns the existing document stack or installs its shared event listeners.
40
+ *
41
+ * @param ownerDocument - Document whose overlay stack is requested.
42
+ * @returns The active dismissible-layer store.
43
+ */
44
+ function getMiaixzDismissibleLayerStore(ownerDocument) {
45
+ const existing = miaixzDismissibleLayerStores.get(ownerDocument);
46
+ if (existing !== undefined)
47
+ return existing;
48
+ const entries = [];
49
+ const handleKeyDown = (event) => {
50
+ if (event.key !== "Escape" || event.defaultPrevented)
51
+ return;
52
+ const topLayer = entries.at(-1);
53
+ if (topLayer === undefined)
54
+ return;
55
+ event.preventDefault();
56
+ topLayer.dismiss("escape");
57
+ };
58
+ const handlePointerDown = (event) => {
59
+ const path = event.composedPath();
60
+ let containingIndex = -1;
61
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
62
+ const entry = entries[index];
63
+ if (entry !== undefined && doesMiaixzLayerContainPath(entry, path)) {
64
+ containingIndex = index;
65
+ break;
66
+ }
67
+ }
68
+ for (let index = entries.length - 1; index > containingIndex; index -= 1) {
69
+ entries[index]?.dismiss("outside");
70
+ }
71
+ };
72
+ ownerDocument.addEventListener("keydown", handleKeyDown, true);
73
+ ownerDocument.addEventListener("pointerdown", handlePointerDown, true);
74
+ const created = {
75
+ entries,
76
+ removeListeners: () => {
77
+ ownerDocument.removeEventListener("keydown", handleKeyDown, true);
78
+ ownerDocument.removeEventListener("pointerdown", handlePointerDown, true);
79
+ },
80
+ };
81
+ miaixzDismissibleLayerStores.set(ownerDocument, created);
82
+ return created;
83
+ }
84
+ /**
85
+ * Tests whether an event path belongs to a layer trigger or Portal surface.
86
+ *
87
+ * @param entry - Layer whose owned nodes should be inspected.
88
+ * @param path - Composed event path crossing shadow and Portal boundaries.
89
+ * @returns Whether the pointer event occurred inside the layer.
90
+ */
91
+ function doesMiaixzLayerContainPath(entry, path) {
92
+ const trigger = entry.triggerRef.current;
93
+ const content = entry.contentRef.current;
94
+ return path.some((target) => target === trigger ||
95
+ target === content ||
96
+ (target instanceof Node &&
97
+ (trigger?.contains(target) === true || content?.contains(target) === true)));
98
+ }
99
+ //# sourceMappingURL=dismissible-layer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dismissible-layer.js","sourceRoot":"","sources":["../../../src/internal/overlay/dismissible-layer.ts"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useRef, type RefObject } from \"react\";\n\n/**\n * Identifies the user interaction that dismissed an overlay layer.\n */\nexport type MiaixzDismissReason = \"escape\" | \"outside\";\n\n/**\n * Configures one active package-owned dismissible layer.\n */\ninterface MiaixzDismissibleLayerOptions {\n /**\n * Controls whether the layer participates in the document stack.\n */\n readonly active: boolean;\n\n /**\n * References the trigger or wrapper owned by the layer.\n */\n readonly triggerRef: RefObject<HTMLElement | null>;\n\n /**\n * References the Portal surface owned by the layer.\n */\n readonly contentRef: RefObject<HTMLElement | null>;\n\n /**\n * Receives a package-defined dismissal request.\n */\n readonly onDismiss: (reason: MiaixzDismissReason) => void;\n\n /**\n * Identifies the current Portal target and document realm.\n */\n readonly portalTarget: HTMLElement | null;\n}\n\n/**\n * Represents one registered layer in document activation order.\n */\ninterface MiaixzDismissibleLayerEntry {\n /**\n * References the trigger or wrapper owned by the layer.\n */\n readonly triggerRef: RefObject<HTMLElement | null>;\n\n /**\n * References the Portal surface owned by the layer.\n */\n readonly contentRef: RefObject<HTMLElement | null>;\n\n /**\n * Requests dismissal using the current React callback.\n */\n readonly dismiss: (reason: MiaixzDismissReason) => void;\n}\n\n/**\n * Stores active dismissible layers and shared listeners for one document realm.\n */\ninterface MiaixzDismissibleLayerStore {\n /**\n * Retains layers in activation order.\n */\n readonly entries: MiaixzDismissibleLayerEntry[];\n\n /**\n * Removes the shared document listeners.\n */\n readonly removeListeners: () => void;\n}\n\n/**\n * Isolates dismissible overlay branches between document realms.\n */\nconst miaixzDismissibleLayerStores = new WeakMap<Document, MiaixzDismissibleLayerStore>();\n\n/**\n * Registers Escape and external-pointer dismissal for one active overlay surface.\n *\n * @param options - Layer registration and dismissal configuration.\n */\nexport function useMiaixzDismissibleLayer(options: MiaixzDismissibleLayerOptions): void {\n const dismissRef = useRef(options.onDismiss);\n\n useEffect(() => {\n dismissRef.current = options.onDismiss;\n }, [options.onDismiss]);\n\n useEffect(() => {\n const ownerDocument = options.portalTarget?.ownerDocument;\n if (!options.active || ownerDocument === undefined) return undefined;\n const entry: MiaixzDismissibleLayerEntry = {\n triggerRef: options.triggerRef,\n contentRef: options.contentRef,\n dismiss: (reason) => dismissRef.current(reason),\n };\n const store = getMiaixzDismissibleLayerStore(ownerDocument);\n store.entries.push(entry);\n return () => {\n const index = store.entries.indexOf(entry);\n if (index >= 0) store.entries.splice(index, 1);\n if (store.entries.length === 0) {\n store.removeListeners();\n miaixzDismissibleLayerStores.delete(ownerDocument);\n }\n };\n }, [options.active, options.contentRef, options.portalTarget, options.triggerRef]);\n}\n\n/**\n * Returns the existing document stack or installs its shared event listeners.\n *\n * @param ownerDocument - Document whose overlay stack is requested.\n * @returns The active dismissible-layer store.\n */\nfunction getMiaixzDismissibleLayerStore(ownerDocument: Document): MiaixzDismissibleLayerStore {\n const existing = miaixzDismissibleLayerStores.get(ownerDocument);\n if (existing !== undefined) return existing;\n\n const entries: MiaixzDismissibleLayerEntry[] = [];\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key !== \"Escape\" || event.defaultPrevented) return;\n const topLayer = entries.at(-1);\n if (topLayer === undefined) return;\n event.preventDefault();\n topLayer.dismiss(\"escape\");\n };\n const handlePointerDown = (event: PointerEvent) => {\n const path = event.composedPath();\n let containingIndex = -1;\n for (let index = entries.length - 1; index >= 0; index -= 1) {\n const entry = entries[index];\n if (entry !== undefined && doesMiaixzLayerContainPath(entry, path)) {\n containingIndex = index;\n break;\n }\n }\n for (let index = entries.length - 1; index > containingIndex; index -= 1) {\n entries[index]?.dismiss(\"outside\");\n }\n };\n\n ownerDocument.addEventListener(\"keydown\", handleKeyDown, true);\n ownerDocument.addEventListener(\"pointerdown\", handlePointerDown, true);\n const created: MiaixzDismissibleLayerStore = {\n entries,\n removeListeners: () => {\n ownerDocument.removeEventListener(\"keydown\", handleKeyDown, true);\n ownerDocument.removeEventListener(\"pointerdown\", handlePointerDown, true);\n },\n };\n miaixzDismissibleLayerStores.set(ownerDocument, created);\n return created;\n}\n\n/**\n * Tests whether an event path belongs to a layer trigger or Portal surface.\n *\n * @param entry - Layer whose owned nodes should be inspected.\n * @param path - Composed event path crossing shadow and Portal boundaries.\n * @returns Whether the pointer event occurred inside the layer.\n */\nfunction doesMiaixzLayerContainPath(\n entry: MiaixzDismissibleLayerEntry,\n path: EventTarget[],\n): boolean {\n const trigger = entry.triggerRef.current;\n const content = entry.contentRef.current;\n return path.some(\n (target) =>\n target === trigger ||\n target === content ||\n (target instanceof Node &&\n (trigger?.contains(target) === true || content?.contains(target) === true)),\n );\n}\n"]}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Locks one document scrolling root while preserving its exact caller-owned inline values.
3
+ *
4
+ * @param ownerDocument - Document whose background scrolling should be suspended.
5
+ * @returns An idempotent unlock function.
6
+ */
7
+ export declare function lockMiaixzDocumentScroll(ownerDocument: Document): () => void;
8
+ //# sourceMappingURL=document-scroll-lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-scroll-lock.d.ts","sourceRoot":"","sources":["../../../src/internal/overlay/document-scroll-lock.ts"],"names":[],"mappings":"AA8BA;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,aAAa,EAAE,QAAQ,GAAG,MAAM,IAAI,CA2B5E"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Coordinates nested native modal scroll locks per document realm.
3
+ */
4
+ const miaixzDocumentScrollLocks = new WeakMap();
5
+ /**
6
+ * Locks one document scrolling root while preserving its exact caller-owned inline values.
7
+ *
8
+ * @param ownerDocument - Document whose background scrolling should be suspended.
9
+ * @returns An idempotent unlock function.
10
+ */
11
+ export function lockMiaixzDocumentScroll(ownerDocument) {
12
+ const existing = miaixzDocumentScrollLocks.get(ownerDocument);
13
+ if (existing !== undefined) {
14
+ existing.count += 1;
15
+ return createMiaixzScrollUnlock(ownerDocument, existing);
16
+ }
17
+ const root = ownerDocument.scrollingElement ?? ownerDocument.documentElement;
18
+ const state = {
19
+ count: 1,
20
+ overflow: root.style.overflow,
21
+ paddingInlineEnd: root.style.paddingInlineEnd,
22
+ root,
23
+ };
24
+ const viewport = ownerDocument.defaultView;
25
+ const scrollbarWidth = Math.max(0, (viewport?.innerWidth ?? root.clientWidth) - root.clientWidth);
26
+ root.style.overflow = "hidden";
27
+ if (scrollbarWidth > 0 && viewport !== null) {
28
+ const computedPadding = viewport.getComputedStyle(root).paddingInlineEnd;
29
+ root.style.paddingInlineEnd =
30
+ computedPadding === "0px"
31
+ ? `${scrollbarWidth}px`
32
+ : `calc(${computedPadding} + ${scrollbarWidth}px)`;
33
+ }
34
+ miaixzDocumentScrollLocks.set(ownerDocument, state);
35
+ return createMiaixzScrollUnlock(ownerDocument, state);
36
+ }
37
+ /**
38
+ * Creates an idempotent release operation for one reference-counted document lock.
39
+ *
40
+ * @param ownerDocument - Document owning the lock.
41
+ * @param state - Shared lock state for that document.
42
+ * @returns An idempotent unlock function.
43
+ */
44
+ function createMiaixzScrollUnlock(ownerDocument, state) {
45
+ let active = true;
46
+ return () => {
47
+ if (!active)
48
+ return;
49
+ active = false;
50
+ state.count -= 1;
51
+ if (state.count > 0)
52
+ return;
53
+ state.root.style.overflow = state.overflow;
54
+ state.root.style.paddingInlineEnd = state.paddingInlineEnd;
55
+ miaixzDocumentScrollLocks.delete(ownerDocument);
56
+ };
57
+ }
58
+ //# sourceMappingURL=document-scroll-lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-scroll-lock.js","sourceRoot":"","sources":["../../../src/internal/overlay/document-scroll-lock.ts"],"names":[],"mappings":"AAyBA;;GAEG;AACH,MAAM,yBAAyB,GAAG,IAAI,OAAO,EAAsC,CAAC;AAEpF;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB,CAAC,aAAuB;IAC9D,MAAM,QAAQ,GAAG,yBAAyB,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC9D,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC;QACpB,OAAO,wBAAwB,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,IAAI,GACP,aAAa,CAAC,gBAAuC,IAAI,aAAa,CAAC,eAAe,CAAC;IAC1F,MAAM,KAAK,GAA6B;QACtC,KAAK,EAAE,CAAC;QACR,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ;QAC7B,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,gBAAgB;QAC7C,IAAI;KACL,CAAC;IACF,MAAM,QAAQ,GAAG,aAAa,CAAC,WAAW,CAAC;IAC3C,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAU,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC;IAClG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC/B,IAAI,cAAc,GAAG,CAAC,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QAC5C,MAAM,eAAe,GAAG,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,gBAAgB,CAAC;QACzE,IAAI,CAAC,KAAK,CAAC,gBAAgB;YACzB,eAAe,KAAK,KAAK;gBACvB,CAAC,CAAC,GAAG,cAAc,IAAI;gBACvB,CAAC,CAAC,QAAQ,eAAe,MAAM,cAAc,KAAK,CAAC;IACzD,CAAC;IACD,yBAAyB,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IACpD,OAAO,wBAAwB,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;AACxD,CAAC;AAED;;;;;;GAMG;AACH,SAAS,wBAAwB,CAC/B,aAAuB,EACvB,KAA+B;IAE/B,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,OAAO,GAAG,EAAE;QACV,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,MAAM,GAAG,KAAK,CAAC;QACf,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;QACjB,IAAI,KAAK,CAAC,KAAK,GAAG,CAAC;YAAE,OAAO;QAC5B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;QAC3C,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,GAAG,KAAK,CAAC,gBAAgB,CAAC;QAC3D,yBAAyB,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAClD,CAAC,CAAC;AACJ,CAAC","sourcesContent":["/**\n * Retains the exact inline styles and nesting depth for one scrolling root.\n */\ninterface MiaixzDocumentScrollLock {\n /**\n * Counts active native modal owners.\n */\n count: number;\n\n /**\n * Preserves the caller-owned inline overflow value.\n */\n readonly overflow: string;\n\n /**\n * Preserves the caller-owned inline logical scrollbar compensation.\n */\n readonly paddingInlineEnd: string;\n\n /**\n * Identifies the root scrolling element being locked.\n */\n readonly root: HTMLElement;\n}\n\n/**\n * Coordinates nested native modal scroll locks per document realm.\n */\nconst miaixzDocumentScrollLocks = new WeakMap<Document, MiaixzDocumentScrollLock>();\n\n/**\n * Locks one document scrolling root while preserving its exact caller-owned inline values.\n *\n * @param ownerDocument - Document whose background scrolling should be suspended.\n * @returns An idempotent unlock function.\n */\nexport function lockMiaixzDocumentScroll(ownerDocument: Document): () => void {\n const existing = miaixzDocumentScrollLocks.get(ownerDocument);\n if (existing !== undefined) {\n existing.count += 1;\n return createMiaixzScrollUnlock(ownerDocument, existing);\n }\n\n const root =\n (ownerDocument.scrollingElement as HTMLElement | null) ?? ownerDocument.documentElement;\n const state: MiaixzDocumentScrollLock = {\n count: 1,\n overflow: root.style.overflow,\n paddingInlineEnd: root.style.paddingInlineEnd,\n root,\n };\n const viewport = ownerDocument.defaultView;\n const scrollbarWidth = Math.max(0, (viewport?.innerWidth ?? root.clientWidth) - root.clientWidth);\n root.style.overflow = \"hidden\";\n if (scrollbarWidth > 0 && viewport !== null) {\n const computedPadding = viewport.getComputedStyle(root).paddingInlineEnd;\n root.style.paddingInlineEnd =\n computedPadding === \"0px\"\n ? `${scrollbarWidth}px`\n : `calc(${computedPadding} + ${scrollbarWidth}px)`;\n }\n miaixzDocumentScrollLocks.set(ownerDocument, state);\n return createMiaixzScrollUnlock(ownerDocument, state);\n}\n\n/**\n * Creates an idempotent release operation for one reference-counted document lock.\n *\n * @param ownerDocument - Document owning the lock.\n * @param state - Shared lock state for that document.\n * @returns An idempotent unlock function.\n */\nfunction createMiaixzScrollUnlock(\n ownerDocument: Document,\n state: MiaixzDocumentScrollLock,\n): () => void {\n let active = true;\n return () => {\n if (!active) return;\n active = false;\n state.count -= 1;\n if (state.count > 0) return;\n state.root.style.overflow = state.overflow;\n state.root.style.paddingInlineEnd = state.paddingInlineEnd;\n miaixzDocumentScrollLocks.delete(ownerDocument);\n };\n}\n"]}
@@ -0,0 +1,46 @@
1
+ import { type RefObject } from "react";
2
+ /**
3
+ * Defines every fixed placement used by package-owned Popover and Tooltip surfaces.
4
+ */
5
+ export type MiaixzFloatingPlacement = "bottom-start" | "bottom-end" | "top-start" | "top-end" | "top" | "right" | "bottom" | "left";
6
+ /**
7
+ * Describes one resolved viewport-relative floating position.
8
+ */
9
+ interface MiaixzFloatingPosition {
10
+ /**
11
+ * Identifies the resolved placement after main-axis flipping.
12
+ */
13
+ readonly placement: MiaixzFloatingPlacement;
14
+ /**
15
+ * Supplies the clamped viewport x coordinate.
16
+ */
17
+ readonly x: number;
18
+ /**
19
+ * Supplies the clamped viewport y coordinate.
20
+ */
21
+ readonly y: number;
22
+ }
23
+ /**
24
+ * Positions one open Portal surface and maintains it across geometry changes.
25
+ *
26
+ * @param triggerRef - Reference containing the anchor element.
27
+ * @param contentRef - Reference containing the fixed surface.
28
+ * @param open - Whether geometry observers should be active.
29
+ * @param placement - Requested logical placement.
30
+ * @param portalTarget - Current Portal target used to retrigger observers after remounting.
31
+ */
32
+ export declare function useMiaixzFloatingPosition(triggerRef: RefObject<HTMLElement | null>, contentRef: RefObject<HTMLElement | null>, open: boolean, placement: MiaixzFloatingPlacement, portalTarget: HTMLElement | null): void;
33
+ /**
34
+ * Resolves flipping, logical alignment, and viewport clamping for one floating surface.
35
+ *
36
+ * @param trigger - Viewport geometry of the anchor element.
37
+ * @param content - Viewport geometry of the floating surface.
38
+ * @param requestedPlacement - Caller-requested logical placement.
39
+ * @param viewportWidth - Current layout viewport width.
40
+ * @param viewportHeight - Current layout viewport height.
41
+ * @param rightToLeft - Whether logical inline start resolves to the right edge.
42
+ * @returns Resolved placement and clamped viewport coordinates.
43
+ */
44
+ export declare function calculateMiaixzFloatingPosition(trigger: DOMRect, content: DOMRect, requestedPlacement: MiaixzFloatingPlacement, viewportWidth: number, viewportHeight: number, rightToLeft: boolean): MiaixzFloatingPosition;
45
+ export {};
46
+ //# sourceMappingURL=floating-position.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"floating-position.d.ts","sourceRoot":"","sources":["../../../src/internal/overlay/floating-position.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEnE;;GAEG;AACH,MAAM,MAAM,uBAAuB,GACjC,cAAc,GAAG,YAAY,GAAG,WAAW,GAAG,SAAS,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEhG;;GAEG;AACH,UAAU,sBAAsB;IAC9B;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,uBAAuB,CAAC;IAE5C;;OAEG;IACH,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;CACpB;AAYD;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EACzC,UAAU,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EACzC,IAAI,EAAE,OAAO,EACb,SAAS,EAAE,uBAAuB,EAClC,YAAY,EAAE,WAAW,GAAG,IAAI,GAC/B,IAAI,CAuCN;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,EAChB,kBAAkB,EAAE,uBAAuB,EAC3C,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,OAAO,GACnB,sBAAsB,CA6CxB"}
@@ -0,0 +1,137 @@
1
+ import { useEffect, useLayoutEffect } from "react";
2
+ /**
3
+ * Keeps floating surfaces and viewport edges separated by the frozen eight-pixel gap.
4
+ */
5
+ const miaixzFloatingGap = 8;
6
+ /**
7
+ * Uses layout timing in browsers and passive timing during server rendering.
8
+ */
9
+ const useMiaixzClientLayoutEffect = typeof document === "undefined" ? useEffect : useLayoutEffect;
10
+ /**
11
+ * Positions one open Portal surface and maintains it across geometry changes.
12
+ *
13
+ * @param triggerRef - Reference containing the anchor element.
14
+ * @param contentRef - Reference containing the fixed surface.
15
+ * @param open - Whether geometry observers should be active.
16
+ * @param placement - Requested logical placement.
17
+ * @param portalTarget - Current Portal target used to retrigger observers after remounting.
18
+ */
19
+ export function useMiaixzFloatingPosition(triggerRef, contentRef, open, placement, portalTarget) {
20
+ useMiaixzClientLayoutEffect(() => {
21
+ const trigger = triggerRef.current;
22
+ const content = contentRef.current;
23
+ if (!open || trigger === null || content === null)
24
+ return undefined;
25
+ const ownerDocument = trigger.ownerDocument;
26
+ const viewport = ownerDocument.defaultView;
27
+ if (viewport === null)
28
+ return undefined;
29
+ const update = () => {
30
+ const position = calculateMiaixzFloatingPosition(trigger.getBoundingClientRect(), content.getBoundingClientRect(), placement, viewport.innerWidth, viewport.innerHeight, viewport.getComputedStyle(trigger).direction === "rtl");
31
+ content.style.left = `${position.x}px`;
32
+ content.style.top = `${position.y}px`;
33
+ content.dataset.placement = position.placement;
34
+ content.dataset.miaixzPositioned = "true";
35
+ };
36
+ update();
37
+ ownerDocument.addEventListener("scroll", update, true);
38
+ viewport.addEventListener("resize", update);
39
+ const resizeObserver = typeof ResizeObserver === "function" ? new ResizeObserver(update) : undefined;
40
+ resizeObserver?.observe(trigger);
41
+ resizeObserver?.observe(content);
42
+ return () => {
43
+ ownerDocument.removeEventListener("scroll", update, true);
44
+ viewport.removeEventListener("resize", update);
45
+ resizeObserver?.disconnect();
46
+ delete content.dataset.miaixzPositioned;
47
+ };
48
+ }, [contentRef, open, placement, portalTarget, triggerRef]);
49
+ }
50
+ /**
51
+ * Resolves flipping, logical alignment, and viewport clamping for one floating surface.
52
+ *
53
+ * @param trigger - Viewport geometry of the anchor element.
54
+ * @param content - Viewport geometry of the floating surface.
55
+ * @param requestedPlacement - Caller-requested logical placement.
56
+ * @param viewportWidth - Current layout viewport width.
57
+ * @param viewportHeight - Current layout viewport height.
58
+ * @param rightToLeft - Whether logical inline start resolves to the right edge.
59
+ * @returns Resolved placement and clamped viewport coordinates.
60
+ */
61
+ export function calculateMiaixzFloatingPosition(trigger, content, requestedPlacement, viewportWidth, viewportHeight, rightToLeft) {
62
+ const placement = resolveMiaixzFloatingPlacement(trigger, content, requestedPlacement, viewportWidth, viewportHeight);
63
+ let x;
64
+ let y;
65
+ if (placement === "top" || placement === "bottom") {
66
+ x = trigger.left + (trigger.width - content.width) / 2;
67
+ y =
68
+ placement === "top"
69
+ ? trigger.top - content.height - miaixzFloatingGap
70
+ : trigger.bottom + miaixzFloatingGap;
71
+ }
72
+ else if (placement === "left" || placement === "right") {
73
+ x =
74
+ placement === "left"
75
+ ? trigger.left - content.width - miaixzFloatingGap
76
+ : trigger.right + miaixzFloatingGap;
77
+ y = trigger.top + (trigger.height - content.height) / 2;
78
+ }
79
+ else {
80
+ const alignStart = placement.endsWith("-start");
81
+ const alignLeft = rightToLeft ? !alignStart : alignStart;
82
+ x = alignLeft ? trigger.left : trigger.right - content.width;
83
+ y = placement.startsWith("top-")
84
+ ? trigger.top - content.height - miaixzFloatingGap
85
+ : trigger.bottom + miaixzFloatingGap;
86
+ }
87
+ return {
88
+ placement,
89
+ x: clampMiaixzFloatingCoordinate(x, miaixzFloatingGap, viewportWidth - content.width - miaixzFloatingGap),
90
+ y: clampMiaixzFloatingCoordinate(y, miaixzFloatingGap, viewportHeight - content.height - miaixzFloatingGap),
91
+ };
92
+ }
93
+ /**
94
+ * Flips one requested placement when its main-axis surface does not fit.
95
+ *
96
+ * @param trigger - Viewport geometry of the anchor element.
97
+ * @param content - Viewport geometry of the floating surface.
98
+ * @param placement - Requested placement.
99
+ * @param viewportWidth - Current layout viewport width.
100
+ * @param viewportHeight - Current layout viewport height.
101
+ * @returns Original or opposite placement.
102
+ */
103
+ function resolveMiaixzFloatingPlacement(trigger, content, placement, viewportWidth, viewportHeight) {
104
+ if ((placement === "bottom" || placement.startsWith("bottom-")) &&
105
+ trigger.bottom + miaixzFloatingGap + content.height > viewportHeight - miaixzFloatingGap) {
106
+ return placement === "bottom"
107
+ ? "top"
108
+ : placement.replace("bottom-", "top-");
109
+ }
110
+ if ((placement === "top" || placement.startsWith("top-")) &&
111
+ trigger.top - miaixzFloatingGap - content.height < miaixzFloatingGap) {
112
+ return placement === "top"
113
+ ? "bottom"
114
+ : placement.replace("top-", "bottom-");
115
+ }
116
+ if (placement === "right" &&
117
+ trigger.right + miaixzFloatingGap + content.width > viewportWidth - miaixzFloatingGap) {
118
+ return "left";
119
+ }
120
+ if (placement === "left" &&
121
+ trigger.left - miaixzFloatingGap - content.width < miaixzFloatingGap) {
122
+ return "right";
123
+ }
124
+ return placement;
125
+ }
126
+ /**
127
+ * Clamps one coordinate while handling surfaces larger than the available viewport.
128
+ *
129
+ * @param value - Requested coordinate.
130
+ * @param minimum - Minimum safe viewport coordinate.
131
+ * @param maximum - Maximum safe viewport coordinate.
132
+ * @returns Coordinate constrained to the valid interval.
133
+ */
134
+ function clampMiaixzFloatingCoordinate(value, minimum, maximum) {
135
+ return Math.min(Math.max(value, minimum), Math.max(minimum, maximum));
136
+ }
137
+ //# sourceMappingURL=floating-position.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"floating-position.js","sourceRoot":"","sources":["../../../src/internal/overlay/floating-position.ts"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useLayoutEffect, type RefObject } from \"react\";\n\n/**\n * Defines every fixed placement used by package-owned Popover and Tooltip surfaces.\n */\nexport type MiaixzFloatingPlacement =\n \"bottom-start\" | \"bottom-end\" | \"top-start\" | \"top-end\" | \"top\" | \"right\" | \"bottom\" | \"left\";\n\n/**\n * Describes one resolved viewport-relative floating position.\n */\ninterface MiaixzFloatingPosition {\n /**\n * Identifies the resolved placement after main-axis flipping.\n */\n readonly placement: MiaixzFloatingPlacement;\n\n /**\n * Supplies the clamped viewport x coordinate.\n */\n readonly x: number;\n\n /**\n * Supplies the clamped viewport y coordinate.\n */\n readonly y: number;\n}\n\n/**\n * Keeps floating surfaces and viewport edges separated by the frozen eight-pixel gap.\n */\nconst miaixzFloatingGap = 8;\n\n/**\n * Uses layout timing in browsers and passive timing during server rendering.\n */\nconst useMiaixzClientLayoutEffect = typeof document === \"undefined\" ? useEffect : useLayoutEffect;\n\n/**\n * Positions one open Portal surface and maintains it across geometry changes.\n *\n * @param triggerRef - Reference containing the anchor element.\n * @param contentRef - Reference containing the fixed surface.\n * @param open - Whether geometry observers should be active.\n * @param placement - Requested logical placement.\n * @param portalTarget - Current Portal target used to retrigger observers after remounting.\n */\nexport function useMiaixzFloatingPosition(\n triggerRef: RefObject<HTMLElement | null>,\n contentRef: RefObject<HTMLElement | null>,\n open: boolean,\n placement: MiaixzFloatingPlacement,\n portalTarget: HTMLElement | null,\n): void {\n useMiaixzClientLayoutEffect(() => {\n const trigger = triggerRef.current;\n const content = contentRef.current;\n if (!open || trigger === null || content === null) return undefined;\n const ownerDocument = trigger.ownerDocument;\n const viewport = ownerDocument.defaultView;\n if (viewport === null) return undefined;\n\n const update = () => {\n const position = calculateMiaixzFloatingPosition(\n trigger.getBoundingClientRect(),\n content.getBoundingClientRect(),\n placement,\n viewport.innerWidth,\n viewport.innerHeight,\n viewport.getComputedStyle(trigger).direction === \"rtl\",\n );\n content.style.left = `${position.x}px`;\n content.style.top = `${position.y}px`;\n content.dataset.placement = position.placement;\n content.dataset.miaixzPositioned = \"true\";\n };\n\n update();\n ownerDocument.addEventListener(\"scroll\", update, true);\n viewport.addEventListener(\"resize\", update);\n const resizeObserver =\n typeof ResizeObserver === \"function\" ? new ResizeObserver(update) : undefined;\n resizeObserver?.observe(trigger);\n resizeObserver?.observe(content);\n\n return () => {\n ownerDocument.removeEventListener(\"scroll\", update, true);\n viewport.removeEventListener(\"resize\", update);\n resizeObserver?.disconnect();\n delete content.dataset.miaixzPositioned;\n };\n }, [contentRef, open, placement, portalTarget, triggerRef]);\n}\n\n/**\n * Resolves flipping, logical alignment, and viewport clamping for one floating surface.\n *\n * @param trigger - Viewport geometry of the anchor element.\n * @param content - Viewport geometry of the floating surface.\n * @param requestedPlacement - Caller-requested logical placement.\n * @param viewportWidth - Current layout viewport width.\n * @param viewportHeight - Current layout viewport height.\n * @param rightToLeft - Whether logical inline start resolves to the right edge.\n * @returns Resolved placement and clamped viewport coordinates.\n */\nexport function calculateMiaixzFloatingPosition(\n trigger: DOMRect,\n content: DOMRect,\n requestedPlacement: MiaixzFloatingPlacement,\n viewportWidth: number,\n viewportHeight: number,\n rightToLeft: boolean,\n): MiaixzFloatingPosition {\n const placement = resolveMiaixzFloatingPlacement(\n trigger,\n content,\n requestedPlacement,\n viewportWidth,\n viewportHeight,\n );\n let x: number;\n let y: number;\n\n if (placement === \"top\" || placement === \"bottom\") {\n x = trigger.left + (trigger.width - content.width) / 2;\n y =\n placement === \"top\"\n ? trigger.top - content.height - miaixzFloatingGap\n : trigger.bottom + miaixzFloatingGap;\n } else if (placement === \"left\" || placement === \"right\") {\n x =\n placement === \"left\"\n ? trigger.left - content.width - miaixzFloatingGap\n : trigger.right + miaixzFloatingGap;\n y = trigger.top + (trigger.height - content.height) / 2;\n } else {\n const alignStart = placement.endsWith(\"-start\");\n const alignLeft = rightToLeft ? !alignStart : alignStart;\n x = alignLeft ? trigger.left : trigger.right - content.width;\n y = placement.startsWith(\"top-\")\n ? trigger.top - content.height - miaixzFloatingGap\n : trigger.bottom + miaixzFloatingGap;\n }\n\n return {\n placement,\n x: clampMiaixzFloatingCoordinate(\n x,\n miaixzFloatingGap,\n viewportWidth - content.width - miaixzFloatingGap,\n ),\n y: clampMiaixzFloatingCoordinate(\n y,\n miaixzFloatingGap,\n viewportHeight - content.height - miaixzFloatingGap,\n ),\n };\n}\n\n/**\n * Flips one requested placement when its main-axis surface does not fit.\n *\n * @param trigger - Viewport geometry of the anchor element.\n * @param content - Viewport geometry of the floating surface.\n * @param placement - Requested placement.\n * @param viewportWidth - Current layout viewport width.\n * @param viewportHeight - Current layout viewport height.\n * @returns Original or opposite placement.\n */\nfunction resolveMiaixzFloatingPlacement(\n trigger: DOMRect,\n content: DOMRect,\n placement: MiaixzFloatingPlacement,\n viewportWidth: number,\n viewportHeight: number,\n): MiaixzFloatingPlacement {\n if (\n (placement === \"bottom\" || placement.startsWith(\"bottom-\")) &&\n trigger.bottom + miaixzFloatingGap + content.height > viewportHeight - miaixzFloatingGap\n ) {\n return placement === \"bottom\"\n ? \"top\"\n : (placement.replace(\"bottom-\", \"top-\") as MiaixzFloatingPlacement);\n }\n if (\n (placement === \"top\" || placement.startsWith(\"top-\")) &&\n trigger.top - miaixzFloatingGap - content.height < miaixzFloatingGap\n ) {\n return placement === \"top\"\n ? \"bottom\"\n : (placement.replace(\"top-\", \"bottom-\") as MiaixzFloatingPlacement);\n }\n if (\n placement === \"right\" &&\n trigger.right + miaixzFloatingGap + content.width > viewportWidth - miaixzFloatingGap\n ) {\n return \"left\";\n }\n if (\n placement === \"left\" &&\n trigger.left - miaixzFloatingGap - content.width < miaixzFloatingGap\n ) {\n return \"right\";\n }\n return placement;\n}\n\n/**\n * Clamps one coordinate while handling surfaces larger than the available viewport.\n *\n * @param value - Requested coordinate.\n * @param minimum - Minimum safe viewport coordinate.\n * @param maximum - Maximum safe viewport coordinate.\n * @returns Coordinate constrained to the valid interval.\n */\nfunction clampMiaixzFloatingCoordinate(value: number, minimum: number, maximum: number): number {\n return Math.min(Math.max(value, minimum), Math.max(minimum, maximum));\n}\n"]}