vue-devui 1.0.0-beta.18 → 1.0.0-beta.19

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 (161) hide show
  1. package/README.md +200 -187
  2. package/accordion/index.es.js +221 -6
  3. package/accordion/index.umd.js +1 -1
  4. package/alert/index.es.js +28 -30
  5. package/alert/index.umd.js +1 -1
  6. package/auto-complete/index.es.js +131 -269
  7. package/auto-complete/index.umd.js +1 -1
  8. package/auto-complete/style.css +1 -1
  9. package/back-top/index.es.js +4 -2
  10. package/badge/index.es.js +13 -19
  11. package/badge/index.umd.js +1 -1
  12. package/badge/style.css +1 -1
  13. package/breadcrumb/index.es.js +2 -1
  14. package/button/index.es.js +39 -40
  15. package/button/index.umd.js +1 -1
  16. package/carousel/index.es.js +38 -53
  17. package/carousel/index.umd.js +1 -1
  18. package/cascader/index.es.js +16 -8
  19. package/cascader/style.css +1 -1
  20. package/color-picker/index.es.js +97 -89
  21. package/color-picker/index.umd.js +7 -7
  22. package/countdown/index.es.js +2 -1
  23. package/date-picker/index.es.js +40 -57
  24. package/date-picker/index.umd.js +1 -1
  25. package/date-picker/style.css +1 -1
  26. package/drawer/index.es.js +162 -5741
  27. package/drawer/index.umd.js +1 -27
  28. package/drawer/style.css +1 -1
  29. package/dropdown/index.es.js +459 -301
  30. package/dropdown/index.umd.js +1 -1
  31. package/dropdown/style.css +1 -1
  32. package/editable-select/index.es.js +6 -3
  33. package/form/index.es.js +1953 -1550
  34. package/form/index.umd.js +18 -18
  35. package/form/style.css +1 -1
  36. package/fullscreen/index.es.js +112 -133
  37. package/fullscreen/index.umd.js +1 -1
  38. package/fullscreen/style.css +1 -1
  39. package/icon/index.es.js +39 -57
  40. package/icon/index.umd.js +1 -1
  41. package/image-preview/index.es.js +2 -1
  42. package/input/style.css +1 -1
  43. package/input-icon/index.es.js +38 -37
  44. package/input-icon/index.umd.js +1 -1
  45. package/input-icon/style.css +1 -1
  46. package/input-number/index.es.js +46 -57
  47. package/input-number/index.umd.js +1 -1
  48. package/input-number/style.css +1 -1
  49. package/{time-axis → list}/index.d.ts +0 -0
  50. package/list/index.es.js +39 -0
  51. package/list/index.umd.js +1 -0
  52. package/{toast → list}/package.json +1 -1
  53. package/list/style.css +1 -0
  54. package/modal/index.es.js +300 -934
  55. package/modal/index.umd.js +1 -1
  56. package/modal/style.css +1 -1
  57. package/{toast → notification}/index.d.ts +0 -0
  58. package/notification/index.es.js +284 -0
  59. package/notification/index.umd.js +1 -0
  60. package/notification/package.json +7 -0
  61. package/notification/style.css +1 -0
  62. package/nuxt/components/DropdownMenu.js +3 -0
  63. package/nuxt/components/IFileOptions.js +3 -0
  64. package/nuxt/components/IUploadOptions.js +3 -0
  65. package/nuxt/components/List.js +3 -0
  66. package/nuxt/components/ListItem.js +3 -0
  67. package/nuxt/components/Notification.js +3 -0
  68. package/nuxt/components/NotificationService.js +3 -0
  69. package/nuxt/components/PanelBody.js +3 -0
  70. package/nuxt/components/PanelFooter.js +3 -0
  71. package/nuxt/components/PanelHeader.js +3 -0
  72. package/nuxt/components/Timeline.js +3 -0
  73. package/nuxt/components/TimelineItem.js +3 -0
  74. package/nuxt/components/UploadStatus.js +3 -0
  75. package/nuxt/components/alertProps.js +3 -0
  76. package/nuxt/components/badgeProps.js +3 -0
  77. package/nuxt/components/dropdownMenuProps.js +3 -0
  78. package/nuxt/components/fixedOverlayProps.js +3 -0
  79. package/nuxt/components/flexibleOverlayProps.js +3 -0
  80. package/nuxt/components/fullscreenProps.js +3 -0
  81. package/nuxt/components/iconProps.js +2 -0
  82. package/nuxt/components/notificationProps.js +3 -0
  83. package/nuxt/components/overlayEmits.js +3 -0
  84. package/nuxt/components/overlayProps.js +3 -0
  85. package/nuxt/components/paginationProps.js +3 -0
  86. package/nuxt/components/panelProps.js +3 -0
  87. package/nuxt/components/popoverProps.js +3 -0
  88. package/nuxt/components/searchProps.js +3 -0
  89. package/nuxt/components/tooltipProps.js +3 -0
  90. package/nuxt/components/uploadProps.js +3 -0
  91. package/overlay/index.es.js +152 -198
  92. package/overlay/index.umd.js +1 -1
  93. package/overlay/style.css +1 -1
  94. package/package.json +40 -87
  95. package/pagination/index.es.js +10 -12
  96. package/pagination/index.umd.js +1 -1
  97. package/panel/index.es.js +45 -32
  98. package/panel/index.umd.js +1 -1
  99. package/popover/index.es.js +5954 -201
  100. package/popover/index.umd.js +27 -1
  101. package/popover/style.css +1 -1
  102. package/read-tip/index.es.js +6 -3
  103. package/result/index.es.js +38 -53
  104. package/result/index.umd.js +1 -1
  105. package/ripple/index.es.js +9 -5
  106. package/search/index.es.js +19 -29
  107. package/search/index.umd.js +6 -6
  108. package/search/style.css +1 -1
  109. package/select/index.es.js +42 -42
  110. package/select/index.umd.js +1 -1
  111. package/select/style.css +1 -1
  112. package/skeleton/index.es.js +17 -17
  113. package/skeleton/index.umd.js +1 -1
  114. package/slider/index.es.js +2 -1
  115. package/splitter/index.es.js +5814 -98
  116. package/splitter/index.umd.js +27 -1
  117. package/splitter/style.css +1 -1
  118. package/status/index.es.js +1 -4
  119. package/status/index.umd.js +1 -1
  120. package/status/style.css +1 -1
  121. package/steps-guide/index.es.js +6 -3
  122. package/style.css +1 -1
  123. package/table/index.es.js +456 -299
  124. package/table/index.umd.js +1 -1
  125. package/table/style.css +1 -1
  126. package/tabs/index.es.js +3 -4
  127. package/tabs/index.umd.js +1 -1
  128. package/tag/index.es.js +2 -1
  129. package/tag-input/index.es.js +4 -2
  130. package/textarea/style.css +1 -1
  131. package/time-picker/index.es.js +43 -42
  132. package/time-picker/index.umd.js +1 -1
  133. package/timeline/index.d.ts +7 -0
  134. package/{time-axis → timeline}/index.es.js +65 -78
  135. package/timeline/index.umd.js +1 -0
  136. package/{time-axis → timeline}/package.json +1 -1
  137. package/timeline/style.css +1 -0
  138. package/tooltip/index.es.js +5804 -94
  139. package/tooltip/index.umd.js +27 -1
  140. package/tooltip/style.css +1 -1
  141. package/transfer/index.es.js +440 -165
  142. package/transfer/index.umd.js +17 -17
  143. package/transfer/style.css +1 -1
  144. package/tree/index.es.js +12 -7
  145. package/tree/index.umd.js +10 -10
  146. package/tree-select/index.es.js +10 -6
  147. package/tree-select/index.umd.js +1 -1
  148. package/upload/index.es.js +335 -6068
  149. package/upload/index.umd.js +1 -27
  150. package/upload/style.css +1 -1
  151. package/vue-devui.es.js +2555 -2799
  152. package/vue-devui.umd.js +16 -16
  153. package/nuxt/components/TimeAxis.js +0 -3
  154. package/nuxt/components/TimeAxisItem.js +0 -3
  155. package/nuxt/components/Toast.js +0 -3
  156. package/nuxt/components/ToastService.js +0 -3
  157. package/time-axis/index.umd.js +0 -1
  158. package/time-axis/style.css +0 -1
  159. package/toast/index.es.js +0 -5918
  160. package/toast/index.umd.js +0 -27
  161. 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 } from "vue";
20
+ import { toRefs, watch, onMounted, onUnmounted, ref, computed, defineComponent, createVNode, Teleport, Transition, renderSlot, isVNode, unref, nextTick, mergeProps, Fragment, withDirectives, vShow } from "vue";
21
+ import { shift, 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,6 +33,18 @@ 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
@@ -46,14 +53,15 @@ const dropdownProps = {
46
53
  type: Boolean,
47
54
  default: true
48
55
  },
49
- width: {
50
- type: [Number, String],
51
- default: "102px"
56
+ overlayClass: {
57
+ type: String,
58
+ default: ""
59
+ },
60
+ destroyOnHide: {
61
+ type: Boolean,
62
+ default: true
52
63
  }
53
64
  };
54
- function isComponent(target) {
55
- return !!(target == null ? void 0 : target.$el);
56
- }
57
65
  function getElement(element) {
58
66
  if (element instanceof Element) {
59
67
  return element;
@@ -63,85 +71,158 @@ function getElement(element) {
63
71
  }
64
72
  return null;
65
73
  }
74
+ const dropdownMap = /* @__PURE__ */ new Map();
66
75
  function subscribeEvent(dom, type, callback) {
67
76
  dom == null ? void 0 : dom.addEventListener(type, callback);
68
77
  return () => {
69
78
  dom == null ? void 0 : dom.removeEventListener(type, callback);
70
79
  };
71
80
  }
72
- const useDropdown = ({
73
- visible,
74
- trigger,
75
- origin,
76
- closeScope,
77
- closeOnMouseLeaveMenu
78
- }) => {
79
- const dropdownElRef = ref();
80
- const closeByScope = () => {
81
- if (closeScope.value === "none") {
82
- return;
83
- }
84
- visible.value = false;
81
+ const useDropdownEvent = ({ id, isOpen, origin, dropdownRef, props, emit }) => {
82
+ let overlayEnter = false;
83
+ let originEnter = false;
84
+ const { trigger, closeScope, closeOnMouseLeaveMenu } = toRefs(props);
85
+ const toggle = (status) => {
86
+ isOpen.value = status;
87
+ emit("toggle", isOpen.value);
85
88
  };
86
- watch([trigger, origin, dropdownElRef], ([trigger2, origin2, dropdownEl], ov, onInvalidate) => {
87
- const originEl = getElement(origin2);
88
- if (!originEl || !dropdownEl) {
89
+ const handleLeave = async (elementType, closeAll) => {
90
+ await new Promise((resolve) => setTimeout(resolve, 50));
91
+ if (elementType === "origin" && overlayEnter || elementType === "dropdown" && originEnter) {
89
92
  return;
90
93
  }
91
- const subscriptions = [
92
- subscribeEvent(dropdownEl, "click", () => {
93
- if (closeScope.value === "all") {
94
- visible.value = false;
95
- }
96
- })
97
- ];
98
- if (trigger2 === "click") {
99
- subscriptions.push(subscribeEvent(originEl, "click", () => visible.value = !visible.value), subscribeEvent(document, "click", (e) => {
100
- if (!visible.value) {
101
- return;
102
- }
103
- const target = e.target;
104
- const isContain = originEl.contains(target) || dropdownEl.contains(target);
105
- if (isContain) {
94
+ if (closeAll) {
95
+ [...dropdownMap.values()].reverse().forEach((item) => {
96
+ setTimeout(() => {
97
+ var _a;
98
+ (_a = item.toggle) == null ? void 0 : _a.call(item);
99
+ }, 0);
100
+ });
101
+ }
102
+ toggle(false);
103
+ };
104
+ watch([trigger, origin, dropdownRef], ([triggerVal, originVal, dropdownEl], ov, onInvalidate) => {
105
+ const originEl = getElement(originVal);
106
+ const subscriptions = [];
107
+ setTimeout(() => {
108
+ subscriptions.push(subscribeEvent(document, "click", (e) => {
109
+ const dropdownValues = [...dropdownMap.values()];
110
+ if (!isOpen.value || closeScope.value === "none" || dropdownEl.contains(e.target) && closeScope.value === "blank" || dropdownValues.some((item) => {
111
+ var _a;
112
+ return (_a = item.toggleEl) == null ? void 0 : _a.contains(e.target);
113
+ }) && dropdownValues.some((item) => {
114
+ var _a;
115
+ return (_a = item.menuEl) == null ? void 0 : _a.contains(e.target);
116
+ })) {
106
117
  return;
107
118
  }
108
- closeByScope();
109
- }), subscribeEvent(dropdownEl, "mouseleave", () => {
110
- if (closeOnMouseLeaveMenu.value) {
111
- visible.value = false;
112
- }
119
+ [...dropdownMap.values()].reverse().forEach((item) => {
120
+ setTimeout(() => {
121
+ var _a, _b;
122
+ if (!((_a = item.toggleEl) == null ? void 0 : _a.contains(e.target))) {
123
+ (_b = item.toggle) == null ? void 0 : _b.call(item);
124
+ }
125
+ }, 0);
126
+ });
127
+ overlayEnter = false;
113
128
  }));
114
- } else if (trigger2 === "hover") {
115
- let overlayEnter = false;
116
- let originEnter = false;
117
- const handleLeave = async (elementType) => {
118
- await new Promise((resolve) => setTimeout(resolve, 50));
119
- if (elementType === "origin" && overlayEnter || elementType === "dropdown" && originEnter) {
120
- return;
129
+ }, 0);
130
+ if (triggerVal === "click") {
131
+ subscriptions.push(subscribeEvent(originEl, "click", () => toggle(!isOpen.value)), subscribeEvent(dropdownEl, "mouseleave", (e) => {
132
+ var _a;
133
+ if (closeOnMouseLeaveMenu.value && !((_a = dropdownMap.get(id).child) == null ? void 0 : _a.contains(e.relatedTarget))) {
134
+ handleLeave("dropdown", true);
121
135
  }
122
- closeByScope();
123
- };
136
+ }));
137
+ } else if (triggerVal === "hover") {
124
138
  subscriptions.push(subscribeEvent(originEl, "mouseenter", () => {
125
139
  originEnter = true;
126
- visible.value = true;
140
+ toggle(true);
127
141
  }), subscribeEvent(originEl, "mouseleave", () => {
128
142
  originEnter = false;
129
- if (!closeOnMouseLeaveMenu.value) {
130
- handleLeave("origin");
131
- }
143
+ handleLeave("origin");
132
144
  }), subscribeEvent(dropdownEl, "mouseenter", () => {
133
145
  overlayEnter = true;
134
- visible.value = true;
135
- }), subscribeEvent(dropdownEl, "mouseleave", () => {
146
+ isOpen.value = true;
147
+ }), subscribeEvent(dropdownEl, "mouseleave", (e) => {
148
+ var _a;
136
149
  overlayEnter = false;
137
- handleLeave("dropdown");
150
+ if (e.relatedTarget && ((originEl == null ? void 0 : originEl.contains(e.relatedTarget)) || ((_a = dropdownMap.get(id).child) == null ? void 0 : _a.contains(e.relatedTarget)))) {
151
+ return;
152
+ }
153
+ handleLeave("dropdown", true);
138
154
  }));
139
155
  }
140
156
  onInvalidate(() => subscriptions.forEach((v) => v()));
141
157
  });
142
- return { dropdownEl: dropdownElRef };
143
158
  };
144
- var overlay = "";
159
+ function useDropdown(id, visible, isOpen, origin, dropdownRef, popDirection, emit) {
160
+ const calcPopDirection = (dropdownEl) => {
161
+ const elementHeight = dropdownEl.offsetHeight;
162
+ const bottomDistance = window.innerHeight - origin.value.getBoundingClientRect().bottom;
163
+ const isBottomEnough = bottomDistance >= elementHeight;
164
+ if (!isBottomEnough) {
165
+ popDirection.value = "top";
166
+ } else {
167
+ popDirection.value = "bottom";
168
+ }
169
+ };
170
+ watch(visible, (newVal, oldVal) => {
171
+ if (oldVal === void 0) {
172
+ return;
173
+ }
174
+ isOpen.value = newVal;
175
+ emit("toggle", isOpen.value);
176
+ }, { immediate: true });
177
+ watch([isOpen, dropdownRef], ([isOpenVal, dropdownEl]) => {
178
+ var _a;
179
+ if (isOpenVal) {
180
+ dropdownMap.set(id, __spreadProps(__spreadValues({}, dropdownMap.get(id)), {
181
+ menuEl: dropdownEl,
182
+ toggle: () => {
183
+ isOpen.value = false;
184
+ emit("toggle", isOpen.value);
185
+ }
186
+ }));
187
+ for (const value of dropdownMap.values()) {
188
+ if ((_a = value.menuEl) == null ? void 0 : _a.contains(origin.value)) {
189
+ value.child = dropdownEl;
190
+ }
191
+ }
192
+ }
193
+ if (dropdownEl) {
194
+ calcPopDirection(dropdownEl);
195
+ }
196
+ });
197
+ onMounted(() => {
198
+ dropdownMap.set(id, { toggleEl: origin.value });
199
+ });
200
+ onUnmounted(() => {
201
+ dropdownMap.delete(id);
202
+ });
203
+ }
204
+ function useOverlayProps(props, currentPosition, isOpen) {
205
+ const { showAnimation, overlayClass, destroyOnHide } = toRefs(props);
206
+ const overlayModelValue = ref(false);
207
+ const overlayShowValue = ref(false);
208
+ const styles = computed(() => ({
209
+ transformOrigin: currentPosition.value === "top" ? "0% 100%" : "0% 0%"
210
+ }));
211
+ const classes = computed(() => ({
212
+ "fade-in-bottom": showAnimation.value && isOpen.value && currentPosition.value === "bottom",
213
+ "fade-in-top": showAnimation.value && isOpen.value && currentPosition.value === "top",
214
+ [`${overlayClass.value}`]: true
215
+ }));
216
+ const handlePositionChange = (pos) => {
217
+ currentPosition.value = pos.includes("top") || pos.includes("end") ? "top" : "bottom";
218
+ };
219
+ watch(isOpen, (isOpenVal) => {
220
+ overlayModelValue.value = destroyOnHide.value ? isOpenVal : true;
221
+ overlayShowValue.value = isOpenVal;
222
+ });
223
+ return { overlayModelValue, overlayShowValue, styles, classes, handlePositionChange };
224
+ }
225
+ var baseOverlay = "";
145
226
  function _isSlot(s) {
146
227
  return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
147
228
  }
@@ -188,28 +269,13 @@ const overlayProps = {
188
269
  default: true
189
270
  }
190
271
  };
191
- const overlayEmits = ["update:visible", "backdropClick"];
192
272
  const fixedOverlayProps = __spreadProps(__spreadValues({}, overlayProps), {
193
273
  overlayStyle: {
194
274
  type: [String, Object],
195
275
  default: void 0
196
276
  }
197
277
  });
198
- const flexibleOverlayProps = __spreadValues({
199
- origin: {
200
- type: Object,
201
- require: true
202
- },
203
- position: {
204
- type: Object,
205
- default: () => ({
206
- originX: "left",
207
- originY: "top",
208
- overlayX: "left",
209
- overlayY: "top"
210
- })
211
- }
212
- }, overlayProps);
278
+ const overlayEmits = ["update:visible", "backdropClick"];
213
279
  function useOverlayLogic(props, ctx) {
214
280
  const backgroundClass = computed(() => {
215
281
  return [
@@ -260,7 +326,8 @@ function useOverlayLogic(props, ctx) {
260
326
  handleOverlayBubbleCancel
261
327
  };
262
328
  }
263
- const FixedOverlay = defineComponent({
329
+ var fixedOverlay = "";
330
+ defineComponent({
264
331
  name: "DFixedOverlay",
265
332
  props: fixedOverlayProps,
266
333
  emits: overlayEmits,
@@ -272,7 +339,7 @@ const FixedOverlay = defineComponent({
272
339
  handleOverlayBubbleCancel
273
340
  } = useOverlayLogic(props, ctx);
274
341
  return () => createVNode(CommonOverlay, null, {
275
- default: () => [withDirectives(createVNode("div", {
342
+ default: () => [props.visible && createVNode("div", {
276
343
  "class": backgroundClass.value,
277
344
  "style": props.backgroundStyle,
278
345
  "onClick": handleBackdropClick
@@ -280,256 +347,347 @@ const FixedOverlay = defineComponent({
280
347
  "class": overlayClass.value,
281
348
  "style": props.overlayStyle,
282
349
  "onClick": handleOverlayBubbleCancel
283
- }, [renderSlot(ctx.slots, "default")])]), [[vShow, props.visible]])]
350
+ }, [renderSlot(ctx.slots, "default")])])]
284
351
  });
285
352
  }
286
353
  });
287
- const FlexibleOverlay = defineComponent({
288
- name: "DFlexibleOverlay",
289
- props: flexibleOverlayProps,
290
- emits: overlayEmits,
291
- setup(props, ctx) {
292
- const overlayRef = ref(null);
293
- const positionedStyle = reactive({
294
- position: "absolute"
295
- });
296
- onMounted(async () => {
297
- const handleRectChange = (position, rect, origin) => {
298
- const point = calculatePosition(position, rect, origin);
299
- positionedStyle.left = `${point.x}px`;
300
- positionedStyle.top = `${point.y}px`;
301
- };
302
- const locationElements = computed(() => {
303
- const overlay2 = overlayRef.value;
304
- const origin = getOrigin(props.origin);
305
- if (!overlay2 || !origin) {
306
- return;
307
- }
308
- return {
309
- origin,
310
- overlay: overlay2
311
- };
312
- });
313
- const visibleRef = toRef(props, "visible");
314
- const positionRef = toRef(props, "position");
315
- watch([locationElements, visibleRef, positionRef], async ([locationElements2, visible, position], ov, onInvalidate) => {
316
- if (!visible || !locationElements2) {
317
- return;
318
- }
319
- const {
320
- origin,
321
- overlay: overlay2
322
- } = locationElements2;
323
- handleRectChange(position, overlay2.getBoundingClientRect(), origin);
324
- const unsubscriptions = [subscribeLayoutEvent(() => handleRectChange(position, overlay2.getBoundingClientRect(), origin)), subscribeOverlayResize(overlay2, (entries) => handleRectChange(position, entries[0].contentRect, origin)), subscribeOriginResize(origin, () => handleRectChange(position, overlay2.getBoundingClientRect(), origin))];
325
- onInvalidate(() => {
326
- unsubscriptions.forEach((fn) => fn());
327
- });
328
- });
329
- });
330
- const {
331
- backgroundClass,
332
- overlayClass,
333
- handleBackdropClick,
334
- handleOverlayBubbleCancel
335
- } = useOverlayLogic(props, ctx);
336
- return () => createVNode(CommonOverlay, null, {
337
- default: () => [withDirectives(createVNode("div", {
338
- "style": props.backgroundStyle,
339
- "class": backgroundClass.value,
340
- "onClick": handleBackdropClick
341
- }, [createVNode("div", {
342
- "ref": overlayRef,
343
- "class": overlayClass.value,
344
- "style": positionedStyle,
345
- "onClick": handleOverlayBubbleCancel
346
- }, [renderSlot(ctx.slots, "default")])]), [[vShow, props.visible]])]
347
- });
348
- }
349
- });
350
- function getOrigin(origin) {
351
- if (origin instanceof Element) {
352
- return origin;
353
- }
354
- if (isRef(origin)) {
355
- return getElement(origin.value);
356
- }
357
- if (isComponent(origin)) {
358
- return getElement(origin);
359
- }
360
- return origin;
361
- }
362
- function calculatePosition(position, rect, origin) {
363
- const originRect = getOriginRect(origin);
364
- const originPoint = getOriginRelativePoint(originRect, position);
365
- return getOverlayPoint(originPoint, rect, position);
366
- }
367
- function getOriginRect(origin) {
368
- if (origin instanceof Element) {
369
- return origin.getBoundingClientRect();
370
- }
371
- const width = origin.width || 0;
372
- const height = origin.height || 0;
373
- return {
374
- top: origin.y,
375
- bottom: origin.y + height,
376
- left: origin.x,
377
- right: origin.x + width,
378
- height,
379
- width
380
- };
381
- }
382
- function getOverlayPoint(originPoint, rect, position) {
383
- let x;
384
- const {
385
- width,
386
- height
387
- } = rect;
388
- if (position.overlayX == "center") {
389
- x = originPoint.x - width / 2;
390
- } else {
391
- x = position.overlayX == "left" ? originPoint.x : originPoint.x - width;
354
+ const flexibleOverlayProps = {
355
+ modelValue: {
356
+ type: Boolean,
357
+ default: false
358
+ },
359
+ origin: {
360
+ type: Object,
361
+ require: true
362
+ },
363
+ position: {
364
+ type: Array,
365
+ default: ["bottom"]
366
+ },
367
+ offset: {
368
+ type: [Number, Object],
369
+ default: 8
370
+ },
371
+ align: {
372
+ type: String,
373
+ default: null
374
+ },
375
+ showArrow: {
376
+ type: Boolean,
377
+ default: false
378
+ },
379
+ isArrowCenter: {
380
+ type: Boolean,
381
+ default: true
392
382
  }
393
- let y;
394
- if (position.overlayY == "center") {
395
- y = originPoint.y - height / 2;
396
- } else {
397
- y = position.overlayY == "top" ? originPoint.y : originPoint.y - height;
383
+ };
384
+ function getScrollParent(element) {
385
+ const overflowRegex = /(auto|scroll|hidden)/;
386
+ for (let parent = element; parent = parent.parentElement; parent.parentElement !== document.body) {
387
+ const style = window.getComputedStyle(parent);
388
+ if (overflowRegex.test(style.overflow + style.overflowX + style.overflowY)) {
389
+ return parent;
390
+ }
398
391
  }
399
- return {
400
- x,
401
- y
402
- };
392
+ return window;
403
393
  }
404
- function getOriginRelativePoint(originRect, position) {
405
- let x;
406
- if (position.originX == "center") {
407
- x = originRect.left + originRect.width / 2;
408
- } else {
409
- const startX = originRect.left;
410
- const endX = originRect.right;
411
- x = position.originX == "left" ? startX : endX;
412
- }
413
- let y;
414
- if (position.originY == "center") {
415
- y = originRect.top + originRect.height / 2;
416
- } else {
417
- y = position.originY == "top" ? originRect.top : originRect.bottom;
394
+ function adjustArrowPosition(isArrowCenter, point, placement, originRect) {
395
+ let { x, y } = point;
396
+ if (!isArrowCenter) {
397
+ const { width, height } = originRect;
398
+ if (x && placement.includes("start")) {
399
+ x = 12;
400
+ }
401
+ if (x && placement.includes("end")) {
402
+ x = Math.round(width - 24);
403
+ }
404
+ if (y && placement.includes("start")) {
405
+ y = 10;
406
+ }
407
+ if (y && placement.includes("end")) {
408
+ y = height - 14;
409
+ }
418
410
  }
419
- return {
420
- x,
421
- y
422
- };
411
+ return { x, y };
423
412
  }
424
- function subscribeLayoutEvent(event) {
425
- window.addEventListener("scroll", event, true);
426
- window.addEventListener("resize", event);
427
- window.addEventListener("orientationchange", event);
428
- return () => {
429
- window.removeEventListener("scroll", event, true);
430
- window.removeEventListener("resize", event);
431
- window.removeEventListener("orientationchange", event);
413
+ function useOverlay(props, emit) {
414
+ const overlayRef = ref();
415
+ const arrowRef = ref();
416
+ const updateArrowPosition = (arrowEl, placement, point, overlayEl) => {
417
+ const { x, y } = adjustArrowPosition(props.isArrowCenter, point, placement, overlayEl.getBoundingClientRect());
418
+ const staticSide = {
419
+ top: "bottom",
420
+ right: "left",
421
+ bottom: "top",
422
+ left: "right"
423
+ }[placement.split("-")[0]];
424
+ Object.assign(arrowEl.style, {
425
+ left: x ? `${x}px` : "",
426
+ top: y ? `${y}px` : "",
427
+ right: "",
428
+ bottom: "",
429
+ [staticSide]: "-4px"
430
+ });
432
431
  };
433
- }
434
- function subscribeOverlayResize(overlay2, callback) {
435
- if (overlay2 instanceof Element) {
436
- const resizeObserver = new ResizeObserver(callback);
437
- resizeObserver.observe(overlay2);
438
- return () => resizeObserver.disconnect();
439
- }
440
- return () => {
432
+ const updatePosition = async () => {
433
+ const hostEl = props.origin;
434
+ const overlayEl = unref(overlayRef.value);
435
+ const arrowEl = unref(arrowRef.value);
436
+ const middleware = [
437
+ shift(),
438
+ offset(props.offset),
439
+ autoPlacement({
440
+ alignment: props.align,
441
+ allowedPlacements: props.position
442
+ })
443
+ ];
444
+ props.showArrow && middleware.push(arrow({ element: arrowEl }));
445
+ const { x, y, placement, middlewareData } = await computePosition(hostEl, overlayEl, {
446
+ strategy: "fixed",
447
+ middleware
448
+ });
449
+ emit("positionChange", placement);
450
+ Object.assign(overlayEl.style, { top: `${y}px`, left: `${x}px` });
451
+ props.showArrow && updateArrowPosition(arrowEl, placement, middlewareData.arrow, overlayEl);
441
452
  };
453
+ watch(() => props.modelValue, () => {
454
+ const originParent = getScrollParent(props.origin);
455
+ if (props.modelValue && props.origin) {
456
+ nextTick(updatePosition);
457
+ originParent.addEventListener("scroll", updatePosition);
458
+ originParent !== window && window.addEventListener("scroll", updatePosition);
459
+ window.addEventListener("resize", updatePosition);
460
+ } else {
461
+ originParent.removeEventListener("scroll", updatePosition);
462
+ originParent !== window && window.removeEventListener("scroll", updatePosition);
463
+ window.removeEventListener("resize", updatePosition);
464
+ }
465
+ });
466
+ onUnmounted(() => {
467
+ const originParent = getScrollParent(props.origin);
468
+ originParent.removeEventListener("scroll", updatePosition);
469
+ originParent !== window && window.removeEventListener("scroll", updatePosition);
470
+ window.removeEventListener("resize", updatePosition);
471
+ });
472
+ return { arrowRef, overlayRef, updatePosition };
442
473
  }
443
- function subscribeOriginResize(origin, callback) {
444
- if (origin instanceof Element) {
445
- const observer = new MutationObserver(callback);
446
- observer.observe(origin, {
447
- attributeFilter: ["style"]
474
+ var flexibleOverlay = "";
475
+ const FlexibleOverlay = defineComponent({
476
+ name: "DFlexibleOverlay",
477
+ inheritAttrs: false,
478
+ props: flexibleOverlayProps,
479
+ emits: ["update:modelValue", "positionChange"],
480
+ setup(props, {
481
+ slots,
482
+ attrs,
483
+ emit,
484
+ expose
485
+ }) {
486
+ const {
487
+ arrowRef,
488
+ overlayRef,
489
+ updatePosition
490
+ } = useOverlay(props, emit);
491
+ expose({
492
+ updatePosition
448
493
  });
449
- return () => observer.disconnect();
494
+ return () => {
495
+ var _a;
496
+ return props.modelValue && createVNode("div", mergeProps({
497
+ "ref": overlayRef,
498
+ "class": "devui-flexible-overlay"
499
+ }, attrs), [(_a = slots.default) == null ? void 0 : _a.call(slots), props.showArrow && createVNode("div", {
500
+ "ref": arrowRef,
501
+ "class": "devui-flexible-overlay-arrow"
502
+ }, null)]);
503
+ };
450
504
  }
451
- return () => {
452
- };
453
- }
454
- FlexibleOverlay.install = function(app) {
455
- app.component(FlexibleOverlay.name, FlexibleOverlay);
456
- };
457
- FixedOverlay.install = function(app) {
458
- app.component(FixedOverlay.name, FixedOverlay);
459
- };
505
+ });
460
506
  var dropdown = "";
507
+ let dropdownId = 1;
461
508
  var Dropdown = defineComponent({
462
509
  name: "DDropdown",
510
+ inheritAttrs: false,
463
511
  props: dropdownProps,
464
- emits: [],
465
- setup(props, ctx) {
512
+ emits: ["toggle"],
513
+ setup(props, {
514
+ slots,
515
+ attrs,
516
+ emit,
517
+ expose
518
+ }) {
466
519
  const {
520
+ visible,
521
+ position,
522
+ align,
523
+ offset: offset2,
524
+ showAnimation
525
+ } = toRefs(props);
526
+ const origin = ref();
527
+ const dropdownRef = ref();
528
+ const overlayRef = ref();
529
+ const id = `dropdown_${dropdownId++}`;
530
+ const isOpen = ref(false);
531
+ const currentPosition = ref("bottom");
532
+ useDropdownEvent({
533
+ id,
467
534
  isOpen,
468
535
  origin,
469
- trigger,
470
- closeScope,
471
- closeOnMouseLeaveMenu
472
- } = toRefs(props);
473
- const visible = ref(false);
474
- watch(isOpen, (value) => {
475
- visible.value = value;
476
- }, {
477
- immediate: true
536
+ dropdownRef,
537
+ props,
538
+ emit
539
+ });
540
+ useDropdown(id, visible, isOpen, origin, dropdownRef, currentPosition, emit);
541
+ const {
542
+ overlayModelValue,
543
+ overlayShowValue,
544
+ styles,
545
+ classes,
546
+ handlePositionChange
547
+ } = useOverlayProps(props, currentPosition, isOpen);
548
+ expose({
549
+ updatePosition: () => overlayRef.value.updatePosition()
478
550
  });
479
- const position = {
480
- originX: "center",
481
- originY: "bottom",
482
- overlayX: "center",
483
- overlayY: "top"
551
+ return () => {
552
+ var _a;
553
+ return createVNode(Fragment, null, [createVNode("div", {
554
+ "ref": origin,
555
+ "class": "devui-dropdown-toggle"
556
+ }, [(_a = slots.default) == null ? void 0 : _a.call(slots)]), createVNode(Teleport, {
557
+ "to": "body"
558
+ }, {
559
+ default: () => [createVNode(Transition, {
560
+ "name": showAnimation.value ? `devui-dropdown-fade-${currentPosition.value}` : ""
561
+ }, {
562
+ default: () => [withDirectives(createVNode(FlexibleOverlay, {
563
+ "modelValue": overlayModelValue.value,
564
+ "onUpdate:modelValue": ($event) => overlayModelValue.value = $event,
565
+ "ref": overlayRef,
566
+ "origin": origin.value,
567
+ "position": position.value,
568
+ "align": align.value,
569
+ "offset": offset2.value,
570
+ "onPositionChange": handlePositionChange,
571
+ "class": classes.value,
572
+ "style": styles.value
573
+ }, {
574
+ default: () => {
575
+ var _a2;
576
+ return [createVNode("div", mergeProps({
577
+ "ref": dropdownRef,
578
+ "class": "devui-dropdown-menu-wrap"
579
+ }, attrs), [(_a2 = slots.menu) == null ? void 0 : _a2.call(slots)])];
580
+ }
581
+ }), [[vShow, overlayShowValue.value]])]
582
+ })]
583
+ })]);
484
584
  };
585
+ }
586
+ });
587
+ const dropdownMenuProps = {
588
+ modelValue: {
589
+ type: Boolean,
590
+ default: false
591
+ },
592
+ origin: {
593
+ type: Object,
594
+ require: true
595
+ },
596
+ position: {
597
+ type: Array,
598
+ default: ["bottom"]
599
+ },
600
+ align: {
601
+ type: String,
602
+ default: null
603
+ },
604
+ offset: {
605
+ type: [Number, Object],
606
+ default: 4
607
+ },
608
+ clickOutside: {
609
+ type: Function,
610
+ default: () => true
611
+ },
612
+ showAnimation: {
613
+ type: Boolean,
614
+ default: true
615
+ },
616
+ overlayClass: {
617
+ type: String,
618
+ default: ""
619
+ }
620
+ };
621
+ var DropdownMenu = defineComponent({
622
+ name: "DDropdownMenu",
623
+ inheritAttrs: false,
624
+ props: dropdownMenuProps,
625
+ emits: ["update:modelValue"],
626
+ setup(props, {
627
+ slots,
628
+ attrs,
629
+ emit
630
+ }) {
485
631
  const {
486
- dropdownEl
487
- } = useDropdown({
488
- visible,
632
+ modelValue,
489
633
  origin,
490
- trigger,
491
- closeScope,
492
- closeOnMouseLeaveMenu
493
- });
494
- const animatedVisible = computed(() => {
495
- return props.showAnimation ? visible.value : true;
496
- });
497
- const wrapStyle = computed(() => typeof props.width === "string" ? {
498
- width: props.width
499
- } : {
500
- width: `${props.width}px`
634
+ position,
635
+ align,
636
+ offset: offset2,
637
+ clickOutside,
638
+ showAnimation,
639
+ overlayClass
640
+ } = toRefs(props);
641
+ const dropdownMenuRef = ref(null);
642
+ onClickOutside(dropdownMenuRef, (value) => {
643
+ var _a, _b;
644
+ if (((_a = clickOutside.value) == null ? void 0 : _a.call(clickOutside)) && !((_b = origin == null ? void 0 : origin.value) == null ? void 0 : _b.contains(value.target))) {
645
+ emit("update:modelValue", false);
646
+ }
501
647
  });
502
- return () => createVNode(FlexibleOverlay, {
503
- "origin": props.origin,
504
- "visible": visible.value,
505
- "onUpdate:visible": ($event) => visible.value = $event,
506
- "position": position,
507
- "hasBackdrop": false
648
+ const currentPosition = ref("bottom");
649
+ const handlePositionChange = (pos) => {
650
+ currentPosition.value = pos.split("-")[0] === "top" ? "top" : "bottom";
651
+ };
652
+ const styles = computed(() => ({
653
+ transformOrigin: currentPosition.value === "top" ? "0% 100%" : "0% 0%"
654
+ }));
655
+ return () => createVNode(Teleport, {
656
+ "to": "body"
508
657
  }, {
509
658
  default: () => [createVNode(Transition, {
510
- "name": "devui-dropdown-fade"
659
+ "name": showAnimation.value ? `devui-dropdown-fade-${currentPosition.value}` : ""
511
660
  }, {
512
- default: () => {
513
- var _a, _b;
514
- return [withDirectives(createVNode("div", {
515
- "ref": dropdownEl,
516
- "class": "devui-dropdown-menu-wrap",
517
- "style": wrapStyle.value
518
- }, [(_b = (_a = ctx.slots).default) == null ? void 0 : _b.call(_a)]), [[vShow, animatedVisible.value]])];
519
- }
661
+ default: () => [createVNode(FlexibleOverlay, {
662
+ "modelValue": modelValue.value,
663
+ "onUpdate:modelValue": ($event) => modelValue.value = $event,
664
+ "origin": origin == null ? void 0 : origin.value,
665
+ "position": position.value,
666
+ "align": align.value,
667
+ "offset": offset2.value,
668
+ "onPositionChange": handlePositionChange,
669
+ "class": overlayClass.value,
670
+ "style": styles.value
671
+ }, {
672
+ default: () => {
673
+ var _a;
674
+ return [createVNode("div", mergeProps({
675
+ "ref": dropdownMenuRef,
676
+ "class": "devui-dropdown-menu-wrap"
677
+ }, attrs), [(_a = slots.default) == null ? void 0 : _a.call(slots)])];
678
+ }
679
+ })]
520
680
  })]
521
681
  });
522
682
  }
523
683
  });
524
- Dropdown.install = function(app) {
525
- app.component(Dropdown.name, Dropdown);
526
- };
527
684
  var index = {
528
685
  title: "Dropdown \u4E0B\u62C9\u83DC\u5355",
529
686
  category: "\u5BFC\u822A",
530
687
  status: "10%",
531
688
  install(app) {
532
- app.use(Dropdown);
689
+ app.component(Dropdown.name, Dropdown);
690
+ app.component(DropdownMenu.name, DropdownMenu);
533
691
  }
534
692
  };
535
- export { Dropdown, index as default };
693
+ export { Dropdown, DropdownMenu, index as default, dropdownMenuProps };