@kine-design/core 0.0.1-beta.1 → 0.0.1-beta.10

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 (426) hide show
  1. package/.vlaude/last-session-id +1 -0
  2. package/.vlaude/session-switch.signal +1 -0
  3. package/assets/style/global.css +1 -0
  4. package/assets/style/var/Wuxing.css +71 -0
  5. package/assets/style/var.css +23 -0
  6. package/components/base/affix/api.ts +16 -0
  7. package/components/base/affix/index.ts +17 -0
  8. package/components/base/affix/props.d.ts +34 -0
  9. package/components/base/affix/useAffix.ts +124 -0
  10. package/components/base/alert/api.ts +18 -0
  11. package/components/base/alert/index.ts +15 -0
  12. package/components/base/alert/props.d.ts +50 -0
  13. package/components/base/anchor/api.ts +20 -0
  14. package/components/base/anchor/index.ts +18 -0
  15. package/components/base/anchor/props.d.ts +46 -0
  16. package/components/base/anchor/useAnchor.ts +84 -0
  17. package/components/base/autoComplete/api.ts +24 -0
  18. package/components/base/autoComplete/index.ts +17 -0
  19. package/components/base/autoComplete/props.d.ts +75 -0
  20. package/components/base/autoComplete/useAutoComplete.ts +157 -0
  21. package/components/base/avatar/api.ts +17 -0
  22. package/components/base/avatar/avatar.css +61 -0
  23. package/components/base/avatar/index.ts +15 -0
  24. package/components/base/avatar/props.d.ts +37 -0
  25. package/components/base/backTop/api.ts +17 -0
  26. package/components/base/backTop/index.ts +17 -0
  27. package/components/base/backTop/props.d.ts +38 -0
  28. package/components/base/backTop/useBackTop.ts +62 -0
  29. package/components/base/badge/api.ts +22 -0
  30. package/components/base/badge/index.ts +15 -0
  31. package/components/base/badge/props.d.ts +50 -0
  32. package/components/base/button/api.ts +28 -0
  33. package/components/base/button/button.css +34 -0
  34. package/components/base/button/index.ts +17 -0
  35. package/components/base/button/props.d.ts +66 -0
  36. package/components/base/button/useButton.ts +37 -0
  37. package/components/base/card/api.ts +17 -0
  38. package/components/base/card/index.ts +15 -0
  39. package/components/base/card/props.d.ts +37 -0
  40. package/components/base/carousel/api.ts +28 -0
  41. package/components/base/carousel/index.ts +17 -0
  42. package/components/base/carousel/props.d.ts +72 -0
  43. package/components/base/carousel/useCarousel.ts +150 -0
  44. package/components/base/cascader/api.ts +23 -0
  45. package/components/base/cascader/index.ts +18 -0
  46. package/components/base/cascader/props.d.ts +103 -0
  47. package/components/base/cascader/useCascader.ts +335 -0
  48. package/components/base/checkbox/api.ts +24 -0
  49. package/components/base/checkbox/checkbox.css +0 -0
  50. package/components/base/checkbox/index.ts +17 -0
  51. package/components/base/checkbox/props.d.ts +77 -0
  52. package/components/base/checkbox/useCheckbox.ts +43 -0
  53. package/components/base/collapse/api.ts +21 -0
  54. package/components/base/collapse/index.ts +18 -0
  55. package/components/base/collapse/props.d.ts +45 -0
  56. package/components/base/collapse/useCollapse.ts +81 -0
  57. package/components/base/datePicker/__tests__/useDatePicker.test.ts +244 -0
  58. package/components/base/datePicker/api.ts +22 -0
  59. package/components/base/datePicker/index.ts +19 -0
  60. package/components/base/datePicker/props.d.ts +86 -0
  61. package/components/base/datePicker/useDatePicker.ts +392 -0
  62. package/components/base/divider/api.ts +15 -0
  63. package/components/base/divider/divider.css +11 -0
  64. package/components/base/divider/index.ts +15 -0
  65. package/components/base/divider/props.d.ts +30 -0
  66. package/components/base/dropdown/api.ts +33 -0
  67. package/components/base/dropdown/index.ts +18 -0
  68. package/components/base/dropdown/props.d.ts +60 -0
  69. package/components/base/dropdown/useDropdown.ts +124 -0
  70. package/components/base/empty/api.ts +15 -0
  71. package/components/base/empty/index.ts +15 -0
  72. package/components/base/empty/props.d.ts +26 -0
  73. package/components/base/image/__tests__/useImage.test.ts +176 -0
  74. package/components/base/image/api.ts +25 -0
  75. package/components/base/image/index.ts +18 -0
  76. package/components/base/image/props.d.ts +67 -0
  77. package/components/base/image/useImage.ts +119 -0
  78. package/components/base/input/api.ts +23 -0
  79. package/components/base/input/index.ts +17 -0
  80. package/components/base/input/input.css +19 -0
  81. package/components/base/input/props.d.ts +85 -0
  82. package/components/base/input/useInput.ts +63 -0
  83. package/components/base/inputNumber/__tests__/useInputNumber.test.ts +189 -0
  84. package/components/base/inputNumber/api.ts +23 -0
  85. package/components/base/inputNumber/index.ts +17 -0
  86. package/components/base/inputNumber/props.d.ts +78 -0
  87. package/components/base/inputNumber/useInputNumber.ts +182 -0
  88. package/components/base/li/api.ts +15 -0
  89. package/components/base/li/index.ts +15 -0
  90. package/components/base/li/props.d.ts +30 -0
  91. package/components/base/list/api.ts +16 -0
  92. package/components/base/list/index.ts +17 -0
  93. package/components/base/list/props.d.ts +33 -0
  94. package/components/base/list/useList.ts +36 -0
  95. package/components/base/loading/api.ts +17 -0
  96. package/components/base/loading/index.ts +15 -0
  97. package/components/base/loading/props.d.ts +40 -0
  98. package/components/base/popover/api.ts +28 -0
  99. package/components/base/popover/index.ts +17 -0
  100. package/components/base/popover/props.d.ts +73 -0
  101. package/components/base/popover/usePopover.ts +193 -0
  102. package/components/base/progress/api.ts +20 -0
  103. package/components/base/progress/index.ts +17 -0
  104. package/components/base/progress/props.d.ts +68 -0
  105. package/components/base/progress/useProgress.ts +28 -0
  106. package/components/base/radio/api.ts +19 -0
  107. package/components/base/radio/index.ts +19 -0
  108. package/components/base/radio/props.d.ts +59 -0
  109. package/components/base/radio/useRadio.ts +11 -0
  110. package/components/base/rate/api.ts +18 -0
  111. package/components/base/rate/index.ts +17 -0
  112. package/components/base/rate/props.d.ts +49 -0
  113. package/components/base/rate/useRate.ts +76 -0
  114. package/components/base/result/api.ts +20 -0
  115. package/components/base/result/index.ts +15 -0
  116. package/components/base/result/props.d.ts +36 -0
  117. package/components/base/select/api.ts +34 -0
  118. package/components/base/select/index.ts +18 -0
  119. package/components/base/select/props.d.ts +152 -0
  120. package/components/base/select/select.css +7 -0
  121. package/components/base/select/useSelect.ts +281 -0
  122. package/components/base/select/useSelectTools.ts +60 -0
  123. package/components/base/skeleton/api.ts +18 -0
  124. package/components/base/skeleton/index.ts +15 -0
  125. package/components/base/skeleton/props.d.ts +41 -0
  126. package/components/base/slider/api.ts +22 -0
  127. package/components/base/slider/index.ts +17 -0
  128. package/components/base/slider/props.d.ts +79 -0
  129. package/components/base/slider/useSlider.ts +87 -0
  130. package/components/base/space/api.ts +17 -0
  131. package/components/base/space/index.ts +15 -0
  132. package/components/base/space/props.d.ts +39 -0
  133. package/components/base/steps/__tests__/useSteps.test.ts +46 -0
  134. package/components/base/steps/api.ts +30 -0
  135. package/components/base/steps/index.ts +22 -0
  136. package/components/base/steps/props.d.ts +88 -0
  137. package/components/base/steps/useSteps.ts +101 -0
  138. package/components/base/switch/api.ts +22 -0
  139. package/components/base/switch/index.ts +19 -0
  140. package/components/base/switch/props.d.ts +66 -0
  141. package/components/base/switch/useSwitch.tsx +80 -0
  142. package/components/base/tabs/api.ts +23 -0
  143. package/components/base/tabs/index.ts +18 -0
  144. package/components/base/tabs/props.d.ts +41 -0
  145. package/components/base/tabs/useTabs.ts +67 -0
  146. package/components/base/tag/api.ts +17 -0
  147. package/components/base/tag/index.ts +15 -0
  148. package/components/base/tag/props.d.ts +51 -0
  149. package/components/base/timePicker/__tests__/useTimePicker.test.ts +124 -0
  150. package/components/base/timePicker/api.ts +24 -0
  151. package/components/base/timePicker/index.ts +18 -0
  152. package/components/base/timePicker/props.d.ts +86 -0
  153. package/components/base/timePicker/useTimePicker.ts +161 -0
  154. package/components/base/timeline/api.ts +24 -0
  155. package/components/base/timeline/index.ts +16 -0
  156. package/components/base/timeline/props.d.ts +60 -0
  157. package/components/base/tooltip/api.ts +21 -0
  158. package/components/base/tooltip/index.ts +18 -0
  159. package/components/base/tooltip/props.d.ts +46 -0
  160. package/components/base/tooltip/useTooltip.ts +208 -0
  161. package/components/base/transfer/api.ts +18 -0
  162. package/components/base/transfer/index.ts +17 -0
  163. package/components/base/transfer/props.d.ts +63 -0
  164. package/components/base/transfer/useTransfer.ts +208 -0
  165. package/components/base/tree/__tests__/tree.test.ts +223 -0
  166. package/components/base/tree/api.ts +47 -0
  167. package/components/base/tree/index.ts +29 -0
  168. package/components/base/tree/props.d.ts +108 -0
  169. package/components/base/tree/tree.ts +263 -0
  170. package/components/base/tree/useTree.ts +114 -0
  171. package/components/message/confirm/api.ts +21 -0
  172. package/components/message/confirm/index.ts +15 -0
  173. package/components/message/confirm/props.d.ts +69 -0
  174. package/components/message/dialog/api.ts +20 -0
  175. package/components/message/dialog/index.ts +15 -0
  176. package/components/message/dialog/props.d.ts +62 -0
  177. package/components/message/drawer/api.ts +33 -0
  178. package/components/message/drawer/index.ts +15 -0
  179. package/components/message/drawer/props.d.ts +80 -0
  180. package/components/message/message/api.ts +27 -0
  181. package/components/message/message/index.ts +20 -0
  182. package/components/message/message/props.d.ts +54 -0
  183. package/components/message/message/useMessage.ts +61 -0
  184. package/components/message/notification/__tests__/useNotification.test.ts +129 -0
  185. package/components/message/notification/api.ts +23 -0
  186. package/components/message/notification/index.ts +19 -0
  187. package/components/message/notification/props.d.ts +64 -0
  188. package/components/message/notification/useNotification.ts +79 -0
  189. package/components/message/popover/MPopover.tsx +94 -0
  190. package/components/message/popover/api.ts +54 -0
  191. package/components/message/popover/index.ts +17 -0
  192. package/components/message/popover/popover.css +21 -0
  193. package/components/message/popover/props.d.ts +76 -0
  194. package/components/message/popover/usePopover.ts +234 -0
  195. package/components/other/darkMode/api.ts +17 -0
  196. package/components/other/darkMode/index.ts +17 -0
  197. package/components/other/darkMode/props.d.ts +37 -0
  198. package/components/other/darkMode/useDarkMode.ts +129 -0
  199. package/components/template/border/api.ts +18 -0
  200. package/components/template/border/index.ts +15 -0
  201. package/components/template/border/props.d.ts +41 -0
  202. package/components/template/breadcrumb/api.ts +15 -0
  203. package/components/template/breadcrumb/index.ts +15 -0
  204. package/components/template/breadcrumb/props.d.ts +45 -0
  205. package/components/template/descriptions/api.ts +23 -0
  206. package/components/template/descriptions/index.ts +16 -0
  207. package/components/template/descriptions/props.d.ts +54 -0
  208. package/components/template/form/api.ts +23 -0
  209. package/components/template/form/index.ts +20 -0
  210. package/components/template/form/props.d.ts +60 -0
  211. package/components/template/grid/api.ts +20 -0
  212. package/components/template/grid/index.ts +15 -0
  213. package/components/template/grid/props.d.ts +48 -0
  214. package/components/template/menu/__tests__/useMenu.test.ts +157 -0
  215. package/components/template/menu/api.ts +26 -0
  216. package/components/template/menu/index.ts +18 -0
  217. package/components/template/menu/props.d.ts +93 -0
  218. package/components/template/menu/useMenu.ts +155 -0
  219. package/components/template/pagination/__tests__/usePagination.test.ts +138 -0
  220. package/components/template/pagination/api.ts +22 -0
  221. package/components/template/pagination/index.ts +19 -0
  222. package/components/template/pagination/props.d.ts +65 -0
  223. package/components/template/pagination/usePagination.ts +186 -0
  224. package/components/template/table/__tests__/useTable.test.ts +138 -0
  225. package/components/template/table/api.ts +18 -0
  226. package/components/template/table/index.ts +18 -0
  227. package/components/template/table/props.d.ts +36 -0
  228. package/components/template/table/useTable.ts +136 -0
  229. package/components/template/tableColumn/api.ts +17 -0
  230. package/components/template/tableColumn/index.ts +15 -0
  231. package/components/template/tableColumn/props.d.ts +32 -0
  232. package/components/template/virtualList/api.ts +16 -0
  233. package/components/template/virtualList/index.ts +17 -0
  234. package/components/template/virtualList/props.d.ts +25 -0
  235. package/components/template/virtualList/useVirtualList.ts +237 -0
  236. package/components/types/hook.d.ts +24 -0
  237. package/components/types/props.d.ts +57 -0
  238. package/components/types/template.d.ts +59 -0
  239. package/compositions/commandPalette/index.ts +11 -0
  240. package/compositions/commandPalette/types.ts +29 -0
  241. package/compositions/commandPalette/useCommandPalette.ts +135 -0
  242. package/compositions/common/__tests__/useDebounceFn.test.ts +62 -0
  243. package/compositions/common/__tests__/useEventListener.test.ts +98 -0
  244. package/compositions/common/__tests__/usePopover.test.ts +43 -0
  245. package/compositions/common/__tests__/useTeleport.test.ts +32 -0
  246. package/compositions/common/defineCore.ts +55 -0
  247. package/compositions/common/testAnchor.ts +211 -0
  248. package/compositions/common/useComponentSize.ts +17 -0
  249. package/compositions/common/useDebounceFn.ts +27 -0
  250. package/compositions/common/useDrag.ts +65 -0
  251. package/compositions/common/useElementSize.ts +37 -0
  252. package/compositions/common/useEventListener.ts +48 -0
  253. package/compositions/common/usePopover.ts +45 -0
  254. package/compositions/common/useResizeObserver.ts +47 -0
  255. package/compositions/common/useTeleport.ts +24 -0
  256. package/compositions/contextMenu/index.ts +10 -0
  257. package/compositions/contextMenu/types.ts +21 -0
  258. package/compositions/contextMenu/useContextMenu.ts +101 -0
  259. package/compositions/editor/index.ts +18 -0
  260. package/compositions/editor/types.ts +147 -0
  261. package/compositions/editor/useEditor.ts +224 -0
  262. package/compositions/index.ts +15 -0
  263. package/compositions/input/__tests__/useBooleanInput.test.ts +73 -0
  264. package/compositions/input/useBooleanInput.ts +52 -0
  265. package/compositions/modal/__tests__/useModal.test.ts +110 -0
  266. package/compositions/modal/useModal.ts +72 -0
  267. package/compositions/overlay/index.ts +14 -0
  268. package/compositions/overlay/useOverlayStack.ts +146 -0
  269. package/compositions/peekView/index.ts +10 -0
  270. package/compositions/peekView/usePeekView.ts +99 -0
  271. package/compositions/popper/useClickAway.ts +41 -0
  272. package/compositions/popper/usePopper.ts +63 -0
  273. package/compositions/theme/index.ts +17 -0
  274. package/compositions/theme/presets/compact.ts +117 -0
  275. package/compositions/theme/presets/dark.ts +113 -0
  276. package/compositions/theme/presets/index.ts +11 -0
  277. package/compositions/theme/presets/light.ts +113 -0
  278. package/compositions/theme/types.ts +46 -0
  279. package/compositions/theme/useTheme.ts +269 -0
  280. package/compositions/toast/index.ts +10 -0
  281. package/compositions/toast/useToast.ts +176 -0
  282. package/compositions/tooltip/index.ts +9 -0
  283. package/compositions/tooltip/useTooltip.ts +10 -0
  284. package/compositions/utils/__tests__/filters.test.ts +136 -0
  285. package/compositions/utils/filters.ts +135 -0
  286. package/compositions/virtualList/__tests__/useHeightCache.test.ts +97 -0
  287. package/compositions/virtualList/enums.ts +52 -0
  288. package/compositions/virtualList/useContainerObserver.ts +89 -0
  289. package/compositions/virtualList/useEntries.ts +248 -0
  290. package/compositions/virtualList/useHeightCache.ts +83 -0
  291. package/compositions/virtualList/useSentinelObserver.ts +81 -0
  292. package/dist/components/base/affix/index.d.ts +2 -1
  293. package/dist/components/base/affix/useAffix.d.ts +7 -5
  294. package/dist/components/base/anchor/index.d.ts +2 -1
  295. package/dist/components/base/anchor/useAnchor.d.ts +3 -2
  296. package/dist/components/base/autoComplete/useAutoComplete.d.ts +14 -5
  297. package/dist/components/base/avatar/index.d.ts +1 -0
  298. package/dist/components/base/backTop/index.d.ts +2 -1
  299. package/dist/components/base/backTop/useBackTop.d.ts +2 -2
  300. package/dist/components/base/button/index.d.ts +3 -21
  301. package/dist/components/base/button/useButton.d.ts +5 -2
  302. package/dist/components/base/carousel/useCarousel.d.ts +7 -3
  303. package/dist/components/base/cascader/useCascader.d.ts +25 -12
  304. package/dist/components/base/checkbox/index.d.ts +2 -1
  305. package/dist/components/base/checkbox/useCheckbox.d.ts +5 -3
  306. package/dist/components/base/collapse/index.d.ts +2 -1
  307. package/dist/components/base/collapse/useCollapse.d.ts +4 -3
  308. package/dist/components/base/datePicker/__tests__/useDatePicker.test.d.ts +1 -0
  309. package/dist/components/base/datePicker/useDatePicker.d.ts +140 -8
  310. package/dist/components/base/dropdown/index.d.ts +2 -1
  311. package/dist/components/base/dropdown/useDropdown.d.ts +13 -6
  312. package/dist/components/base/image/__tests__/useImage.test.d.ts +1 -0
  313. package/dist/components/base/image/useImage.d.ts +5 -5
  314. package/dist/components/base/input/index.d.ts +2 -1
  315. package/dist/components/base/input/useInput.d.ts +4 -2
  316. package/dist/components/base/inputNumber/__tests__/useInputNumber.test.d.ts +1 -0
  317. package/dist/components/base/inputNumber/index.d.ts +2 -1
  318. package/dist/components/base/inputNumber/useInputNumber.d.ts +4 -3
  319. package/dist/components/base/li/index.d.ts +1 -0
  320. package/dist/components/base/list/index.d.ts +2 -1
  321. package/dist/components/base/list/useList.d.ts +1 -1
  322. package/dist/components/base/popover/index.d.ts +2 -1
  323. package/dist/components/base/popover/usePopover.d.ts +10 -9
  324. package/dist/components/base/progress/index.d.ts +2 -1
  325. package/dist/components/base/progress/useProgress.d.ts +2 -2
  326. package/dist/components/base/rate/index.d.ts +2 -1
  327. package/dist/components/base/rate/useRate.d.ts +3 -2
  328. package/dist/components/base/select/useSelect.d.ts +10 -9
  329. package/dist/components/base/slider/index.d.ts +2 -1
  330. package/dist/components/base/slider/useSlider.d.ts +5 -4
  331. package/dist/components/base/steps/__tests__/useSteps.test.d.ts +1 -0
  332. package/dist/components/base/steps/index.d.ts +1 -1
  333. package/dist/components/base/steps/useSteps.d.ts +5 -5
  334. package/dist/components/base/switch/index.d.ts +2 -1
  335. package/dist/components/base/switch/useSwitch.d.ts +9 -3
  336. package/dist/components/base/tabs/index.d.ts +1 -1
  337. package/dist/components/base/tabs/useTabs.d.ts +4 -3
  338. package/dist/components/base/tag/index.d.ts +1 -0
  339. package/dist/components/base/timePicker/__tests__/useTimePicker.test.d.ts +1 -0
  340. package/dist/components/base/timePicker/useTimePicker.d.ts +14 -6
  341. package/dist/components/base/tooltip/index.d.ts +2 -1
  342. package/dist/components/base/tooltip/useTooltip.d.ts +24 -11
  343. package/dist/components/base/transfer/useTransfer.d.ts +17 -16
  344. package/dist/components/base/tree/__tests__/tree.test.d.ts +1 -0
  345. package/dist/components/base/tree/index.d.ts +1 -1
  346. package/dist/components/base/tree/useTree.d.ts +2 -1
  347. package/dist/components/message/drawer/index.d.ts +2 -2
  348. package/dist/components/message/message/useMessage.d.ts +11 -1
  349. package/dist/components/message/notification/__tests__/useNotification.test.d.ts +1 -0
  350. package/dist/components/message/notification/useNotification.d.ts +17 -1
  351. package/dist/components/message/popover/MPopover.d.ts +6 -1
  352. package/dist/components/message/popover/index.d.ts +1 -1
  353. package/dist/components/message/popover/usePopover.d.ts +7 -7
  354. package/dist/components/other/darkMode/useDarkMode.d.ts +3 -4
  355. package/dist/components/template/menu/__tests__/useMenu.test.d.ts +1 -0
  356. package/dist/components/template/menu/index.d.ts +0 -1
  357. package/dist/components/template/menu/useMenu.d.ts +2 -1
  358. package/dist/components/template/pagination/__tests__/usePagination.test.d.ts +1 -0
  359. package/dist/components/template/pagination/index.d.ts +2 -1
  360. package/dist/components/template/table/__tests__/useTable.test.d.ts +1 -0
  361. package/dist/components/template/virtualList/index.d.ts +0 -1
  362. package/dist/components/template/virtualList/useVirtualList.d.ts +10 -7
  363. package/dist/compositions/commandPalette/index.d.ts +11 -0
  364. package/dist/compositions/commandPalette/types.d.ts +20 -0
  365. package/dist/compositions/commandPalette/useCommandPalette.d.ts +32 -0
  366. package/dist/compositions/common/__tests__/useDebounceFn.test.d.ts +1 -0
  367. package/dist/compositions/common/__tests__/useEventListener.test.d.ts +1 -0
  368. package/dist/compositions/common/__tests__/usePopover.test.d.ts +1 -0
  369. package/dist/compositions/common/__tests__/useTeleport.test.d.ts +1 -0
  370. package/dist/compositions/common/testAnchor.d.ts +40 -0
  371. package/dist/compositions/common/useComponentSize.d.ts +6 -0
  372. package/dist/compositions/common/useDrag.d.ts +1 -1
  373. package/dist/compositions/common/useElementSize.d.ts +2 -2
  374. package/dist/compositions/common/useEventListener.d.ts +2 -2
  375. package/dist/compositions/common/useTeleport.d.ts +4 -2
  376. package/dist/compositions/contextMenu/index.d.ts +10 -0
  377. package/dist/compositions/contextMenu/types.d.ts +12 -0
  378. package/dist/compositions/contextMenu/useContextMenu.d.ts +52 -0
  379. package/dist/compositions/editor/index.d.ts +10 -0
  380. package/dist/compositions/editor/types.d.ts +132 -0
  381. package/dist/compositions/editor/useEditor.d.ts +13 -0
  382. package/dist/compositions/index.d.ts +15 -0
  383. package/dist/compositions/input/__tests__/useBooleanInput.test.d.ts +1 -0
  384. package/dist/compositions/modal/__tests__/useModal.test.d.ts +1 -0
  385. package/dist/compositions/modal/useModal.d.ts +3 -2
  386. package/dist/compositions/overlay/index.d.ts +10 -0
  387. package/dist/compositions/overlay/useOverlayStack.d.ts +188 -0
  388. package/dist/compositions/peekView/index.d.ts +10 -0
  389. package/dist/compositions/peekView/usePeekView.d.ts +16 -0
  390. package/dist/compositions/popper/useClickAway.d.ts +3 -3
  391. package/dist/compositions/theme/index.d.ts +11 -0
  392. package/dist/compositions/theme/presets/compact.d.ts +6 -0
  393. package/dist/compositions/theme/presets/dark.d.ts +2 -0
  394. package/dist/compositions/theme/presets/index.d.ts +11 -0
  395. package/dist/compositions/theme/presets/light.d.ts +2 -0
  396. package/dist/compositions/theme/types.d.ts +41 -0
  397. package/dist/compositions/theme/useTheme.d.ts +167 -0
  398. package/dist/compositions/toast/index.d.ts +10 -0
  399. package/dist/compositions/toast/useToast.d.ts +71 -0
  400. package/dist/compositions/tooltip/index.d.ts +9 -0
  401. package/dist/compositions/tooltip/useTooltip.d.ts +10 -0
  402. package/dist/compositions/utils/__tests__/filters.test.d.ts +1 -0
  403. package/dist/compositions/virtualList/__tests__/useHeightCache.test.d.ts +1 -0
  404. package/dist/core.js +7050 -4188
  405. package/dist/index.d.ts +1 -0
  406. package/dist/runtime/defineHook.d.ts +1 -1
  407. package/dist/tools/__tests__/empty.test.d.ts +1 -0
  408. package/dist/tools/empty.d.ts +2 -2
  409. package/dist/tools/types.d.ts +1 -1
  410. package/dist/vitest.config.d.ts +10 -0
  411. package/index.css +1 -0
  412. package/index.ts +73 -0
  413. package/package.json +41 -22
  414. package/runtime/defineHook.ts +21 -0
  415. package/tools/__tests__/empty.test.ts +91 -0
  416. package/tools/empty.ts +81 -0
  417. package/tools/index.ts +15 -0
  418. package/tools/types.ts +11 -0
  419. package/tsconfig.json +8 -0
  420. package/types/common/common.d.ts +25 -0
  421. package/types/common/model.d.ts +25 -0
  422. package/types/index.d.ts +11 -0
  423. package/types/props.d.ts +13 -0
  424. package/vite.config.build.ts +41 -0
  425. package/vitest.config.ts +17 -0
  426. package/dist/vite.config.build.d.ts +0 -2
@@ -0,0 +1,176 @@
1
+ /**
2
+ * @description toast 队列 composable — Promise-based 通知系统
3
+ * @author 阿怪
4
+ * @date 2026/5/22
5
+ * @version v1.0.0
6
+ *
7
+ * 江湖的业务千篇一律,复杂的代码好几百行。
8
+ */
9
+ import { ref } from 'vue';
10
+
11
+ /**
12
+ * Toast 类型
13
+ */
14
+ export type ToastType = 'success' | 'error' | 'warning' | 'info' | 'loading';
15
+
16
+ /**
17
+ * Toast 队列中每一条 toast 的内部结构
18
+ */
19
+ export interface ToastItem {
20
+ id: number;
21
+ type: ToastType;
22
+ title: string;
23
+ message?: string;
24
+ duration: number;
25
+ createdAt: number;
26
+ }
27
+
28
+ /**
29
+ * 创建 toast 时的配置参数
30
+ */
31
+ export interface ToastShowOptions {
32
+ type?: ToastType;
33
+ title: string;
34
+ message?: string;
35
+ duration?: number;
36
+ }
37
+
38
+ /**
39
+ * promise() 方法的三阶段配置
40
+ */
41
+ export interface ToastPromiseOptions<T> {
42
+ loading: string | { title: string; message?: string };
43
+ success: string | { title: string; message?: string } | ((data: T) => string | { title: string; message?: string });
44
+ error: string | { title: string; message?: string } | ((err: unknown) => string | { title: string; message?: string });
45
+ }
46
+
47
+ /** 各类型默认自动关闭时间(毫秒) */
48
+ const DEFAULT_DURATIONS: Record<ToastType, number> = {
49
+ success: 3000,
50
+ error: 5000,
51
+ warning: 4000,
52
+ info: 3000,
53
+ loading: 0, // loading never auto-dismiss
54
+ };
55
+
56
+ /** 最大可见 toast 数量 */
57
+ const MAX_VISIBLE = 3;
58
+
59
+ let nextId = 0;
60
+
61
+ /**
62
+ * Toast 队列 composable
63
+ * 管理 toast 的增删、自动关闭定时器与 Promise 模式
64
+ */
65
+ export function useToast() {
66
+ const toasts = ref<ToastItem[]>([]);
67
+ const timers = new Map<number, ReturnType<typeof setTimeout>>();
68
+
69
+ /**
70
+ * 展示一条 toast,返回 id
71
+ */
72
+ const show = (options: ToastShowOptions): number => {
73
+ const id = nextId++;
74
+ const type = options.type ?? 'info';
75
+ const duration = options.duration ?? DEFAULT_DURATIONS[type];
76
+
77
+ const item: ToastItem = {
78
+ id,
79
+ type,
80
+ title: options.title,
81
+ message: options.message,
82
+ duration,
83
+ createdAt: Date.now(),
84
+ };
85
+
86
+ toasts.value.push(item);
87
+
88
+ // enforce max visible — remove oldest (non-loading) if exceeding limit
89
+ while (toasts.value.length > MAX_VISIBLE) {
90
+ const oldest = toasts.value.find(t => t.type !== 'loading');
91
+ if (oldest) {
92
+ dismiss(oldest.id);
93
+ } else {
94
+ // all are loading, remove the very first
95
+ dismiss(toasts.value[0].id);
96
+ }
97
+ }
98
+
99
+ if (duration > 0) {
100
+ const timer = setTimeout(() => dismiss(id), duration);
101
+ timers.set(id, timer);
102
+ }
103
+
104
+ return id;
105
+ };
106
+
107
+ /**
108
+ * 按 id 移除一条 toast
109
+ */
110
+ const dismiss = (id: number): void => {
111
+ const idx = toasts.value.findIndex(t => t.id === id);
112
+ if (idx !== -1) {
113
+ toasts.value.splice(idx, 1);
114
+ }
115
+ const timer = timers.get(id);
116
+ if (timer) {
117
+ clearTimeout(timer);
118
+ timers.delete(id);
119
+ }
120
+ };
121
+
122
+ /**
123
+ * 将 stage 配置标准化为 { title, message }
124
+ */
125
+ function normalizeStage(stage: string | { title: string; message?: string }): { title: string; message?: string } {
126
+ if (typeof stage === 'string') {
127
+ return { title: stage };
128
+ }
129
+ return stage;
130
+ }
131
+
132
+ /**
133
+ * Promise toast pattern:
134
+ * - 立即展示 loading toast
135
+ * - resolve → 替换为 success toast
136
+ * - reject → 替换为 error toast
137
+ */
138
+ const promise = <T>(
139
+ p: Promise<T>,
140
+ options: ToastPromiseOptions<T>,
141
+ ): Promise<T> => {
142
+ const loadingStage = normalizeStage(options.loading);
143
+ const loadingId = show({
144
+ type: 'loading',
145
+ title: loadingStage.title,
146
+ message: loadingStage.message,
147
+ });
148
+
149
+ return p.then(
150
+ (data) => {
151
+ dismiss(loadingId);
152
+ const raw = typeof options.success === 'function' ? options.success(data) : options.success;
153
+ const successStage = normalizeStage(raw);
154
+ show({
155
+ type: 'success',
156
+ title: successStage.title,
157
+ message: successStage.message,
158
+ });
159
+ return data;
160
+ },
161
+ (err: unknown) => {
162
+ dismiss(loadingId);
163
+ const raw = typeof options.error === 'function' ? options.error(err) : options.error;
164
+ const errorStage = normalizeStage(raw);
165
+ show({
166
+ type: 'error',
167
+ title: errorStage.title,
168
+ message: errorStage.message,
169
+ });
170
+ throw err;
171
+ },
172
+ );
173
+ };
174
+
175
+ return { toasts, show, dismiss, promise };
176
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @description tooltip compositions barrel export
3
+ * @author 阿怪
4
+ * @date 2026/5/22
5
+ * @version v1.0.0
6
+ *
7
+ * 江湖的业务千篇一律,复杂的代码好几百行。
8
+ */
9
+ export { useTooltip, type TooltipPlacement, type TooltipPositionData } from './useTooltip';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @description tooltip composable re-export from component layer
3
+ * @author 阿怪
4
+ * @date 2026/5/22
5
+ * @version v1.0.0
6
+ *
7
+ * 江湖的业务千篇一律,复杂的代码好几百行。
8
+ */
9
+ export { useTooltip } from '../../components/base/tooltip/useTooltip';
10
+ export type { TooltipPlacement, TooltipPositionData } from '../../components/base/tooltip/useTooltip';
@@ -0,0 +1,136 @@
1
+ /**
2
+ * @description debounceFilter / throttleFilter / createFilterWrapper 测试
3
+ * @author 阿怪
4
+ * @date 2026/3/23
5
+ * @version v1.0.0
6
+ *
7
+ * 江湖的业务千篇一律,复杂的代码好几百行。
8
+ */
9
+ import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest';
10
+ import { createFilterWrapper, debounceFilter, throttleFilter } from '../filters';
11
+
12
+ beforeEach(() => { vi.useFakeTimers(); });
13
+ afterEach(() => { vi.useRealTimers(); });
14
+
15
+ describe('debounceFilter', () => {
16
+ it('延迟执行函数', () => {
17
+ const fn = vi.fn();
18
+ const debounced = createFilterWrapper(debounceFilter(100), fn);
19
+
20
+ debounced();
21
+ expect(fn).not.toHaveBeenCalled();
22
+
23
+ vi.advanceTimersByTime(100);
24
+ expect(fn).toHaveBeenCalledOnce();
25
+ });
26
+
27
+ it('多次调用只执行最后一次', () => {
28
+ const fn = vi.fn();
29
+ const debounced = createFilterWrapper(debounceFilter(100), fn);
30
+
31
+ debounced();
32
+ debounced();
33
+ debounced();
34
+
35
+ vi.advanceTimersByTime(100);
36
+ expect(fn).toHaveBeenCalledOnce();
37
+ });
38
+
39
+ it('ms <= 0 时立即执行', () => {
40
+ const fn = vi.fn();
41
+ const debounced = createFilterWrapper(debounceFilter(0), fn);
42
+
43
+ debounced();
44
+ expect(fn).toHaveBeenCalledOnce();
45
+ });
46
+
47
+ it('maxWait 限制最大等待时间', () => {
48
+ const fn = vi.fn();
49
+ const debounced = createFilterWrapper(debounceFilter(100, { maxWait: 150 }), fn);
50
+
51
+ debounced();
52
+ vi.advanceTimersByTime(80);
53
+ debounced(); // 重置 debounce timer
54
+ vi.advanceTimersByTime(80); // 总共 160ms,超过 maxWait
55
+ expect(fn).toHaveBeenCalledOnce();
56
+ });
57
+
58
+ it('maxWait <= 0 时立即执行', () => {
59
+ const fn = vi.fn();
60
+ const debounced = createFilterWrapper(debounceFilter(100, { maxWait: 0 }), fn);
61
+
62
+ debounced();
63
+ expect(fn).toHaveBeenCalledOnce();
64
+ });
65
+
66
+ it('保留参数传递', () => {
67
+ const fn = vi.fn();
68
+ const debounced = createFilterWrapper(debounceFilter(50), fn);
69
+
70
+ debounced('a', 'b');
71
+ vi.advanceTimersByTime(50);
72
+ expect(fn).toHaveBeenCalledWith('a', 'b');
73
+ });
74
+ });
75
+
76
+ describe('throttleFilter', () => {
77
+ it('首次立即执行(leading=true 默认)', () => {
78
+ const fn = vi.fn();
79
+ const throttled = createFilterWrapper(throttleFilter(100), fn);
80
+
81
+ throttled();
82
+ expect(fn).toHaveBeenCalledOnce();
83
+ });
84
+
85
+ it('间隔内不重复执行', () => {
86
+ const fn = vi.fn();
87
+ const throttled = createFilterWrapper(throttleFilter(100), fn);
88
+
89
+ throttled();
90
+ throttled();
91
+ throttled();
92
+ expect(fn).toHaveBeenCalledOnce();
93
+ });
94
+
95
+ it('trailing=true 时间隔结束后执行尾部调用', () => {
96
+ const fn = vi.fn();
97
+ const throttled = createFilterWrapper(throttleFilter(100, true, true), fn);
98
+
99
+ throttled(); // leading 执行
100
+ throttled(); // 排队 trailing
101
+
102
+ vi.advanceTimersByTime(100);
103
+ expect(fn).toHaveBeenCalledTimes(2);
104
+ });
105
+
106
+ it('trailing=false 不执行尾部调用', () => {
107
+ const fn = vi.fn();
108
+ const throttled = createFilterWrapper(throttleFilter(100, false, true), fn);
109
+
110
+ throttled(); // leading 执行
111
+ throttled(); // 不排队
112
+
113
+ vi.advanceTimersByTime(100);
114
+ expect(fn).toHaveBeenCalledOnce();
115
+ });
116
+
117
+ it('leading=false 首次不执行', () => {
118
+ const fn = vi.fn();
119
+ const throttled = createFilterWrapper(throttleFilter(100, true, false), fn);
120
+
121
+ throttled();
122
+ expect(fn).not.toHaveBeenCalled();
123
+
124
+ vi.advanceTimersByTime(100);
125
+ expect(fn).toHaveBeenCalledOnce();
126
+ });
127
+
128
+ it('ms <= 0 时立即执行', () => {
129
+ const fn = vi.fn();
130
+ const throttled = createFilterWrapper(throttleFilter(0), fn);
131
+
132
+ throttled();
133
+ throttled();
134
+ expect(fn).toHaveBeenCalledTimes(2);
135
+ });
136
+ });
@@ -0,0 +1,135 @@
1
+ /**
2
+ * @description event filter(防抖、节流)
3
+ * @author youus
4
+ * @date 2022/8/20 00:17
5
+ * @version v1.0.0
6
+ *
7
+ * Hello, humor
8
+ */
9
+
10
+
11
+ export type FunctionArgs<Args extends any[] = any[], Return = void> = (...args: Args) => Return;
12
+
13
+ export interface FunctionWrapperOptions<Args extends any[] = any[], This = any> {
14
+ fn: FunctionArgs<Args, This>,
15
+ args: Args,
16
+ thisArg: This
17
+ }
18
+
19
+ export type EventFilter<Args extends any[] = any[], This = any> = (
20
+ invoke: () => void,
21
+ options: FunctionWrapperOptions<Args, This>,
22
+ ) => void;
23
+
24
+ export interface DebounceFilterOptions {
25
+ /**
26
+ * The maximum time allowed to be delayed before it's invoked.
27
+ * In milliseconds.
28
+ */
29
+ maxWait?: number;
30
+ }
31
+
32
+ /**
33
+ * @internal
34
+ */
35
+ export function createFilterWrapper<T extends FunctionArgs>(filter: EventFilter, fn: T) {
36
+ function wrapper(this: any, ...args: any[]) {
37
+ filter(() => fn.apply(this, args), { fn, thisArg: this, args });
38
+ }
39
+
40
+ return wrapper as any as T;
41
+ }
42
+
43
+ /**
44
+ * Create an EventFilter that debounce the events
45
+ *
46
+ * @param ms
47
+ * @param options
48
+ */
49
+ export function debounceFilter(ms: number, options: DebounceFilterOptions = {}) {
50
+ let timer: ReturnType<typeof setTimeout> | undefined;
51
+ let maxTimer: ReturnType<typeof setTimeout> | undefined | null;
52
+
53
+ const filter: EventFilter = invoke => {
54
+ const duration = ms;
55
+ const maxDuration = options.maxWait;
56
+
57
+ if (timer) clearTimeout(timer);
58
+
59
+ if (duration <= 0 || (maxDuration !== undefined && maxDuration <= 0)) {
60
+ if (maxTimer) {
61
+ clearTimeout(maxTimer);
62
+ maxTimer = null;
63
+ }
64
+ return invoke();
65
+ }
66
+
67
+ // Create the maxTimer. Clears the regular timer on invoke
68
+ if (maxDuration && !maxTimer) {
69
+ maxTimer = setTimeout(() => {
70
+ if (timer) clearTimeout(timer);
71
+ maxTimer = null;
72
+ invoke();
73
+ }, maxDuration);
74
+ }
75
+
76
+ // Create the regular timer. Clears the max timer on invoke
77
+ timer = setTimeout(() => {
78
+ if (maxTimer) clearTimeout(maxTimer);
79
+ maxTimer = null;
80
+ invoke();
81
+ }, duration);
82
+ };
83
+
84
+ return filter;
85
+ }
86
+
87
+ /**
88
+ * Create an EventFilter that throttle the events
89
+ *
90
+ * @param ms
91
+ * @param [trailing=true]
92
+ * @param [leading=true]
93
+ */
94
+ export function throttleFilter(ms: number, trailing = true, leading = true) {
95
+ let lastExec = 0;
96
+ let timer: ReturnType<typeof setTimeout> | undefined;
97
+ let isLeading = true;
98
+
99
+ const clear = () => {
100
+ if (timer) {
101
+ clearTimeout(timer);
102
+ timer = undefined;
103
+ }
104
+ };
105
+
106
+ const filter: EventFilter = invoke => {
107
+ const duration = ms;
108
+ const elapsed = Date.now() - lastExec;
109
+
110
+ clear();
111
+
112
+ if (duration <= 0) {
113
+ lastExec = Date.now();
114
+ return invoke();
115
+ }
116
+
117
+ if (elapsed > duration && (leading || !isLeading)) {
118
+ lastExec = Date.now();
119
+ invoke();
120
+ } else if (trailing) {
121
+ timer = setTimeout(() => {
122
+ lastExec = Date.now();
123
+ isLeading = true;
124
+ clear();
125
+ invoke();
126
+ }, duration);
127
+ }
128
+
129
+ if (!leading && !timer) timer = setTimeout(() => (isLeading = true), duration);
130
+
131
+ isLeading = false;
132
+ };
133
+
134
+ return filter;
135
+ }
@@ -0,0 +1,97 @@
1
+ /**
2
+ * @description createHeightCache 测试
3
+ * @author 阿怪
4
+ * @date 2026/3/23
5
+ * @version v1.0.0
6
+ *
7
+ * 江湖的业务千篇一律,复杂的代码好几百行。
8
+ */
9
+ import { describe, expect, it } from 'vitest';
10
+ import { createHeightCache } from '../useHeightCache';
11
+
12
+ describe('createHeightCache', () => {
13
+ it('初始化后 getHeight 返回预估高度', () => {
14
+ const cache = createHeightCache(10, 40);
15
+ expect(cache.getHeight(0)).toBe(40);
16
+ expect(cache.getHeight(5)).toBe(40);
17
+ expect(cache.getHeight(9)).toBe(40);
18
+ });
19
+
20
+ it('update 后 getHeight 返回实际高度', () => {
21
+ const cache = createHeightCache(10, 40);
22
+ cache.update(3, 60);
23
+ expect(cache.getHeight(3)).toBe(60);
24
+ // 其他未更新的仍为预估值
25
+ expect(cache.getHeight(4)).toBe(40);
26
+ });
27
+
28
+ it('update 越界不报错', () => {
29
+ const cache = createHeightCache(5, 40);
30
+ cache.update(-1, 50); // 越界
31
+ cache.update(10, 50); // 越界
32
+ expect(cache.getHeight(0)).toBe(40); // 不受影响
33
+ });
34
+
35
+ it('getOffset 返回累计高度', () => {
36
+ const cache = createHeightCache(5, 40);
37
+ // 全部预估:0*40=0, 1*40=40, ...
38
+ expect(cache.getOffset(0)).toBe(0);
39
+ expect(cache.getOffset(1)).toBe(40);
40
+ expect(cache.getOffset(3)).toBe(120);
41
+
42
+ // 更新某项后
43
+ cache.update(1, 60);
44
+ expect(cache.getOffset(2)).toBe(40 + 60); // 100
45
+ expect(cache.getOffset(3)).toBe(40 + 60 + 40); // 140
46
+ });
47
+
48
+ it('getTotalHeight 返回所有项高度之和', () => {
49
+ const cache = createHeightCache(5, 40);
50
+ expect(cache.getTotalHeight()).toBe(200);
51
+
52
+ cache.update(0, 50);
53
+ expect(cache.getTotalHeight()).toBe(210);
54
+ });
55
+
56
+ it('findIndex 二分查找定位正确', () => {
57
+ const cache = createHeightCache(100, 40);
58
+
59
+ // scrollTop=0 → index 0
60
+ expect(cache.findIndex(0)).toBe(0);
61
+
62
+ // scrollTop=40 → index 1
63
+ expect(cache.findIndex(40)).toBe(1);
64
+
65
+ // scrollTop=39 → 仍在 index 0 区间内
66
+ expect(cache.findIndex(39)).toBe(0);
67
+
68
+ // scrollTop=80 → index 2
69
+ expect(cache.findIndex(80)).toBe(2);
70
+
71
+ // scrollTop 超过总高度 → 最后一项
72
+ expect(cache.findIndex(99999)).toBe(99);
73
+ });
74
+
75
+ it('findIndex 在实际高度不等时也能正确定位', () => {
76
+ const cache = createHeightCache(5, 40);
77
+ cache.update(0, 100); // [100, 40, 40, 40, 40]
78
+
79
+ // scrollTop=50 → 还在 index 0(0-100)
80
+ expect(cache.findIndex(50)).toBe(0);
81
+
82
+ // scrollTop=100 → index 1(100-140)
83
+ expect(cache.findIndex(100)).toBe(1);
84
+
85
+ // scrollTop=140 → index 2(140-180)
86
+ expect(cache.findIndex(140)).toBe(2);
87
+ });
88
+
89
+ it('reset 重置缓存', () => {
90
+ const cache = createHeightCache(5, 40);
91
+ cache.update(0, 100);
92
+
93
+ cache.reset(3);
94
+ expect(cache.getHeight(0)).toBe(40); // 重置为预估值
95
+ expect(cache.getTotalHeight()).toBe(120); // 3 * 40
96
+ });
97
+ });
@@ -0,0 +1,52 @@
1
+ /**
2
+ * @description 虚拟列表 action 枚举
3
+ * @author 阿怪
4
+ * @date 2026/2/25 13:30
5
+ * @version v1.0.0
6
+ *
7
+ * 江湖的业务千篇一律,复杂的代码好几百行。
8
+ */
9
+
10
+ /** 元素可见性变化的动作类型 */
11
+ export enum ACTION {
12
+ /** 从顶部进入可视区域(开始露出) */
13
+ ENTER_TOP_START,
14
+ /** 从顶部完全进入可视区域 */
15
+ ENTER_TOP_END,
16
+ /** 从底部进入可视区域(开始露出) */
17
+ ENTER_BOTTOM_START,
18
+ /** 从底部完全进入可视区域 */
19
+ ENTER_BOTTOM_END,
20
+ /** 从顶部开始离开可视区域 */
21
+ LEAVE_TOP_START,
22
+ /** 从顶部完全离开可视区域 */
23
+ LEAVE_TOP_END,
24
+ /** 从底部开始离开可视区域 */
25
+ LEAVE_BOTTOM_START,
26
+ /** 从底部完全离开可视区域 */
27
+ LEAVE_BOTTOM_END,
28
+ /** 未知状态 */
29
+ UNKNOWN,
30
+ }
31
+
32
+ /** 元素相对于容器的位置类型 */
33
+ export enum POSITION_TYPE {
34
+ /** 完全在可视区域上方 */
35
+ TOP,
36
+ /** 部分在可视区域上方(上半部分露出) */
37
+ TOP_VISIBLE,
38
+ /** 完全在可视区域内 */
39
+ VISIBLE,
40
+ /** 部分在可视区域下方(下半部分露出) */
41
+ BOTTOM_VISIBLE,
42
+ /** 完全在可视区域下方 */
43
+ BOTTOM,
44
+ }
45
+
46
+ /** 元素信息记录 */
47
+ export type EntryInfo = {
48
+ ratio: number;
49
+ position: POSITION_TYPE;
50
+ realIndex: number;
51
+ translateY: number;
52
+ };
@@ -0,0 +1,89 @@
1
+ /**
2
+ * @description 容器 IntersectionObserver 管理
3
+ * @author 阿怪
4
+ * @date 2026/2/25 13:30
5
+ * @version v2.0.0
6
+ *
7
+ * 江湖的业务千篇一律,复杂的代码好几百行。
8
+ *
9
+ * 管理 IntersectionObserver 的创建、observe/unobserve,配合 ResizeObserver 处理容器尺寸变化
10
+ */
11
+ import { onBeforeUnmount, Ref } from 'vue';
12
+ import { useResizeObserver } from '../common/useResizeObserver';
13
+
14
+ export default function useContainerObserver(options: {
15
+ containerRef: Ref<HTMLElement | null>;
16
+ threshold?: number | number[];
17
+ getTarget: () => ArrayLike<Element>;
18
+ callback: (entries: IntersectionObserverEntry[], observer: IntersectionObserver) => void;
19
+ }) {
20
+ let ob: IntersectionObserver | undefined;
21
+ const observeList: Element[] = [];
22
+
23
+ // 队列:在 observer 创建前缓存操作
24
+ const eventQueue: Array<{ target: ArrayLike<Element> | Element; type: 'observe' | 'unobserve' }> = [];
25
+
26
+ const processTarget = (target: ArrayLike<Element> | Element, type: 'observe' | 'unobserve') => {
27
+ if (!ob) {
28
+ eventQueue.push({ target, type });
29
+ return;
30
+ }
31
+ if ('length' in target) {
32
+ for (let i = 0; i < target.length; i++) {
33
+ if (target[i]) {
34
+ ob[type](target[i]);
35
+ }
36
+ }
37
+ } else {
38
+ ob[type](target);
39
+ }
40
+ };
41
+
42
+ const clearQueue = () => {
43
+ while (eventQueue.length) {
44
+ const { target, type } = eventQueue.shift()!;
45
+ processTarget(target, type);
46
+ }
47
+ };
48
+
49
+ const reObserve = (target: ArrayLike<Element>) => {
50
+ // 先 unobserve 所有已观察的
51
+ processTarget(observeList, 'unobserve');
52
+ observeList.length = 0;
53
+ // 再 observe 新的
54
+ for (let i = 0; i < target.length; i++) {
55
+ observeList.push(target[i]);
56
+ }
57
+ processTarget(target, 'observe');
58
+ };
59
+
60
+ const initOb = () => {
61
+ if (ob) {
62
+ ob.disconnect();
63
+ }
64
+ ob = new IntersectionObserver(options.callback, {
65
+ root: options.containerRef.value,
66
+ threshold: options.threshold ?? [0, 1],
67
+ });
68
+ clearQueue();
69
+ };
70
+
71
+ useResizeObserver(options.containerRef, () => {
72
+ if (options.containerRef.value) {
73
+ if (!ob) {
74
+ initOb();
75
+ }
76
+ const target = options.getTarget();
77
+ reObserve(target);
78
+ }
79
+ });
80
+
81
+ onBeforeUnmount(() => {
82
+ if (ob) {
83
+ ob.disconnect();
84
+ ob = undefined;
85
+ }
86
+ });
87
+
88
+ return { reObserve };
89
+ }