@destyler/popover 0.0.1-beta.2 → 0.0.1-beta.20

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