@greypan/web-ui 1.4.2 → 2.0.1

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 (346) hide show
  1. package/README.CN.md +674 -232
  2. package/README.md +683 -237
  3. package/dist/_virtual/{_@oxc-project_runtime@0.138.0 → _@oxc-project_runtime@0.140.0}/helpers/esm/decorate.js +1 -1
  4. package/dist/assets/glass.js +6 -0
  5. package/dist/assets/glass.js.map +1 -0
  6. package/dist/assets/menu-portal.js +6 -0
  7. package/dist/assets/menu-portal.js.map +1 -0
  8. package/dist/assets/overlay-motion.js +6 -0
  9. package/dist/assets/overlay-motion.js.map +1 -0
  10. package/dist/assets/toast-containers.js +6 -0
  11. package/dist/assets/toast-containers.js.map +1 -0
  12. package/dist/components/avatar/index.d.ts +30 -0
  13. package/dist/components/avatar/index.js +112 -0
  14. package/dist/components/avatar/index.js.map +1 -0
  15. package/dist/components/avatar/style.js +6 -0
  16. package/dist/components/avatar/style.js.map +1 -0
  17. package/dist/components/back-top/index.d.ts +8 -7
  18. package/dist/components/back-top/index.js +37 -32
  19. package/dist/components/back-top/index.js.map +1 -1
  20. package/dist/components/back-top/style.js +1 -1
  21. package/dist/components/back-top/style.js.map +1 -1
  22. package/dist/components/badge/index.d.ts +27 -0
  23. package/dist/components/badge/index.js +121 -0
  24. package/dist/components/badge/index.js.map +1 -0
  25. package/dist/components/badge/style.js +6 -0
  26. package/dist/components/badge/style.js.map +1 -0
  27. package/dist/components/button/index.d.ts +16 -3
  28. package/dist/components/button/index.js +56 -17
  29. package/dist/components/button/index.js.map +1 -1
  30. package/dist/components/button/style.js +1 -1
  31. package/dist/components/button/style.js.map +1 -1
  32. package/dist/components/button-group/index.d.ts +16 -0
  33. package/dist/components/button-group/index.js +49 -0
  34. package/dist/components/button-group/index.js.map +1 -0
  35. package/dist/components/button-group/style.js +6 -0
  36. package/dist/components/button-group/style.js.map +1 -0
  37. package/dist/components/checkbox/index.d.ts +39 -0
  38. package/dist/components/checkbox/index.js +111 -0
  39. package/dist/components/checkbox/index.js.map +1 -0
  40. package/dist/components/checkbox/style.js +6 -0
  41. package/dist/components/checkbox/style.js.map +1 -0
  42. package/dist/components/checkbox-group/index.d.ts +35 -0
  43. package/dist/components/checkbox-group/index.js +99 -0
  44. package/dist/components/checkbox-group/index.js.map +1 -0
  45. package/dist/components/checkbox-group/style.js +6 -0
  46. package/dist/components/checkbox-group/style.js.map +1 -0
  47. package/dist/components/context-menu/index.d.ts +84 -0
  48. package/dist/components/context-menu/index.js +294 -0
  49. package/dist/components/context-menu/index.js.map +1 -0
  50. package/dist/components/context-menu/style.js +6 -0
  51. package/dist/components/context-menu/style.js.map +1 -0
  52. package/dist/components/dialog/index.d.ts +41 -0
  53. package/dist/components/dialog/index.js +118 -0
  54. package/dist/components/dialog/index.js.map +1 -0
  55. package/dist/components/dialog/style.js +6 -0
  56. package/dist/components/dialog/style.js.map +1 -0
  57. package/dist/components/drawer/index.d.ts +57 -0
  58. package/dist/components/drawer/index.js +172 -0
  59. package/dist/components/drawer/index.js.map +1 -0
  60. package/dist/components/drawer/style.js +6 -0
  61. package/dist/components/drawer/style.js.map +1 -0
  62. package/dist/components/dropdown/index.d.ts +87 -0
  63. package/dist/components/dropdown/index.js +324 -0
  64. package/dist/components/dropdown/index.js.map +1 -0
  65. package/dist/components/dropdown/style.js +6 -0
  66. package/dist/components/dropdown/style.js.map +1 -0
  67. package/dist/components/dropdown-divider/index.d.ts +11 -0
  68. package/dist/components/dropdown-divider/index.js +18 -0
  69. package/dist/components/dropdown-divider/index.js.map +1 -0
  70. package/dist/components/dropdown-divider/style.js +6 -0
  71. package/dist/components/dropdown-divider/style.js.map +1 -0
  72. package/dist/components/dropdown-header/index.d.ts +11 -0
  73. package/dist/components/dropdown-header/index.js +18 -0
  74. package/dist/components/dropdown-header/index.js.map +1 -0
  75. package/dist/components/dropdown-header/style.js +6 -0
  76. package/dist/components/dropdown-header/style.js.map +1 -0
  77. package/dist/components/dropdown-item/index.d.ts +17 -0
  78. package/dist/components/dropdown-item/index.js +44 -0
  79. package/dist/components/dropdown-item/index.js.map +1 -0
  80. package/dist/components/dropdown-item/style.js +6 -0
  81. package/dist/components/dropdown-item/style.js.map +1 -0
  82. package/dist/components/empty/index.d.ts +23 -0
  83. package/dist/components/empty/index.js +83 -0
  84. package/dist/components/empty/index.js.map +1 -0
  85. package/dist/components/empty/style.js +6 -0
  86. package/dist/components/empty/style.js.map +1 -0
  87. package/dist/components/icon/index.d.ts +16 -0
  88. package/dist/components/icon/index.js +45 -0
  89. package/dist/components/icon/index.js.map +1 -0
  90. package/dist/components/icon/style.js +6 -0
  91. package/dist/components/icon/style.js.map +1 -0
  92. package/dist/components/index.d.ts +34 -0
  93. package/dist/components/index.js +37 -0
  94. package/dist/components/input/index.d.ts +47 -0
  95. package/dist/components/input/index.js +140 -0
  96. package/dist/components/input/index.js.map +1 -0
  97. package/dist/components/input/style.js +6 -0
  98. package/dist/components/input/style.js.map +1 -0
  99. package/dist/components/input-number/index.d.ts +52 -0
  100. package/dist/components/input-number/index.js +178 -0
  101. package/dist/components/input-number/index.js.map +1 -0
  102. package/dist/components/input-number/style.js +6 -0
  103. package/dist/components/input-number/style.js.map +1 -0
  104. package/dist/components/layout/index.d.ts +11 -1
  105. package/dist/components/layout/index.js +55 -21
  106. package/dist/components/layout/index.js.map +1 -1
  107. package/dist/components/layout/style.js +1 -1
  108. package/dist/components/layout/style.js.map +1 -1
  109. package/dist/components/option/index.d.ts +33 -0
  110. package/dist/components/option/index.js +78 -0
  111. package/dist/components/option/index.js.map +1 -0
  112. package/dist/components/option/style.js +6 -0
  113. package/dist/components/option/style.js.map +1 -0
  114. package/dist/components/popover/index.d.ts +69 -0
  115. package/dist/components/popover/index.js +231 -0
  116. package/dist/components/popover/index.js.map +1 -0
  117. package/dist/components/popover/style.js +6 -0
  118. package/dist/components/popover/style.js.map +1 -0
  119. package/dist/components/radio/index.d.ts +39 -0
  120. package/dist/components/radio/index.js +105 -0
  121. package/dist/components/radio/index.js.map +1 -0
  122. package/dist/components/radio/style.js +6 -0
  123. package/dist/components/radio/style.js.map +1 -0
  124. package/dist/components/radio-group/index.d.ts +35 -0
  125. package/dist/components/radio-group/index.js +87 -0
  126. package/dist/components/radio-group/index.js.map +1 -0
  127. package/dist/components/radio-group/style.js +6 -0
  128. package/dist/components/radio-group/style.js.map +1 -0
  129. package/dist/components/segmented/index.d.ts +33 -0
  130. package/dist/components/segmented/index.js +95 -0
  131. package/dist/components/segmented/index.js.map +1 -0
  132. package/dist/components/segmented/style.js +6 -0
  133. package/dist/components/segmented/style.js.map +1 -0
  134. package/dist/components/segmented-trigger/index.d.ts +18 -0
  135. package/dist/components/segmented-trigger/index.js +52 -0
  136. package/dist/components/segmented-trigger/index.js.map +1 -0
  137. package/dist/components/segmented-trigger/style.js +6 -0
  138. package/dist/components/segmented-trigger/style.js.map +1 -0
  139. package/dist/components/select/index.d.ts +80 -0
  140. package/dist/components/select/index.js +291 -0
  141. package/dist/components/select/index.js.map +1 -0
  142. package/dist/components/select/style.js +6 -0
  143. package/dist/components/select/style.js.map +1 -0
  144. package/dist/components/slider/index.d.ts +61 -0
  145. package/dist/components/slider/index.js +219 -0
  146. package/dist/components/slider/index.js.map +1 -0
  147. package/dist/components/slider/style.js +6 -0
  148. package/dist/components/slider/style.js.map +1 -0
  149. package/dist/components/spinner/index.d.ts +32 -0
  150. package/dist/components/spinner/index.js +52 -0
  151. package/dist/components/spinner/index.js.map +1 -0
  152. package/dist/components/spinner/style.js +6 -0
  153. package/dist/components/spinner/style.js.map +1 -0
  154. package/dist/components/svg-draw-lines/index.d.ts +30 -9
  155. package/dist/components/svg-draw-lines/index.js +87 -62
  156. package/dist/components/svg-draw-lines/index.js.map +1 -1
  157. package/dist/components/svg-draw-lines/style.js +1 -1
  158. package/dist/components/svg-draw-lines/style.js.map +1 -1
  159. package/dist/components/switch/index.d.ts +37 -0
  160. package/dist/components/switch/index.js +117 -0
  161. package/dist/components/switch/index.js.map +1 -0
  162. package/dist/components/switch/style.js +6 -0
  163. package/dist/components/switch/style.js.map +1 -0
  164. package/dist/components/textarea/index.d.ts +65 -0
  165. package/dist/components/textarea/index.js +204 -0
  166. package/dist/components/textarea/index.js.map +1 -0
  167. package/dist/components/textarea/style.js +6 -0
  168. package/dist/components/textarea/style.js.map +1 -0
  169. package/dist/components/theme/index.d.ts +29 -0
  170. package/dist/components/theme/index.js +78 -0
  171. package/dist/components/theme/index.js.map +1 -0
  172. package/dist/components/theme/style.js +6 -0
  173. package/dist/components/theme/style.js.map +1 -0
  174. package/dist/components/toast/index.d.ts +3 -0
  175. package/dist/components/toast/index.js +3 -0
  176. package/dist/components/toast/manager.d.ts +15 -0
  177. package/dist/components/toast/manager.js +98 -0
  178. package/dist/components/toast/manager.js.map +1 -0
  179. package/dist/components/toast/style.js +6 -0
  180. package/dist/components/toast/style.js.map +1 -0
  181. package/dist/components/toast/toast.d.ts +42 -0
  182. package/dist/components/toast/toast.js +122 -0
  183. package/dist/components/toast/toast.js.map +1 -0
  184. package/dist/components/toast/types.d.ts +23 -0
  185. package/dist/components/tooltip/index.d.ts +59 -0
  186. package/dist/components/tooltip/index.js +190 -0
  187. package/dist/components/tooltip/index.js.map +1 -0
  188. package/dist/components/tooltip/style.js +6 -0
  189. package/dist/components/tooltip/style.js.map +1 -0
  190. package/dist/icons/generated/heroicons-check-16-solid.d.ts +6 -0
  191. package/dist/icons/generated/heroicons-check-16-solid.js +10 -0
  192. package/dist/icons/generated/heroicons-check-16-solid.js.map +1 -0
  193. package/dist/icons/generated/heroicons-x-mark-16-solid.d.ts +6 -0
  194. package/dist/icons/generated/heroicons-x-mark-16-solid.js +10 -0
  195. package/dist/icons/generated/heroicons-x-mark-16-solid.js.map +1 -0
  196. package/dist/icons/generated/jam-close-circle-f.d.ts +8 -0
  197. package/dist/icons/generated/jam-close-circle-f.js +12 -0
  198. package/dist/icons/generated/jam-close-circle-f.js.map +1 -0
  199. package/dist/icons/generated/jam-volume.d.ts +8 -0
  200. package/dist/icons/generated/jam-watch-f.d.ts +8 -0
  201. package/dist/icons/generated/lucide-arrow-down-to-line.d.ts +6 -0
  202. package/dist/icons/generated/lucide-arrow-down-to-line.js +10 -0
  203. package/dist/icons/generated/lucide-arrow-down-to-line.js.map +1 -0
  204. package/dist/icons/generated/lucide-arrow-up-to-line.d.ts +6 -0
  205. package/dist/icons/generated/lucide-arrow-up-to-line.js +10 -0
  206. package/dist/icons/generated/lucide-arrow-up-to-line.js.map +1 -0
  207. package/dist/icons/generated/lucide-bell.d.ts +6 -0
  208. package/dist/icons/generated/lucide-bell.js +10 -0
  209. package/dist/icons/generated/lucide-bell.js.map +1 -0
  210. package/dist/icons/generated/lucide-check.d.ts +6 -0
  211. package/dist/icons/generated/lucide-check.js +10 -0
  212. package/dist/icons/generated/lucide-check.js.map +1 -0
  213. package/dist/icons/generated/lucide-chevron-down.d.ts +6 -0
  214. package/dist/icons/generated/lucide-chevron-down.js +10 -0
  215. package/dist/icons/generated/lucide-chevron-down.js.map +1 -0
  216. package/dist/icons/generated/lucide-chevron-left.d.ts +6 -0
  217. package/dist/icons/generated/lucide-chevron-left.js +10 -0
  218. package/dist/icons/generated/lucide-chevron-left.js.map +1 -0
  219. package/dist/icons/generated/lucide-chevron-right.d.ts +6 -0
  220. package/dist/icons/generated/lucide-chevron-right.js +10 -0
  221. package/dist/icons/generated/lucide-chevron-right.js.map +1 -0
  222. package/dist/icons/generated/lucide-chevron-up.d.ts +6 -0
  223. package/dist/icons/generated/lucide-chevron-up.js +10 -0
  224. package/dist/icons/generated/lucide-chevron-up.js.map +1 -0
  225. package/dist/icons/generated/lucide-circle-alert.d.ts +6 -0
  226. package/dist/icons/generated/lucide-circle-alert.js +10 -0
  227. package/dist/icons/generated/lucide-circle-alert.js.map +1 -0
  228. package/dist/icons/generated/lucide-clipboard-paste.d.ts +6 -0
  229. package/dist/icons/generated/lucide-clipboard-paste.js +10 -0
  230. package/dist/icons/generated/lucide-clipboard-paste.js.map +1 -0
  231. package/dist/icons/generated/lucide-copy.d.ts +6 -0
  232. package/dist/icons/generated/lucide-copy.js +10 -0
  233. package/dist/icons/generated/lucide-copy.js.map +1 -0
  234. package/dist/icons/generated/lucide-download.d.ts +6 -0
  235. package/dist/icons/generated/lucide-download.js +10 -0
  236. package/dist/icons/generated/lucide-download.js.map +1 -0
  237. package/dist/icons/generated/lucide-file.d.ts +6 -0
  238. package/dist/icons/generated/lucide-file.js +10 -0
  239. package/dist/icons/generated/lucide-file.js.map +1 -0
  240. package/dist/icons/generated/lucide-folder.d.ts +6 -0
  241. package/dist/icons/generated/lucide-folder.js +10 -0
  242. package/dist/icons/generated/lucide-folder.js.map +1 -0
  243. package/dist/icons/generated/lucide-globe.d.ts +6 -0
  244. package/dist/icons/generated/lucide-globe.js +10 -0
  245. package/dist/icons/generated/lucide-globe.js.map +1 -0
  246. package/dist/icons/generated/lucide-heart.d.ts +6 -0
  247. package/dist/icons/generated/lucide-heart.js +10 -0
  248. package/dist/icons/generated/lucide-heart.js.map +1 -0
  249. package/dist/icons/generated/lucide-image.d.ts +6 -0
  250. package/dist/icons/generated/lucide-image.js +10 -0
  251. package/dist/icons/generated/lucide-image.js.map +1 -0
  252. package/dist/icons/generated/lucide-inbox.d.ts +6 -0
  253. package/dist/icons/generated/lucide-inbox.js +10 -0
  254. package/dist/icons/generated/lucide-inbox.js.map +1 -0
  255. package/dist/icons/generated/lucide-info.d.ts +6 -0
  256. package/dist/icons/generated/lucide-info.js +10 -0
  257. package/dist/icons/generated/lucide-info.js.map +1 -0
  258. package/dist/icons/generated/lucide-loader-circle.d.ts +6 -0
  259. package/dist/icons/generated/lucide-loader-circle.js +10 -0
  260. package/dist/icons/generated/lucide-loader-circle.js.map +1 -0
  261. package/dist/icons/generated/lucide-mail.d.ts +6 -0
  262. package/dist/icons/generated/lucide-mail.js +10 -0
  263. package/dist/icons/generated/lucide-mail.js.map +1 -0
  264. package/dist/icons/generated/lucide-minus.d.ts +6 -0
  265. package/dist/icons/generated/lucide-minus.js +10 -0
  266. package/dist/icons/generated/lucide-minus.js.map +1 -0
  267. package/dist/icons/generated/lucide-plus.d.ts +6 -0
  268. package/dist/icons/generated/lucide-plus.js +10 -0
  269. package/dist/icons/generated/lucide-plus.js.map +1 -0
  270. package/dist/icons/generated/lucide-printer.d.ts +6 -0
  271. package/dist/icons/generated/lucide-printer.js +10 -0
  272. package/dist/icons/generated/lucide-printer.js.map +1 -0
  273. package/dist/icons/generated/lucide-redo-2.d.ts +6 -0
  274. package/dist/icons/generated/lucide-redo-2.js +10 -0
  275. package/dist/icons/generated/lucide-redo-2.js.map +1 -0
  276. package/dist/icons/generated/lucide-scissors.d.ts +6 -0
  277. package/dist/icons/generated/lucide-scissors.js +10 -0
  278. package/dist/icons/generated/lucide-scissors.js.map +1 -0
  279. package/dist/icons/generated/lucide-search.d.ts +6 -0
  280. package/dist/icons/generated/lucide-search.js +10 -0
  281. package/dist/icons/generated/lucide-search.js.map +1 -0
  282. package/dist/icons/generated/lucide-settings.d.ts +6 -0
  283. package/dist/icons/generated/lucide-settings.js +10 -0
  284. package/dist/icons/generated/lucide-settings.js.map +1 -0
  285. package/dist/icons/generated/lucide-star.d.ts +6 -0
  286. package/dist/icons/generated/lucide-star.js +10 -0
  287. package/dist/icons/generated/lucide-star.js.map +1 -0
  288. package/dist/icons/generated/lucide-trash-2.d.ts +6 -0
  289. package/dist/icons/generated/lucide-trash-2.js +10 -0
  290. package/dist/icons/generated/lucide-trash-2.js.map +1 -0
  291. package/dist/icons/generated/lucide-triangle-alert.d.ts +6 -0
  292. package/dist/icons/generated/lucide-triangle-alert.js +10 -0
  293. package/dist/icons/generated/lucide-triangle-alert.js.map +1 -0
  294. package/dist/icons/generated/lucide-undo-2.d.ts +6 -0
  295. package/dist/icons/generated/lucide-undo-2.js +10 -0
  296. package/dist/icons/generated/lucide-undo-2.js.map +1 -0
  297. package/dist/icons/generated/lucide-upload.d.ts +6 -0
  298. package/dist/icons/generated/lucide-upload.js +10 -0
  299. package/dist/icons/generated/lucide-upload.js.map +1 -0
  300. package/dist/icons/generated/lucide-user.d.ts +6 -0
  301. package/dist/icons/generated/lucide-user.js +10 -0
  302. package/dist/icons/generated/lucide-user.js.map +1 -0
  303. package/dist/icons/generated/lucide-x.d.ts +6 -0
  304. package/dist/icons/generated/lucide-x.js +10 -0
  305. package/dist/icons/generated/lucide-x.js.map +1 -0
  306. package/dist/icons/generated/ooui-check.d.ts +6 -0
  307. package/dist/icons/generated/radix-icons-check.d.ts +6 -0
  308. package/dist/icons/generated/radix-icons-panel-left-minimized.d.ts +6 -0
  309. package/dist/icons/generated/radix-icons-panel-left-minimized.js +10 -0
  310. package/dist/icons/generated/radix-icons-panel-left-minimized.js.map +1 -0
  311. package/dist/icons/generated/si-check-alt-fill.d.ts +6 -0
  312. package/dist/icons/index.d.ts +39 -0
  313. package/dist/icons/index.js +40 -0
  314. package/dist/node_modules/.pnpm/@floating-ui_core@1.8.0/node_modules/@floating-ui/core/dist/floating-ui.core.js +248 -0
  315. package/dist/node_modules/.pnpm/@floating-ui_core@1.8.0/node_modules/@floating-ui/core/dist/floating-ui.core.js.map +1 -0
  316. package/dist/node_modules/.pnpm/@floating-ui_dom@1.8.0/node_modules/@floating-ui/dom/dist/floating-ui.dom.js +324 -0
  317. package/dist/node_modules/.pnpm/@floating-ui_dom@1.8.0/node_modules/@floating-ui/dom/dist/floating-ui.dom.js.map +1 -0
  318. package/dist/node_modules/.pnpm/@floating-ui_utils@0.2.12/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.js +99 -0
  319. package/dist/node_modules/.pnpm/@floating-ui_utils@0.2.12/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.js.map +1 -0
  320. package/dist/node_modules/.pnpm/@floating-ui_utils@0.2.12/node_modules/@floating-ui/utils/dist/floating-ui.utils.js +102 -0
  321. package/dist/node_modules/.pnpm/@floating-ui_utils@0.2.12/node_modules/@floating-ui/utils/dist/floating-ui.utils.js.map +1 -0
  322. package/dist/shared/menu-portal/menu-portal.js +11 -0
  323. package/dist/shared/menu-portal/menu-portal.js.map +1 -0
  324. package/dist/shared/normalize/index.js +11 -0
  325. package/dist/shared/normalize/index.js.map +1 -0
  326. package/dist/shared/overlay/overlay.js +68 -0
  327. package/dist/shared/overlay/overlay.js.map +1 -0
  328. package/dist/shared/overlay/portal.js +29 -0
  329. package/dist/shared/overlay/portal.js.map +1 -0
  330. package/dist/shared/overlay/presence.js +34 -0
  331. package/dist/shared/overlay/presence.js.map +1 -0
  332. package/dist/shared/property-converters/boolean-with-false-string.js +9 -0
  333. package/dist/shared/property-converters/boolean-with-false-string.js.map +1 -0
  334. package/dist/shared/scroll-lock/scroll-lock.js +12 -0
  335. package/dist/shared/scroll-lock/scroll-lock.js.map +1 -0
  336. package/dist/shared/theme/overlay-root.js +28 -0
  337. package/dist/shared/theme/overlay-root.js.map +1 -0
  338. package/dist/shared/theme/theme-scope.js +27 -0
  339. package/dist/shared/theme/theme-scope.js.map +1 -0
  340. package/dist/types/iconify.d.ts +1 -0
  341. package/dist/types/react.d.ts +35 -9
  342. package/dist/types/utils.d.ts +14 -0
  343. package/dist/types/vue.d.ts +47 -7
  344. package/package.json +29 -13
  345. package/dist/index.d.ts +0 -4
  346. package/dist/index.js +0 -5
package/README.CN.md CHANGED
@@ -4,32 +4,13 @@
4
4
 
5
5
  [English](./README.md) | 简体中文
6
6
 
7
- ## 功能
8
-
9
- - **Button**:带 full/primary/text/icon 变体的样式化按钮
10
- - **BackTop**:可配置阈值和平滑滚动的回到顶部按钮
11
- - **Layout**:带 header/sidebar/tabbar 插槽的页面布局
12
- - **SVG Draw Lines**:带缓动控制的 SVG 线条绘制动画
13
- - **框架兼容**:支持 React、Vue 和原生 HTML
14
- - **类型安全**:为 React 和 Vue 提供完整的 TypeScript 类型
15
-
16
7
  ## 安装
17
8
 
18
9
  ```bash
19
- # npm
20
10
  npm install @greypan/web-ui
21
-
22
- # pnpm
23
- pnpm add @greypan/web-ui
24
-
25
- # yarn
26
- yarn add @greypan/web-ui
27
-
28
- # bun
29
- bun add @greypan/web-ui
30
11
  ```
31
12
 
32
- > 需要 `lit` 作为依赖。
13
+ 需要 `lit` 作为依赖。
33
14
 
34
15
  ## 快速开始
35
16
 
@@ -39,133 +20,45 @@ import '@greypan/web-ui'
39
20
  ```
40
21
 
41
22
  ```html
42
- <web-ui-button primary>点击我</web-ui-button>
43
- <web-ui-button text>取消</web-ui-button>
44
- <web-ui-button icon>
45
- <iconify-icon icon="lucide:plus"></iconify-icon>
46
- </web-ui-button>
23
+ <web-ui-button variant="primary">点击我</web-ui-button> <web-ui-icon .icon="${lucidePlus}"></web-ui-icon>
47
24
  ```
48
25
 
49
- ## React 中使用
50
-
51
- > 需要 `@types/react >= 16` 作为可选 peer 依赖,用于类型支持。
26
+ ## 框架集成
52
27
 
53
- ### 初始化
28
+ ### React
54
29
 
55
- **方式 A — auto-import(Vite,推荐)**
56
-
57
- 使用 `unplugin-web-components` 自动注册自定义组件:
30
+ 需要 `@types/react >= 16` 作为可选 peer 依赖。
58
31
 
59
32
  ```ts
60
33
  // vite.config.ts
61
34
  import unpluginWebComponents from '@greypan/unplugin-web-components/vite'
62
35
 
63
36
  export default {
64
- plugins: [
65
- unpluginWebComponents({
66
- tagPrefix: 'web-ui',
67
- packageName: '@greypan/web-ui',
68
- sideEffects: true
69
- })
70
- ]
37
+ plugins: [unpluginWebComponents({ tagPrefix: 'web-ui', packageName: '@greypan/web-ui', sideEffects: true })]
71
38
  }
72
- ```
73
-
74
- **方式 B — 手动导入**
75
-
76
- 在应用入口全量导入,注册所有组件(side-effect 注册):
77
39
 
78
- ```tsx
79
- // main.tsx
80
- import '@greypan/web-ui'
81
- ```
82
-
83
- 或按需导入,只注册需要的组件:
84
-
85
- ```tsx
86
- // main.tsx 或任意组件文件
87
- import '@greypan/web-ui/components/button'
88
- import '@greypan/web-ui/components/back-top'
89
- ```
90
-
91
- 添加类型声明以让 TypeScript 识别自定义元素 JSX 属性:
92
-
93
- ```tsx
94
- // env.d.ts 或任意类型声明文件
40
+ // env.d.ts
95
41
  import '@greypan/web-ui/types/react'
96
42
  ```
97
43
 
98
- ### 应用布局
99
-
100
- 用 `<web-ui-layout>` 包裹路由,配合 `<web-ui-back-top>` 实现全局回到顶部:
101
-
102
44
  ```tsx
103
- // root.tsx
104
- import { Outlet } from '@tanstack/react-router'
45
+ import '@greypan/web-ui'
105
46
 
106
- export function Root() {
47
+ function App() {
107
48
  return (
108
49
  <>
109
- <web-ui-layout>
110
- <h1>My App</h1>
111
-
112
- {/* 按钮变体 */}
113
- <div className="flex gap-2">
114
- <web-ui-button>默认</web-ui-button>
115
- <web-ui-button primary>Primary</web-ui-button>
116
- <web-ui-button text>Text</web-ui-button>
117
- <web-ui-button full>Full Width</web-ui-button>
118
- </div>
119
-
120
- {/* 具名插槽 */}
121
- <web-ui-button>
122
- <span slot="prefix">前缀</span>
123
- 带前后缀插槽的按钮
124
- <span slot="suffix">后缀</span>
125
- </web-ui-button>
126
-
127
- {/* 路由出口 */}
128
- <Outlet />
129
- </web-ui-layout>
130
-
131
- <web-ui-back-top
132
- threshold={300}
133
- onvisible-change={e => {
134
- console.log('visible: ', e.detail.visible)
135
- }}
136
- />
50
+ <web-ui-button variant="primary" onClick={() => alert('点击')}>
51
+ 按钮
52
+ </web-ui-button>
53
+ <web-ui-input onInput={e => console.log((e.target as any).value)} />
137
54
  </>
138
55
  )
139
56
  }
140
57
  ```
141
58
 
142
- > `onvisible-change` 在 React 19+ 中可用(props 转发到 custom element)。React 18 请改用 `ref` + `addEventListener`。
143
-
144
- ### SVG 线条动画
145
-
146
- 包裹内联 `<svg>` 来实现线条绘制动画:
147
-
148
- ```tsx
149
- function SvgDemo() {
150
- return (
151
- <web-ui-svg-draw-lines>
152
- <svg viewBox="0 0 24 24" width="100" height="100" fill="none" stroke="currentColor" stroke-width="2">
153
- <path d="M4 4v16M8 6h12M8 12h6m-6 6h10" />
154
- </svg>
155
- </web-ui-svg-draw-lines>
156
- )
157
- }
158
- ```
159
-
160
- ## Vue 中使用
161
-
162
- > 需要 `vue >= 3` 作为可选 peer 依赖。
163
-
164
- ### 初始化
165
-
166
- **方式 A — auto-import(Vite,推荐)**
59
+ ### Vue
167
60
 
168
- 使用 `unplugin-web-components` 自动注册:
61
+ 需要 `vue >= 3` 作为可选 peer 依赖。
169
62
 
170
63
  ```ts
171
64
  // vite.config.ts
@@ -175,155 +68,704 @@ import unpluginWebComponents from '@greypan/unplugin-web-components/vite'
175
68
  export default {
176
69
  plugins: [
177
70
  vue({
178
- template: {
179
- compilerOptions: {
180
- // 告诉 Vue 模板编译器将 web-ui-* 标签视为自定义元素
181
- isCustomElement: tag => tag.startsWith('web-ui-') || tag.startsWith('WebUi')
182
- }
183
- }
71
+ template: { compilerOptions: { isCustomElement: tag => tag.startsWith('web-ui-') } }
184
72
  }),
185
- unpluginWebComponents({
186
- tagPrefix: 'web-ui',
187
- packageName: '@greypan/web-ui',
188
- sideEffects: true
189
- })
73
+ unpluginWebComponents({ tagPrefix: 'web-ui', packageName: '@greypan/web-ui', sideEffects: true })
190
74
  ]
191
75
  }
76
+
77
+ // env.d.ts
78
+ import '@greypan/web-ui/types/vue'
192
79
  ```
193
80
 
194
- **方式 B — 手动导入**
81
+ ```vue
82
+ <template>
83
+ <web-ui-button variant="primary" @click="handleClick">按钮</web-ui-button>
84
+ <web-ui-input v-model="value" />
85
+ </template>
86
+ ```
195
87
 
196
- ```ts
197
- // main.ts
198
- import { createApp } from 'vue'
199
- import '@greypan/web-ui' // 全量导入
200
- // import '@greypan/web-ui/components/button'
201
- import App from './App.vue'
88
+ ## 所有组件
89
+
90
+ | 分类 | 组件 |
91
+ | --------------- | --------------------------------------------------------- |
92
+ | **表单控件** | [`<web-ui-input>`](#web-ui-input) |
93
+ | | [`<web-ui-textarea>`](#web-ui-textarea) |
94
+ | | [`<web-ui-input-number>`](#web-ui-input-number) |
95
+ | | [`<web-ui-select>`](#web-ui-select) |
96
+ | | [`<web-ui-slider>`](#web-ui-slider) |
97
+ | | [`<web-ui-checkbox>`](#web-ui-checkbox) |
98
+ | | [`<web-ui-radio>`](#web-ui-radio) |
99
+ | | [`<web-ui-switch>`](#web-ui-switch) |
100
+ | | [`<web-ui-segmented>`](#web-ui-segmented) |
101
+ | | [`<web-ui-checkbox-group>`](#web-ui-checkbox-group) |
102
+ | | [`<web-ui-radio-group>`](#web-ui-radio-group) |
103
+ | **按钮** | [`<web-ui-button>`](#web-ui-button) |
104
+ | | [`<web-ui-button-group>`](#web-ui-button-group) |
105
+ | **浮层 / 模态** | [`<web-ui-dialog>`](#web-ui-dialog) |
106
+ | | [`<web-ui-drawer>`](#web-ui-drawer) |
107
+ | **浮动** | [`<web-ui-popover>`](#web-ui-popover) |
108
+ | | [`<web-ui-tooltip>`](#web-ui-tooltip) |
109
+ | | [`<web-ui-context-menu>`](#web-ui-context-menu) |
110
+ | **菜单** | [`<web-ui-dropdown>`](#web-ui-dropdown) |
111
+ | | [`<web-ui-dropdown-item>`](#web-ui-dropdown-item) |
112
+ | | [`<web-ui-dropdown-divider>`](#web-ui-dropdown-divider) |
113
+ | | [`<web-ui-dropdown-header>`](#web-ui-dropdown-header) |
114
+ | **数据展示** | [`<web-ui-avatar>`](#web-ui-avatar) |
115
+ | | [`<web-ui-badge>`](#web-ui-badge) |
116
+ | | [`<web-ui-empty>`](#web-ui-empty) |
117
+ | | [`<web-ui-icon>`](#web-ui-icon) |
118
+ | | [`<web-ui-spinner>`](#web-ui-spinner) |
119
+ | **布局与工具** | [`<web-ui-layout>`](#web-ui-layout) |
120
+ | | [`<web-ui-back-top>`](#web-ui-back-top) |
121
+ | | [`<web-ui-svg-draw-lines>`](#web-ui-svg-draw-lines) |
122
+ | | [`<web-ui-theme>`](#web-ui-theme) |
123
+ | **通知** | [`<web-ui-toast>`](#web-ui-toast) |
124
+ | **子项** | [`<web-ui-option>`](#web-ui-option) |
125
+ | | [`<web-ui-segmented-trigger>`](#web-ui-segmented-trigger) |
126
+
127
+ ## API 参考
128
+
129
+ ### 表单控件
130
+
131
+ 表单控件声明 `static formAssociated = true`,集成原生 `<form>`:通过 `FormData` 提交值,实现 `formResetCallback()` / `formDisabledCallback()`。
132
+
133
+ #### `<web-ui-input>`
134
+
135
+ 文本输入框,支持清除按钮和前后缀插槽。
136
+
137
+ | 属性 | 类型 | 默认值 | 说明 |
138
+ | ------------- | --------- | -------- | --------------- |
139
+ | `value` | `string` | `''` | 输入值 |
140
+ | `type` | `string` | `'text'` | HTML input 类型 |
141
+ | `placeholder` | `string` | `''` | 占位文本 |
142
+ | `name` | `string` | `''` | 表单字段名 |
143
+ | `disabled` | `boolean` | `false` | 禁用状态 |
144
+ | `required` | `boolean` | `false` | 必填校验 |
145
+ | `clearable` | `boolean` | `false` | 显示清除按钮 |
146
+ | `full` | `boolean` | `false` | 全宽 |
147
+ | `borderless` | `boolean` | `false` | 无边框 |
148
+
149
+ **事件:** `input`, `change`, `focus`, `blur`
150
+
151
+ **插槽:** `prefix`, `default`, `suffix`
152
+
153
+ #### `<web-ui-textarea>`
154
+
155
+ 多行文本输入框,支持自动调整高度。
156
+
157
+ | 属性 | 类型 | 默认值 | 说明 |
158
+ | ----------------- | --------- | ------- | -------------- |
159
+ | `value` | `string` | `''` | 输入值 |
160
+ | `placeholder` | `string` | `''` | 占位文本 |
161
+ | `rows` | `number` | `3` | 显示行数 |
162
+ | `name` | `string` | `''` | 表单字段名 |
163
+ | `disabled` | `boolean` | `false` | 禁用状态 |
164
+ | `readonly` | `boolean` | `false` | 只读状态 |
165
+ | `required` | `boolean` | `false` | 必填校验 |
166
+ | `clearable` | `boolean` | `false` | 显示清除按钮 |
167
+ | `full` | `boolean` | `false` | 全宽 |
168
+ | `borderless` | `boolean` | `false` | 无边框 |
169
+ | `autosize` | `boolean` | `false` | 自动调整高度 |
170
+ | `minlength` | `number` | — | 最小长度校验 |
171
+ | `maxlength` | `number` | — | 最大长度校验 |
172
+ | `aria-label` | `string` | — | 无障碍标签 |
173
+ | `aria-labelledby` | `string` | — | 无障碍标签引用 |
174
+
175
+ **事件:** `input`, `change`, `focus`, `blur`
176
+
177
+ **方法:** `focus()`, `blur()`, `select()`
178
+
179
+ **插槽:** `prefix`, `suffix`
180
+
181
+ #### `<web-ui-input-number>`
182
+
183
+ 数字输入框,支持步进按钮和键盘操作。
184
+
185
+ | 属性 | 类型 | 默认值 | 说明 |
186
+ | ------------- | --------- | ---------- | ---------- |
187
+ | `value` | `number` | `0` | 当前值 |
188
+ | `min` | `number` | `0` | 最小值 |
189
+ | `max` | `number` | `Infinity` | 最大值 |
190
+ | `step` | `number` | `1` | 步进值 |
191
+ | `precision` | `number` | `0` | 小数精度 |
192
+ | `placeholder` | `string` | `''` | 占位文本 |
193
+ | `name` | `string` | `''` | 表单字段名 |
194
+ | `disabled` | `boolean` | `false` | 禁用状态 |
195
+ | `required` | `boolean` | `false` | 必填校验 |
196
+
197
+ **事件:** `input`, `change`
202
198
 
203
- createApp(App).mount('#app')
204
- ```
199
+ ArrowUp/ArrowDown 键增减数值。
205
200
 
206
- 同时配置 Vue 编译器以识别自定义元素:
201
+ #### `<web-ui-select>`
207
202
 
208
- ```ts
209
- // vite.config.ts
210
- vue({
211
- template: {
212
- compilerOptions: {
213
- isCustomElement: tag => tag.startsWith('web-ui-') || tag.startsWith('WebUi')
214
- }
215
- }
216
- })
217
- ```
203
+ 选择器下拉框,支持键盘导航和 Portal。
218
204
 
219
- Vue 模板中的类型增强:
205
+ | 属性 | 类型 | 默认值 | 说明 |
206
+ | ------------------ | ---------------------------------- | ------- | -------------------- |
207
+ | `value` | `string` | `''` | 选中值 |
208
+ | `placeholder` | `string` | `''` | 占位文本 |
209
+ | `name` | `string` | `''` | 表单字段名 |
210
+ | `disabled` | `boolean` | `false` | 禁用状态 |
211
+ | `required` | `boolean` | `false` | 必填校验 |
212
+ | `portal` | `boolean` | `false` | 在主题浮层容器中渲染 |
213
+ | `lock-scroll` | `boolean` | `true` | 打开时锁定页面滚动 |
214
+ | `overlayContainer` | `HTMLElement \| () => HTMLElement` | — | 显式 Portal 容器 |
220
215
 
221
- ```ts
222
- // env.d.ts 或任意类型声明文件
223
- import '@greypan/web-ui/types/vue'
224
- ```
216
+ **事件:** `input`, `change`, `open-change` (`CustomEvent<{ open: boolean }>`)
225
217
 
226
- ### 应用布局
218
+ **插槽:** `default`(投影 `<web-ui-option>` 元素)、`trigger`(自定义触发区域内容,替换默认 label 和箭头)
227
219
 
228
- 用 `<web-ui-layout>` 包裹应用,使用按钮的各种变体:
220
+ 子 `<web-ui-option>` 通过 `option-register` / `option-unregister` 注册。支持 ArrowDown/ArrowUp/Enter/Escape 键盘导航。
229
221
 
230
- ```vue
231
- <template>
232
- <web-ui-layout>
233
- <h1>My App</h1>
234
-
235
- <div class="flex gap-2">
236
- <web-ui-button>默认</web-ui-button>
237
- <web-ui-button primary>Primary</web-ui-button>
238
- <web-ui-button text>Text</web-ui-button>
239
- <web-ui-button full>Full Width</web-ui-button>
240
- </div>
241
-
242
- <web-ui-button>
243
- <span slot="prefix">前缀</span>
244
- 带前后缀插槽的按钮
245
- <span slot="suffix">后缀</span>
246
- </web-ui-button>
247
-
248
- <RouterView />
249
- </web-ui-layout>
250
-
251
- <web-ui-back-top :threshold="300" @visible-change="onVisibleChange" />
252
- </template>
222
+ #### `<web-ui-slider>`
253
223
 
254
- <script setup lang="ts">
255
- function onVisibleChange(e: CustomEvent<{ visible: boolean }>) {
256
- console.log('visible: ', e.detail.visible)
257
- }
258
- </script>
224
+ 范围滑块,支持刻度标记和垂直方向。
225
+
226
+ | 属性 | 类型 | 默认值 | 说明 |
227
+ | ---------- | --------- | ------- | ------------ |
228
+ | `value` | `number` | `0` | 当前值 |
229
+ | `min` | `number` | `0` | 最小值 |
230
+ | `max` | `number` | `100` | 最大值 |
231
+ | `step` | `number` | `1` | 步进值 |
232
+ | `name` | `string` | `''` | 表单字段名 |
233
+ | `disabled` | `boolean` | `false` | 禁用状态 |
234
+ | `required` | `boolean` | `false` | 必填校验 |
235
+ | `marks` | `boolean` | `false` | 显示刻度标记 |
236
+ | `vertical` | `boolean` | `false` | 垂直方向 |
237
+
238
+ **事件:** `input`(拖拽中)、`change`(松开或键盘确认)
239
+
240
+ **方法:** `focus()`, `blur()`
241
+
242
+ 支持 ArrowLeft/Right/Up/Down、Home/End、PageUp/PageDown 键盘导航。使用 pointer capture 处理鼠标、触控笔和触摸交互。
243
+
244
+ #### `<web-ui-checkbox>`
245
+
246
+ 单个复选框。
247
+
248
+ | 属性 | 类型 | 默认值 | 说明 |
249
+ | ---------- | --------- | ------- | ---------- |
250
+ | `checked` | `boolean` | `false` | 选中状态 |
251
+ | `value` | `string` | `''` | 表单提交值 |
252
+ | `name` | `string` | `''` | 表单字段名 |
253
+ | `disabled` | `boolean` | `false` | 禁用状态 |
254
+ | `required` | `boolean` | `false` | 必填校验 |
255
+
256
+ **事件:** `input`, `change`
257
+
258
+ **插槽:** `default`(标签文本)
259
+
260
+ 使用 `role="checkbox"` 和 `aria-checked`。Enter/Space 键盘切换。
261
+
262
+ #### `<web-ui-radio>`
263
+
264
+ 单个单选按钮。
265
+
266
+ | 属性 | 类型 | 默认值 | 说明 |
267
+ | ---------- | --------- | ------- | ---------- |
268
+ | `checked` | `boolean` | `false` | 选中状态 |
269
+ | `value` | `string` | `''` | 表单提交值 |
270
+ | `name` | `string` | `''` | 表单字段名 |
271
+ | `disabled` | `boolean` | `false` | 禁用状态 |
272
+ | `required` | `boolean` | `false` | 必填校验 |
273
+
274
+ **事件:** `input`, `change`
275
+
276
+ **插槽:** `default`(标签文本)
277
+
278
+ #### `<web-ui-switch>`
279
+
280
+ 开关切换。
281
+
282
+ | 属性 | 类型 | 默认值 | 说明 |
283
+ | ---------- | --------- | ------- | ------------- |
284
+ | `checked` | `boolean` | `false` | 打开/关闭状态 |
285
+ | `value` | `string` | `''` | 表单提交值 |
286
+ | `name` | `string` | `''` | 表单字段名 |
287
+ | `disabled` | `boolean` | `false` | 禁用状态 |
288
+ | `required` | `boolean` | `false` | 必填校验 |
289
+ | `loading` | `boolean` | `false` | 加载状态 |
290
+
291
+ **事件:** `input`, `change`
292
+
293
+ 使用 `role="switch"` 和 `aria-checked`。Pointer 事件管理按下状态。
294
+
295
+ #### `<web-ui-segmented>`
296
+
297
+ 分段控制——单选按钮组。
298
+
299
+ | 属性 | 类型 | 默认值 | 说明 |
300
+ | ---------- | --------- | ------- | ---------- |
301
+ | `value` | `string` | `''` | 当前选中值 |
302
+ | `name` | `string` | `''` | 表单字段名 |
303
+ | `disabled` | `boolean` | `false` | 禁用状态 |
304
+ | `required` | `boolean` | `false` | 必填校验 |
305
+
306
+ **事件:** `input`, `change`
307
+
308
+ **插槽:** `default`(投影 `<web-ui-segmented-trigger>` 元素)
309
+
310
+ 与原生 `<form>` 集成(通过 `ElementInternals`)。
311
+
312
+ 根据 `value` 同步子 trigger 的 `checked` 状态。直接设 `value` 不派发事件。
313
+
314
+ #### `<web-ui-checkbox-group>`
315
+
316
+ 多选复选框组。
317
+
318
+ | 属性 | 类型 | 默认值 | 说明 |
319
+ | ---------- | ---------- | ------- | ---------------------- |
320
+ | `value` | `string[]` | `[]` | 已选项的值数组 |
321
+ | `name` | `string` | `''` | 表单字段名 |
322
+ | `disabled` | `boolean` | `false` | 禁用状态(传递到子项) |
323
+ | `required` | `boolean` | `false` | 必填校验 |
324
+
325
+ **事件:** `input`, `change`
326
+
327
+ **插槽:** `default`(投影 `<web-ui-checkbox>` 元素)
328
+
329
+ 通过子项公开属性同步 `checked`/`disabled`。监听子项 `change` 事件。
330
+
331
+ #### `<web-ui-radio-group>`
332
+
333
+ 单选组。
334
+
335
+ | 属性 | 类型 | 默认值 | 说明 |
336
+ | ---------- | --------- | ------- | ------------------------ |
337
+ | `value` | `string` | `''` | 当前选中值 |
338
+ | `name` | `string` | `''` | 表单字段名(传递到子项) |
339
+ | `disabled` | `boolean` | `false` | 禁用状态(传递到子项) |
340
+ | `required` | `boolean` | `false` | 必填校验 |
341
+
342
+ **事件:** `input`, `change`
343
+
344
+ **插槽:** `default`(投影 `<web-ui-radio>` 元素)
345
+
346
+ ---
347
+
348
+ ### 按钮
349
+
350
+ #### `<web-ui-button>`
351
+
352
+ 样式化按钮,支持多种变体和加载状态。
353
+
354
+ | 属性 | 类型 | 默认值 | 说明 |
355
+ | ---------- | ------------------------------------------------------------ | --------- | ------------------------------ |
356
+ | `variant` | `'primary' \| 'secondary' \| 'ghost' \| 'danger' \| 'glass'` | `'glass'` | 按钮变体 |
357
+ | `disabled` | `boolean` | `false` | 禁用状态 |
358
+ | `loading` | `boolean` | `false` | 加载旋转动画 |
359
+ | `full` | `boolean` | `false` | 全宽 |
360
+ | `icon` | `boolean` | `false` | 纯图标模式 |
361
+ | `size` | `string` | `''` | 尺寸格式 `高度` 或 `高度x宽度` |
362
+
363
+ **事件:** 标准 `click`
364
+
365
+ **插槽:** `prefix`, `default`, `suffix`
366
+
367
+ 禁用和加载状态阻止 `click` 事件。
368
+
369
+ #### `<web-ui-button-group>`
370
+
371
+ 按钮组,管理子按钮布局和方向。
372
+
373
+ | 属性 | 类型 | 默认值 | 说明 |
374
+ | ----------- | ---------------------------- | -------------- | -------- |
375
+ | `direction` | `'horizontal' \| 'vertical'` | `'horizontal'` | 布局方向 |
376
+
377
+ **插槽:** `default`(投影 `<web-ui-button>` 元素)
378
+
379
+ 向子按钮传递 `direction` 属性。
380
+
381
+ ---
382
+
383
+ ### 浮层 / 模态
384
+
385
+ #### `<web-ui-dialog>`
386
+
387
+ 模态对话框,使用原生 `<dialog>` 的 `showModal()`。
388
+
389
+ | 属性 | 类型 | 默认值 | 说明 |
390
+ | ------------------ | --------- | ------- | ------------------ |
391
+ | `open` | `boolean` | `false` | 对话框可见性 |
392
+ | `lock-scroll` | `boolean` | `true` | 打开时锁定页面滚动 |
393
+ | `overlay-closable` | `boolean` | `true` | 点击遮罩关闭对话框 |
394
+
395
+ **事件:** `open-change` (`CustomEvent<{ open: boolean }>`)
396
+
397
+ **插槽:** `body`, `title`, `default`, `footer`
398
+
399
+ **方法:** `showModal()`, `close()`
400
+
401
+ 使用原生 `<dialog>`,`@cancel` 阻止默认关闭行为(Escape 调用 `close()`)。点击遮罩关闭。
402
+
403
+ #### `<web-ui-drawer>`
404
+
405
+ 侧边抽屉,使用原生 `<dialog>` 并自带关闭动画。
406
+
407
+ | 属性 | 类型 | 默认值 | 说明 |
408
+ | ------------------ | ---------------------------------------- | --------- | -------------------------------- |
409
+ | `open` | `boolean` | `false` | 抽屉可见性 |
410
+ | `placement` | `'right' \| 'left' \| 'top' \| 'bottom'` | `'right'` | 滑入方向 |
411
+ | `heading` | `string` | `''` | 标题文字(无 header 插槽时显示) |
412
+ | `closable` | `boolean` | `false` | 显示关闭按钮 |
413
+ | `lock-scroll` | `boolean` | `true` | 打开时锁定页面滚动 |
414
+ | `overlay-closable` | `boolean` | `true` | 点击遮罩关闭抽屉 |
415
+
416
+ **事件:** `open-change` (`CustomEvent<{ open: boolean }>`)
417
+
418
+ **插槽:** `header`, `default`, `footer`
419
+
420
+ **方法:** `show()`, `close()`
421
+
422
+ 关闭时保留原生 dialog 的 top layer,待 `--wui-duration-drawer` 过渡完成(默认 280ms)后调用 `dialog.close()`。Escape 始终走此关闭路径;`overlay-closable` 仅控制遮罩点击。
423
+
424
+ ---
425
+
426
+ ### 浮动
427
+
428
+ #### `<web-ui-popover>`
429
+
430
+ 锚定触发元素的弹出层。
431
+
432
+ | 属性 | 类型 | 默认值 | 说明 |
433
+ | ------------------ | ---------------------------------- | ---------- | -------------------- |
434
+ | `open` | `boolean` | `false` | 弹出层可见性 |
435
+ | `disabled` | `boolean` | `false` | 禁用状态 |
436
+ | `placement` | `Placement` | `'bottom'` | Floating UI 位置 |
437
+ | `trigger` | `'click' \| 'hover' \| 'manual'` | `'click'` | 触发方式 |
438
+ | `offset` | `number` | `8` | 与锚点距离 |
439
+ | `portal` | `boolean` | `false` | 在主题浮层容器中渲染 |
440
+ | `overlayContainer` | `HTMLElement \| () => HTMLElement` | — | 显式 Portal 容器 |
441
+
442
+ **事件:** `open-change` (`CustomEvent<{ open: boolean }>`)
443
+
444
+ **插槽:** `trigger`, `default`
445
+
446
+ **方法:** `show()`, `close()`, `toggle()`
447
+
448
+ Hover 模式使用 `pointerenter`/`pointerleave` 加延迟控制。Click 模式点击切换。Manual 模式仅响应命令式调用。
449
+
450
+ #### `<web-ui-tooltip>`
451
+
452
+ 工具提示,支持指针和焦点触发。
453
+
454
+ | 属性 | 类型 | 默认值 | 说明 |
455
+ | ------------------ | ---------------------------------- | ------- | -------------------- |
456
+ | `placement` | `Placement` | `'top'` | Floating UI 位置 |
457
+ | `content` | `string` | `''` | 提示文本(替代插槽) |
458
+ | `open` | `boolean` | `false` | 可见性 |
459
+ | `disabled` | `boolean` | `false` | 禁用状态 |
460
+ | `show-delay` | `number` | `200` | 显示延迟(毫秒) |
461
+ | `hide-delay` | `number` | `100` | 隐藏延迟(毫秒) |
462
+ | `offset` | `number` | `6` | 与触发器的距离 |
463
+ | `portal` | `boolean` | `false` | 在主题浮层容器中渲染 |
464
+ | `overlayContainer` | `HTMLElement \| () => HTMLElement` | — | 显式 Portal 容器 |
465
+
466
+ **事件:** `open-change` (`CustomEvent<{ open: boolean }>`)
467
+
468
+ **插槽:** `default`(触发器)、`content`(提示面板)
469
+
470
+ `open` 是受控可见性属性。指针/焦点触发会更新它,直接设置也会同步本地或 Portal 面板。第一个 Tooltip 显示后,相邻 Tooltip 会立即切换;其余 pointer/focus 触发使用延迟计时器。
471
+
472
+ #### `<web-ui-context-menu>`
473
+
474
+ 右键上下文菜单。
475
+
476
+ | 属性 | 类型 | 默认值 | 说明 |
477
+ | ------------- | --------- | ------- | ------------ |
478
+ | `disabled` | `boolean` | `false` | 禁用状态 |
479
+ | `lock-scroll` | `boolean` | `true` | 阻止背景滚动 |
480
+
481
+ **事件:** `open-change` (`CustomEvent<{ open: boolean }>`)
482
+
483
+ **插槽:** `default`(菜单项内容)
484
+
485
+ **方法:** `openAt(x: number, y: number)`, `close()`
486
+
487
+ 通过 `contextmenu` 事件打开。菜单项:`web-ui-dropdown-item`、`web-ui-dropdown-divider`、`web-ui-dropdown-header`。支持键盘导航和子菜单 hover。
488
+
489
+ ---
490
+
491
+ ### 菜单
492
+
493
+ #### `<web-ui-dropdown>`
494
+
495
+ 下拉菜单,支持多级子菜单。
496
+
497
+ | 属性 | 类型 | 默认值 | 说明 |
498
+ | ------------- | ----------- | ---------------- | ---------------- |
499
+ | `open` | `boolean` | `false` | 菜单可见性 |
500
+ | `disabled` | `boolean` | `false` | 禁用状态 |
501
+ | `placement` | `Placement` | `'bottom-start'` | Floating UI 位置 |
502
+ | `offset` | `number` | `4` | 与触发器距离 |
503
+ | `match-width` | `boolean` | `false` | 匹配触发器宽度 |
504
+ | `lock-scroll` | `boolean` | `true` | 锁定页面滚动 |
505
+
506
+ **事件:** `open-change` (`CustomEvent<{ open: boolean }>`)
507
+
508
+ **插槽:** `trigger`, `default`(菜单项)
509
+
510
+ **方法:** `openMenu()`, `closeAll()`
511
+
512
+ 菜单项:`web-ui-dropdown-item`、`web-ui-dropdown-divider`、`web-ui-dropdown-header`。子菜单在 `web-ui-dropdown-item` 上通过 `submenu` 属性启用。完整键盘导航支持。
513
+
514
+ #### `<web-ui-dropdown-item>`
515
+
516
+ 菜单项。
517
+
518
+ | 属性 | 类型 | 默认值 | 说明 |
519
+ | ---------- | --------- | ------- | ------------ |
520
+ | `disabled` | `boolean` | `false` | 禁用状态 |
521
+ | `submenu` | `boolean` | `false` | 是否有子菜单 |
522
+ | `value` | `string` | `''` | 菜单项值 |
523
+ | `pl` | `string` | `''` | 左侧内边距 |
524
+
525
+ **插槽:** `prefix`, `default`, `suffix`
526
+
527
+ **方法:** `focusItem()`
528
+
529
+ 角色:`menuitem`。
530
+
531
+ #### `<web-ui-dropdown-divider>`
532
+
533
+ 菜单分隔线。角色:`separator`。无属性。
534
+
535
+ #### `<web-ui-dropdown-header>`
536
+
537
+ 菜单分组标题。无属性。插槽:`default`(文本内容)。
538
+
539
+ ---
540
+
541
+ ### 数据展示
542
+
543
+ #### `<web-ui-avatar>`
544
+
545
+ 头像组件,支持图片加载失败回退。
546
+
547
+ | 属性 | 类型 | 默认值 | 说明 |
548
+ | ------- | ---------------------- | ---------- | ---------------------- |
549
+ | `src` | `string` | `''` | 图片 URL |
550
+ | `alt` | `string` | `''` | 替代文本 |
551
+ | `name` | `string` | `''` | 展示名称(首字母回退) |
552
+ | `size` | `number` | `40` | 头像尺寸(px) |
553
+ | `shape` | `'circle' \| 'square'` | `'circle'` | 形状 |
554
+
555
+ **插槽:** `default`(图片加载失败的降级内容)
556
+
557
+ #### `<web-ui-badge>`
558
+
559
+ 徽标 / 通知计数。
560
+
561
+ | 属性 | 类型 | 默认值 | 说明 |
562
+ | ----------- | -------------------------------------------------------------- | ------------- | ---------------------- |
563
+ | `count` | `number` | `0` | 显示数字 |
564
+ | `max` | `number` | `99` | 最大值(超过显示 99+) |
565
+ | `dot` | `boolean` | `false` | 点模式(不显示数字) |
566
+ | `show-zero` | `boolean` | `false` | count 为 0 时也显示 |
567
+ | `hidden` | `boolean` | `false` | 完全隐藏 |
568
+ | `offset-x` | `number` | `0` | 水平偏移 |
569
+ | `offset-y` | `number` | `0` | 垂直偏移 |
570
+ | `placement` | `'top-right' \| 'top-left' \| 'bottom-right' \| 'bottom-left'` | `'top-right'` | 徽标位置 |
571
+
572
+ #### `<web-ui-empty>`
573
+
574
+ 空状态占位。
575
+
576
+ | 属性 | 类型 | 默认值 | 说明 |
577
+ | ------------- | -------------------------------- | ---------- | -------- |
578
+ | `title` | `string` | `''` | 标题 |
579
+ | `description` | `string` | `''` | 描述文本 |
580
+ | `size` | `'small' \| 'medium' \| 'large'` | `'medium'` | 尺寸 |
581
+
582
+ **插槽:** `default`(标题,覆盖 `title` 属性)、`icon`、`description`、`action`
583
+
584
+ #### `<web-ui-icon>`
585
+
586
+ 图标渲染组件。接受 Iconify 数据对象。
587
+
588
+ | 属性 | 类型 | 默认值 | 说明 |
589
+ | ------- | ------------- | ------- | ------------------------ |
590
+ | `.icon` | `IconifyIcon` | — | 图标数据(Lit 属性绑定) |
591
+ | `size` | `number` | `18` | 尺寸(px) |
592
+ | `color` | `string` | — | 颜色 |
593
+ | `spin` | `boolean` | `false` | 旋转动画 |
594
+
595
+ 内置 `aria-hidden="true"`。
596
+
597
+ ```js
598
+ import { lucideLoaderCircle } from '@greypan/web-ui/icons'
599
+ html`<web-ui-icon .icon=${lucideLoaderCircle} spin />`
259
600
  ```
260
601
 
261
- ### SVG 线条动画
602
+ #### `<web-ui-spinner>`
262
603
 
263
- ```vue
264
- <template>
265
- <web-ui-svg-draw-lines>
266
- <svg viewBox="0 0 24 24" width="100" height="100" fill="none" stroke="currentColor" stroke-width="2">
267
- <path d="M4 4v16M8 6h12M8 12h6m-6 6h10" />
268
- </svg>
269
- </web-ui-svg-draw-lines>
270
- </template>
604
+ 加载旋转器。
605
+
606
+ | 属性 | 类型 | 默认值 | 说明 |
607
+ | ------------- | -------- | ------ | ---------- |
608
+ | `size` | `number` | `24` | 尺寸(px) |
609
+ | `color` | `string` | — | 颜色 |
610
+ | `description` | `string` | `''` | 描述文字 |
611
+
612
+ 角色:`status`,`aria-label="加载中"`。
613
+
614
+ **插槽:** `description`
615
+
616
+ **静态 API:**
617
+
618
+ ```ts
619
+ import { WebUiSpinner } from '@greypan/web-ui'
620
+
621
+ WebUiSpinner.show() // 显示
622
+ WebUiSpinner.show({ size: 32, duration: 2000 }) // 带选项显示
623
+ WebUiSpinner.hide() // 隐藏
271
624
  ```
272
625
 
273
- ## API
626
+ `WebUiSpinner.show(options?: { size?: number; duration?: number; description?: string })`
627
+
628
+ ---
629
+
630
+ ### 布局与工具
274
631
 
275
- ### `<web-ui-button>`
632
+ #### `<web-ui-layout>`
276
633
 
277
- 样式化按钮组件。
634
+ 页面布局网格。
278
635
 
279
- | 属性 | 类型 | 默认值 | 说明 |
280
- | --------- | --------- | ------- | ---------- |
281
- | `full` | `boolean` | `false` | 全宽按钮 |
282
- | `primary` | `boolean` | `false` | 主要样式 |
283
- | `text` | `boolean` | `false` | 纯文本样式 |
284
- | `icon` | `boolean` | `false` | 纯图标模式 |
636
+ | 插槽 | 说明 |
637
+ | --------- | ---------- |
638
+ | `header` | 顶部横幅 |
639
+ | `default` | 主内容区 |
640
+ | `sidebar` | 侧边栏 |
641
+ | `tabbar` | 底部标签栏 |
285
642
 
286
- ### `<web-ui-back-top>`
643
+ #### `<web-ui-back-top>`
287
644
 
288
645
  回到顶部按钮。
289
646
 
290
647
  | 属性 | 类型 | 默认值 | 说明 |
291
648
  | -------------- | ----------------------- | -------- | ------------------ |
292
- | `smooth` | `boolean` | `true` | 平滑滚动动画 |
649
+ | `smooth` | `boolean` | `true` | 平滑滚动 |
293
650
  | `threshold` | `number` | `200` | 显示按钮的滚动阈值 |
294
651
  | `visible` | `boolean` | `false` | 当前可见状态 |
295
652
  | `scrollTarget` | `HTMLElement \| Window` | `window` | 滚动容器 |
296
653
 
297
- **事件:**
654
+ **插槽:** `default`(自定义按钮内容)
298
655
 
299
- | 事件名 | 详情 | 说明 |
300
- | ---------------- | ---------------------- | ------------ |
301
- | `visible-change` | `{ visible: boolean }` | 可见状态变更 |
656
+ **方法:** `toTop()`
302
657
 
303
- ### `<web-ui-layout>`
658
+ 角色:`button`,键盘 Enter 触发回到顶部。
304
659
 
305
- 带插槽的页面布局。
660
+ #### `<web-ui-svg-draw-lines>`
306
661
 
307
- | 插槽 | 说明 |
308
- | --------- | -------------- |
309
- | `header` | 顶部区域 |
310
- | `sidebar` | 侧边栏区域 |
311
- | `tabbar` | 底部标签栏区域 |
312
- | (默认) | 主内容区域 |
662
+ SVG 线条绘制动画,基于 `stroke-dashoffset`。直接在原元素上动画 —— 不克隆、不操作 DOM。
313
663
 
314
- ### `<web-ui-svg-draw-lines>`
664
+ | 属性 | 类型 | 默认值 | 说明 |
665
+ | ---------- | -------- | ---------- | -------------------------------------------- |
666
+ | `duration` | `number` | `1000` | 动画时长(毫秒),限制在 `[0, 30000]` 范围内 |
667
+ | `easing` | `string` | `'linear'` | CSS 缓动函数,传递给 `element.animate()` |
315
668
 
316
- SVG 线条绘制动画组件。包裹 `<svg>` 元素并动画化 stroke-dashoffset。
669
+ 两个属性均会反射(reflected)。
317
670
 
318
- | 属性 | 类型 | 默认值 | 说明 |
319
- | ---------- | -------- | ---------- | ---------------- |
320
- | `duration` | `number` | `1000` | 动画时长(毫秒) |
321
- | `easing` | `string` | `'linear'` | CSS 缓动函数 |
671
+ **方法:** `replay(): Promise<void>` — 取消当前动画,重新从 DOM 收集几何元素并开始新动画。所有目标以相同的 duration/easing 并行播放。动画全部完成后 resolve。最近主题范围为 `motion="reduced"` 时立即返回,不播放动画;`motion="system"` 则在匹配 `prefers-reduced-motion: reduce` 时执行相同行为。
322
672
 
323
- ```html
324
- <web-ui-svg-draw-lines duration="2000" easing="ease-in-out">
325
- <svg viewBox="0 0 100 100">
326
- <path d="M10 10 L90 10 L90 90 L10 90 Z" fill="none" stroke="black" />
327
- </svg>
328
- </web-ui-svg-draw-lines>
673
+ **插槽:** `default` — 需要动画的 SVG 内容。接受内联 `<svg>` 元素(light DOM)以及将 SVG 渲染在开放 Shadow DOM 中的组件(如 `<web-ui-icon>`)。closed Shadow Root 被跳过。
674
+
675
+ 递归遍历 light DOM 和所有开放 Shadow Root,查找 `path`、`rect`、`circle`、`line`、`polyline`、`polygon`、`ellipse` 元素。以 `Z`/`z` 结尾的 `<path>` 会临时应用缺口修复逻辑确保闭合段正确渲染。动画完成或取消后恢复所有内联样式。
676
+
677
+ #### `<web-ui-theme>`
678
+
679
+ 主题提供者,定义 CSS 自定义属性 token。
680
+
681
+ | 属性 | 类型 | 默认值 | 说明 |
682
+ | ------------ | --------------------------------- | ---------- | -------------------------- |
683
+ | `appearance` | `'light' \| 'dark' \| 'system'` | `'light'` | 配色方案 |
684
+ | `motion` | `'full' \| 'reduced' \| 'system'` | `'system'` | 当前嵌套主题范围的动效偏好 |
685
+
686
+ **方法:** `getOverlayRoot()` — 返回 Portal 浮层容器
687
+
688
+ 定义 `--wui-color-*`、`--wui-shadow-*`、`--wui-layer-*` 与 motion token。motion token 是稳定的主题契约,可在主题范围覆盖:`--wui-duration-press`、`--wui-duration-fast`、`--wui-duration-overlay-enter`、`--wui-duration-overlay-exit`、`--wui-duration-drawer`、`--wui-ease-out`、`--wui-ease-standard`、`--wui-scale-press`、`--wui-scale-enter`。`motion="system"` 跟随 `prefers-reduced-motion`;使用 `motion="reduced"` 降低当前作用域动效,或在嵌套主题中使用 `motion="full"` 恢复默认 token。System 配色模式跟随 `prefers-color-scheme`。
689
+
690
+ ---
691
+
692
+ ### 通知
693
+
694
+ #### `<web-ui-toast>`
695
+
696
+ 单个 Toast 通知。通过命令式 API 使用。
697
+
698
+ **命令式 API:**
699
+
700
+ ```ts
701
+ import { toast } from '@greypan/web-ui'
702
+
703
+ // 创建
704
+ toast.success('操作成功')
705
+ toast.error('出错了', { duration: 5000 })
706
+ toast.info('提示信息')
707
+ toast.warning('请注意')
708
+
709
+ // 带选项
710
+ const id = toast({ message: '自定义', type: 'info', position: 'bottom-right', duration: 4000, closable: true })
711
+
712
+ // 关闭
713
+ toast.close(id)
714
+ toast.clear()
715
+
716
+ // 更新可见内容,不重置自动关闭计时
717
+ toast.updateMessage(id, { message: '上传已完成 60%', heading: '正在上传' })
329
718
  ```
719
+
720
+ **ToastOptions:**
721
+
722
+ | 选项 | 类型 | 默认值 | 说明 |
723
+ | ----------- | --------------------------------------------- | ------------------------- | ---------------------------- |
724
+ | `message` | `string` | — | 通知文本 |
725
+ | `type` | `'success' \| 'info' \| 'warning' \| 'error'` | `'info'` | 类型 |
726
+ | `duration` | `number` | `3000`(error 为 `5000`) | 自动关闭时间(0=不自动关闭) |
727
+ | `closable` | `boolean` | `true` | 显示关闭按钮 |
728
+ | `id` | `string` | auto | 去重标识符 |
729
+ | `heading` | `string` | `''` | 粗体标题 |
730
+ | `position` | 6 种位置 | `'top-right'` | 屏幕位置 |
731
+ | `target` | `Element` | — | 用于查找最近主题作用域 |
732
+ | `container` | `HTMLElement` | — | 显式挂载容器(最高优先级) |
733
+
734
+ **`toast.updateMessage(id, options)`** 更新可见 Toast 的 `message`,并在传入时更新 `heading`;不会重置自动关闭计时。`options` 类型为 `ToastMessageUpdateOptions`:`{ message: string; heading?: string }`。
735
+
736
+ **事件:** `toast-close` (`CustomEvent<{ id: string; reason: 'auto' | 'manual' | 'programmatic' | 'clear' }>`)
737
+
738
+ 悬停暂停自动关闭计时器(使用 `pointerenter`/`pointerleave`)。同一微任务中批量挂载 Toast。
739
+
740
+ ---
741
+
742
+ ### 子项
743
+
744
+ #### `<web-ui-option>`
745
+
746
+ `<web-ui-select>` 的选择选项。
747
+
748
+ | 属性 | 类型 | 默认值 | 说明 |
749
+ | ---------- | --------- | ------- | ---------------------------------- |
750
+ | `value` | `string` | `''` | 选中值 |
751
+ | `label` | `string` | `''` | 显示文本;未设置时回退默认插槽文本 |
752
+ | `selected` | `boolean` | `false` | 当前是否选中 |
753
+ | `disabled` | `boolean` | `false` | 禁用状态 |
754
+
755
+ **插槽:** `default`(标签文本回退)、`prefix`(标签前装饰内容)、`suffix`(标签后装饰内容)
756
+
757
+ 非表单关联组件(父级 select 统一提交)。
758
+
759
+ #### `<web-ui-segmented-trigger>`
760
+
761
+ `<web-ui-segmented>` 的分段按钮。
762
+
763
+ | 属性 | 类型 | 默认值 | 说明 |
764
+ | ---------- | --------- | ------- | -------- |
765
+ | `value` | `string` | `''` | 分段值 |
766
+ | `checked` | `boolean` | `false` | 当前选中 |
767
+ | `disabled` | `boolean` | `false` | 禁用状态 |
768
+
769
+ **事件:** `change`
770
+
771
+ 非表单关联组件(父级 segmented 统一提交)。