@destyler/popover 0.0.0 → 0.0.1-beta.10

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.
package/dist/index.mjs CHANGED
@@ -1,1168 +1,11 @@
1
- import { defineComponent, provide, getCurrentInstance, inject, ref, onBeforeUnmount, withDirectives, toRef, computed, h, Teleport, onMounted, watch, Fragment, watchEffect, vShow, mergeProps, cloneVNode } from 'vue';
2
- import { off, getSlot, on, beforeNextFrameOnce, getFirstVNode, createId, resolveTo, getPreciseEventTarget, isJsdom, isSlotEmpty, resolveWrappedSlot, getFirstSlotVNode, keep, call } from '@destyler/shared';
3
- import { zindexable, clickoutside, mousemoveoutside } from '@destyler/directives';
4
- import { useFalseUntilTruthy, useMemo, useIsMounted, useMergedState } from '@destyler/composition';
5
-
6
- function getParentNode(node) {
7
- if (node.nodeType === 9)
8
- return null;
9
- return node.parentNode;
10
- }
11
- function getScrollParent(node) {
12
- if (node === null)
13
- return null;
14
- const parentNode = getParentNode(node);
15
- if (parentNode === null)
16
- return null;
17
- if (parentNode.nodeType === 9)
18
- return document;
19
- if (parentNode.nodeType === 1) {
20
- const { overflow, overflowX, overflowY } = getComputedStyle(
21
- parentNode
22
- );
23
- if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX))
24
- return parentNode;
25
- }
26
- return getScrollParent(parentNode);
27
- }
28
-
29
- const DestylerBinder = defineComponent({
30
- name: "DestylerBinder",
31
- props: {
32
- syncTargetWithParent: {
33
- type: Boolean
34
- },
35
- syncTarget: {
36
- type: Boolean,
37
- default: true
38
- }
39
- },
40
- setup(props, { slots }) {
41
- provide("DestylerBinder", getCurrentInstance()?.proxy);
42
- const DestylerBinder = inject("DestylerBinder", null);
43
- const targetRef = ref(null);
44
- const followerResizeListeners = /* @__PURE__ */ new Set();
45
- const followerScrollListeners = /* @__PURE__ */ new Set();
46
- const onScrollRaf = () => {
47
- followerScrollListeners.forEach((listener) => listener());
48
- };
49
- const onScroll = () => {
50
- beforeNextFrameOnce(onScrollRaf);
51
- };
52
- const onResize = () => {
53
- followerResizeListeners.forEach((listener) => listener());
54
- };
55
- const setTargetRef = (el) => {
56
- targetRef.value = el;
57
- if (DestylerBinder && props.syncTargetWithParent)
58
- DestylerBinder.setTargetRef(el);
59
- };
60
- let scrollableNodes = [];
61
- const ensureScrollListener = () => {
62
- let cursor = targetRef.value;
63
- while (true) {
64
- cursor = getScrollParent(cursor);
65
- if (cursor === null)
66
- break;
67
- scrollableNodes.push(cursor);
68
- }
69
- for (const el of scrollableNodes)
70
- on("scroll", el, onScroll, true);
71
- };
72
- const removeScrollListeners = () => {
73
- for (const el of scrollableNodes)
74
- off("scroll", el, onScroll, true);
75
- scrollableNodes = [];
76
- };
77
- const addScrollListener = (listener) => {
78
- if (followerScrollListeners.size === 0)
79
- ensureScrollListener();
80
- if (!followerScrollListeners.has(listener))
81
- followerScrollListeners.add(listener);
82
- };
83
- const removeScrollListener = (listener) => {
84
- if (followerScrollListeners.has(listener))
85
- followerScrollListeners.delete(listener);
86
- if (followerScrollListeners.size === 0)
87
- removeScrollListeners();
88
- };
89
- const addResizeListener = (listener) => {
90
- if (followerResizeListeners.size === 0)
91
- on("resize", window, onResize);
92
- if (!followerResizeListeners.has(listener))
93
- followerResizeListeners.add(listener);
94
- };
95
- const removeResizeListener = (listener) => {
96
- if (followerResizeListeners.has(listener))
97
- followerResizeListeners.delete(listener);
98
- if (followerResizeListeners.size === 0)
99
- off("resize", window, onResize);
100
- };
101
- onBeforeUnmount(() => {
102
- off("resize", window, onResize);
103
- removeScrollListeners();
104
- });
105
- return {
106
- targetRef,
107
- setTargetRef,
108
- addScrollListener,
109
- removeScrollListener,
110
- addResizeListener,
111
- removeResizeListener
112
- };
113
- },
114
- render() {
115
- return getSlot("binder", this.$slots);
116
- }
117
- });
118
-
119
- const DestylerTarget = defineComponent({
120
- name: "DestylerTarget",
121
- setup() {
122
- const { setTargetRef, syncTarget } = inject("DestylerBinder");
123
- const setTargetDirective = {
124
- mounted(el) {
125
- setTargetRef(el);
126
- },
127
- updated(el) {
128
- setTargetRef(el);
129
- }
130
- };
131
- return {
132
- syncTarget,
133
- setTargetDirective
134
- };
135
- },
136
- render() {
137
- const { syncTarget, setTargetDirective } = this;
138
- if (syncTarget) {
139
- return withDirectives(getFirstVNode("follower", this.$slots), [
140
- [setTargetDirective]
141
- ]);
142
- }
143
- return getFirstVNode("follower", this.$slots);
144
- }
145
- });
146
-
147
- const DestylerLazyTeleport = defineComponent({
148
- name: "DestylerLazyTeleport",
149
- props: {
150
- to: {
151
- type: [String, Object],
152
- default: "body"
153
- },
154
- disabled: {
155
- type: Boolean
156
- },
157
- show: {
158
- type: Boolean,
159
- required: true
160
- }
161
- },
162
- setup(props) {
163
- return {
164
- showTeleport: useFalseUntilTruthy(toRef(props, "show")),
165
- mergedTo: computed(() => {
166
- const { to } = props;
167
- return to ?? "body";
168
- })
169
- };
170
- },
171
- render() {
172
- return this.showTeleport ? this.disabled ? getSlot("lazy-teleport", this.$slots) : h(
173
- Teleport,
174
- {
175
- disabled: this.disabled,
176
- to: this.mergedTo
177
- },
178
- getSlot("lazy-teleport", this.$slots)
179
- ) : null;
180
- }
181
- });
182
-
183
- const DestylerFollower = defineComponent({
184
- name: "DestylerFollower",
185
- inheritAttrs: true,
186
- props: {
187
- show: {
188
- type: Boolean,
189
- default: false
190
- },
191
- enabled: {
192
- type: Boolean,
193
- default: void 0
194
- },
195
- to: {
196
- type: [String, Object],
197
- default: "body"
198
- },
199
- flip: {
200
- type: Boolean,
201
- default: true
202
- },
203
- internalShift: {
204
- type: Boolean
205
- },
206
- x: {
207
- type: Number
208
- },
209
- y: {
210
- type: Number
211
- },
212
- width: {
213
- type: String
214
- },
215
- minWidth: {
216
- type: String
217
- },
218
- containerClass: {
219
- type: String
220
- },
221
- teleportDisabled: {
222
- type: Boolean
223
- },
224
- zindexable: {
225
- type: Boolean,
226
- default: true
227
- },
228
- zIndex: {
229
- type: Number
230
- },
231
- overlap: {
232
- type: Boolean
233
- }
234
- },
235
- setup(props) {
236
- const DestylerBinder = inject("DestylerBinder");
237
- const mergedEnabled = useMemo(() => {
238
- return props.enabled !== void 0 ? props.enabled : props.show;
239
- });
240
- const follower = ref(null);
241
- const offsetContainer = ref(null);
242
- const isMounted = useIsMounted();
243
- const mergedTo = useMemo(
244
- () => {
245
- const { to } = props;
246
- if (to !== void 0)
247
- return to;
248
- if (isMounted.value) {
249
- return void 0;
250
- }
251
- return void 0;
252
- }
253
- );
254
- function getElementBounding() {
255
- if (DestylerBinder.targetRef === null) {
256
- return {
257
- x: 0,
258
- y: 0,
259
- width: 0,
260
- height: 0
261
- };
262
- } else {
263
- const rect = DestylerBinder.targetRef.getBoundingClientRect();
264
- return {
265
- x: rect.x,
266
- y: rect.y,
267
- width: rect.width,
268
- height: rect.height
269
- };
270
- }
271
- }
272
- return {
273
- mergedEnabled,
274
- follower,
275
- offsetContainer,
276
- mergedTo,
277
- getElementBounding
278
- };
279
- },
280
- render() {
281
- return h(DestylerLazyTeleport, {
282
- to: this.mergedTo,
283
- disabled: this.$props.teleportDisabled,
284
- show: this.$props.show
285
- }, {
286
- default: () => {
287
- const vNode = h("div", {
288
- ref: "offsetContainer",
289
- destyler: "offset-container"
290
- }, [
291
- h("div", {
292
- ref: "follower",
293
- destyler: "follower",
294
- style: `
295
- --destyler-follower-x:${this.getElementBounding().x}px;
296
- --destyler-follower-y:${this.getElementBounding().y}px;
297
- --destyler-follower-width:${this.getElementBounding().width}px;
298
- --destyler-follower-height:${this.getElementBounding().height}px;
299
- `
300
- }, this.$slots.default?.())
301
- ]);
302
- if (this.$props.zindexable) {
303
- return withDirectives(vNode, [
304
- [
305
- zindexable,
306
- {
307
- enabled: this.mergedEnabled,
308
- zIndex: this.$props.zIndex
309
- }
310
- ]
311
- ]);
312
- }
313
- return vNode;
314
- }
315
- });
316
- }
317
- });
318
-
319
- function isHTMLElement(node) {
320
- return node instanceof HTMLElement;
321
- }
322
- function focusFirstDescendant(node) {
323
- for (let i = 0; i < node.childNodes.length; i++) {
324
- const child = node.childNodes[i];
325
- if (isHTMLElement(child)) {
326
- if (attemptFocus(child) || focusFirstDescendant(child))
327
- return true;
328
- }
329
- }
330
- return false;
331
- }
332
- function focusLastDescendant(element) {
333
- for (let i = element.childNodes.length - 1; i >= 0; i--) {
334
- const child = element.childNodes[i];
335
- if (isHTMLElement(child)) {
336
- if (attemptFocus(child) || focusLastDescendant(child))
337
- return true;
338
- }
339
- }
340
- return false;
341
- }
342
- function attemptFocus(element) {
343
- if (!isFocusable(element))
344
- return false;
345
- try {
346
- element.focus({ preventScroll: true });
347
- } catch (e) {
348
- }
349
- return document.activeElement === element;
350
- }
351
- function isFocusable(element) {
352
- if (element.tabIndex > 0 || element.tabIndex === 0 && element.getAttribute("tabIndex") !== null)
353
- return true;
354
- if (element.getAttribute("disabled"))
355
- return false;
356
- switch (element.nodeName) {
357
- case "A":
358
- return !!element.href && element.rel !== "ignore";
359
- case "INPUT":
360
- return element.type !== "hidden" && element.type !== "file";
361
- case "BUTTON":
362
- case "SELECT":
363
- case "TEXTAREA":
364
- return true;
365
- default:
366
- return false;
367
- }
368
- }
369
-
370
- let stack = [];
371
- const DestylerFocusTrap = defineComponent({
372
- name: "DestylerFocusTrap",
373
- props: {
374
- disabled: {
375
- type: Boolean
376
- },
377
- active: {
378
- type: Boolean
379
- },
380
- autoFocus: {
381
- type: Boolean,
382
- default: true
383
- },
384
- onEsc: {
385
- type: Function
386
- },
387
- initialFocusTo: {
388
- type: String
389
- },
390
- finalFocusTo: {
391
- type: String
392
- },
393
- returnFocusOnDeactivated: {
394
- type: Boolean,
395
- default: true
396
- }
397
- },
398
- setup(props) {
399
- const id = createId();
400
- const focusableStartRef = ref(null);
401
- const focusableEndRef = ref(null);
402
- let activated = false;
403
- let ignoreInternalFocusChange = false;
404
- const lastFocusedElement = typeof document === "undefined" ? null : document.activeElement;
405
- function isCurrentActive() {
406
- const currentActiveId = stack[stack.length - 1];
407
- return currentActiveId === id;
408
- }
409
- function handleDocumentKeydown(e) {
410
- if (e.code === "Escape") {
411
- if (isCurrentActive())
412
- props.onEsc?.(e);
413
- }
414
- }
415
- onMounted(() => {
416
- watch(
417
- () => props.active,
418
- (value) => {
419
- if (value) {
420
- activate();
421
- on("keydown", document, handleDocumentKeydown);
422
- } else {
423
- off("keydown", document, handleDocumentKeydown);
424
- if (activated)
425
- deactivate();
426
- }
427
- },
428
- {
429
- immediate: true
430
- }
431
- );
432
- });
433
- onBeforeUnmount(() => {
434
- off("keydown", document, handleDocumentKeydown);
435
- if (activated)
436
- deactivate();
437
- });
438
- function handleDocumentFocus(e) {
439
- if (ignoreInternalFocusChange)
440
- return;
441
- if (isCurrentActive()) {
442
- const mainEl = getMainEl();
443
- if (mainEl === null)
444
- return;
445
- if (mainEl.contains(getPreciseEventTarget(e)))
446
- return;
447
- resetFocusTo("first");
448
- }
449
- }
450
- function getMainEl() {
451
- const focusableStartEl = focusableStartRef.value;
452
- if (focusableStartEl === null)
453
- return null;
454
- let mainEl = focusableStartEl;
455
- while (true) {
456
- mainEl = mainEl.nextSibling;
457
- if (mainEl === null)
458
- break;
459
- if (mainEl instanceof Element && mainEl.tagName === "DIV")
460
- break;
461
- }
462
- return mainEl;
463
- }
464
- function activate() {
465
- if (props.disabled)
466
- return;
467
- stack.push(id);
468
- if (props.autoFocus) {
469
- const { initialFocusTo } = props;
470
- if (initialFocusTo === void 0)
471
- resetFocusTo("first");
472
- else
473
- resolveTo(initialFocusTo)?.focus({ preventScroll: true });
474
- }
475
- activated = true;
476
- document.addEventListener("focus", handleDocumentFocus, true);
477
- }
478
- function deactivate() {
479
- if (props.disabled)
480
- return;
481
- document.removeEventListener("focus", handleDocumentFocus, true);
482
- stack = stack.filter((idInStack) => idInStack !== id);
483
- if (isCurrentActive())
484
- return;
485
- const { finalFocusTo } = props;
486
- if (finalFocusTo !== void 0) {
487
- resolveTo(finalFocusTo)?.focus({ preventScroll: true });
488
- } else if (props.returnFocusOnDeactivated) {
489
- if (lastFocusedElement instanceof HTMLElement) {
490
- ignoreInternalFocusChange = true;
491
- lastFocusedElement.focus({ preventScroll: true });
492
- ignoreInternalFocusChange = false;
493
- }
494
- }
495
- }
496
- function resetFocusTo(target) {
497
- if (!isCurrentActive())
498
- return;
499
- if (props.active) {
500
- const focusableStartEl = focusableStartRef.value;
501
- const focusableEndEl = focusableEndRef.value;
502
- if (focusableStartEl !== null && focusableEndEl !== null) {
503
- const mainEl = getMainEl();
504
- if (mainEl == null || mainEl === focusableEndEl) {
505
- ignoreInternalFocusChange = true;
506
- focusableStartEl.focus({ preventScroll: true });
507
- ignoreInternalFocusChange = false;
508
- return;
509
- }
510
- ignoreInternalFocusChange = true;
511
- const focused = target === "first" ? focusFirstDescendant(mainEl) : focusLastDescendant(mainEl);
512
- ignoreInternalFocusChange = false;
513
- if (!focused) {
514
- ignoreInternalFocusChange = true;
515
- focusableStartEl.focus({ preventScroll: true });
516
- ignoreInternalFocusChange = false;
517
- }
518
- }
519
- }
520
- }
521
- function handleStartFocus(e) {
522
- if (ignoreInternalFocusChange)
523
- return;
524
- const mainEl = getMainEl();
525
- if (mainEl === null)
526
- return;
527
- if (e.relatedTarget !== null && mainEl.contains(e.relatedTarget)) {
528
- resetFocusTo("last");
529
- } else {
530
- resetFocusTo("first");
531
- }
532
- }
533
- function handleEndFocus(e) {
534
- if (ignoreInternalFocusChange)
535
- return;
536
- if (e.relatedTarget !== null && e.relatedTarget === focusableStartRef.value) {
537
- resetFocusTo("last");
538
- } else {
539
- resetFocusTo("first");
540
- }
541
- }
542
- return {
543
- focusableStartRef,
544
- focusableEndRef,
545
- focusableStyle: "position: absolute; height: 0; width: 0;",
546
- handleStartFocus,
547
- handleEndFocus
548
- };
549
- },
550
- render() {
551
- const { default: defaultSlot } = this.$slots;
552
- if (defaultSlot === void 0)
553
- return null;
554
- if (this.disabled)
555
- return defaultSlot();
556
- const { active, focusableStyle } = this;
557
- return h(Fragment, null, [
558
- h("div", {
559
- "destyler": "focusable-start",
560
- "aria-hidden": "true",
561
- "tabindex": active ? "0" : "-1",
562
- "ref": "focusableStartRef",
563
- "style": focusableStyle,
564
- "onFocus": this.handleStartFocus
565
- }),
566
- h("div", {
567
- destyler: "focusable-content"
568
- }, defaultSlot()),
569
- h("div", {
570
- "destyler": "focusable-end",
571
- "aria-hidden": "true",
572
- "style": focusableStyle,
573
- "ref": "focusableEndRef",
574
- "tabindex": active ? "0" : "-1",
575
- "onFocus": this.handleEndFocus
576
- })
577
- ]);
578
- }
579
- });
580
-
581
- const popoverBodyProps = {
582
- show: {
583
- type: Boolean
584
- },
585
- trigger: {
586
- type: String
587
- },
588
- delay: {
589
- type: Number
590
- },
591
- duration: {
592
- type: Number
593
- },
594
- displayDirective: {
595
- type: String
596
- },
597
- x: {
598
- type: Number
599
- },
600
- y: {
601
- type: Number
602
- },
603
- flip: {
604
- type: Boolean
605
- },
606
- internalTrapFocus: {
607
- type: Boolean
608
- },
609
- overlap: {
610
- type: Boolean
611
- },
612
- keepAliveOnHover: {
613
- type: Boolean
614
- },
615
- scrollable: {
616
- type: Boolean
617
- },
618
- internalDeactivateImmediately: {
619
- type: Boolean
620
- },
621
- onClickoutside: {
622
- type: Function
623
- }
624
- };
625
- const DestylerPopoverBody = defineComponent({
626
- name: "DestylerPopoverBody",
627
- props: popoverBodyProps,
628
- setup(props, { slots, attrs }) {
629
- const follower = ref(null);
630
- const DestylerPopover = inject("DestylerPopover");
631
- const body = ref(null);
632
- const followerEnabled = ref(props.show);
633
- const displayed = ref(false);
634
- watchEffect(() => {
635
- const { show } = props;
636
- if (show && !isJsdom() && !props.internalDeactivateImmediately)
637
- displayed.value = true;
638
- else
639
- displayed.value = false;
640
- });
641
- onBeforeUnmount(() => {
642
- DestylerPopover.setBodyInstance(null);
643
- });
644
- watch(toRef(props, "show"), (value) => {
645
- if (value)
646
- followerEnabled.value = true;
647
- else
648
- followerEnabled.value = false;
649
- });
650
- function syncPosition() {
651
- follower.value?.syncPosition();
652
- }
653
- DestylerPopover.setBodyInstance({
654
- syncPosition
655
- });
656
- function handleMouseEnter(e) {
657
- if (props.trigger === "hover" && props.keepAliveOnHover && props.show)
658
- DestylerPopover.handleMouseEnter(e);
659
- }
660
- function handleMouseLeave(e) {
661
- if (props.trigger === "hover" && props.keepAliveOnHover)
662
- DestylerPopover.handleMouseLeave(e);
663
- }
664
- function handleMouseMoveOutside(e) {
665
- if (props.trigger === "hover" && !getTriggerElement().contains(getPreciseEventTarget(e)))
666
- DestylerPopover.handleMouseMoveOutside(e);
667
- }
668
- function getTriggerElement() {
669
- return DestylerPopover.getTriggerElement();
670
- }
671
- function handleClickOutside(e) {
672
- if (props.trigger === "click" && !getTriggerElement().contains(
673
- getPreciseEventTarget(e)
674
- ) || props.onClickoutside)
675
- DestylerPopover.handleClickOutside(e);
676
- }
677
- const directives = computed(() => {
678
- const { trigger, onClickoutside } = props;
679
- const directives2 = [];
680
- const {
681
- positionManually: { value: positionManually }
682
- } = DestylerPopover;
683
- if (!positionManually) {
684
- if (trigger === "click" && !onClickoutside) {
685
- directives2.push([
686
- clickoutside,
687
- handleClickOutside,
688
- void 0,
689
- { capture: true }
690
- ]);
691
- }
692
- if (trigger === "hover")
693
- directives2.push([mousemoveoutside, handleMouseMoveOutside]);
694
- }
695
- if (onClickoutside) {
696
- directives2.push([
697
- clickoutside,
698
- handleClickOutside,
699
- void 0,
700
- { capture: true }
701
- ]);
702
- }
703
- if (props.displayDirective === "show" || displayed.value)
704
- directives2.push([vShow, props.show]);
705
- return directives2;
706
- });
707
- function renderContentNode() {
708
- const shouldRenderDom = props.displayDirective === "show" || props.show || displayed.value;
709
- if (!shouldRenderDom)
710
- return null;
711
- let contentNode;
712
- const renderBody = DestylerPopover.internalRenderBody.value;
713
- if (!renderBody) {
714
- const { internalTrapFocus } = props;
715
- const hasHeaderOrFooter = !isSlotEmpty(slots.header) || !isSlotEmpty(slots.footer);
716
- const renderContentInnerNode = () => {
717
- const body2 = hasHeaderOrFooter ? [
718
- resolveWrappedSlot(slots.header, (children) => {
719
- return children ? h("div", null, children) : null;
720
- }),
721
- resolveWrappedSlot(slots.default, (children) => {
722
- return children ? h("div", null, children) : null;
723
- }),
724
- resolveWrappedSlot(slots.footer, (children) => {
725
- return children ? h("div", null, children) : null;
726
- })
727
- ] : h("div", {
728
- destyler: "popover-body-content"
729
- }, slots);
730
- return [body2];
731
- };
732
- contentNode = h(
733
- "div",
734
- mergeProps({
735
- ref: body,
736
- destyler: "popover-body-toggle",
737
- onMouseenter: handleMouseEnter,
738
- onMouseleave: handleMouseLeave
739
- }, attrs),
740
- internalTrapFocus ? h(DestylerFocusTrap, {
741
- active: props.show,
742
- autoFocus: true
743
- }, renderContentInnerNode) : renderContentInnerNode()
744
- );
745
- } else {
746
- contentNode = renderBody(body, handleMouseEnter, handleMouseLeave);
747
- }
748
- return withDirectives(contentNode, directives.value);
749
- }
750
- return {
751
- displayed,
752
- isMounted: DestylerPopover.isMounted,
753
- zIndex: DestylerPopover.zIndex,
754
- follower,
755
- followerEnabled,
756
- renderContentNode
757
- };
758
- },
759
- render() {
760
- return h(DestylerFollower, {
761
- ref: "follower",
762
- zIndex: this.zIndex,
763
- show: this.$props.show,
764
- enabled: this.followerEnabled,
765
- to: "body",
766
- x: this.$props.x,
767
- y: this.$props.y,
768
- flip: this.$props.flip,
769
- overlap: this.$props.overlap
770
- }, () => this.renderContentNode());
771
- }
772
- });
773
-
774
- const bodyPropKeys = Object.keys(popoverBodyProps);
775
- const triggerEventMap = {
776
- focus: ["onFocus", "onBlur"],
777
- click: ["onClick"],
778
- hover: ["onMouseenter", "onMouseleave"],
779
- manual: [],
780
- nested: ["onFocus", "onBlur", "onMouseenter", "onMouseleave", "onClick"]
781
- };
782
- function appendEvents(vNode, trigger, events) {
783
- triggerEventMap[trigger].forEach((eventName) => {
784
- if (!vNode.props)
785
- vNode.props = {};
786
- else
787
- vNode.props = Object.assign({}, vNode.props);
788
- const originalHandler = vNode.props[eventName];
789
- const handler = events[eventName];
790
- if (!originalHandler) {
791
- vNode.props[eventName] = handler;
792
- } else {
793
- vNode.props[eventName] = (...args) => {
794
- originalHandler(...args);
795
- handler(...args);
796
- };
797
- }
798
- });
799
- }
800
- const destylerPopoverProps = {
801
- "show": {
802
- type: Boolean,
803
- default: void 0
804
- },
805
- "defaultShow": {
806
- type: Boolean
807
- },
808
- "trigger": {
809
- type: String,
810
- default: "hover"
811
- },
812
- "delay": {
813
- type: Number,
814
- default: 100
815
- },
816
- "duration": {
817
- type: Number,
818
- default: 100
819
- },
820
- "x": {
821
- type: Number
822
- },
823
- "y": {
824
- type: Number
825
- },
826
- "disabled": {
827
- type: Boolean
828
- },
829
- "getDisabled": {
830
- type: Function
831
- },
832
- "displayDirective": {
833
- type: String,
834
- default: "if"
835
- },
836
- "zIndex": {
837
- type: Number
838
- },
839
- "internalSyncTargetWithParent": {
840
- type: Boolean
841
- },
842
- "internalInheritedEventHandlers": {
843
- type: Array,
844
- default: () => []
845
- },
846
- "internalTrapFocus": {
847
- type: Boolean
848
- },
849
- "onClickoutside": {
850
- type: Function
851
- },
852
- "onUpdate:show": {
853
- type: [Function, Array]
854
- },
855
- "onUpdateShow": {
856
- type: [Function, Array]
857
- },
858
- "onShow": {
859
- type: [Function, Array]
860
- },
861
- "onHide": {
862
- type: [Function, Array]
863
- },
864
- "internalRenderBody": {
865
- type: Function
866
- }
867
- };
868
- const DestylerPopover = defineComponent({
869
- name: "DestylerPopover",
870
- inheritAttrs: false,
871
- props: destylerPopoverProps,
872
- __popover__: true,
873
- setup(props, { slots, attrs }) {
874
- const isMounted = useIsMounted();
875
- const binderInst = ref(null);
876
- const controlledShow = computed(() => props.show);
877
- const uncontrolledShow = ref(props.defaultShow);
878
- const mergedShowWithoutDisabled = useMergedState(
879
- controlledShow,
880
- uncontrolledShow
881
- );
882
- const mergedShowConsideringDisabledProp = useMemo(() => {
883
- if (props.disabled)
884
- return false;
885
- return mergedShowWithoutDisabled.value;
886
- });
887
- const getMergedDisabled = () => {
888
- if (props.disabled)
889
- return true;
890
- const { getDisabled } = props;
891
- if (getDisabled?.())
892
- return true;
893
- return false;
894
- };
895
- const getMergedShow = () => {
896
- if (getMergedDisabled())
897
- return false;
898
- return mergedShowWithoutDisabled.value;
899
- };
900
- const showTimerId = ref(null);
901
- const hideTimerId = ref(null);
902
- const positionManually = useMemo(() => {
903
- return props.x !== void 0 && props.y !== void 0;
904
- });
905
- function doUpdateShow(value) {
906
- const {
907
- "onUpdate:show": _onUpdateShow,
908
- onUpdateShow,
909
- onShow,
910
- onHide
911
- } = props;
912
- uncontrolledShow.value = value;
913
- if (_onUpdateShow)
914
- call(_onUpdateShow, value);
915
- if (onUpdateShow)
916
- call(onUpdateShow, value);
917
- if (value && onShow)
918
- call(onShow, true);
919
- if (value && onHide)
920
- call(onHide, false);
921
- }
922
- function clearShowTimer() {
923
- if (showTimerId.value) {
924
- window.clearTimeout(showTimerId.value);
925
- showTimerId.value = null;
926
- }
927
- }
928
- function clearHideTimer() {
929
- if (hideTimerId.value) {
930
- window.clearTimeout(hideTimerId.value);
931
- hideTimerId.value = null;
932
- }
933
- }
934
- function handleFocus() {
935
- const mergedDisabled = getMergedDisabled();
936
- if (props.trigger === "focus" && !mergedDisabled) {
937
- if (getMergedShow())
938
- return;
939
- doUpdateShow(true);
940
- }
941
- }
942
- function handleBlur() {
943
- const mergedDisabled = getMergedDisabled();
944
- if (props.trigger === "focus" && !mergedDisabled) {
945
- if (!getMergedShow())
946
- return;
947
- doUpdateShow(false);
948
- }
949
- }
950
- function handleMouseEnter() {
951
- const mergedDisabled = getMergedDisabled();
952
- if (props.trigger === "hover" && !mergedDisabled) {
953
- clearHideTimer();
954
- if (showTimerId.value !== null)
955
- return;
956
- if (getMergedShow())
957
- return;
958
- const delayCallback = () => {
959
- doUpdateShow(true);
960
- showTimerId.value = null;
961
- };
962
- const { delay } = props;
963
- if (delay === 0)
964
- delayCallback();
965
- else
966
- showTimerId.value = window.setTimeout(delayCallback, delay);
967
- }
968
- }
969
- function handleMouseLeave() {
970
- const mergedDisabled = getMergedDisabled();
971
- if (props.trigger === "hover" && !mergedDisabled) {
972
- clearShowTimer();
973
- if (hideTimerId.value !== null)
974
- return;
975
- if (!getMergedShow())
976
- return;
977
- const delayedCallback = () => {
978
- doUpdateShow(false);
979
- hideTimerId.value = null;
980
- };
981
- const { duration } = props;
982
- if (duration === 0)
983
- delayedCallback();
984
- else
985
- hideTimerId.value = window.setTimeout(delayedCallback, duration);
986
- }
987
- }
988
- function handleMouseMoveOutside() {
989
- handleMouseLeave();
990
- }
991
- function handleClickOutside(e) {
992
- if (!getMergedShow())
993
- return;
994
- if (props.trigger === "click") {
995
- clearShowTimer();
996
- clearHideTimer();
997
- doUpdateShow(false);
998
- }
999
- props.onClickoutside?.(e);
1000
- }
1001
- function handleClick() {
1002
- if (props.trigger === "click" && !getMergedDisabled()) {
1003
- clearShowTimer();
1004
- clearHideTimer();
1005
- const nextShow = !getMergedShow();
1006
- doUpdateShow(nextShow);
1007
- }
1008
- }
1009
- function getTriggerElement() {
1010
- return binderInst.value?.targetRef;
1011
- }
1012
- function setBodyInstance(value) {
1013
- }
1014
- provide("DestylerPopover", {
1015
- getTriggerElement,
1016
- handleMouseEnter,
1017
- handleMouseLeave,
1018
- handleClickOutside,
1019
- handleMouseMoveOutside,
1020
- setBodyInstance,
1021
- positionManually,
1022
- isMounted,
1023
- zIndex: toRef(props, "zIndex"),
1024
- internalRenderBody: toRef(props, "internalRenderBody")
1025
- });
1026
- watchEffect(() => {
1027
- if (mergedShowWithoutDisabled.value && getMergedDisabled())
1028
- doUpdateShow(false);
1029
- });
1030
- function setShow(value) {
1031
- uncontrolledShow.value = value;
1032
- }
1033
- return {
1034
- binderInst,
1035
- positionManually,
1036
- mergedShowConsideringDisabledProp,
1037
- // if to show popover body
1038
- uncontrolledShow,
1039
- setShow,
1040
- getMergedShow,
1041
- handleClick,
1042
- handleMouseEnter,
1043
- handleMouseLeave,
1044
- handleFocus,
1045
- handleBlur
1046
- };
1047
- },
1048
- render() {
1049
- let triggerVNode;
1050
- let popoverInside = false;
1051
- if (!this.positionManually) {
1052
- if (this.$slots.activator)
1053
- triggerVNode = getFirstSlotVNode(this.$slots, "activator");
1054
- else
1055
- triggerVNode = getFirstSlotVNode(this.$slots, "trigger");
1056
- if (triggerVNode) {
1057
- triggerVNode = cloneVNode(triggerVNode);
1058
- triggerVNode = triggerVNode.type === Text ? h("span", [triggerVNode]) : triggerVNode;
1059
- const handlers = {
1060
- onClick: this.handleClick,
1061
- onMouseenter: this.handleMouseEnter,
1062
- onMouseleave: this.handleMouseLeave,
1063
- onFocus: this.handleFocus,
1064
- onBlur: this.handleBlur
1065
- };
1066
- if (triggerVNode.type?.__popover__) {
1067
- popoverInside = true;
1068
- if (!triggerVNode.props) {
1069
- triggerVNode.props = {
1070
- internalSyncTargetWithParent: true,
1071
- internalInheritedEventHandlers: []
1072
- };
1073
- }
1074
- triggerVNode.props.internalSyncTargetWithParent = true;
1075
- if (!triggerVNode.props.internalInheritedEventHandlers) {
1076
- triggerVNode.props.internalInheritedEventHandlers = [handlers];
1077
- } else {
1078
- triggerVNode.props.internalInheritedEventHandlers = [
1079
- handlers,
1080
- ...triggerVNode.props.internalInheritedEventHandlers
1081
- ];
1082
- }
1083
- } else {
1084
- const { internalInheritedEventHandlers } = this.$props;
1085
- const ascendantAndCurrentHandlers = [
1086
- handlers,
1087
- ...internalInheritedEventHandlers
1088
- ];
1089
- const mergedHandlers = {
1090
- onBlur: (e) => {
1091
- ascendantAndCurrentHandlers.forEach((_handlers) => {
1092
- _handlers.onBlur(e);
1093
- });
1094
- },
1095
- onFocus: (e) => {
1096
- ascendantAndCurrentHandlers.forEach((_handlers) => {
1097
- _handlers.onFocus(e);
1098
- });
1099
- },
1100
- onClick: (e) => {
1101
- ascendantAndCurrentHandlers.forEach((_handlers) => {
1102
- _handlers.onClick(e);
1103
- });
1104
- },
1105
- onMouseenter: (e) => {
1106
- ascendantAndCurrentHandlers.forEach((_handlers) => {
1107
- _handlers.onMouseenter(e);
1108
- });
1109
- },
1110
- onMouseleave: (e) => {
1111
- ascendantAndCurrentHandlers.forEach((_handlers) => {
1112
- _handlers.onMouseleave(e);
1113
- });
1114
- }
1115
- };
1116
- appendEvents(
1117
- triggerVNode,
1118
- internalInheritedEventHandlers ? "nested" : this.positionManually ? "manual" : this.$props.trigger,
1119
- mergedHandlers
1120
- );
1121
- }
1122
- }
1123
- }
1124
- return h(
1125
- DestylerBinder,
1126
- {
1127
- ref: "binderInst",
1128
- syncTarget: !popoverInside,
1129
- syncTargetWithParent: this.$props.internalSyncTargetWithParent
1130
- },
1131
- () => {
1132
- return [
1133
- this.$props.internalTrapFocus && this.getMergedShow() ? withDirectives(h("div"), [[zindexable, { enabled: this.getMergedShow(), zIndex: this.$props.zIndex }]]) : null,
1134
- this.positionManually ? null : h(DestylerTarget, null, {
1135
- default: () => triggerVNode
1136
- }),
1137
- h(
1138
- DestylerPopoverBody,
1139
- keep(this.$props, bodyPropKeys, {
1140
- ...this.$attrs,
1141
- show: this.getMergedShow()
1142
- }),
1143
- {
1144
- default: () => this.$slots.default?.(),
1145
- header: () => this.$slots.header?.(),
1146
- footer: () => this.$slots.footer?.()
1147
- }
1148
- )
1149
- ];
1150
- }
1151
- );
1152
- }
1153
- });
1154
-
1155
- const name = "@destyler/popover";
1156
-
1157
- const packageName = name;
1158
- function DestylerPopoverResolver() {
1159
- return {
1160
- type: "component",
1161
- resolve: (name2) => {
1162
- if (name2 === "DestylerPopover")
1163
- return { name: name2, from: packageName };
1164
- }
1165
- };
1166
- }
1167
-
1168
- export { DestylerPopover, DestylerPopoverBody, DestylerPopoverResolver, destylerPopoverProps, popoverBodyProps };
1
+ export { D as DestylerPopoverArrow, a as DestylerPopoverClose, b as DestylerPopoverContent, f as DestylerPopoverPortal, g as DestylerPopoverRoot, h as DestylerPopoverTrigger } from './shared/popover.ada869b3.mjs';
2
+ import 'vue';
3
+ import '@destyler/popper';
4
+ import '@destyler/primitive';
5
+ import '@destyler/shared';
6
+ import '@destyler/composition';
7
+ import '@destyler/presence';
8
+ import '@destyler/dismissable-layer';
9
+ import '@destyler/focus-scope';
10
+ import '@destyler/directives';
11
+ import '@destyler/teleport';