vft 0.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 (321) hide show
  1. package/package.json +54 -0
  2. package/src/app/index.ts +3 -0
  3. package/src/app/page-loading/assets/spin.gif +0 -0
  4. package/src/app/page-loading/index.less +10 -0
  5. package/src/app/page-loading/index.ts +3 -0
  6. package/src/app/page-loading/index.vue +38 -0
  7. package/src/app/table/assets/sort_triangle.png +0 -0
  8. package/src/app/table/demos/basic.vue +117 -0
  9. package/src/app/table/demos/complex.vue +2543 -0
  10. package/src/app/table/demos/index.vue +453 -0
  11. package/src/app/table/demos/rightAngle.png +0 -0
  12. package/src/app/table/header.vue +203 -0
  13. package/src/app/table/index.less +119 -0
  14. package/src/app/table/index.ts +5 -0
  15. package/src/app/table/index.vue +478 -0
  16. package/src/app/table/md/api.md +23 -0
  17. package/src/app/table/md/demo.md +3 -0
  18. package/src/app/table/types.ts +45 -0
  19. package/src/common/badge/index.scss +78 -0
  20. package/src/common/badge/index.ts +4 -0
  21. package/src/common/badge/index.vue +111 -0
  22. package/src/common/badge/types.ts +1 -0
  23. package/src/common/clamp/clamp-toggle.vue +91 -0
  24. package/src/common/clamp/index.ts +4 -0
  25. package/src/common/clamp/index.vue +247 -0
  26. package/src/common/code/index.less +321 -0
  27. package/src/common/code/index.ts +3 -0
  28. package/src/common/code/index.vue +60 -0
  29. package/src/common/config-provider/index.ts +4 -0
  30. package/src/common/config-provider/index.vue +94 -0
  31. package/src/common/config-provider/types.ts +29 -0
  32. package/src/common/icon/iconfont/iconfont.css +334 -0
  33. package/src/common/icon/index.scss +31 -0
  34. package/src/common/icon/index.ts +4 -0
  35. package/src/common/icon/index.vue +74 -0
  36. package/src/common/icon/types.ts +16 -0
  37. package/src/common/index.ts +6 -0
  38. package/src/common/message/index.ts +5 -0
  39. package/src/common/message/instance.ts +29 -0
  40. package/src/common/message/message.scss +108 -0
  41. package/src/common/message/message.ts +80 -0
  42. package/src/common/message/message.vue +162 -0
  43. package/src/common/message/method.ts +172 -0
  44. package/src/common/overlay/index.scss +14 -0
  45. package/src/common/overlay/index.ts +3 -0
  46. package/src/common/overlay/index.vue +117 -0
  47. package/src/constants/comp.ts +1 -0
  48. package/src/constants/index.ts +1 -0
  49. package/src/index.ts +3 -0
  50. package/src/page/index.ts +1 -0
  51. package/src/page/page-wrapper/index.scss +31 -0
  52. package/src/page/page-wrapper/index.ts +5 -0
  53. package/src/page/page-wrapper/index.vue +31 -0
  54. package/src/styles/vars.scss +500 -0
  55. package/src/use/index.ts +14 -0
  56. package/src/use/onPopupReopen.ts +15 -0
  57. package/src/use/use-delayed-toggle/index.ts +30 -0
  58. package/src/use/use-floating/index.ts +121 -0
  59. package/src/use/use-forward-ref.ts +35 -0
  60. package/src/use/use-global-config/index.ts +81 -0
  61. package/src/use/use-id/index.ts +43 -0
  62. package/src/use/use-model-toggle/index.ts +151 -0
  63. package/src/use/use-namespace/index.ts +91 -0
  64. package/src/use/use-ordered-children/index.ts +43 -0
  65. package/src/use/use-popper-container/index.ts +43 -0
  66. package/src/use/use-timeout/index.ts +18 -0
  67. package/src/use/use-z-index/index.ts +20 -0
  68. package/src/use/useGlobalZIndex.ts +24 -0
  69. package/src/use/useLazyRender.ts +17 -0
  70. package/src/use/useLockScroll.ts +66 -0
  71. package/src/utils/aria.ts +126 -0
  72. package/src/utils/arrays.ts +13 -0
  73. package/src/utils/error.ts +23 -0
  74. package/src/utils/event.ts +15 -0
  75. package/src/utils/helper.ts +7 -0
  76. package/src/utils/index.ts +8 -0
  77. package/src/utils/interceptor.ts +39 -0
  78. package/src/utils/mount-component.ts +65 -0
  79. package/src/utils/popper.ts +6 -0
  80. package/src/utils/rand.ts +12 -0
  81. package/src/utils/scroll.ts +101 -0
  82. package/src/utils/vnode.ts +169 -0
  83. package/src/web/avatar/index.scss +50 -0
  84. package/src/web/avatar/index.ts +3 -0
  85. package/src/web/avatar/index.vue +83 -0
  86. package/src/web/back-top/index.scss +35 -0
  87. package/src/web/back-top/index.ts +3 -0
  88. package/src/web/back-top/index.vue +72 -0
  89. package/src/web/back-top/types.ts +14 -0
  90. package/src/web/back-top/use-back-top.ts +65 -0
  91. package/src/web/cascader/index.scss +214 -0
  92. package/src/web/cascader/index.ts +5 -0
  93. package/src/web/cascader/index.vue +767 -0
  94. package/src/web/cascader-panel/config.ts +44 -0
  95. package/src/web/cascader-panel/index.scss +134 -0
  96. package/src/web/cascader-panel/index.ts +5 -0
  97. package/src/web/cascader-panel/index.vue +319 -0
  98. package/src/web/cascader-panel/menu.vue +135 -0
  99. package/src/web/cascader-panel/node-content.ts +23 -0
  100. package/src/web/cascader-panel/node.ts +218 -0
  101. package/src/web/cascader-panel/node.vue +197 -0
  102. package/src/web/cascader-panel/store.ts +83 -0
  103. package/src/web/cascader-panel/types.ts +56 -0
  104. package/src/web/cascader-panel/utils.ts +40 -0
  105. package/src/web/cascader-select/README.md +31 -0
  106. package/src/web/cascader-select/index.scss +54 -0
  107. package/src/web/cascader-select/index.ts +5 -0
  108. package/src/web/cascader-select/index.vue +132 -0
  109. package/src/web/cascader-select/types.ts +9 -0
  110. package/src/web/context-menu/createContextMenu.ts +72 -0
  111. package/src/web/context-menu/index.ts +4 -0
  112. package/src/web/context-menu/index.vue +89 -0
  113. package/src/web/context-menu/types.ts +27 -0
  114. package/src/web/context-menu/useContextMenu.ts +14 -0
  115. package/src/web/descriptions/description-item.vue +34 -0
  116. package/src/web/descriptions/description.vue +124 -0
  117. package/src/web/descriptions/descriptions-cell.ts +95 -0
  118. package/src/web/descriptions/descriptions-item.scss +68 -0
  119. package/src/web/descriptions/descriptions-row.vue +49 -0
  120. package/src/web/descriptions/descriptions.scss +153 -0
  121. package/src/web/descriptions/descriptions.type.ts +19 -0
  122. package/src/web/descriptions/index.ts +4 -0
  123. package/src/web/descriptions/token.ts +4 -0
  124. package/src/web/divider/index.scss +53 -0
  125. package/src/web/divider/index.ts +5 -0
  126. package/src/web/divider/index.vue +60 -0
  127. package/src/web/divider/types.ts +2 -0
  128. package/src/web/empty/assets/no-collect.png +0 -0
  129. package/src/web/empty/assets/no-data.png +0 -0
  130. package/src/web/empty/assets/no-filter.png +0 -0
  131. package/src/web/empty/assets/no-page-data.png +0 -0
  132. package/src/web/empty/assets/no-search.png +0 -0
  133. package/src/web/empty/constants.ts +12 -0
  134. package/src/web/empty/index.scss +57 -0
  135. package/src/web/empty/index.ts +5 -0
  136. package/src/web/empty/index.vue +96 -0
  137. package/src/web/exception/exception.png +0 -0
  138. package/src/web/exception/index.ts +3 -0
  139. package/src/web/exception/index.vue +44 -0
  140. package/src/web/filter/README.md +25 -0
  141. package/src/web/filter/index.scss +14 -0
  142. package/src/web/filter/index.ts +5 -0
  143. package/src/web/filter/index.vue +60 -0
  144. package/src/web/filter/type.ts +13 -0
  145. package/src/web/focus-trap/index.ts +6 -0
  146. package/src/web/focus-trap/index.vue +328 -0
  147. package/src/web/focus-trap/tokens.ts +23 -0
  148. package/src/web/focus-trap/utils.ts +178 -0
  149. package/src/web/full-screen/index.scss +22 -0
  150. package/src/web/full-screen/index.ts +3 -0
  151. package/src/web/full-screen/index.vue +24 -0
  152. package/src/web/icon-text/index.ts +3 -0
  153. package/src/web/icon-text/index.vue +77 -0
  154. package/src/web/image/index.scss +46 -0
  155. package/src/web/image/index.ts +5 -0
  156. package/src/web/image/index.vue +251 -0
  157. package/src/web/image/types.ts +1 -0
  158. package/src/web/index.ts +33 -0
  159. package/src/web/input/index.scss +473 -0
  160. package/src/web/input/index.ts +3 -0
  161. package/src/web/input/index.vue +533 -0
  162. package/src/web/input/utils.ts +102 -0
  163. package/src/web/layouts/blank.vue +4 -0
  164. package/src/web/layouts/footer/index.scss +31 -0
  165. package/src/web/layouts/footer/index.ts +3 -0
  166. package/src/web/layouts/footer/index.vue +38 -0
  167. package/src/web/layouts/header/index.scss +35 -0
  168. package/src/web/layouts/header/index.ts +3 -0
  169. package/src/web/layouts/header/index.vue +47 -0
  170. package/src/web/layouts/iframe/index.scss +18 -0
  171. package/src/web/layouts/iframe/index.vue +36 -0
  172. package/src/web/layouts/iframe/page.vue +30 -0
  173. package/src/web/layouts/index.ts +8 -0
  174. package/src/web/layouts/router-view-content/index.vue +70 -0
  175. package/src/web/link/index.scss +95 -0
  176. package/src/web/link/index.ts +3 -0
  177. package/src/web/link/index.vue +68 -0
  178. package/src/web/loading/directive.ts +104 -0
  179. package/src/web/loading/index.ts +6 -0
  180. package/src/web/loading/loading.scss +108 -0
  181. package/src/web/loading/loading.ts +156 -0
  182. package/src/web/loading/service.ts +145 -0
  183. package/src/web/loading/types.ts +29 -0
  184. package/src/web/logo/index.scss +31 -0
  185. package/src/web/logo/index.ts +5 -0
  186. package/src/web/logo/index.vue +45 -0
  187. package/src/web/logo/types.ts +6 -0
  188. package/src/web/menu/index.scss +336 -0
  189. package/src/web/menu/index.ts +8 -0
  190. package/src/web/menu/menu-collapse-transition.vue +62 -0
  191. package/src/web/menu/menu-item-group.vue +27 -0
  192. package/src/web/menu/menu-item.vue +126 -0
  193. package/src/web/menu/menu.vue +459 -0
  194. package/src/web/menu/sub-menu.vue +440 -0
  195. package/src/web/menu/types.ts +66 -0
  196. package/src/web/menu/use-menu-css-var.ts +11 -0
  197. package/src/web/menu/use-menu.ts +60 -0
  198. package/src/web/menu/utils/menu-bar.ts +19 -0
  199. package/src/web/menu/utils/menu-item.ts +55 -0
  200. package/src/web/menu/utils/submenu.ts +66 -0
  201. package/src/web/multiple-select-flat/index.ts +5 -0
  202. package/src/web/multiple-select-flat/index.vue +53 -0
  203. package/src/web/multiple-select-flat/types.ts +5 -0
  204. package/src/web/multiple-tabs/index.scss +16 -0
  205. package/src/web/multiple-tabs/index.ts +5 -0
  206. package/src/web/multiple-tabs/index.vue +193 -0
  207. package/src/web/multiple-tabs/tab-content.vue +40 -0
  208. package/src/web/multiple-tabs/types.ts +3 -0
  209. package/src/web/multiple-tabs/use/index.ts +2 -0
  210. package/src/web/multiple-tabs/use/use-multiple-tabs.ts +86 -0
  211. package/src/web/multiple-tabs/use/use-tab-dropdown.ts +101 -0
  212. package/src/web/nodata/README.md +42 -0
  213. package/src/web/nodata/fail.vue +13 -0
  214. package/src/web/nodata/img/100.png +0 -0
  215. package/src/web/nodata/img/101.png +0 -0
  216. package/src/web/nodata/img/102.png +0 -0
  217. package/src/web/nodata/img/103.png +0 -0
  218. package/src/web/nodata/img/104.png +0 -0
  219. package/src/web/nodata/img/105.png +0 -0
  220. package/src/web/nodata/img/106.png +0 -0
  221. package/src/web/nodata/img/107.png +0 -0
  222. package/src/web/nodata/img/200.png +0 -0
  223. package/src/web/nodata/img/201.png +0 -0
  224. package/src/web/nodata/img/202.png +0 -0
  225. package/src/web/nodata/img/203.png +0 -0
  226. package/src/web/nodata/index.scss +37 -0
  227. package/src/web/nodata/index.ts +6 -0
  228. package/src/web/nodata/index.vue +46 -0
  229. package/src/web/nodata/types.ts +17 -0
  230. package/src/web/only-child/index.tsx +69 -0
  231. package/src/web/pagination/components/jumper.vue +49 -0
  232. package/src/web/pagination/components/next.vue +40 -0
  233. package/src/web/pagination/components/pager.vue +215 -0
  234. package/src/web/pagination/components/prev.vue +35 -0
  235. package/src/web/pagination/components/sizes.vue +76 -0
  236. package/src/web/pagination/components/total.vue +21 -0
  237. package/src/web/pagination/index.scss +231 -0
  238. package/src/web/pagination/index.ts +5 -0
  239. package/src/web/pagination/pagination.ts +363 -0
  240. package/src/web/pagination/usePagination.ts +13 -0
  241. package/src/web/popover/directive.ts +21 -0
  242. package/src/web/popover/index.scss +58 -0
  243. package/src/web/popover/index.ts +3 -0
  244. package/src/web/popover/index.vue +161 -0
  245. package/src/web/popover/types.ts +26 -0
  246. package/src/web/popper/arrow.vue +45 -0
  247. package/src/web/popper/content.vue +311 -0
  248. package/src/web/popper/index.scss +108 -0
  249. package/src/web/popper/index.ts +11 -0
  250. package/src/web/popper/popper.vue +57 -0
  251. package/src/web/popper/tokens.ts +28 -0
  252. package/src/web/popper/trigger.vue +166 -0
  253. package/src/web/popper/types.ts +49 -0
  254. package/src/web/popper/utils.ts +81 -0
  255. package/src/web/qrcode/drawCanvas.ts +32 -0
  256. package/src/web/qrcode/drawLogo.ts +82 -0
  257. package/src/web/qrcode/index.ts +5 -0
  258. package/src/web/qrcode/index.vue +107 -0
  259. package/src/web/qrcode/qrcodePlus.ts +4 -0
  260. package/src/web/qrcode/toCanvas.ts +11 -0
  261. package/src/web/qrcode/types.ts +38 -0
  262. package/src/web/result/index.scss +69 -0
  263. package/src/web/result/index.ts +3 -0
  264. package/src/web/result/index.vue +63 -0
  265. package/src/web/scrollbar/bar.vue +48 -0
  266. package/src/web/scrollbar/index.scss +91 -0
  267. package/src/web/scrollbar/index.ts +5 -0
  268. package/src/web/scrollbar/index.vue +236 -0
  269. package/src/web/scrollbar/thumb.vue +183 -0
  270. package/src/web/scrollbar/tokens.ts +10 -0
  271. package/src/web/scrollbar/types.ts +7 -0
  272. package/src/web/scrollbar/util.ts +38 -0
  273. package/src/web/select/constants.ts +13 -0
  274. package/src/web/select/index.ts +11 -0
  275. package/src/web/select/index.vue +555 -0
  276. package/src/web/select/option-group.scss +49 -0
  277. package/src/web/select/option-group.vue +97 -0
  278. package/src/web/select/option-item.scss +66 -0
  279. package/src/web/select/option.scss +32 -0
  280. package/src/web/select/option.vue +110 -0
  281. package/src/web/select/select-dropdown.scss +86 -0
  282. package/src/web/select/select-dropdown.vue +51 -0
  283. package/src/web/select/select.scss +213 -0
  284. package/src/web/select/token.ts +56 -0
  285. package/src/web/select/useOption.ts +146 -0
  286. package/src/web/select/useSelect.ts +942 -0
  287. package/src/web/select/utils.ts +5 -0
  288. package/src/web/side-menu/index.scss +66 -0
  289. package/src/web/side-menu/index.ts +4 -0
  290. package/src/web/side-menu/index.vue +228 -0
  291. package/src/web/side-menu/types.ts +20 -0
  292. package/src/web/single-select/index.scss +60 -0
  293. package/src/web/single-select/index.ts +5 -0
  294. package/src/web/single-select/index.vue +70 -0
  295. package/src/web/single-select/select@2x.png +0 -0
  296. package/src/web/single-select/types.ts +5 -0
  297. package/src/web/svg/index.ts +3 -0
  298. package/src/web/svg/index.vue +22 -0
  299. package/src/web/tabs/index.scss +579 -0
  300. package/src/web/tabs/index.ts +6 -0
  301. package/src/web/tabs/index.vue +236 -0
  302. package/src/web/tabs/tab-bar.vue +90 -0
  303. package/src/web/tabs/tab-nav.vue +403 -0
  304. package/src/web/tabs/tab-pane.vue +90 -0
  305. package/src/web/tabs/types.ts +66 -0
  306. package/src/web/tag/index.scss +182 -0
  307. package/src/web/tag/index.ts +5 -0
  308. package/src/web/tag/index.vue +78 -0
  309. package/src/web/tag/types.ts +2 -0
  310. package/src/web/tooltip/content.vue +239 -0
  311. package/src/web/tooltip/index.ts +4 -0
  312. package/src/web/tooltip/tokens.ts +21 -0
  313. package/src/web/tooltip/tooltip.vue +270 -0
  314. package/src/web/tooltip/trigger.vue +119 -0
  315. package/src/web/tooltip/types.ts +56 -0
  316. package/src/web/tooltip/utils.ts +20 -0
  317. package/src/web/transition/collapse-transition.vue +73 -0
  318. package/src/web/transition/index.ts +5 -0
  319. package/tsconfig.json +8 -0
  320. package/types/component.ts +1 -0
  321. package/types/index.d.ts +286 -0
@@ -0,0 +1,126 @@
1
+ const FOCUSABLE_ELEMENT_SELECTORS = 'a[href],button:not([disabled]),button:not([hidden]),:not([tabindex="-1"]),input:not([disabled]),input:not([type="hidden"]),select:not([disabled]),textarea:not([disabled])';
2
+
3
+ /**
4
+ * Determine if the testing element is visible on screen no matter if its on the viewport or not
5
+ */
6
+ export const isVisible = (element: HTMLElement) => {
7
+ if (process.env.NODE_ENV === 'test') return true;
8
+ const computed = getComputedStyle(element);
9
+ // element.offsetParent won't work on fix positioned
10
+ // WARNING: potential issue here, going to need some expert advices on this issue
11
+ return computed.position === 'fixed' ? false : element.offsetParent !== null;
12
+ };
13
+
14
+ export const obtainAllFocusableElements = (
15
+ element: HTMLElement
16
+ ): HTMLElement[] => {
17
+ return Array.from(
18
+ element.querySelectorAll<HTMLElement>(FOCUSABLE_ELEMENT_SELECTORS)
19
+ ).filter((item: HTMLElement) => isFocusable(item) && isVisible(item));
20
+ };
21
+
22
+ /**
23
+ * @desc Determine if target element is focusable
24
+ * @param element {HTMLElement}
25
+ * @returns {Boolean} true if it is focusable
26
+ */
27
+ export const isFocusable = (element: HTMLElement): boolean => {
28
+ if (
29
+ element.tabIndex > 0 ||
30
+ (element.tabIndex === 0 && element.getAttribute('tabIndex') !== null)
31
+ ) {
32
+ return true;
33
+ }
34
+ // HTMLButtonElement has disabled
35
+ if ((element as HTMLButtonElement).disabled) {
36
+ return false;
37
+ }
38
+
39
+ switch (element.nodeName) {
40
+ case 'A': {
41
+ // casting current element to Specific HTMLElement in order to be more type precise
42
+ return (
43
+ !!(element as HTMLAnchorElement).href &&
44
+ (element as HTMLAnchorElement).rel !== 'ignore'
45
+ );
46
+ }
47
+ case 'INPUT': {
48
+ return !(
49
+ (element as HTMLInputElement).type === 'hidden' ||
50
+ (element as HTMLInputElement).type === 'file'
51
+ );
52
+ }
53
+ case 'BUTTON':
54
+ case 'SELECT':
55
+ case 'TEXTAREA': {
56
+ return true;
57
+ }
58
+ default: {
59
+ return false;
60
+ }
61
+ }
62
+ };
63
+
64
+ /**
65
+ * @desc Set Attempt to set focus on the current node.
66
+ * @param element
67
+ * The node to attempt to focus on.
68
+ * @returns
69
+ * true if element is focused.
70
+ */
71
+ export const attemptFocus = (element: HTMLElement): boolean => {
72
+ if (!isFocusable(element)) {
73
+ return false;
74
+ }
75
+ // Remove the old try catch block since there will be no error to be thrown
76
+ element.focus?.();
77
+ return document.activeElement === element;
78
+ };
79
+
80
+ /**
81
+ * Trigger an event
82
+ * mouseenter, mouseleave, mouseover, keyup, change, click, etc.
83
+ * @param {HTMLElement} elm
84
+ * @param {String} name
85
+ * @param {*} opts
86
+ */
87
+ export const triggerEvent = function (
88
+ elm: HTMLElement,
89
+ name: string,
90
+ ...opts: Array<boolean>
91
+ ): HTMLElement {
92
+ let eventName: string;
93
+
94
+ if (name.includes('mouse') || name.includes('click')) {
95
+ eventName = 'MouseEvents';
96
+ } else if (name.includes('key')) {
97
+ eventName = 'KeyboardEvent';
98
+ } else {
99
+ eventName = 'HTMLEvents';
100
+ }
101
+ const evt = document.createEvent(eventName);
102
+
103
+ evt.initEvent(name, ...opts);
104
+ elm.dispatchEvent(evt);
105
+ return elm;
106
+ };
107
+
108
+ export const isLeaf = (el: HTMLElement) => !el.getAttribute('aria-owns');
109
+
110
+ export const getSibling = (
111
+ el: HTMLElement,
112
+ distance: number,
113
+ elClass: string
114
+ ) => {
115
+ const { parentNode } = el;
116
+ if (!parentNode) return null;
117
+ const siblings = parentNode.querySelectorAll(elClass);
118
+ const index = Array.prototype.indexOf.call(siblings, el);
119
+ return siblings[index + distance] || null;
120
+ };
121
+
122
+ export const focusNode = (el: HTMLElement) => {
123
+ if (!el) return;
124
+ el.focus();
125
+ !isLeaf(el) && el.click();
126
+ };
@@ -0,0 +1,13 @@
1
+ export const unique = <T>(arr: T[]) => [...new Set(arr)];
2
+
3
+ type Many<T> = T | ReadonlyArray<T>
4
+ // TODO: rename to `ensureArray`
5
+ /** like `_.castArray`, except falsy value returns empty array. */
6
+ export const castArray = <T>(arr: Many<T>): T[] => {
7
+ if (!arr && (arr as any) !== 0) return [];
8
+ return Array.isArray(arr) ? arr : [arr];
9
+ };
10
+
11
+ // TODO: remove import alias
12
+ // avoid naming conflicts
13
+ export { castArray as ensureArray } from 'lodash';
@@ -0,0 +1,23 @@
1
+ import { isString } from '@vri/utils';
2
+
3
+ class VriError extends Error {
4
+ constructor(m: string) {
5
+ super(m);
6
+ this.name = 'VriError';
7
+ }
8
+ }
9
+
10
+ export function throwError(scope: string, m: string): never {
11
+ throw new VriError(`[${scope}] ${m}`);
12
+ }
13
+
14
+ export function debugWarn(err: Error): void
15
+ export function debugWarn(scope: string, message: string): void
16
+ export function debugWarn(scope: string | Error, message?: string): void {
17
+ if (process.env.NODE_ENV !== 'production') {
18
+ const error: Error = isString(scope)
19
+ ? new VriError(`[${scope}] ${message}`)
20
+ : scope;
21
+ console.warn(error);
22
+ }
23
+ }
@@ -0,0 +1,15 @@
1
+ export const composeEventHandlers = <E>(theirsHandler?: (event: E) => boolean | void, oursHandler?: (event: E) => void, { checkForDefaultPrevented = true } = {}) => {
2
+ const handleEvent = (event: E) => {
3
+ const shouldPrevent = theirsHandler?.(event);
4
+
5
+ if (checkForDefaultPrevented === false || !shouldPrevent) {
6
+ return oursHandler?.(event);
7
+ }
8
+ };
9
+ return handleEvent;
10
+ };
11
+
12
+ type WhenMouseHandler = (e: PointerEvent) => any;
13
+ export const whenMouse = (handler: WhenMouseHandler): WhenMouseHandler => {
14
+ return (e: PointerEvent) => (e.pointerType === 'mouse' ? handler(e) : undefined);
15
+ };
@@ -0,0 +1,7 @@
1
+ export const getSizeType = (type) => {
2
+ const typeList = ['large', 'small'];
3
+ if (typeList.includes(type)) {
4
+ return type;
5
+ }
6
+ return false;
7
+ };
@@ -0,0 +1,8 @@
1
+ export * from './error';
2
+ export * from './vnode';
3
+ export * from './event';
4
+ export * from './scroll';
5
+ export * from './aria';
6
+ export * from './arrays';
7
+ export * from './rand';
8
+ export * from './helper';
@@ -0,0 +1,39 @@
1
+ import { isPromise, noop } from '@vri/utils';
2
+
3
+ export type Interceptor = (...args: any[]) => Promise<boolean> | boolean | undefined | void;
4
+
5
+ export function callInterceptor(
6
+ interceptor: Interceptor | undefined,
7
+ {
8
+ args = [],
9
+ done,
10
+ canceled
11
+ }: {
12
+ args?: unknown[];
13
+ done: () => void;
14
+ canceled?: () => void;
15
+ }
16
+ ) {
17
+ if (interceptor) {
18
+ // eslint-disable-next-line prefer-spread
19
+ const returnVal = interceptor.apply(null, args);
20
+
21
+ if (isPromise(returnVal)) {
22
+ returnVal
23
+ .then((value) => {
24
+ if (value) {
25
+ done();
26
+ } else if (canceled) {
27
+ canceled();
28
+ }
29
+ })
30
+ .catch(noop);
31
+ } else if (returnVal) {
32
+ done();
33
+ } else if (canceled) {
34
+ canceled();
35
+ }
36
+ } else {
37
+ done();
38
+ }
39
+ }
@@ -0,0 +1,65 @@
1
+ import { createApp, reactive, type Component } from 'vue';
2
+ import { useExpose } from '@vri/use';
3
+
4
+ /**
5
+ * @description popup 组件的状态控制
6
+ * @author wfd
7
+ * @date 2022/7/13 13:40
8
+ * @example
9
+ */
10
+ export function usePopupState() {
11
+ const state = reactive<{
12
+ show: boolean;
13
+ [key: string]: any;
14
+ }>({
15
+ show: false
16
+ });
17
+
18
+ // 切换 show 的状态
19
+ const toggle = (show: boolean) => {
20
+ state.show = show;
21
+ };
22
+
23
+ // 如果是 open 说明是打开 popup,transitionAppear 设置为 true
24
+ const open = (props: Record<string, any>) => {
25
+ // 这里直接用 Object.assign 的原因是可以,合并后 state 会被直接改变
26
+ Object.assign(state, props, { transitionAppear: true });
27
+ // 将 show 改为 true
28
+ toggle(true);
29
+ };
30
+
31
+ // 关闭 popup 事件
32
+ const close = () => toggle(false);
33
+
34
+ // 将 open, close, toggle 合并到 instance 实例对象的 proxy 属性中
35
+ useExpose({ open, close, toggle });
36
+
37
+ return {
38
+ open,
39
+ close,
40
+ state,
41
+ toggle
42
+ };
43
+ }
44
+
45
+ /**
46
+ * @description mountComponent
47
+ * @author wfd
48
+ * @date 2022/7/12 20:13
49
+ * @example
50
+ * @param RootComponent
51
+ */
52
+ export function mountComponent(RootComponent: Component) {
53
+ const app = createApp(RootComponent);
54
+ const root = document.createElement('div');
55
+
56
+ document.body.appendChild(root);
57
+
58
+ return {
59
+ instance: app.mount(root),
60
+ unmount() {
61
+ app.unmount();
62
+ document.body.removeChild(root);
63
+ }
64
+ };
65
+ }
@@ -0,0 +1,6 @@
1
+ import { createPopper } from '@popperjs/core/lib/popper-lite';
2
+ import offsetModifier from '@popperjs/core/lib/modifiers/offset';
3
+ import type { Instance, Placement } from '@popperjs/core';
4
+
5
+ export { createPopper, offsetModifier };
6
+ export type { Instance, Placement };
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Generate random number in range [0, 1000]
3
+ * Maybe replace with [uuid](https://www.npmjs.com/package/uuid)
4
+ */
5
+ export const generateId = (): number => Math.floor(Math.random() * 10000);
6
+
7
+ /**
8
+ * Generating a random int in range (0, max - 1)
9
+ * @param max {number}
10
+ */
11
+ export const getRandomInt = (max: number) =>
12
+ Math.floor(Math.random() * Math.floor(max));
@@ -0,0 +1,101 @@
1
+ import { isClient } from '@vueuse/core';
2
+ import { getStyle } from '@vri/utils';
3
+
4
+ export const isScroll = (el: HTMLElement, isVertical?: boolean): boolean => {
5
+ if (!isClient) return false;
6
+
7
+ const key = (
8
+ {
9
+ undefined: 'overflow',
10
+ true: 'overflow-y',
11
+ false: 'overflow-x'
12
+ } as const
13
+ )[String(isVertical)]!;
14
+ const overflow = getStyle(el, key);
15
+ return ['scroll', 'auto', 'overlay'].some((s) => overflow.includes(s));
16
+ };
17
+
18
+ export const getScrollContainer = (
19
+ el: HTMLElement,
20
+ isVertical?: boolean
21
+ ): Window | HTMLElement | undefined => {
22
+ if (!isClient) return;
23
+
24
+ let parent: HTMLElement = el;
25
+ while (parent) {
26
+ if ([window, document, document.documentElement].includes(parent))
27
+ return window;
28
+
29
+ if (isScroll(parent, isVertical)) return parent;
30
+
31
+ parent = parent.parentNode as HTMLElement;
32
+ }
33
+
34
+ return parent;
35
+ };
36
+
37
+ let scrollBarWidth: number;
38
+ export const getScrollBarWidth = (namespace: string): number => {
39
+ if (!isClient) return 0;
40
+ if (scrollBarWidth !== undefined) return scrollBarWidth;
41
+
42
+ const outer = document.createElement('div');
43
+ outer.className = `${namespace}-scrollbar__wrap`;
44
+ outer.style.visibility = 'hidden';
45
+ outer.style.width = '100px';
46
+ outer.style.position = 'absolute';
47
+ outer.style.top = '-9999px';
48
+ document.body.appendChild(outer);
49
+
50
+ const widthNoScroll = outer.offsetWidth;
51
+ outer.style.overflow = 'scroll';
52
+
53
+ const inner = document.createElement('div');
54
+ inner.style.width = '100%';
55
+ outer.appendChild(inner);
56
+
57
+ const widthWithScroll = inner.offsetWidth;
58
+ outer.parentNode?.removeChild(outer);
59
+ scrollBarWidth = widthNoScroll - widthWithScroll;
60
+
61
+ return scrollBarWidth;
62
+ };
63
+
64
+ /**
65
+ * Scroll with in the container element, positioning the **selected** element at the top
66
+ * of the container
67
+ */
68
+ export function scrollIntoView(
69
+ container: HTMLElement,
70
+ selected: HTMLElement
71
+ ): void {
72
+ if (!isClient) return;
73
+
74
+ if (!selected) {
75
+ container.scrollTop = 0;
76
+ return;
77
+ }
78
+
79
+ const offsetParents: HTMLElement[] = [];
80
+ let pointer = selected.offsetParent;
81
+ while (
82
+ pointer !== null &&
83
+ container !== pointer &&
84
+ container.contains(pointer)
85
+ ) {
86
+ offsetParents.push(pointer as HTMLElement);
87
+ pointer = (pointer as HTMLElement).offsetParent;
88
+ }
89
+ const top =
90
+ selected.offsetTop +
91
+ offsetParents.reduce((prev, curr) => prev + curr.offsetTop, 0);
92
+ const bottom = top + selected.offsetHeight;
93
+ const viewRectTop = container.scrollTop;
94
+ const viewRectBottom = viewRectTop + container.clientHeight;
95
+
96
+ if (top < viewRectTop) {
97
+ container.scrollTop = top;
98
+ } else if (bottom > viewRectBottom) {
99
+ container.scrollTop = bottom - container.clientHeight;
100
+ }
101
+ }
@@ -0,0 +1,169 @@
1
+ import {
2
+ Comment,
3
+ Fragment,
4
+ Text,
5
+ createBlock,
6
+ createCommentVNode,
7
+ isVNode,
8
+ openBlock
9
+ } from 'vue';
10
+ import { camelize, hasOwn, isArray } from '@vue/shared';
11
+ import { debugWarn } from './error';
12
+ import type {
13
+ VNode,
14
+ VNodeArrayChildren,
15
+ VNodeChild,
16
+ VNodeNormalizedChildren
17
+ } from 'vue';
18
+
19
+ const SCOPE = 'utils/vue/vnode';
20
+
21
+ export enum PatchFlags {
22
+ TEXT = 1,
23
+ CLASS = 2,
24
+ STYLE = 4,
25
+ PROPS = 8,
26
+ FULL_PROPS = 16,
27
+ HYDRATE_EVENTS = 32,
28
+ STABLE_FRAGMENT = 64,
29
+ KEYED_FRAGMENT = 128,
30
+ UNKEYED_FRAGMENT = 256,
31
+ NEED_PATCH = 512,
32
+ DYNAMIC_SLOTS = 1024,
33
+ HOISTED = -1,
34
+ BAIL = -2,
35
+ }
36
+
37
+ export type VNodeChildAtom = Exclude<VNodeChild, Array<any>>
38
+ export type RawSlots = Exclude<
39
+ VNodeNormalizedChildren,
40
+ Array<any> | null | string
41
+ >
42
+
43
+ export function isFragment(node: VNode): boolean
44
+ export function isFragment(node: unknown): node is VNode
45
+ export function isFragment(node: unknown): node is VNode {
46
+ return isVNode(node) && node.type === Fragment;
47
+ }
48
+
49
+ export function isText(node: VNode): boolean
50
+ export function isText(node: unknown): node is VNode
51
+ export function isText(node: unknown): node is VNode {
52
+ return isVNode(node) && node.type === Text;
53
+ }
54
+
55
+ export function isComment(node: VNode): boolean
56
+ export function isComment(node: unknown): node is VNode
57
+ export function isComment(node: unknown): node is VNode {
58
+ return isVNode(node) && node.type === Comment;
59
+ }
60
+
61
+ const TEMPLATE = 'template';
62
+ export function isTemplate(node: VNode): boolean
63
+ export function isTemplate(node: unknown): node is VNode
64
+ export function isTemplate(node: unknown): node is VNode {
65
+ return isVNode(node) && node.type === TEMPLATE;
66
+ }
67
+
68
+ /**
69
+ * determine if the element is a valid element type rather than fragments and comment e.g. <template> v-if
70
+ * @param node {VNode} node to be tested
71
+ */
72
+ export function isValidElementNode(node: VNode): boolean
73
+ export function isValidElementNode(node: unknown): node is VNode
74
+ export function isValidElementNode(node: unknown): node is VNode {
75
+ return isVNode(node) && !isFragment(node) && !isComment(node);
76
+ }
77
+
78
+ /**
79
+ * get a valid child node (not fragment nor comment)
80
+ * @param node {VNode} node to be searched
81
+ * @param depth {number} depth to be searched
82
+ */
83
+ function getChildren(
84
+ node: VNodeNormalizedChildren | VNodeChild,
85
+ depth: number
86
+ ): VNodeNormalizedChildren | VNodeChild {
87
+ if (isComment(node)) return;
88
+ if (isFragment(node) || isTemplate(node)) {
89
+ return depth > 0 ? getFirstValidNode(node.children, depth - 1) : undefined;
90
+ }
91
+ return node;
92
+ }
93
+
94
+ export const getFirstValidNode = (
95
+ nodes: VNodeNormalizedChildren,
96
+ maxDepth = 3
97
+ ) => {
98
+ if (Array.isArray(nodes)) {
99
+ return getChildren(nodes[0], maxDepth);
100
+ } else {
101
+ return getChildren(nodes, maxDepth);
102
+ }
103
+ };
104
+
105
+ export function renderIf(
106
+ condition: boolean,
107
+ ...args: Parameters<typeof createBlock>
108
+ ) {
109
+ return condition ? renderBlock(...args) : createCommentVNode('v-if', true);
110
+ }
111
+
112
+ export function renderBlock(...args: Parameters<typeof createBlock>) {
113
+ return openBlock(), createBlock(...args);
114
+ }
115
+
116
+ export const getNormalizedProps = (node: VNode) => {
117
+ if (!isVNode(node)) {
118
+ debugWarn(SCOPE, '[getNormalizedProps] must be a VNode');
119
+ return {};
120
+ }
121
+
122
+ const raw = node.props || {};
123
+ const type = (isVNode(node.type) ? node.type.props : undefined) || {};
124
+ const props: Record<string, any> = {};
125
+
126
+ Object.keys(type).forEach((key) => {
127
+ if (hasOwn(type[key], 'default')) {
128
+ props[key] = type[key].default;
129
+ }
130
+ });
131
+
132
+ Object.keys(raw).forEach((key) => {
133
+ props[camelize(key)] = raw[key];
134
+ });
135
+
136
+ return props;
137
+ };
138
+
139
+ export const ensureOnlyChild = (children: VNodeArrayChildren | undefined) => {
140
+ if (!isArray(children) || children.length > 1) {
141
+ throw new Error('expect to receive a single Vue element child');
142
+ }
143
+ return children[0];
144
+ };
145
+
146
+ export type FlattenVNodes = Array<VNodeChildAtom | RawSlots>
147
+
148
+ export const flattedChildren = (
149
+ children: FlattenVNodes | VNode | VNodeNormalizedChildren
150
+ ): FlattenVNodes => {
151
+ // transform to array
152
+ const vNodes = isArray(children) ? children : [children];
153
+ const result: FlattenVNodes = [];
154
+
155
+ vNodes.forEach((child) => {
156
+ if (isArray(child)) {
157
+ result.push(...flattedChildren(child));
158
+ } else if (isVNode(child) && isArray(child.children)) {
159
+ result.push(...flattedChildren(child.children));
160
+ } else {
161
+ result.push(child);
162
+ if (isVNode(child) && child.component?.subTree) {
163
+ result.push(...flattedChildren(child.component.subTree));
164
+ }
165
+ }
166
+ });
167
+
168
+ return result;
169
+ };
@@ -0,0 +1,50 @@
1
+ $name: avatar;
2
+
3
+ @include set-root-css-vars($name, $avatar);
4
+
5
+ @include b($name) {
6
+ @include set-component-css-var('avatar-size', $avatar-size);
7
+
8
+ @include set-css-var-value(
9
+ ('avatar', 'size'),
10
+ map-get($avatar-size, 'default')
11
+ );
12
+
13
+ display: inline-flex;
14
+ justify-content: center;
15
+ align-items: center;
16
+ box-sizing: border-box;
17
+ text-align: center;
18
+ overflow: hidden;
19
+ color: getCssVar('avatar', 'text-color');
20
+ background: getCssVar('avatar', 'bg-color');
21
+ width: getCssVar('avatar', 'size');
22
+ height: getCssVar('avatar', 'size');
23
+ font-size: getCssVar('avatar', 'text-size');
24
+
25
+ > img {
26
+ display: block;
27
+ height: 100%;
28
+ }
29
+
30
+ @include m(circle) {
31
+ border-radius: 50%;
32
+ }
33
+
34
+ @include m(square) {
35
+ border-radius: getCssVar('avatar', 'border-radius');
36
+ }
37
+
38
+ @include m(icon) {
39
+ font-size: getCssVar('avatar', 'icon-size');
40
+ }
41
+
42
+ @each $size in (small, large) {
43
+ @include m($size) {
44
+ @include set-css-var-value(
45
+ ('avatar', 'size'),
46
+ map-get($avatar-size, $size)
47
+ );
48
+ }
49
+ }
50
+ }
@@ -0,0 +1,3 @@
1
+ import Avatar from './index.vue';
2
+
3
+ export { Avatar };