vue-devui 1.0.0-beta.8 → 1.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (278) hide show
  1. package/README.md +81 -66
  2. package/accordion/index.es.js +522 -39
  3. package/accordion/index.umd.js +1 -1
  4. package/accordion/style.css +1 -1
  5. package/alert/index.es.js +6 -7
  6. package/alert/index.umd.js +1 -1
  7. package/alert/style.css +1 -1
  8. package/{toast → auto-complete}/index.d.ts +0 -0
  9. package/auto-complete/index.es.js +976 -0
  10. package/auto-complete/index.umd.js +1 -0
  11. package/auto-complete/package.json +7 -0
  12. package/auto-complete/style.css +1 -0
  13. package/back-top/index.es.js +1 -1
  14. package/back-top/index.umd.js +1 -1
  15. package/badge/index.es.js +12 -18
  16. package/badge/index.umd.js +1 -1
  17. package/button/index.es.js +262 -82
  18. package/button/index.umd.js +1 -1
  19. package/button/style.css +1 -1
  20. package/carousel/index.es.js +7 -6
  21. package/carousel/index.umd.js +1 -1
  22. package/cascader/index.es.js +5392 -772
  23. package/cascader/index.umd.js +27 -1
  24. package/checkbox/style.css +1 -1
  25. package/color-picker/index.d.ts +7 -0
  26. package/color-picker/index.es.js +8187 -0
  27. package/color-picker/index.umd.js +27 -0
  28. package/color-picker/package.json +7 -0
  29. package/color-picker/style.css +1 -0
  30. package/comment/index.es.js +42 -13
  31. package/comment/index.umd.js +1 -1
  32. package/comment/style.css +1 -1
  33. package/countdown/index.es.js +27 -18
  34. package/countdown/index.umd.js +1 -1
  35. package/countdown/style.css +1 -1
  36. package/date-picker/index.es.js +10 -11
  37. package/date-picker/index.umd.js +1 -1
  38. package/date-picker/style.css +1 -1
  39. package/dragdrop/index.es.js +135 -10
  40. package/dragdrop/index.umd.js +1 -1
  41. package/drawer/index.es.js +169 -223
  42. package/drawer/index.umd.js +1 -1
  43. package/drawer/style.css +1 -1
  44. package/dropdown/index.es.js +408 -300
  45. package/dropdown/index.umd.js +1 -1
  46. package/dropdown/style.css +1 -1
  47. package/editable-select/index.es.js +275 -5610
  48. package/editable-select/index.umd.js +1 -27
  49. package/editable-select/style.css +1 -1
  50. package/form/index.es.js +6129 -461
  51. package/form/index.umd.js +27 -1
  52. package/form/style.css +1 -1
  53. package/fullscreen/index.es.js +110 -118
  54. package/fullscreen/index.umd.js +1 -1
  55. package/fullscreen/style.css +1 -1
  56. package/gantt/index.es.js +6 -18
  57. package/gantt/index.umd.js +1 -1
  58. package/gantt/style.css +1 -1
  59. package/grid/index.es.js +1 -1
  60. package/grid/style.css +1 -1
  61. package/icon/index.es.js +2 -1
  62. package/icon/index.umd.js +1 -1
  63. package/image-preview/index.es.js +77 -19
  64. package/image-preview/index.umd.js +1 -1
  65. package/image-preview/style.css +1 -1
  66. package/input/index.es.js +4 -5
  67. package/input/index.umd.js +1 -1
  68. package/input/style.css +1 -1
  69. package/input-icon/index.es.js +6 -6
  70. package/input-icon/index.umd.js +1 -1
  71. package/input-icon/style.css +1 -1
  72. package/input-number/index.es.js +2 -1
  73. package/input-number/index.umd.js +1 -1
  74. package/list/index.d.ts +7 -0
  75. package/list/index.es.js +39 -0
  76. package/list/index.umd.js +1 -0
  77. package/{toast → list}/package.json +1 -1
  78. package/list/style.css +1 -0
  79. package/loading/index.es.js +2 -2
  80. package/modal/index.es.js +293 -759
  81. package/modal/index.umd.js +1 -1
  82. package/modal/style.css +1 -1
  83. package/nav-sprite/index.es.js +1 -675
  84. package/nav-sprite/index.umd.js +1 -1
  85. package/notification/index.d.ts +7 -0
  86. package/notification/index.es.js +286 -0
  87. package/notification/index.umd.js +1 -0
  88. package/notification/package.json +7 -0
  89. package/notification/style.css +1 -0
  90. package/nuxt/components/Accordion.js +3 -0
  91. package/nuxt/components/Alert.js +3 -0
  92. package/nuxt/components/Anchor.js +3 -0
  93. package/nuxt/components/Aside.js +3 -0
  94. package/nuxt/components/AutoComplete.js +3 -0
  95. package/nuxt/components/Avatar.js +3 -0
  96. package/nuxt/components/BackTop.js +3 -0
  97. package/nuxt/components/Badge.js +3 -0
  98. package/nuxt/components/Breadcrumb.js +3 -0
  99. package/nuxt/components/Button.js +3 -0
  100. package/nuxt/components/Card.js +3 -0
  101. package/nuxt/components/Carousel.js +3 -0
  102. package/nuxt/components/CarouselItem.js +3 -0
  103. package/nuxt/components/Cascader.js +3 -0
  104. package/nuxt/components/Checkbox.js +3 -0
  105. package/nuxt/components/Col.js +3 -0
  106. package/nuxt/components/ColorPicker.js +3 -0
  107. package/nuxt/components/Column.js +3 -0
  108. package/nuxt/components/Comment.js +3 -0
  109. package/nuxt/components/Content.js +3 -0
  110. package/nuxt/components/Countdown.js +3 -0
  111. package/nuxt/components/DatePicker.js +3 -0
  112. package/nuxt/components/Drawer.js +3 -0
  113. package/nuxt/components/DrawerService.js +3 -0
  114. package/nuxt/components/Dropdown.js +3 -0
  115. package/nuxt/components/DropdownMenu.js +3 -0
  116. package/nuxt/components/EditableSelect.js +3 -0
  117. package/nuxt/components/FixedOverlay.js +3 -0
  118. package/nuxt/components/FlexibleOverlay.js +3 -0
  119. package/nuxt/components/Footer.js +3 -0
  120. package/nuxt/components/Form.js +3 -0
  121. package/nuxt/components/FormControl.js +3 -0
  122. package/nuxt/components/FormItem.js +3 -0
  123. package/nuxt/components/FormLabel.js +3 -0
  124. package/nuxt/components/FormOperation.js +3 -0
  125. package/nuxt/components/Fullscreen.js +3 -0
  126. package/nuxt/components/Gantt.js +3 -0
  127. package/nuxt/components/Header.js +3 -0
  128. package/nuxt/components/IFileOptions.js +3 -0
  129. package/nuxt/components/IUploadOptions.js +3 -0
  130. package/nuxt/components/Icon.js +2 -0
  131. package/nuxt/components/ImagePreviewService.js +3 -0
  132. package/nuxt/components/Input.js +3 -0
  133. package/nuxt/components/InputIcon.js +3 -0
  134. package/nuxt/components/InputNumber.js +3 -0
  135. package/nuxt/components/Layout.js +3 -0
  136. package/nuxt/components/List.js +3 -0
  137. package/nuxt/components/ListItem.js +3 -0
  138. package/nuxt/components/Loading.js +3 -0
  139. package/nuxt/components/LoadingService.js +3 -0
  140. package/nuxt/components/Modal.js +3 -0
  141. package/nuxt/components/NavSprite.js +2 -0
  142. package/nuxt/components/Notification.js +3 -0
  143. package/nuxt/components/NotificationService.js +3 -0
  144. package/nuxt/components/Pagination.js +3 -0
  145. package/nuxt/components/Panel.js +3 -0
  146. package/nuxt/components/Popover.js +3 -0
  147. package/nuxt/components/Progress.js +3 -0
  148. package/nuxt/components/QuadrantDiagram.js +3 -0
  149. package/nuxt/components/Radio.js +3 -0
  150. package/nuxt/components/RadioGroup.js +3 -0
  151. package/nuxt/components/Rate.js +3 -0
  152. package/nuxt/components/ReadTip.js +3 -0
  153. package/nuxt/components/Result.js +3 -0
  154. package/nuxt/components/Row.js +3 -0
  155. package/nuxt/components/Search.js +3 -0
  156. package/nuxt/components/Select.js +3 -0
  157. package/nuxt/components/Skeleton.js +3 -0
  158. package/nuxt/components/SkeletonItem.js +3 -0
  159. package/nuxt/components/Slider.js +3 -0
  160. package/nuxt/components/Splitter.js +3 -0
  161. package/nuxt/components/Statistic.js +3 -0
  162. package/nuxt/components/Status.js +3 -0
  163. package/nuxt/components/StepsGuide.js +3 -0
  164. package/nuxt/components/StickSlider.js +3 -0
  165. package/nuxt/components/Sticky.js +2 -0
  166. package/nuxt/components/Switch.js +3 -0
  167. package/nuxt/components/Table.js +3 -0
  168. package/nuxt/components/Tabs.js +3 -0
  169. package/nuxt/components/Tag.js +3 -0
  170. package/nuxt/components/TagInput.js +3 -0
  171. package/nuxt/components/Textarea.js +3 -0
  172. package/nuxt/components/TimeAxis.js +3 -0
  173. package/nuxt/components/TimeAxisItem.js +3 -0
  174. package/nuxt/components/TimePicker.js +3 -0
  175. package/nuxt/components/Tooltip.js +3 -0
  176. package/nuxt/components/Transfer.js +3 -0
  177. package/nuxt/components/Tree.js +3 -0
  178. package/nuxt/components/TreeSelect.js +3 -0
  179. package/nuxt/components/Upload.js +3 -0
  180. package/nuxt/components/UploadStatus.js +3 -0
  181. package/nuxt/components/badgeProps.js +3 -0
  182. package/nuxt/components/buttonProps.js +3 -0
  183. package/nuxt/components/dropdownMenuProps.js +3 -0
  184. package/nuxt/components/fixedOverlayProps.js +3 -0
  185. package/nuxt/components/flexibleOverlayProps.js +3 -0
  186. package/nuxt/components/notificationProps.js +3 -0
  187. package/nuxt/components/overlayEmits.js +3 -0
  188. package/nuxt/components/overlayProps.js +3 -0
  189. package/nuxt/components/popoverProps.js +3 -0
  190. package/nuxt/components/tooltipProps.js +3 -0
  191. package/nuxt/components/uploadProps.js +3 -0
  192. package/nuxt/index.js +13 -0
  193. package/overlay/index.es.js +142 -198
  194. package/overlay/index.umd.js +1 -1
  195. package/overlay/style.css +1 -1
  196. package/package.json +10 -18
  197. package/pagination/index.es.js +1 -1
  198. package/pagination/style.css +1 -1
  199. package/panel/index.es.js +3 -3
  200. package/panel/index.umd.js +1 -1
  201. package/popover/index.es.js +5947 -189
  202. package/popover/index.umd.js +27 -1
  203. package/popover/style.css +1 -1
  204. package/progress/index.es.js +8 -8
  205. package/progress/index.umd.js +3 -3
  206. package/quadrant-diagram/index.es.js +5405 -166
  207. package/quadrant-diagram/index.umd.js +27 -1
  208. package/radio/index.es.js +5 -5
  209. package/radio/index.umd.js +1 -1
  210. package/radio/style.css +1 -1
  211. package/read-tip/index.es.js +17 -4
  212. package/read-tip/index.umd.js +1 -1
  213. package/read-tip/style.css +1 -1
  214. package/result/index.es.js +2 -1
  215. package/result/index.umd.js +1 -1
  216. package/ripple/index.es.js +1 -1
  217. package/search/index.es.js +5432 -198
  218. package/search/index.umd.js +27 -1
  219. package/search/style.css +1 -1
  220. package/select/index.es.js +3 -2
  221. package/select/index.umd.js +1 -1
  222. package/select/style.css +1 -1
  223. package/slider/index.es.js +2 -5
  224. package/slider/index.umd.js +1 -1
  225. package/slider/style.css +1 -1
  226. package/splitter/index.es.js +5881 -36
  227. package/splitter/index.umd.js +27 -1
  228. package/splitter/style.css +1 -1
  229. package/statistic/index.d.ts +7 -0
  230. package/statistic/index.es.js +267 -0
  231. package/statistic/index.umd.js +1 -0
  232. package/statistic/package.json +7 -0
  233. package/statistic/style.css +1 -0
  234. package/status/index.es.js +1 -1
  235. package/status/index.umd.js +1 -1
  236. package/status/style.css +1 -1
  237. package/steps-guide/index.es.js +8 -6
  238. package/steps-guide/index.umd.js +1 -1
  239. package/sticky/index.umd.js +1 -1
  240. package/style.css +1 -1
  241. package/table/index.es.js +698 -358
  242. package/table/index.umd.js +1 -1
  243. package/table/style.css +1 -1
  244. package/tabs/index.es.js +3 -4
  245. package/tabs/index.umd.js +1 -1
  246. package/tabs/style.css +1 -1
  247. package/tag/index.es.js +2 -2
  248. package/tag/index.umd.js +1 -1
  249. package/tag/style.css +1 -1
  250. package/tag-input/index.es.js +0 -12
  251. package/tag-input/index.umd.js +1 -1
  252. package/textarea/style.css +1 -1
  253. package/{theme → theme/theme.scss} +0 -0
  254. package/time-axis/index.es.js +2 -1
  255. package/time-axis/index.umd.js +1 -1
  256. package/time-picker/index.es.js +269 -84
  257. package/time-picker/index.umd.js +1 -1
  258. package/time-picker/style.css +1 -1
  259. package/tooltip/index.es.js +5798 -141
  260. package/tooltip/index.umd.js +27 -1
  261. package/tooltip/style.css +1 -1
  262. package/transfer/index.es.js +6522 -635
  263. package/transfer/index.umd.js +27 -1
  264. package/transfer/style.css +1 -1
  265. package/tree/index.es.js +5775 -192
  266. package/tree/index.umd.js +27 -1
  267. package/tree/style.css +1 -1
  268. package/tree-select/index.es.js +130 -35
  269. package/tree-select/index.umd.js +1 -1
  270. package/tree-select/style.css +1 -1
  271. package/upload/index.es.js +463 -2680
  272. package/upload/index.umd.js +1 -1
  273. package/upload/style.css +1 -1
  274. package/vue-devui.es.js +14630 -14010
  275. package/vue-devui.umd.js +18 -18
  276. package/toast/index.es.js +0 -2059
  277. package/toast/index.umd.js +0 -1
  278. package/toast/style.css +0 -1
@@ -17,16 +17,11 @@ var __spreadValues = (a, b) => {
17
17
  return a;
18
18
  };
19
19
  var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
- import { ref, watch, defineComponent, createVNode, Teleport, Transition, renderSlot, isVNode, computed, onMounted, onUnmounted, withDirectives, vShow, reactive, toRef, isRef, toRefs, Fragment } from "vue";
20
+ import { toRefs, watch, onMounted, onUnmounted, defineComponent, createVNode, Teleport, Transition, renderSlot, isVNode, computed, ref, nextTick, unref, mergeProps, Fragment } from "vue";
21
+ import { offset, autoPlacement, arrow, computePosition } from "@floating-ui/dom";
22
+ import { onClickOutside } from "@vueuse/core";
21
23
  const dropdownProps = {
22
- origin: {
23
- type: Object
24
- },
25
- isOpen: {
26
- type: Boolean,
27
- default: false
28
- },
29
- disabled: {
24
+ visible: {
30
25
  type: Boolean,
31
26
  default: false
32
27
  },
@@ -38,18 +33,23 @@ const dropdownProps = {
38
33
  type: String,
39
34
  default: "all"
40
35
  },
36
+ position: {
37
+ type: Array,
38
+ default: ["bottom"]
39
+ },
40
+ align: {
41
+ type: String,
42
+ default: null
43
+ },
44
+ offset: {
45
+ type: [Number, Object],
46
+ default: 4
47
+ },
41
48
  closeOnMouseLeaveMenu: {
42
49
  type: Boolean,
43
50
  default: false
44
- },
45
- showAnimation: {
46
- type: Boolean,
47
- default: true
48
51
  }
49
52
  };
50
- function isComponent(target) {
51
- return !!(target == null ? void 0 : target.$el);
52
- }
53
53
  function getElement(element) {
54
54
  if (element instanceof Element) {
55
55
  return element;
@@ -59,84 +59,136 @@ function getElement(element) {
59
59
  }
60
60
  return null;
61
61
  }
62
+ const dropdownMap = /* @__PURE__ */ new Map();
62
63
  function subscribeEvent(dom, type, callback) {
63
64
  dom == null ? void 0 : dom.addEventListener(type, callback);
64
65
  return () => {
65
66
  dom == null ? void 0 : dom.removeEventListener(type, callback);
66
67
  };
67
68
  }
68
- const useDropdown = ({
69
- visible,
70
- trigger,
71
- origin,
72
- closeScope,
73
- closeOnMouseLeaveMenu
74
- }) => {
75
- const dropdownElRef = ref();
76
- const closeByScope = () => {
77
- if (closeScope.value === "none") {
78
- return;
79
- }
80
- visible.value = false;
69
+ const useDropdownEvent = ({ id, isOpen, origin, dropdownRef, props, emit }) => {
70
+ let overlayEnter = false;
71
+ let originEnter = false;
72
+ const { trigger, closeScope, closeOnMouseLeaveMenu } = toRefs(props);
73
+ const toggle = (status) => {
74
+ isOpen.value = status;
75
+ emit("toggle", isOpen.value);
81
76
  };
82
- watch([trigger, origin, dropdownElRef], ([trigger2, origin2, dropdownEl], ov, onInvalidate) => {
83
- const originEl = getElement(origin2);
84
- if (!originEl || !dropdownEl) {
77
+ const handleLeave = async (elementType, e) => {
78
+ await new Promise((resolve) => setTimeout(resolve, 50));
79
+ if (elementType === "origin" && overlayEnter || elementType === "dropdown" && originEnter) {
85
80
  return;
86
81
  }
87
- const subscriptions = [
88
- subscribeEvent(dropdownEl, "click", () => {
89
- if (closeScope.value === "all") {
90
- visible.value = false;
91
- }
92
- })
93
- ];
94
- if (trigger2 === "click") {
95
- subscriptions.push(subscribeEvent(originEl, "click", () => visible.value = !visible.value), subscribeEvent(document, "click", (e) => {
96
- if (!visible.value) {
97
- return;
98
- }
99
- const target = e.target;
100
- const isContain = originEl.contains(target) || dropdownEl.contains(target);
101
- if (isContain) {
82
+ if (e) {
83
+ [...dropdownMap.values()].reverse().forEach((item) => {
84
+ setTimeout(() => {
85
+ var _a;
86
+ (_a = item.toggle) == null ? void 0 : _a.call(item);
87
+ }, 0);
88
+ });
89
+ }
90
+ toggle(false);
91
+ };
92
+ watch([trigger, origin, dropdownRef], ([triggerVal, originVal, dropdownEl], ov, onInvalidate) => {
93
+ const originEl = getElement(originVal);
94
+ const subscriptions = [];
95
+ setTimeout(() => {
96
+ subscriptions.push(subscribeEvent(document, "click", (e) => {
97
+ const dropdownValues = [...dropdownMap.values()];
98
+ if (!isOpen.value || closeScope.value === "none" || dropdownEl.contains(e.target) && closeScope.value === "blank" || dropdownValues.some((item) => {
99
+ var _a;
100
+ return (_a = item.toggleEl) == null ? void 0 : _a.contains(e.target);
101
+ }) && dropdownValues.some((item) => {
102
+ var _a;
103
+ return (_a = item.menuEl) == null ? void 0 : _a.contains(e.target);
104
+ })) {
102
105
  return;
103
106
  }
104
- closeByScope();
105
- }), subscribeEvent(dropdownEl, "mouseleave", () => {
106
- if (closeOnMouseLeaveMenu.value) {
107
- visible.value = false;
108
- }
107
+ [...dropdownMap.values()].reverse().forEach((item) => {
108
+ setTimeout(() => {
109
+ var _a, _b;
110
+ if (!((_a = item.toggleEl) == null ? void 0 : _a.contains(e.target))) {
111
+ (_b = item.toggle) == null ? void 0 : _b.call(item);
112
+ }
113
+ }, 0);
114
+ });
115
+ overlayEnter = false;
109
116
  }));
110
- } else if (trigger2 === "hover") {
111
- let overlayEnter = false;
112
- let originEnter = false;
113
- const handleLeave = async (elementType) => {
114
- await new Promise((resolve) => setTimeout(resolve, 50));
115
- if (elementType === "origin" && overlayEnter || elementType === "dropdown" && originEnter) {
116
- return;
117
+ }, 0);
118
+ if (triggerVal === "click") {
119
+ subscriptions.push(subscribeEvent(originEl, "click", () => toggle(!isOpen.value)), subscribeEvent(dropdownEl, "mouseleave", (e) => {
120
+ var _a;
121
+ if (closeOnMouseLeaveMenu.value && !((_a = dropdownMap.get(id).child) == null ? void 0 : _a.contains(e.relatedTarget))) {
122
+ handleLeave("dropdown", e);
117
123
  }
118
- closeByScope();
119
- };
124
+ }));
125
+ } else if (triggerVal === "hover") {
120
126
  subscriptions.push(subscribeEvent(originEl, "mouseenter", () => {
121
127
  originEnter = true;
122
- visible.value = true;
128
+ toggle(true);
123
129
  }), subscribeEvent(originEl, "mouseleave", () => {
124
130
  originEnter = false;
125
- if (!closeOnMouseLeaveMenu.value) {
126
- handleLeave("origin");
127
- }
131
+ handleLeave("origin");
128
132
  }), subscribeEvent(dropdownEl, "mouseenter", () => {
129
133
  overlayEnter = true;
130
- visible.value = true;
131
- }), subscribeEvent(dropdownEl, "mouseleave", () => {
134
+ isOpen.value = true;
135
+ }), subscribeEvent(dropdownEl, "mouseleave", (e) => {
136
+ var _a;
132
137
  overlayEnter = false;
133
- handleLeave("dropdown");
138
+ if (e.relatedTarget && ((originEl == null ? void 0 : originEl.contains(e.relatedTarget)) || ((_a = dropdownMap.get(id).child) == null ? void 0 : _a.contains(e.relatedTarget)))) {
139
+ return;
140
+ }
141
+ handleLeave("dropdown", e);
134
142
  }));
135
143
  }
136
144
  onInvalidate(() => subscriptions.forEach((v) => v()));
137
145
  });
138
- return { dropdownEl: dropdownElRef };
139
146
  };
147
+ function useDropdown(id, visible, isOpen, origin, dropdownRef, popDirection, emit) {
148
+ const calcPopDirection = (dropdownEl) => {
149
+ const elementHeight = dropdownEl.offsetHeight;
150
+ const bottomDistance = window.innerHeight - origin.value.getBoundingClientRect().bottom;
151
+ const isBottomEnough = bottomDistance >= elementHeight;
152
+ if (!isBottomEnough) {
153
+ popDirection.value = "top";
154
+ } else {
155
+ popDirection.value = "bottom";
156
+ }
157
+ };
158
+ watch(visible, (newVal, oldVal) => {
159
+ if (oldVal === void 0) {
160
+ return;
161
+ }
162
+ isOpen.value = newVal;
163
+ emit("toggle", isOpen.value);
164
+ }, { immediate: true });
165
+ watch([isOpen, dropdownRef], ([isOpenVal, dropdownEl]) => {
166
+ var _a;
167
+ if (isOpenVal) {
168
+ dropdownMap.set(id, __spreadProps(__spreadValues({}, dropdownMap.get(id)), {
169
+ menuEl: dropdownEl,
170
+ toggle: () => {
171
+ isOpen.value = false;
172
+ emit("toggle", isOpen.value);
173
+ }
174
+ }));
175
+ for (const value of dropdownMap.values()) {
176
+ if ((_a = value.menuEl) == null ? void 0 : _a.contains(origin.value)) {
177
+ value.child = dropdownEl;
178
+ }
179
+ }
180
+ }
181
+ if (dropdownEl) {
182
+ calcPopDirection(dropdownEl);
183
+ }
184
+ });
185
+ onMounted(() => {
186
+ dropdownMap.set(id, { toggleEl: origin.value });
187
+ });
188
+ onUnmounted(() => {
189
+ dropdownMap.delete(id);
190
+ });
191
+ }
140
192
  var overlay = "";
141
193
  function _isSlot(s) {
142
194
  return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
@@ -161,9 +213,6 @@ const overlayProps = {
161
213
  visible: {
162
214
  type: Boolean
163
215
  },
164
- "onUpdate:visible": {
165
- type: Function
166
- },
167
216
  backgroundBlock: {
168
217
  type: Boolean,
169
218
  default: false
@@ -187,29 +236,44 @@ const overlayProps = {
187
236
  default: true
188
237
  }
189
238
  };
190
- const overlayEmits = ["onUpdate:visible", "backdropClick"];
239
+ const overlayEmits = ["update:visible", "backdropClick"];
191
240
  const fixedOverlayProps = __spreadProps(__spreadValues({}, overlayProps), {
192
241
  overlayStyle: {
193
242
  type: [String, Object],
194
243
  default: void 0
195
244
  }
196
245
  });
197
- const flexibleOverlayProps = __spreadValues({
246
+ const flexibleOverlayProps = {
247
+ modelValue: {
248
+ type: Boolean,
249
+ default: false
250
+ },
198
251
  origin: {
199
252
  type: Object,
200
253
  require: true
201
254
  },
202
255
  position: {
203
- type: Object,
204
- default: () => ({
205
- originX: "left",
206
- originY: "top",
207
- overlayX: "left",
208
- overlayY: "top"
209
- })
256
+ type: Array,
257
+ default: ["bottom"]
258
+ },
259
+ offset: {
260
+ type: [Number, Object],
261
+ default: 8
262
+ },
263
+ align: {
264
+ type: String,
265
+ default: null
266
+ },
267
+ showArrow: {
268
+ type: Boolean,
269
+ default: false
270
+ },
271
+ isArrowCenter: {
272
+ type: Boolean,
273
+ default: true
210
274
  }
211
- }, overlayProps);
212
- function useOverlayLogic(props) {
275
+ };
276
+ function useOverlayLogic(props, ctx) {
213
277
  const backgroundClass = computed(() => {
214
278
  return [
215
279
  "devui-overlay-background",
@@ -221,11 +285,11 @@ function useOverlayLogic(props) {
221
285
  return "devui-overlay";
222
286
  });
223
287
  const handleBackdropClick = (event) => {
224
- var _a, _b;
288
+ var _a;
225
289
  event.preventDefault();
226
290
  (_a = props.onBackdropClick) == null ? void 0 : _a.call(props);
227
291
  if (props.backdropClose) {
228
- (_b = props["onUpdate:visible"]) == null ? void 0 : _b.call(props, false);
292
+ ctx.emit("update:visible", false);
229
293
  }
230
294
  };
231
295
  const handleOverlayBubbleCancel = (event) => event.cancelBubble = true;
@@ -259,7 +323,7 @@ function useOverlayLogic(props) {
259
323
  handleOverlayBubbleCancel
260
324
  };
261
325
  }
262
- const FixedOverlay = defineComponent({
326
+ defineComponent({
263
327
  name: "DFixedOverlay",
264
328
  props: fixedOverlayProps,
265
329
  emits: overlayEmits,
@@ -269,9 +333,9 @@ const FixedOverlay = defineComponent({
269
333
  overlayClass,
270
334
  handleBackdropClick,
271
335
  handleOverlayBubbleCancel
272
- } = useOverlayLogic(props);
336
+ } = useOverlayLogic(props, ctx);
273
337
  return () => createVNode(CommonOverlay, null, {
274
- default: () => [withDirectives(createVNode("div", {
338
+ default: () => [props.visible && createVNode("div", {
275
339
  "class": backgroundClass.value,
276
340
  "style": props.backgroundStyle,
277
341
  "onClick": handleBackdropClick
@@ -279,252 +343,296 @@ const FixedOverlay = defineComponent({
279
343
  "class": overlayClass.value,
280
344
  "style": props.overlayStyle,
281
345
  "onClick": handleOverlayBubbleCancel
282
- }, [renderSlot(ctx.slots, "default")])]), [[vShow, props.visible]])]
346
+ }, [renderSlot(ctx.slots, "default")])])]
283
347
  });
284
348
  }
285
349
  });
286
- const FlexibleOverlay = defineComponent({
287
- name: "DFlexibleOverlay",
288
- props: flexibleOverlayProps,
289
- emits: overlayEmits,
290
- setup(props, ctx) {
291
- const overlayRef = ref(null);
292
- const positionedStyle = reactive({
293
- position: "absolute"
294
- });
295
- onMounted(async () => {
296
- const handleRectChange = (position, rect, origin) => {
297
- const point = calculatePosition(position, rect, origin);
298
- positionedStyle.left = `${point.x}px`;
299
- positionedStyle.top = `${point.y}px`;
300
- };
301
- const locationElements = computed(() => {
302
- const overlay2 = overlayRef.value;
303
- const origin = getOrigin(props.origin);
304
- if (!overlay2 || !origin) {
305
- return;
306
- }
307
- return {
308
- origin,
309
- overlay: overlay2
310
- };
311
- });
312
- const visibleRef = toRef(props, "visible");
313
- const positionRef = toRef(props, "position");
314
- watch([locationElements, visibleRef, positionRef], async ([locationElements2, visible, position], ov, onInvalidate) => {
315
- if (!visible || !locationElements2) {
316
- return;
317
- }
318
- const {
319
- origin,
320
- overlay: overlay2
321
- } = locationElements2;
322
- handleRectChange(position, overlay2.getBoundingClientRect(), origin);
323
- const unsubscriptions = [subscribeLayoutEvent(() => handleRectChange(position, overlay2.getBoundingClientRect(), origin)), subscribeOverlayResize(overlay2, (entries) => handleRectChange(position, entries[0].contentRect, origin)), subscribeOriginResize(origin, () => handleRectChange(position, overlay2.getBoundingClientRect(), origin))];
324
- onInvalidate(() => {
325
- unsubscriptions.forEach((fn) => fn());
326
- });
327
- });
328
- });
329
- const {
330
- backgroundClass,
331
- overlayClass,
332
- handleBackdropClick,
333
- handleOverlayBubbleCancel
334
- } = useOverlayLogic(props);
335
- return () => createVNode(CommonOverlay, null, {
336
- default: () => [withDirectives(createVNode("div", {
337
- "style": props.backgroundStyle,
338
- "class": backgroundClass.value,
339
- "onClick": handleBackdropClick
340
- }, [createVNode("div", {
341
- "ref": overlayRef,
342
- "class": overlayClass.value,
343
- "style": positionedStyle,
344
- "onClick": handleOverlayBubbleCancel
345
- }, [renderSlot(ctx.slots, "default")])]), [[vShow, props.visible]])]
346
- });
347
- }
348
- });
349
- function getOrigin(origin) {
350
- if (origin instanceof Element) {
351
- return origin;
352
- }
353
- if (isRef(origin)) {
354
- return getElement(origin.value);
355
- }
356
- if (isComponent(origin)) {
357
- return getElement(origin);
358
- }
359
- return origin;
360
- }
361
- function calculatePosition(position, rect, origin) {
362
- const originRect = getOriginRect(origin);
363
- const originPoint = getOriginRelativePoint(originRect, position);
364
- return getOverlayPoint(originPoint, rect, position);
365
- }
366
- function getOriginRect(origin) {
367
- if (origin instanceof Element) {
368
- return origin.getBoundingClientRect();
350
+ function getScrollParent(element) {
351
+ const overflowRegex = /(auto|scroll|hidden)/;
352
+ for (let parent = element; parent = parent.parentElement; parent.parentElement !== document.body) {
353
+ const style = window.getComputedStyle(parent);
354
+ if (overflowRegex.test(style.overflow + style.overflowX + style.overflowY)) {
355
+ return parent;
356
+ }
369
357
  }
370
- const width = origin.width || 0;
371
- const height = origin.height || 0;
372
- return {
373
- top: origin.y,
374
- bottom: origin.y + height,
375
- left: origin.x,
376
- right: origin.x + width,
377
- height,
378
- width
379
- };
358
+ return window;
380
359
  }
381
- function getOverlayPoint(originPoint, rect, position) {
382
- let x;
383
- const {
384
- width,
385
- height
386
- } = rect;
387
- if (position.overlayX == "center") {
388
- x = originPoint.x - width / 2;
389
- } else {
390
- x = position.overlayX == "left" ? originPoint.x : originPoint.x - width;
391
- }
392
- let y;
393
- if (position.overlayY == "center") {
394
- y = originPoint.y - height / 2;
395
- } else {
396
- y = position.overlayY == "top" ? originPoint.y : originPoint.y - height;
360
+ function adjustArrowPosition(isArrowCenter, point, placement, originRect) {
361
+ let { x, y } = point;
362
+ if (!isArrowCenter) {
363
+ const { width, height } = originRect;
364
+ if (x && placement.includes("start")) {
365
+ x = 12;
366
+ }
367
+ if (x && placement.includes("end")) {
368
+ x = Math.round(width - 24);
369
+ }
370
+ if (y && placement.includes("start")) {
371
+ y = 10;
372
+ }
373
+ if (y && placement.includes("end")) {
374
+ y = height - 14;
375
+ }
397
376
  }
398
- return {
399
- x,
400
- y
401
- };
377
+ return { x, y };
402
378
  }
403
- function getOriginRelativePoint(originRect, position) {
404
- let x;
405
- if (position.originX == "center") {
406
- x = originRect.left + originRect.width / 2;
407
- } else {
408
- const startX = originRect.left;
409
- const endX = originRect.right;
410
- x = position.originX == "left" ? startX : endX;
411
- }
412
- let y;
413
- if (position.originY == "center") {
414
- y = originRect.top + originRect.height / 2;
415
- } else {
416
- y = position.originY == "top" ? originRect.top : originRect.bottom;
417
- }
418
- return {
419
- x,
420
- y
421
- };
422
- }
423
- function subscribeLayoutEvent(event) {
424
- window.addEventListener("scroll", event, true);
425
- window.addEventListener("resize", event);
426
- window.addEventListener("orientationchange", event);
427
- return () => {
428
- window.removeEventListener("scroll", event, true);
429
- window.removeEventListener("resize", event);
430
- window.removeEventListener("orientationchange", event);
431
- };
432
- }
433
- function subscribeOverlayResize(overlay2, callback) {
434
- if (overlay2 instanceof Element) {
435
- const resizeObserver = new ResizeObserver(callback);
436
- resizeObserver.observe(overlay2);
437
- return () => resizeObserver.disconnect();
438
- }
439
- return () => {
379
+ function useOverlay(props, emit) {
380
+ const overlayRef = ref();
381
+ const arrowRef = ref();
382
+ const updateArrowPosition = (arrowEl, placement, point, overlayEl) => {
383
+ const { x, y } = adjustArrowPosition(props.isArrowCenter, point, placement, overlayEl.getBoundingClientRect());
384
+ const staticSide = {
385
+ top: "bottom",
386
+ right: "left",
387
+ bottom: "top",
388
+ left: "right"
389
+ }[placement.split("-")[0]];
390
+ Object.assign(arrowEl.style, {
391
+ left: x ? `${x}px` : "",
392
+ top: y ? `${y}px` : "",
393
+ right: "",
394
+ bottom: "",
395
+ [staticSide]: "-4px"
396
+ });
440
397
  };
441
- }
442
- function subscribeOriginResize(origin, callback) {
443
- if (origin instanceof Element) {
444
- const observer = new MutationObserver(callback);
445
- observer.observe(origin, {
446
- attributeFilter: ["style"]
398
+ const updatePosition = async () => {
399
+ const hostEl = props.origin;
400
+ const overlayEl = unref(overlayRef.value);
401
+ const arrowEl = unref(arrowRef.value);
402
+ const middleware = [
403
+ offset(props.offset),
404
+ autoPlacement({
405
+ alignment: props.align,
406
+ allowedPlacements: props.position
407
+ })
408
+ ];
409
+ props.showArrow && middleware.push(arrow({ element: arrowEl }));
410
+ const { x, y, placement, middlewareData } = await computePosition(hostEl, overlayEl, {
411
+ strategy: "fixed",
412
+ middleware
447
413
  });
448
- return () => observer.disconnect();
449
- }
450
- return () => {
414
+ emit("positionChange", placement);
415
+ Object.assign(overlayEl.style, { top: `${y}px`, left: `${x}px` });
416
+ props.showArrow && updateArrowPosition(arrowEl, placement, middlewareData.arrow, overlayEl);
451
417
  };
418
+ watch(() => props.modelValue, () => {
419
+ const originParent = getScrollParent(props.origin);
420
+ if (props.modelValue && props.origin) {
421
+ nextTick(updatePosition);
422
+ originParent.addEventListener("scroll", updatePosition);
423
+ originParent !== window && window.addEventListener("scroll", updatePosition);
424
+ window.addEventListener("resize", updatePosition);
425
+ } else {
426
+ originParent.removeEventListener("scroll", updatePosition);
427
+ originParent !== window && window.removeEventListener("scroll", updatePosition);
428
+ window.removeEventListener("resize", updatePosition);
429
+ }
430
+ });
431
+ onUnmounted(() => {
432
+ const originParent = getScrollParent(props.origin);
433
+ originParent.removeEventListener("scroll", updatePosition);
434
+ originParent !== window && window.removeEventListener("scroll", updatePosition);
435
+ window.removeEventListener("resize", updatePosition);
436
+ });
437
+ return { arrowRef, overlayRef };
452
438
  }
453
- FlexibleOverlay.install = function(app) {
454
- app.component(FlexibleOverlay.name, FlexibleOverlay);
455
- };
456
- FixedOverlay.install = function(app) {
457
- app.component(FixedOverlay.name, FixedOverlay);
458
- };
439
+ var flexibleOverlay = "";
440
+ const FlexibleOverlay = defineComponent({
441
+ name: "DFlexibleOverlay",
442
+ inheritAttrs: false,
443
+ props: flexibleOverlayProps,
444
+ emits: ["update:modelValue", "positionChange"],
445
+ setup(props, {
446
+ slots,
447
+ attrs,
448
+ emit
449
+ }) {
450
+ const {
451
+ arrowRef,
452
+ overlayRef
453
+ } = useOverlay(props, emit);
454
+ return () => {
455
+ var _a;
456
+ return props.modelValue && createVNode("div", mergeProps({
457
+ "ref": overlayRef,
458
+ "class": "devui-flexible-overlay"
459
+ }, attrs), [(_a = slots.default) == null ? void 0 : _a.call(slots), props.showArrow && createVNode("div", {
460
+ "ref": arrowRef,
461
+ "class": "devui-flexible-overlay-arrow"
462
+ }, null)]);
463
+ };
464
+ }
465
+ });
459
466
  var dropdown = "";
467
+ let dropdownId = 1;
460
468
  var Dropdown = defineComponent({
461
469
  name: "DDropdown",
470
+ inheritAttrs: false,
462
471
  props: dropdownProps,
463
- emits: [],
464
- setup(props, ctx) {
472
+ emits: ["toggle"],
473
+ setup(props, {
474
+ slots,
475
+ attrs,
476
+ emit
477
+ }) {
465
478
  const {
466
- isOpen,
467
- origin,
468
- trigger,
469
- closeScope,
470
- closeOnMouseLeaveMenu
479
+ visible,
480
+ position,
481
+ align,
482
+ offset: offset2
471
483
  } = toRefs(props);
472
- const visible = ref(false);
473
- watch(isOpen, (value) => {
474
- visible.value = value;
475
- }, {
476
- immediate: true
477
- });
478
- const position = {
479
- originX: "center",
480
- originY: "bottom",
481
- overlayX: "center",
482
- overlayY: "top"
484
+ const origin = ref();
485
+ const dropdownRef = ref();
486
+ const id = `dropdown_${dropdownId++}`;
487
+ const isOpen = ref(false);
488
+ const currentPosition = ref("bottom");
489
+ const handlePositionChange = (pos) => {
490
+ currentPosition.value = pos.includes("top") || pos.includes("end") ? "top" : "bottom";
483
491
  };
484
- const {
485
- dropdownEl
486
- } = useDropdown({
487
- visible,
492
+ const styles = computed(() => ({
493
+ transformOrigin: currentPosition.value === "top" ? "0% 100%" : "0% 0%"
494
+ }));
495
+ const classes = computed(() => ({
496
+ "fade-in-bottom": isOpen.value && currentPosition.value === "bottom",
497
+ "fade-in-top": isOpen.value && currentPosition.value === "top"
498
+ }));
499
+ useDropdownEvent({
500
+ id,
501
+ isOpen,
488
502
  origin,
489
- trigger,
490
- closeScope,
491
- closeOnMouseLeaveMenu
492
- });
493
- const animatedVisible = computed(() => {
494
- return props.showAnimation ? visible.value : true;
503
+ dropdownRef,
504
+ props,
505
+ emit
495
506
  });
507
+ useDropdown(id, visible, isOpen, origin, dropdownRef, currentPosition, emit);
496
508
  return () => {
497
- return createVNode(Fragment, null, [createVNode(FlexibleOverlay, {
498
- "origin": props.origin,
499
- "visible": visible.value,
500
- "onUpdate:visible": ($event) => visible.value = $event,
501
- "position": position,
502
- "hasBackdrop": false
509
+ var _a;
510
+ return createVNode(Fragment, null, [createVNode("div", {
511
+ "ref": origin,
512
+ "class": "devui-dropdown-toggle"
513
+ }, [(_a = slots.default) == null ? void 0 : _a.call(slots)]), createVNode(Teleport, {
514
+ "to": "body"
503
515
  }, {
504
516
  default: () => [createVNode(Transition, {
505
- "name": "devui-dropdown-fade"
517
+ "name": `devui-dropdown-fade-${currentPosition.value}`
506
518
  }, {
507
- default: () => {
508
- var _a, _b;
509
- return [withDirectives(createVNode("div", {
510
- "ref": dropdownEl,
511
- "style": "min-width:102px"
512
- }, [(_b = (_a = ctx.slots).default) == null ? void 0 : _b.call(_a)]), [[vShow, animatedVisible.value]])];
513
- }
519
+ default: () => [createVNode(FlexibleOverlay, {
520
+ "modelValue": isOpen.value,
521
+ "onUpdate:modelValue": ($event) => isOpen.value = $event,
522
+ "origin": origin.value,
523
+ "position": position.value,
524
+ "align": align.value,
525
+ "offset": offset2.value,
526
+ "onPositionChange": handlePositionChange,
527
+ "class": classes.value,
528
+ "style": styles.value
529
+ }, {
530
+ default: () => {
531
+ var _a2;
532
+ return [createVNode("div", mergeProps({
533
+ "ref": dropdownRef,
534
+ "class": "devui-dropdown-menu-wrap"
535
+ }, attrs), [(_a2 = slots.menu) == null ? void 0 : _a2.call(slots)])];
536
+ }
537
+ })]
514
538
  })]
515
539
  })]);
516
540
  };
517
541
  }
518
542
  });
519
- Dropdown.install = function(app) {
520
- app.component(Dropdown.name, Dropdown);
543
+ const dropdownMenuProps = {
544
+ modelValue: {
545
+ type: Boolean,
546
+ default: false
547
+ },
548
+ origin: {
549
+ type: Object,
550
+ require: true
551
+ },
552
+ position: {
553
+ type: Array,
554
+ default: ["bottom"]
555
+ },
556
+ align: {
557
+ type: String,
558
+ default: null
559
+ },
560
+ offset: {
561
+ type: [Number, Object],
562
+ default: 4
563
+ },
564
+ clickOutside: {
565
+ type: Function,
566
+ default: () => true
567
+ }
521
568
  };
569
+ var DropdownMenu = defineComponent({
570
+ name: "DDropdownMenu",
571
+ inheritAttrs: false,
572
+ props: dropdownMenuProps,
573
+ emits: ["update:modelValue"],
574
+ setup(props, {
575
+ slots,
576
+ attrs,
577
+ emit
578
+ }) {
579
+ const {
580
+ modelValue,
581
+ origin,
582
+ position,
583
+ align,
584
+ offset: offset2,
585
+ clickOutside
586
+ } = toRefs(props);
587
+ const dropdownMenuRef = ref(null);
588
+ onClickOutside(dropdownMenuRef, (value) => {
589
+ var _a;
590
+ if (((_a = clickOutside.value) == null ? void 0 : _a.call(clickOutside)) && !origin.value.contains(value.target)) {
591
+ emit("update:modelValue", false);
592
+ }
593
+ });
594
+ const currentPosition = ref("bottom");
595
+ const handlePositionChange = (pos) => {
596
+ currentPosition.value = pos.split("-")[0] === "top" ? "top" : "bottom";
597
+ };
598
+ const styles = computed(() => ({
599
+ transformOrigin: currentPosition.value === "top" ? "0% 100%" : "0% 0%"
600
+ }));
601
+ return () => createVNode(Teleport, {
602
+ "to": "body"
603
+ }, {
604
+ default: () => [createVNode(Transition, {
605
+ "name": `devui-dropdown-fade-${currentPosition.value}`
606
+ }, {
607
+ default: () => [createVNode(FlexibleOverlay, {
608
+ "modelValue": modelValue.value,
609
+ "onUpdate:modelValue": ($event) => modelValue.value = $event,
610
+ "origin": origin == null ? void 0 : origin.value,
611
+ "position": position.value,
612
+ "align": align.value,
613
+ "offset": offset2.value,
614
+ "onPositionChange": handlePositionChange,
615
+ "style": styles.value
616
+ }, {
617
+ default: () => {
618
+ var _a;
619
+ return [createVNode("div", mergeProps({
620
+ "ref": dropdownMenuRef,
621
+ "class": "devui-dropdown-menu-wrap"
622
+ }, attrs), [(_a = slots.default) == null ? void 0 : _a.call(slots)])];
623
+ }
624
+ })]
625
+ })]
626
+ });
627
+ }
628
+ });
522
629
  var index = {
523
630
  title: "Dropdown \u4E0B\u62C9\u83DC\u5355",
524
631
  category: "\u5BFC\u822A",
525
632
  status: "10%",
526
633
  install(app) {
527
- app.use(Dropdown);
634
+ app.component(Dropdown.name, Dropdown);
635
+ app.component(DropdownMenu.name, DropdownMenu);
528
636
  }
529
637
  };
530
- export { Dropdown, index as default };
638
+ export { Dropdown, DropdownMenu, index as default, dropdownMenuProps };