@wot-ui/ui 1.0.0 → 2.0.0-alpha.4

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 (386) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +134 -0
  3. package/attributes.json +1 -0
  4. package/changelog.md +63 -0
  5. package/common/AbortablePromise.ts +28 -0
  6. package/common/canvasHelper.ts +49 -0
  7. package/common/clickoutside.ts +25 -0
  8. package/common/event.ts +8 -0
  9. package/common/formatDate.ts +68 -0
  10. package/common/interceptor.ts +43 -0
  11. package/common/props.ts +53 -0
  12. package/common/util.ts +836 -0
  13. package/components/wd-action-sheet/index.scss +232 -0
  14. package/components/wd-action-sheet/types.ts +155 -0
  15. package/components/wd-action-sheet/wd-action-sheet.vue +176 -0
  16. package/components/wd-avatar/index.scss +150 -0
  17. package/components/wd-avatar/types.ts +98 -0
  18. package/components/wd-avatar/wd-avatar.vue +184 -0
  19. package/components/wd-avatar-group/index.scss +11 -0
  20. package/components/wd-avatar-group/types.ts +61 -0
  21. package/components/wd-avatar-group/wd-avatar-group.vue +115 -0
  22. package/components/wd-backtop/index.scss +67 -0
  23. package/components/wd-backtop/types.ts +66 -0
  24. package/components/wd-backtop/wd-backtop.vue +57 -0
  25. package/components/wd-badge/index.scss +116 -0
  26. package/components/wd-badge/types.ts +94 -0
  27. package/components/wd-badge/wd-badge.vue +78 -0
  28. package/components/wd-button/index.scss +436 -0
  29. package/components/wd-button/types.ts +204 -0
  30. package/components/wd-button/wd-button.vue +210 -0
  31. package/components/wd-calendar/index.scss +97 -0
  32. package/components/wd-calendar/types.ts +221 -0
  33. package/components/wd-calendar/wd-calendar.vue +339 -0
  34. package/components/wd-calendar-view/index.scss +41 -0
  35. package/components/wd-calendar-view/month/index.scss +144 -0
  36. package/components/wd-calendar-view/month/month.vue +389 -0
  37. package/components/wd-calendar-view/month/types.ts +70 -0
  38. package/components/wd-calendar-view/monthPanel/index.scss +84 -0
  39. package/components/wd-calendar-view/monthPanel/month-panel.vue +541 -0
  40. package/components/wd-calendar-view/monthPanel/types.ts +151 -0
  41. package/components/wd-calendar-view/types.ts +166 -0
  42. package/components/wd-calendar-view/utils.ts +318 -0
  43. package/components/wd-calendar-view/wd-calendar-view.vue +117 -0
  44. package/components/wd-calendar-view/year/index.scss +148 -0
  45. package/components/wd-calendar-view/year/types.ts +74 -0
  46. package/components/wd-calendar-view/year/year.vue +206 -0
  47. package/components/wd-calendar-view/yearPanel/index.scss +42 -0
  48. package/components/wd-calendar-view/yearPanel/types.ts +96 -0
  49. package/components/wd-calendar-view/yearPanel/year-panel.vue +249 -0
  50. package/components/wd-card/index.scss +104 -0
  51. package/components/wd-card/types.ts +47 -0
  52. package/components/wd-card/wd-card.vue +38 -0
  53. package/components/wd-cascader/index.scss +154 -0
  54. package/components/wd-cascader/types.ts +191 -0
  55. package/components/wd-cascader/wd-cascader.vue +589 -0
  56. package/components/wd-cell/index.scss +244 -0
  57. package/components/wd-cell/types.ts +205 -0
  58. package/components/wd-cell/wd-cell.vue +172 -0
  59. package/components/wd-cell-group/index.scss +53 -0
  60. package/components/wd-cell-group/types.ts +97 -0
  61. package/components/wd-cell-group/wd-cell-group.vue +48 -0
  62. package/components/wd-checkbox/index.scss +166 -0
  63. package/components/wd-checkbox/types.ts +118 -0
  64. package/components/wd-checkbox/wd-checkbox.vue +216 -0
  65. package/components/wd-checkbox-group/index.scss +5 -0
  66. package/components/wd-checkbox-group/types.ts +93 -0
  67. package/components/wd-checkbox-group/wd-checkbox-group.vue +148 -0
  68. package/components/wd-circle/index.scss +28 -0
  69. package/components/wd-circle/types.ts +54 -0
  70. package/components/wd-circle/wd-circle.vue +306 -0
  71. package/components/wd-col/index.scss +5 -0
  72. package/components/wd-col/types.ts +16 -0
  73. package/components/wd-col/wd-col.vue +83 -0
  74. package/components/wd-collapse/index.scss +71 -0
  75. package/components/wd-collapse/types.ts +68 -0
  76. package/components/wd-collapse/wd-collapse.vue +165 -0
  77. package/components/wd-collapse-item/index.scss +86 -0
  78. package/components/wd-collapse-item/types.ts +62 -0
  79. package/components/wd-collapse-item/wd-collapse-item.vue +184 -0
  80. package/components/wd-config-provider/index.scss +10 -0
  81. package/components/wd-config-provider/types.ts +2061 -0
  82. package/components/wd-config-provider/wd-config-provider.vue +61 -0
  83. package/components/wd-count-down/index.scss +16 -0
  84. package/components/wd-count-down/types.ts +58 -0
  85. package/components/wd-count-down/utils.ts +52 -0
  86. package/components/wd-count-down/wd-count-down.vue +62 -0
  87. package/components/wd-count-to/index.scss +25 -0
  88. package/components/wd-count-to/types.ts +121 -0
  89. package/components/wd-count-to/wd-count-to.vue +126 -0
  90. package/components/wd-curtain/index.scss +96 -0
  91. package/components/wd-curtain/types.ts +82 -0
  92. package/components/wd-curtain/wd-curtain.vue +172 -0
  93. package/components/wd-datetime-picker/index.scss +133 -0
  94. package/components/wd-datetime-picker/types.ts +198 -0
  95. package/components/wd-datetime-picker/wd-datetime-picker.vue +526 -0
  96. package/components/wd-datetime-picker-view/types.ts +171 -0
  97. package/components/wd-datetime-picker-view/util.ts +30 -0
  98. package/components/wd-datetime-picker-view/wd-datetime-picker-view.vue +402 -0
  99. package/components/wd-dialog/index.scss +281 -0
  100. package/components/wd-dialog/index.ts +168 -0
  101. package/components/wd-dialog/types.ts +452 -0
  102. package/components/wd-dialog/wd-dialog.vue +586 -0
  103. package/components/wd-divider/index.scss +122 -0
  104. package/components/wd-divider/types.ts +50 -0
  105. package/components/wd-divider/wd-divider.vue +54 -0
  106. package/components/wd-drop-menu/index.scss +90 -0
  107. package/components/wd-drop-menu/types.ts +38 -0
  108. package/components/wd-drop-menu/wd-drop-menu.vue +168 -0
  109. package/components/wd-drop-menu-item/index.scss +96 -0
  110. package/components/wd-drop-menu-item/types.ts +93 -0
  111. package/components/wd-drop-menu-item/wd-drop-menu-item.vue +205 -0
  112. package/components/wd-empty/index.scss +46 -0
  113. package/components/wd-empty/types.ts +37 -0
  114. package/components/wd-empty/wd-empty.vue +47 -0
  115. package/components/wd-fab/index.scss +124 -0
  116. package/components/wd-fab/types.ts +119 -0
  117. package/components/wd-fab/wd-fab.vue +322 -0
  118. package/components/wd-floating-panel/index.scss +73 -0
  119. package/components/wd-floating-panel/type.ts +32 -0
  120. package/components/wd-floating-panel/wd-floating-panel.vue +142 -0
  121. package/components/wd-form/adapters/zod.ts +56 -0
  122. package/components/wd-form/index.ts +2 -0
  123. package/components/wd-form/types.ts +133 -0
  124. package/components/wd-form/wd-form.vue +121 -0
  125. package/components/wd-form-item/index.scss +26 -0
  126. package/components/wd-form-item/types.ts +134 -0
  127. package/components/wd-form-item/wd-form-item.vue +182 -0
  128. package/components/wd-gap/index.scss +9 -0
  129. package/components/wd-gap/types.ts +26 -0
  130. package/components/wd-gap/wd-gap.vue +38 -0
  131. package/components/wd-grid/index.scss +11 -0
  132. package/components/wd-grid/types.ts +97 -0
  133. package/components/wd-grid/wd-grid.vue +48 -0
  134. package/components/wd-grid-item/index.scss +187 -0
  135. package/components/wd-grid-item/types.ts +98 -0
  136. package/components/wd-grid-item/wd-grid-item.vue +295 -0
  137. package/components/wd-icon/index.scss +46 -0
  138. package/components/wd-icon/types.ts +44 -0
  139. package/components/wd-icon/wd-icon.vue +66 -0
  140. package/components/wd-image-preview/index.scss +94 -0
  141. package/components/wd-image-preview/index.ts +95 -0
  142. package/components/wd-image-preview/types.ts +165 -0
  143. package/components/wd-image-preview/wd-image-preview.vue +233 -0
  144. package/components/wd-img/index.scss +82 -0
  145. package/components/wd-img/types.ts +96 -0
  146. package/components/wd-img/wd-img.vue +91 -0
  147. package/components/wd-img-cropper/index.scss +259 -0
  148. package/components/wd-img-cropper/types.ts +101 -0
  149. package/components/wd-img-cropper/wd-img-cropper.vue +653 -0
  150. package/components/wd-index-anchor/index.scss +34 -0
  151. package/components/wd-index-anchor/type.ts +9 -0
  152. package/components/wd-index-anchor/wd-index-anchor.vue +55 -0
  153. package/components/wd-index-bar/index.scss +68 -0
  154. package/components/wd-index-bar/type.ts +23 -0
  155. package/components/wd-index-bar/wd-index-bar.vue +157 -0
  156. package/components/wd-input/index.scss +129 -0
  157. package/components/wd-input/types.ts +165 -0
  158. package/components/wd-input/wd-input.vue +237 -0
  159. package/components/wd-input-number/index.scss +233 -0
  160. package/components/wd-input-number/types.ts +131 -0
  161. package/components/wd-input-number/wd-input-number.vue +473 -0
  162. package/components/wd-keyboard/constants.ts +81 -0
  163. package/components/wd-keyboard/index.scss +104 -0
  164. package/components/wd-keyboard/key/index.scss +103 -0
  165. package/components/wd-keyboard/key/index.vue +84 -0
  166. package/components/wd-keyboard/key/types.ts +44 -0
  167. package/components/wd-keyboard/types.ts +138 -0
  168. package/components/wd-keyboard/wd-keyboard.vue +236 -0
  169. package/components/wd-loading/index.scss +205 -0
  170. package/components/wd-loading/types.ts +61 -0
  171. package/components/wd-loading/wd-loading.vue +70 -0
  172. package/components/wd-loadmore/index.scss +62 -0
  173. package/components/wd-loadmore/types.ts +42 -0
  174. package/components/wd-loadmore/wd-loadmore.vue +68 -0
  175. package/components/wd-navbar/index.scss +96 -0
  176. package/components/wd-navbar/types.ts +74 -0
  177. package/components/wd-navbar/wd-navbar.vue +136 -0
  178. package/components/wd-navbar-capsule/index.scss +70 -0
  179. package/components/wd-navbar-capsule/types.ts +11 -0
  180. package/components/wd-navbar-capsule/wd-navbar-capsule.vue +48 -0
  181. package/components/wd-notice-bar/index.scss +94 -0
  182. package/components/wd-notice-bar/types.ts +97 -0
  183. package/components/wd-notice-bar/wd-notice-bar.vue +270 -0
  184. package/components/wd-notify/index.scss +114 -0
  185. package/components/wd-notify/index.ts +63 -0
  186. package/components/wd-notify/types.ts +130 -0
  187. package/components/wd-notify/wd-notify.vue +162 -0
  188. package/components/wd-overlay/index.scss +14 -0
  189. package/components/wd-overlay/types.ts +42 -0
  190. package/components/wd-overlay/wd-overlay.vue +55 -0
  191. package/components/wd-pagination/index.scss +71 -0
  192. package/components/wd-pagination/types.ts +69 -0
  193. package/components/wd-pagination/wd-pagination.vue +118 -0
  194. package/components/wd-password-input/index.scss +134 -0
  195. package/components/wd-password-input/types.ts +42 -0
  196. package/components/wd-password-input/wd-password-input.vue +51 -0
  197. package/components/wd-picker/index.scss +72 -0
  198. package/components/wd-picker/types.ts +141 -0
  199. package/components/wd-picker/wd-picker.vue +220 -0
  200. package/components/wd-picker-view/index.scss +93 -0
  201. package/components/wd-picker-view/types.ts +145 -0
  202. package/components/wd-picker-view/useSelection.ts +385 -0
  203. package/components/wd-picker-view/wd-picker-view.vue +227 -0
  204. package/components/wd-popover/index.scss +117 -0
  205. package/components/wd-popover/types.ts +106 -0
  206. package/components/wd-popover/wd-popover.vue +212 -0
  207. package/components/wd-popup/index.scss +89 -0
  208. package/components/wd-popup/types.ts +110 -0
  209. package/components/wd-popup/wd-popup.vue +174 -0
  210. package/components/wd-progress/index.scss +155 -0
  211. package/components/wd-progress/types.ts +94 -0
  212. package/components/wd-progress/wd-progress.vue +249 -0
  213. package/components/wd-radio/index.scss +189 -0
  214. package/components/wd-radio/types.ts +64 -0
  215. package/components/wd-radio/wd-radio.vue +164 -0
  216. package/components/wd-radio-group/index.scss +5 -0
  217. package/components/wd-radio-group/types.ts +70 -0
  218. package/components/wd-radio-group/wd-radio-group.vue +53 -0
  219. package/components/wd-rate/index.scss +57 -0
  220. package/components/wd-rate/types.ts +86 -0
  221. package/components/wd-rate/wd-rate.vue +168 -0
  222. package/components/wd-resize/index.scss +31 -0
  223. package/components/wd-resize/types.ts +14 -0
  224. package/components/wd-resize/wd-resize.vue +157 -0
  225. package/components/wd-root-portal/wd-root-portal.vue +77 -0
  226. package/components/wd-row/index.scss +6 -0
  227. package/components/wd-row/types.ts +36 -0
  228. package/components/wd-row/wd-row.vue +88 -0
  229. package/components/wd-search/index.scss +171 -0
  230. package/components/wd-search/types.ts +107 -0
  231. package/components/wd-search/wd-search.vue +198 -0
  232. package/components/wd-segmented/index.scss +155 -0
  233. package/components/wd-segmented/types.ts +81 -0
  234. package/components/wd-segmented/wd-segmented.vue +169 -0
  235. package/components/wd-select-picker/index.scss +72 -0
  236. package/components/wd-select-picker/types.ts +72 -0
  237. package/components/wd-select-picker/wd-select-picker.vue +371 -0
  238. package/components/wd-sidebar/index.scss +25 -0
  239. package/components/wd-sidebar/types.ts +34 -0
  240. package/components/wd-sidebar/wd-sidebar.vue +57 -0
  241. package/components/wd-sidebar-item/index.scss +91 -0
  242. package/components/wd-sidebar-item/types.ts +28 -0
  243. package/components/wd-sidebar-item/wd-sidebar-item.vue +118 -0
  244. package/components/wd-signature/index.scss +42 -0
  245. package/components/wd-signature/types.ts +295 -0
  246. package/components/wd-signature/wd-signature.vue +664 -0
  247. package/components/wd-skeleton/index.scss +112 -0
  248. package/components/wd-skeleton/types.ts +124 -0
  249. package/components/wd-skeleton/wd-skeleton.vue +110 -0
  250. package/components/wd-slide-verify/index.scss +112 -0
  251. package/components/wd-slide-verify/types.ts +98 -0
  252. package/components/wd-slide-verify/wd-slide-verify.vue +222 -0
  253. package/components/wd-slider/index.scss +485 -0
  254. package/components/wd-slider/types.ts +166 -0
  255. package/components/wd-slider/wd-slider.vue +529 -0
  256. package/components/wd-sort-button/index.scss +126 -0
  257. package/components/wd-sort-button/types.ts +68 -0
  258. package/components/wd-sort-button/wd-sort-button.vue +67 -0
  259. package/components/wd-step/index.scss +366 -0
  260. package/components/wd-step/types.ts +43 -0
  261. package/components/wd-step/wd-step.vue +181 -0
  262. package/components/wd-steps/index.scss +7 -0
  263. package/components/wd-steps/types.ts +50 -0
  264. package/components/wd-steps/wd-steps.vue +39 -0
  265. package/components/wd-sticky/index.scss +9 -0
  266. package/components/wd-sticky/types.ts +13 -0
  267. package/components/wd-sticky/wd-sticky.vue +192 -0
  268. package/components/wd-sticky-box/index.scss +6 -0
  269. package/components/wd-sticky-box/types.ts +20 -0
  270. package/components/wd-sticky-box/wd-sticky-box.vue +157 -0
  271. package/components/wd-swipe-action/index.scss +22 -0
  272. package/components/wd-swipe-action/types.ts +87 -0
  273. package/components/wd-swipe-action/wd-swipe-action.vue +320 -0
  274. package/components/wd-swiper/index.scss +69 -0
  275. package/components/wd-swiper/types.ts +275 -0
  276. package/components/wd-swiper/wd-swiper.vue +332 -0
  277. package/components/wd-swiper-nav/index.scss +179 -0
  278. package/components/wd-swiper-nav/types.ts +42 -0
  279. package/components/wd-swiper-nav/wd-swiper-nav.vue +42 -0
  280. package/components/wd-switch/index.scss +177 -0
  281. package/components/wd-switch/types.ts +93 -0
  282. package/components/wd-switch/wd-switch.vue +107 -0
  283. package/components/wd-tab/index.scss +16 -0
  284. package/components/wd-tab/types.ts +45 -0
  285. package/components/wd-tab/wd-tab.vue +99 -0
  286. package/components/wd-tabbar/index.scss +71 -0
  287. package/components/wd-tabbar/types.ts +79 -0
  288. package/components/wd-tabbar/wd-tabbar.vue +109 -0
  289. package/components/wd-tabbar-item/index.scss +50 -0
  290. package/components/wd-tabbar-item/types.ts +45 -0
  291. package/components/wd-tabbar-item/wd-tabbar-item.vue +101 -0
  292. package/components/wd-table/index.scss +128 -0
  293. package/components/wd-table/types.ts +160 -0
  294. package/components/wd-table/wd-table.vue +331 -0
  295. package/components/wd-table-column/index.scss +15 -0
  296. package/components/wd-table-column/types.ts +81 -0
  297. package/components/wd-table-column/wd-table-column.vue +198 -0
  298. package/components/wd-tabs/index.scss +332 -0
  299. package/components/wd-tabs/types.ts +155 -0
  300. package/components/wd-tabs/wd-tabs.vue +508 -0
  301. package/components/wd-tag/index.scss +325 -0
  302. package/components/wd-tag/types.ts +90 -0
  303. package/components/wd-tag/wd-tag.vue +158 -0
  304. package/components/wd-text/index.scss +52 -0
  305. package/components/wd-text/types.ts +107 -0
  306. package/components/wd-text/wd-text.vue +141 -0
  307. package/components/wd-textarea/index.scss +112 -0
  308. package/components/wd-textarea/types.ts +151 -0
  309. package/components/wd-textarea/wd-textarea.vue +212 -0
  310. package/components/wd-toast/index.scss +92 -0
  311. package/components/wd-toast/index.ts +97 -0
  312. package/components/wd-toast/types.ts +190 -0
  313. package/components/wd-toast/wd-toast.vue +158 -0
  314. package/components/wd-tooltip/index.scss +77 -0
  315. package/components/wd-tooltip/types.ts +105 -0
  316. package/components/wd-tooltip/wd-tooltip.vue +169 -0
  317. package/components/wd-tour/index.scss +106 -0
  318. package/components/wd-tour/types.ts +268 -0
  319. package/components/wd-tour/wd-tour.vue +518 -0
  320. package/components/wd-transition/index.scss +67 -0
  321. package/components/wd-transition/types.ts +106 -0
  322. package/components/wd-transition/wd-transition.vue +238 -0
  323. package/components/wd-upload/index.scss +204 -0
  324. package/components/wd-upload/types.ts +390 -0
  325. package/components/wd-upload/wd-upload.vue +565 -0
  326. package/components/wd-video-preview/index.scss +54 -0
  327. package/components/wd-video-preview/index.ts +64 -0
  328. package/components/wd-video-preview/types.ts +66 -0
  329. package/components/wd-video-preview/wd-video-preview.vue +141 -0
  330. package/components/wd-watermark/index.scss +21 -0
  331. package/components/wd-watermark/types.ts +130 -0
  332. package/components/wd-watermark/wd-watermark.vue +718 -0
  333. package/components/wot-ui/wot-ui.vue +5 -0
  334. package/composables/index.ts +16 -0
  335. package/composables/useCell.ts +34 -0
  336. package/composables/useChildren.ts +120 -0
  337. package/composables/useConfigProvider.ts +45 -0
  338. package/composables/useCountDown.ts +138 -0
  339. package/composables/useDeviceInfo.ts +136 -0
  340. package/composables/useLockScroll.ts +37 -0
  341. package/composables/useParent.ts +51 -0
  342. package/composables/usePopover.ts +212 -0
  343. package/composables/useQueue.ts +52 -0
  344. package/composables/useRaf.ts +37 -0
  345. package/composables/useTouch.ts +43 -0
  346. package/composables/useTranslate.ts +12 -0
  347. package/composables/useUpload.ts +366 -0
  348. package/global.d.ts +106 -0
  349. package/index.ts +6 -0
  350. package/locale/index.ts +32 -0
  351. package/locale/lang/ar-SA.ts +150 -0
  352. package/locale/lang/de-DE.ts +150 -0
  353. package/locale/lang/en-US.ts +150 -0
  354. package/locale/lang/es-ES.ts +150 -0
  355. package/locale/lang/fr-FR.ts +150 -0
  356. package/locale/lang/ja-JP.ts +150 -0
  357. package/locale/lang/ko-KR.ts +150 -0
  358. package/locale/lang/pt-PT.ts +150 -0
  359. package/locale/lang/ru-RU.ts +150 -0
  360. package/locale/lang/th-TH.ts +150 -0
  361. package/locale/lang/tr-TR.ts +155 -0
  362. package/locale/lang/ug-CN.ts +154 -0
  363. package/locale/lang/vi-VN.ts +89 -0
  364. package/locale/lang/zh-CN.ts +154 -0
  365. package/locale/lang/zh-HK.ts +78 -0
  366. package/locale/lang/zh-TW.ts +78 -0
  367. package/package.json +1 -11
  368. package/styles/iconfont/iconfont.scss +1243 -0
  369. package/styles/mixin/_config.scss +7 -0
  370. package/styles/mixin/_function.scss +44 -0
  371. package/styles/mixin/_mixin.scss +473 -0
  372. package/styles/theme/base/color.scss +210 -0
  373. package/styles/theme/base/font.scss +13 -0
  374. package/styles/theme/base/index.scss +8 -0
  375. package/styles/theme/base/insets.scss +32 -0
  376. package/styles/theme/base/number.scss +36 -0
  377. package/styles/theme/base/opacity.scss +9 -0
  378. package/styles/theme/base/radius.scss +13 -0
  379. package/styles/theme/base/stroke.scss +9 -0
  380. package/styles/theme/base/typography.scss +44 -0
  381. package/styles/theme/dark.scss +101 -0
  382. package/styles/theme/index.scss +16 -0
  383. package/styles/theme/light.scss +101 -0
  384. package/styles/variable.scss +472 -0
  385. package/tags.json +1 -0
  386. package/web-types.json +1 -0
@@ -0,0 +1,133 @@
1
+ import { type ComponentPublicInstance, type ExtractPropTypes, type InjectionKey, type PropType } from 'vue'
2
+ import { baseProps, makeBooleanProp, makeRequiredProp, numericProp } from '../../common/props'
3
+ import type { CellLayout, CellSize, CellValueAlign, CellAsteriskPosition } from '../wd-cell/types'
4
+
5
+ export type FormSchemaIssue = {
6
+ path: Array<string | number>
7
+ message: string
8
+ }
9
+
10
+ export type FormSchema = {
11
+ validate: (model: Record<string, any>) => FormSchemaIssue[] | Promise<FormSchemaIssue[]>
12
+ isRequired?: (path: string) => boolean | undefined
13
+ }
14
+
15
+ export const FORM_VALIDATE_EVENTS = ['change', 'blur', 'submit'] as const
16
+
17
+ export type FormValidateEvent = (typeof FORM_VALIDATE_EVENTS)[number]
18
+
19
+ export type FormValidateTrigger = FormValidateEvent
20
+
21
+ export type ErrorMessage = {
22
+ prop: string
23
+ message: string
24
+ }
25
+
26
+ export const formProps = {
27
+ ...baseProps,
28
+ /**
29
+ * 表单数据对象
30
+ */
31
+ model: makeRequiredProp(Object as PropType<Record<string, any>>),
32
+ /**
33
+ * 表单验证规则
34
+ */
35
+ schema: Object as PropType<FormSchema>,
36
+ /**
37
+ * 校验触发时机
38
+ */
39
+ validateTrigger: {
40
+ type: [String, Array] as PropType<FormValidateTrigger | FormValidateTrigger[]>,
41
+ default: 'submit'
42
+ },
43
+ /**
44
+ * 是否在输入时重置表单校验信息
45
+ */
46
+ resetOnChange: makeBooleanProp(true),
47
+ /**
48
+ * 错误提示类型
49
+ */
50
+ errorType: {
51
+ type: String as PropType<'toast' | 'message' | 'none'>,
52
+ default: 'message'
53
+ },
54
+ // ========== 公共配置属性(可被 form-item 继承)==========
55
+ /**
56
+ * 是否展示边框线
57
+ * 类型: boolean
58
+ * 默认值: false
59
+ */
60
+ border: makeBooleanProp(false),
61
+ /**
62
+ * 是否使内容垂直居中
63
+ * 类型: boolean
64
+ * 默认值: false
65
+ */
66
+ center: makeBooleanProp(false),
67
+ /**
68
+ * 单元格大小,可选值: 'large'
69
+ * 类型: CellSize
70
+ */
71
+ size: String as PropType<CellSize>,
72
+ /**
73
+ * 左侧标题宽度
74
+ * 类型: string | number
75
+ */
76
+ titleWidth: numericProp,
77
+ /**
78
+ * 单元格布局方式
79
+ * 类型: CellLayout
80
+ * 可选值: 'horizontal' | 'vertical'
81
+ */
82
+ layout: String as PropType<CellLayout>,
83
+ /**
84
+ * 右侧内容对齐方式
85
+ * 类型: CellValueAlign
86
+ * 可选值: 'left' | 'right' | 'center'
87
+ */
88
+ valueAlign: String as PropType<CellValueAlign>,
89
+ /**
90
+ * 必填星号位置
91
+ * 类型: CellAsteriskPosition
92
+ * 可选值: 'start' | 'end'
93
+ */
94
+ asteriskPosition: String as PropType<CellAsteriskPosition>,
95
+ /**
96
+ * 是否隐藏必填星号
97
+ * 类型: boolean
98
+ * 默认值: false
99
+ */
100
+ hideAsterisk: makeBooleanProp(false),
101
+ /**
102
+ * 是否超出隐藏显示省略号
103
+ * 类型: boolean
104
+ * 默认值: false
105
+ */
106
+ ellipsis: makeBooleanProp(false)
107
+ }
108
+ export type FormProps = ExtractPropTypes<typeof formProps>
109
+
110
+ export type FormExpose = {
111
+ /**
112
+ * 表单校验
113
+ * @param prop 指定校验字段
114
+ */
115
+ validate: (prop?: string | Array<string>) => Promise<{
116
+ valid: boolean
117
+ errors: ErrorMessage[]
118
+ }>
119
+ /**
120
+ * 重置表单项的验证提示
121
+ */
122
+ reset: () => void
123
+ }
124
+
125
+ export type FormProvide = {
126
+ props: Partial<FormProps>
127
+ errorMessages?: Record<string, string>
128
+ validate?: (prop?: string | string[]) => Promise<{ valid: boolean; errors: ErrorMessage[] }>
129
+ }
130
+
131
+ export const FORM_KEY: InjectionKey<FormProvide> = Symbol('wd-form')
132
+
133
+ export type FormInstance = ComponentPublicInstance<FormProps, FormExpose>
@@ -0,0 +1,121 @@
1
+ <template>
2
+ <view :class="`wd-form ${customClass}`" :style="customStyle">
3
+ <slot></slot>
4
+ <wd-toast v-if="props.errorType === 'toast'" selector="wd-form-toast" />
5
+ </view>
6
+ </template>
7
+
8
+ <script lang="ts">
9
+ export default {
10
+ name: 'wd-form',
11
+ options: {
12
+ addGlobalClass: true,
13
+ // #ifndef MP-TOUTIAO
14
+ virtualHost: true,
15
+ // #endif
16
+ styleIsolation: 'shared'
17
+ }
18
+ }
19
+ </script>
20
+
21
+ <script lang="ts" setup>
22
+ import wdToast from '../wd-toast/wd-toast.vue'
23
+ import { reactive, watch } from 'vue'
24
+ import { isArray, isDef } from '../../common/util'
25
+ import { useChildren } from '../../composables/useChildren'
26
+ import { useToast } from '../wd-toast'
27
+ import { FORM_KEY, type ErrorMessage, formProps, type FormExpose, type FormSchemaIssue } from './types'
28
+
29
+ const { show: showToast } = useToast('wd-form-toast')
30
+ const props = defineProps(formProps)
31
+
32
+ const { children, linkChildren } = useChildren(FORM_KEY)
33
+ let errorMessages = reactive<Record<string, string>>({})
34
+
35
+ linkChildren({ props, errorMessages, validate })
36
+
37
+ watch(
38
+ () => props.model,
39
+ () => {
40
+ if (props.resetOnChange) {
41
+ clearMessage()
42
+ }
43
+ },
44
+ { immediate: true, deep: true }
45
+ )
46
+
47
+ /**
48
+ * 表单校验
49
+ * @param prop 指定校验字段或字段数组
50
+ */
51
+ async function validate(prop?: string | string[]): Promise<{ valid: boolean; errors: ErrorMessage[] }> {
52
+ const propsToValidate = isArray(prop) ? prop : isDef(prop) ? [prop] : []
53
+ const rawIssues: FormSchemaIssue[] = props.schema ? await Promise.resolve(props.schema.validate(props.model)) : []
54
+ const errors = rawIssues
55
+ .filter((issue) => issue.path && issue.path.length > 0 && issue.message)
56
+ .map((issue) => ({
57
+ prop: issue.path.map((item) => String(item)).join('.'),
58
+ message: issue.message
59
+ }))
60
+ const filteredErrors =
61
+ propsToValidate.length > 0
62
+ ? errors.filter((error) =>
63
+ propsToValidate.some((target) => error.prop === target || error.prop.startsWith(`${target}.`) || target.startsWith(`${error.prop}.`))
64
+ )
65
+ : errors
66
+ const valid = filteredErrors.length === 0
67
+
68
+ showMessage(filteredErrors)
69
+
70
+ if (valid) {
71
+ if (propsToValidate.length) {
72
+ propsToValidate.forEach(clearMessage)
73
+ } else {
74
+ clearMessage()
75
+ }
76
+ }
77
+
78
+ return {
79
+ valid,
80
+ errors: filteredErrors
81
+ }
82
+ }
83
+
84
+ function showMessage(errors: ErrorMessage[]) {
85
+ const childrenProps = children.map((e) => e.prop).filter(Boolean)
86
+ const messages = errors.filter((error) => error.message && childrenProps.includes(error.prop))
87
+ if (messages.length) {
88
+ messages.sort((a, b) => {
89
+ return childrenProps.indexOf(a.prop) - childrenProps.indexOf(b.prop)
90
+ })
91
+ if (props.errorType === 'toast') {
92
+ showToast(messages[0].message)
93
+ } else if (props.errorType === 'message') {
94
+ messages.forEach((error) => {
95
+ errorMessages[error.prop] = error.message
96
+ })
97
+ }
98
+ }
99
+ }
100
+
101
+ function clearMessage(prop?: string) {
102
+ if (prop) {
103
+ errorMessages[prop] = ''
104
+ } else {
105
+ Object.keys(errorMessages).forEach((key) => {
106
+ errorMessages[key] = ''
107
+ })
108
+ }
109
+ }
110
+
111
+ /**
112
+ * 重置表单项的验证提示
113
+ */
114
+ function reset() {
115
+ clearMessage()
116
+ }
117
+
118
+ defineExpose<FormExpose>({ validate, reset })
119
+ </script>
120
+
121
+ <style lang="scss" scoped></style>
@@ -0,0 +1,26 @@
1
+ @use '../../styles/variable.scss' as *;
2
+ @use '../../styles/mixin/mixin.scss' as *;
3
+
4
+ // 错误提示文字颜色
5
+ $form-item-error-message-color: var(--wot-form-item-error-message-color, $danger-main) !default;
6
+ // 错误提示文字字号
7
+ $form-item-error-message-font-size: var(--wot-form-item-error-message-font-size, $typography-label-size-main) !default;
8
+ // 错误提示文字行高
9
+ $form-item-error-message-line-height: var(--wot-form-item-error-message-line-height, $typography-label-line--height-size-small) !default;
10
+ // 错误提示顶部外边距
11
+ $form-item-error-message-margin-top: var(--wot-form-item-error-message-margin-top, $spacing-super-tight) !default;
12
+ // 占位符文字颜色
13
+ $form-item-placeholder-color: var(--wot-form-item-placeholder-color, $text-placeholder) !default;
14
+
15
+ @include b(form-item) {
16
+ @include e(placeholder) {
17
+ color: $form-item-placeholder-color;
18
+ }
19
+
20
+ @include e(error-message) {
21
+ color: $form-item-error-message-color;
22
+ font-size: $form-item-error-message-font-size;
23
+ line-height: $form-item-error-message-line-height;
24
+ margin-top: $form-item-error-message-margin-top;
25
+ }
26
+ }
@@ -0,0 +1,134 @@
1
+ import type { ExtractPropTypes, InjectionKey, PropType } from 'vue'
2
+ import { baseProps, makeBooleanProp, makeStringProp, numericProp } from '../../common/props'
3
+ import { type CellValueAlign, type CellAsteriskPosition, type CellLayout, type CellSize } from '../wd-cell/types'
4
+ import type { FormValidateEvent, FormValidateTrigger } from '../wd-form/types'
5
+
6
+ export type FormItemValidateProvide = {
7
+ prop?: string
8
+ shouldTrigger: (event: FormValidateEvent) => boolean
9
+ validateByTrigger: (event: FormValidateEvent) => Promise<void>
10
+ }
11
+
12
+ export const FORM_ITEM_VALIDATE_KEY: InjectionKey<FormItemValidateProvide> = Symbol('wd-form-item-validate')
13
+
14
+ export const formItemProps = {
15
+ ...baseProps,
16
+ /**
17
+ * 表单域 model 字段名
18
+ */
19
+ prop: String,
20
+ /**
21
+ * 标题
22
+ */
23
+ title: String,
24
+ /**
25
+ * 右侧展示值,用于配合 placeholder 判断是否显示占位文字
26
+ * 类型: string | number
27
+ */
28
+ value: numericProp,
29
+ /**
30
+ * 值为空时显示的占位文字,需与 value 配合使用
31
+ * 类型: string
32
+ */
33
+ placeholder: String,
34
+ /**
35
+ * 前置图标类名
36
+ */
37
+ prefixIcon: String,
38
+ /**
39
+ * 图标大小
40
+ */
41
+ iconSize: numericProp,
42
+ /**
43
+ * 类名前缀,用于使用自定义图标
44
+ */
45
+ iconPrefix: String,
46
+ /**
47
+ * 描述信息
48
+ */
49
+ label: String,
50
+ /**
51
+ * 是否开启点击反馈
52
+ */
53
+ clickable: makeBooleanProp(false),
54
+ /**
55
+ * 是否展示右侧箭头并开启点击反馈
56
+ */
57
+ isLink: makeBooleanProp(false),
58
+ // ========== 可继承属性(使用 undefined 默认值)==========
59
+ /**
60
+ * 设置单元格大小,可选值:large
61
+ * 类型: CellSize
62
+ */
63
+ size: String as PropType<CellSize>,
64
+ /**
65
+ * 是否展示边框线
66
+ * 类型: boolean
67
+ */
68
+ border: makeBooleanProp(void 0),
69
+ /**
70
+ * 设置左侧标题宽度
71
+ * 类型: string | number
72
+ */
73
+ titleWidth: numericProp,
74
+ /**
75
+ * 是否使内容垂直居中
76
+ * 类型: boolean
77
+ */
78
+ center: makeBooleanProp(void 0),
79
+ /**
80
+ * 是否必填
81
+ * 类型: boolean
82
+ */
83
+ required: makeBooleanProp(void 0),
84
+ /**
85
+ * 校验触发时机
86
+ */
87
+ validateTrigger: [String, Array] as PropType<FormValidateTrigger | FormValidateTrigger[]>,
88
+ /**
89
+ * 表单布局方式
90
+ * 类型: CellLayout
91
+ * 可选值: 'horizontal' | 'vertical'
92
+ */
93
+ layout: String as PropType<CellLayout>,
94
+ /**
95
+ * value 文字对齐方式
96
+ * 类型: CellValueAlign
97
+ * 可选值: 'left' | 'right' | 'center'
98
+ */
99
+ valueAlign: String as PropType<CellValueAlign>,
100
+ /**
101
+ * 是否超出隐藏,显示省略号
102
+ * 类型: boolean
103
+ */
104
+ ellipsis: makeBooleanProp(void 0),
105
+ /**
106
+ * 必填星号位置
107
+ * 类型: CellAsteriskPosition
108
+ * 可选值: 'start' | 'end'
109
+ */
110
+ asteriskPosition: String as PropType<CellAsteriskPosition>,
111
+ /**
112
+ * 是否隐藏必填星号
113
+ * 类型: boolean
114
+ */
115
+ hideAsterisk: makeBooleanProp(void 0),
116
+ /**
117
+ * 前置图标自定义样式类
118
+ */
119
+ customPrefixClass: makeStringProp(''),
120
+ /**
121
+ * label 使用 slot 时的自定义样式
122
+ */
123
+ customLabelClass: makeStringProp(''),
124
+ /**
125
+ * value 使用 slot 时的自定义样式
126
+ */
127
+ customValueClass: makeStringProp(''),
128
+ /**
129
+ * title 使用 slot 时的自定义样式
130
+ */
131
+ customTitleClass: makeStringProp('')
132
+ }
133
+
134
+ export type FormItemProps = ExtractPropTypes<typeof formItemProps>
@@ -0,0 +1,182 @@
1
+ <template>
2
+ <wd-cell
3
+ :custom-class="`wd-form-item ${customClass}`"
4
+ :custom-style="customStyle"
5
+ :use-title-slot="!!$slots.title"
6
+ :title="title"
7
+ :title-width="formItemTitleWidth"
8
+ :prefix-icon="prefixIcon"
9
+ :icon-size="iconSize"
10
+ :icon-prefix="iconPrefix"
11
+ :required="isRequired"
12
+ :size="formItemSize"
13
+ :value-align="formItemValueAlign"
14
+ :center="formItemCenter"
15
+ :ellipsis="formItemEllipsis"
16
+ :clickable="clickable"
17
+ :is-link="isLink"
18
+ :asterisk-position="formItemAsteriskPosition"
19
+ :border="formItemBorder"
20
+ :hide-asterisk="formItemHideAsterisk"
21
+ :layout="formItemLayout"
22
+ :custom-prefix-class="customPrefixClass"
23
+ :custom-label-class="customLabelClass"
24
+ :custom-title-class="customTitleClass"
25
+ :custom-value-class="customValueClass"
26
+ @click="emit('click')"
27
+ >
28
+ <template #title v-if="$slots.title">
29
+ <slot name="title"></slot>
30
+ </template>
31
+
32
+ <slot>
33
+ <text v-if="showPlaceholder" class="wd-form-item__placeholder">{{ placeholder }}</text>
34
+ <text v-else-if="isDef(value)">{{ value }}</text>
35
+ </slot>
36
+ <view v-if="errorMessage" class="wd-form-item__error-message">{{ errorMessage }}</view>
37
+ </wd-cell>
38
+ </template>
39
+ <script lang="ts">
40
+ export default {
41
+ name: 'wd-form-item',
42
+ options: {
43
+ addGlobalClass: true,
44
+ // #ifndef MP-TOUTIAO
45
+ virtualHost: true,
46
+ // #endif
47
+ styleIsolation: 'shared'
48
+ }
49
+ }
50
+ </script>
51
+
52
+ <script lang="ts" setup>
53
+ import { computed, watch } from 'vue'
54
+ import { useChildren } from '../../composables/useChildren'
55
+ import { useParent } from '../../composables/useParent'
56
+ import WdCell from '../wd-cell/wd-cell.vue'
57
+ import { FORM_KEY, FORM_VALIDATE_EVENTS, type FormValidateEvent, type FormValidateTrigger } from '../wd-form/types'
58
+ import { FORM_ITEM_VALIDATE_KEY, formItemProps } from './types'
59
+ import { getPropByPath, isDef } from '../../common/util'
60
+
61
+ const props = defineProps(formItemProps)
62
+
63
+ const { parent: form, index } = useParent(FORM_KEY)
64
+ const { linkChildren } = useChildren(FORM_ITEM_VALIDATE_KEY)
65
+
66
+ const emit = defineEmits(['click'])
67
+
68
+ function normalizeValidateTrigger(trigger?: FormValidateTrigger | FormValidateTrigger[]): FormValidateEvent[] {
69
+ const triggerList = Array.isArray(trigger) ? trigger : trigger ? [trigger] : []
70
+ return triggerList.filter((item): item is FormValidateEvent => {
71
+ return FORM_VALIDATE_EVENTS.includes(item as FormValidateEvent)
72
+ })
73
+ }
74
+
75
+ const validateTriggerSet = computed(() => {
76
+ const formTrigger = form.value?.props.validateTrigger
77
+ const currentTrigger = isDef(props.validateTrigger) ? props.validateTrigger : formTrigger
78
+ return new Set(normalizeValidateTrigger(currentTrigger))
79
+ })
80
+
81
+ function shouldTrigger(event: FormValidateEvent): boolean {
82
+ return validateTriggerSet.value.has(event)
83
+ }
84
+
85
+ async function validateByTrigger(event: FormValidateEvent): Promise<void> {
86
+ if (!props.prop || !shouldTrigger(event)) {
87
+ return
88
+ }
89
+ await form.value?.validate?.(props.prop)
90
+ }
91
+
92
+ const propValue = computed(() => {
93
+ if (!props.prop) {
94
+ return undefined
95
+ }
96
+ return getPropByPath(form.value?.props.model, props.prop)
97
+ })
98
+
99
+ watch(
100
+ () => propValue.value,
101
+ async () => {
102
+ await validateByTrigger('change')
103
+ },
104
+ {
105
+ deep: true
106
+ }
107
+ )
108
+
109
+ linkChildren({
110
+ prop: props.prop,
111
+ shouldTrigger,
112
+ validateByTrigger
113
+ })
114
+
115
+ const errorMessage = computed(() => {
116
+ if (form.value && props.prop && form.value.errorMessages && form.value.errorMessages[props.prop]) {
117
+ return form.value.errorMessages[props.prop]
118
+ } else {
119
+ return ''
120
+ }
121
+ })
122
+
123
+ const formItemBorder = computed(() => {
124
+ if (isDef(props.border)) {
125
+ return props.border
126
+ }
127
+ if (index.value > 0 && form.value && form.value.props.border) {
128
+ return true
129
+ }
130
+ return false
131
+ })
132
+
133
+ const formItemCenter = computed(() => {
134
+ return isDef(props.center) ? props.center : form.value?.props.center
135
+ })
136
+
137
+ const formItemSize = computed(() => {
138
+ return isDef(props.size) ? props.size : form.value?.props.size
139
+ })
140
+
141
+ const formItemTitleWidth = computed(() => {
142
+ return isDef(props.titleWidth) ? props.titleWidth : form.value?.props.titleWidth || '98px'
143
+ })
144
+
145
+ const formItemLayout = computed(() => {
146
+ return isDef(props.layout) ? props.layout : form.value?.props.layout || 'horizontal'
147
+ })
148
+
149
+ const formItemValueAlign = computed(() => {
150
+ return isDef(props.valueAlign) ? props.valueAlign : form.value?.props.valueAlign || 'left'
151
+ })
152
+
153
+ const formItemEllipsis = computed(() => {
154
+ return isDef(props.ellipsis) ? props.ellipsis : form.value?.props.ellipsis
155
+ })
156
+
157
+ const formItemAsteriskPosition = computed(() => {
158
+ return isDef(props.asteriskPosition) ? props.asteriskPosition : form.value?.props.asteriskPosition || 'start'
159
+ })
160
+
161
+ const formItemHideAsterisk = computed(() => {
162
+ return isDef(props.hideAsterisk) ? props.hideAsterisk : form.value?.props.hideAsterisk
163
+ })
164
+
165
+ const showPlaceholder = computed(() => {
166
+ return Boolean(props.placeholder && (props.value === '' || props.value === undefined || props.value === null))
167
+ })
168
+
169
+ const isRequired = computed(() => {
170
+ if (props.required === true) {
171
+ return true
172
+ }
173
+ if (!props.prop || !form.value?.props.schema?.isRequired) {
174
+ return false
175
+ }
176
+ return !!form.value.props.schema.isRequired(props.prop)
177
+ })
178
+ </script>
179
+
180
+ <style lang="scss">
181
+ @use './index.scss';
182
+ </style>
@@ -0,0 +1,9 @@
1
+ @use '../../styles/mixin/mixin.scss' as *;
2
+ @use '../../styles/variable.scss' as *;
3
+
4
+ @include b(gap) {
5
+ @include m(safe) {
6
+ padding-bottom: constant(safe-area-inset-bottom);
7
+ padding-bottom: env(safe-area-inset-bottom);
8
+ }
9
+ }
@@ -0,0 +1,26 @@
1
+ import type { ExtractPropTypes } from 'vue'
2
+ import { baseProps, makeBooleanProp, makeNumericProp, makeStringProp } from '../../common/props'
3
+
4
+ export const gapProps = {
5
+ ...baseProps,
6
+ /**
7
+ * 背景颜色
8
+ * 类型: string
9
+ * 默认值: 'transparent'
10
+ */
11
+ bgColor: makeStringProp('transparent'),
12
+ /**
13
+ * 是否开启底部安全区适配
14
+ * 类型: boolean
15
+ * 默认值: false
16
+ */
17
+ safeAreaBottom: makeBooleanProp(false),
18
+ /**
19
+ * 间隔槽高度,支持传入数值(单位px)或字符串(如 '20rpx')
20
+ * 类型: string | number
21
+ * 默认值: 14
22
+ */
23
+ height: makeNumericProp(14)
24
+ }
25
+
26
+ export type GapProps = ExtractPropTypes<typeof gapProps>
@@ -0,0 +1,38 @@
1
+ <template>
2
+ <view :class="`wd-gap ${safeAreaBottom ? 'wd-gap--safe' : ''} ${customClass}`" :style="rootStyle"></view>
3
+ </template>
4
+
5
+ <script lang="ts">
6
+ export default {
7
+ name: 'wd-gap',
8
+ options: {
9
+ addGlobalClass: true,
10
+ // #ifndef MP-TOUTIAO
11
+ virtualHost: true,
12
+ // #endif
13
+ styleIsolation: 'shared'
14
+ }
15
+ }
16
+ </script>
17
+
18
+ <script setup lang="ts">
19
+ import { type CSSProperties, computed } from 'vue'
20
+ import { addUnit, isDef, objToStyle } from '../../common/util'
21
+ import { gapProps } from './types'
22
+
23
+ const props = defineProps(gapProps)
24
+
25
+ const rootStyle = computed(() => {
26
+ const rootStyle: CSSProperties = {}
27
+ if (isDef(props.bgColor)) {
28
+ rootStyle['background'] = props.bgColor
29
+ }
30
+ if (isDef(props.height)) {
31
+ rootStyle['height'] = addUnit(props.height)
32
+ }
33
+ return `${objToStyle(rootStyle)}${props.customStyle}`
34
+ })
35
+ </script>
36
+ <style lang="scss">
37
+ @use './index.scss';
38
+ </style>
@@ -0,0 +1,11 @@
1
+ @use '../../styles/mixin/mixin.scss' as *;
2
+ @use '../../styles/variable.scss' as *;
3
+
4
+ @include b(grid) {
5
+ position: relative;
6
+ box-sizing: border-box;
7
+ overflow: hidden;
8
+ display: flex;
9
+ flex-wrap: wrap;
10
+ height: auto;
11
+ }