@maas/vue-equipment 1.0.0-beta.42 → 1.0.0-beta.44

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 (106) hide show
  1. package/dist/composables/useScrollLockPadding/index.d.ts +9 -0
  2. package/dist/composables/useScrollLockPadding/index.js +57 -0
  3. package/dist/composables/useScrollLockPadding/index.js.map +1 -0
  4. package/dist/nuxt/module.json +1 -1
  5. package/dist/nuxt/module.mjs +7 -0
  6. package/dist/plugins/MagicAccordion/src/components/MagicAccordionProvider.vue +2 -5
  7. package/dist/plugins/MagicAccordion/src/composables/private/useAccordionState.d.ts +2 -3
  8. package/dist/plugins/MagicAccordion/src/composables/private/useAccordionState.mjs +38 -11
  9. package/dist/plugins/MagicAccordion/src/types/index.d.ts +1 -0
  10. package/dist/plugins/MagicCommand/src/components/MagicCommandProvider.vue +2 -5
  11. package/dist/plugins/MagicCommand/src/components/MagicCommandRenderer.vue +1 -0
  12. package/dist/plugins/MagicCommand/src/components/MagicCommandView.vue +1 -1
  13. package/dist/plugins/MagicCommand/src/composables/private/useCommandState.d.ts +2 -3
  14. package/dist/plugins/MagicCommand/src/composables/private/useCommandState.mjs +36 -11
  15. package/dist/plugins/MagicCommand/src/types/index.d.ts +1 -0
  16. package/dist/plugins/MagicCookie/src/composables/private/useCookieState.d.ts +2 -3
  17. package/dist/plugins/MagicCookie/src/composables/private/useCookieState.mjs +35 -12
  18. package/dist/plugins/MagicCookie/src/composables/useMagicCookie.mjs +6 -1
  19. package/dist/plugins/MagicCookie/src/types/index.d.ts +1 -0
  20. package/dist/plugins/MagicDraggable/src/composables/private/useDraggableDrag.mjs +33 -25
  21. package/dist/plugins/MagicDraggable/src/composables/private/useDraggableScrollLock.d.ts +2 -4
  22. package/dist/plugins/MagicDraggable/src/composables/private/useDraggableScrollLock.mjs +11 -51
  23. package/dist/plugins/MagicDraggable/src/composables/private/useDraggableSnap.mjs +11 -1
  24. package/dist/plugins/MagicDraggable/src/composables/private/useDraggableState.d.ts +1 -1
  25. package/dist/plugins/MagicDraggable/src/composables/private/useDraggableState.mjs +41 -11
  26. package/dist/plugins/MagicDraggable/src/composables/useMagicDraggable.mjs +2 -1
  27. package/dist/plugins/MagicDraggable/src/types/index.d.ts +1 -0
  28. package/dist/plugins/MagicDrawer/src/components/MagicDrawer.d.vue.ts +2 -2
  29. package/dist/plugins/MagicDrawer/src/components/MagicDrawer.vue +15 -19
  30. package/dist/plugins/MagicDrawer/src/components/MagicDrawer.vue.d.ts +2 -2
  31. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerCallback.d.ts +0 -4
  32. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerCallback.mjs +8 -12
  33. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerDOM.d.ts +2 -4
  34. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerDOM.mjs +15 -58
  35. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerDrag.d.ts +2 -0
  36. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerDrag.mjs +184 -29
  37. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerState.d.ts +2 -3
  38. package/dist/plugins/MagicDrawer/src/composables/private/useDrawerState.mjs +35 -10
  39. package/dist/plugins/MagicDrawer/src/composables/useMagicDrawer.mjs +2 -1
  40. package/dist/plugins/MagicDrawer/src/types/index.d.ts +1 -0
  41. package/dist/plugins/MagicEmitter/src/composables/useMagicEmitter.mjs +10 -5
  42. package/dist/plugins/MagicMarquee/src/components/MagicMarquee.vue +2 -5
  43. package/dist/plugins/MagicMarquee/src/composables/private/useMarqueeState.d.ts +2 -3
  44. package/dist/plugins/MagicMarquee/src/composables/private/useMarqueeState.mjs +36 -11
  45. package/dist/plugins/MagicMarquee/src/types/index.d.ts +1 -0
  46. package/dist/plugins/MagicMenu/src/components/MagicMenuContent.vue +4 -12
  47. package/dist/plugins/MagicMenu/src/components/MagicMenuProvider.vue +2 -6
  48. package/dist/plugins/MagicMenu/src/composables/private/useMenuCallback.d.ts +1 -4
  49. package/dist/plugins/MagicMenu/src/composables/private/useMenuCallback.mjs +7 -21
  50. package/dist/plugins/MagicMenu/src/composables/private/useMenuCursor.mjs +13 -1
  51. package/dist/plugins/MagicMenu/src/composables/private/useMenuDOM.d.ts +2 -4
  52. package/dist/plugins/MagicMenu/src/composables/private/useMenuDOM.mjs +13 -51
  53. package/dist/plugins/MagicMenu/src/composables/private/useMenuState.d.ts +2 -3
  54. package/dist/plugins/MagicMenu/src/composables/private/useMenuState.mjs +32 -12
  55. package/dist/plugins/MagicMenu/src/composables/private/useMenuTrigger.mjs +1 -1
  56. package/dist/plugins/MagicMenu/src/types/index.d.ts +1 -0
  57. package/dist/plugins/MagicModal/src/components/MagicModal.vue +4 -16
  58. package/dist/plugins/MagicModal/src/composables/private/useModalCallback.d.ts +0 -4
  59. package/dist/plugins/MagicModal/src/composables/private/useModalCallback.mjs +9 -19
  60. package/dist/plugins/MagicModal/src/composables/private/useModalDOM.d.ts +2 -4
  61. package/dist/plugins/MagicModal/src/composables/private/useModalDOM.mjs +15 -58
  62. package/dist/plugins/MagicModal/src/composables/private/useModalState.d.ts +6 -0
  63. package/dist/plugins/MagicModal/src/composables/private/useModalState.mjs +58 -0
  64. package/dist/plugins/MagicModal/src/composables/private/useModalStore.d.ts +1 -5
  65. package/dist/plugins/MagicModal/src/composables/private/useModalStore.mjs +1 -15
  66. package/dist/plugins/MagicModal/src/composables/useMagicModal.mjs +7 -6
  67. package/dist/plugins/MagicModal/src/types/index.d.ts +5 -0
  68. package/dist/plugins/MagicNoise/src/components/MagicNoise.vue +14 -2
  69. package/dist/plugins/MagicPie/src/components/MagicPie.vue +12 -6
  70. package/dist/plugins/MagicPie/src/composables/private/usePieState.d.ts +1 -1
  71. package/dist/plugins/MagicPie/src/composables/private/usePieState.mjs +33 -12
  72. package/dist/plugins/MagicPie/src/types/index.d.ts +1 -0
  73. package/dist/plugins/MagicPlayer/src/components/MagicPlayerAudio.vue +9 -6
  74. package/dist/plugins/MagicPlayer/src/components/MagicPlayerAudioControls.vue +4 -8
  75. package/dist/plugins/MagicPlayer/src/components/MagicPlayerMuxPopover.vue +8 -1
  76. package/dist/plugins/MagicPlayer/src/components/MagicPlayerProvider.vue +2 -11
  77. package/dist/plugins/MagicPlayer/src/components/MagicPlayerVideo.vue +10 -6
  78. package/dist/plugins/MagicPlayer/src/components/MagicPlayerVideoControls.vue +4 -8
  79. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerControlsApi.d.ts +0 -1
  80. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerControlsApi.mjs +20 -9
  81. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerEmitter.mjs +124 -75
  82. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerMediaApi.mjs +100 -32
  83. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerRuntime.d.ts +0 -1
  84. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerRuntime.mjs +33 -13
  85. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerState.d.ts +2 -3
  86. package/dist/plugins/MagicPlayer/src/composables/private/usePlayerState.mjs +35 -10
  87. package/dist/plugins/MagicPlayer/src/composables/useMagicPlayer.d.ts +0 -2
  88. package/dist/plugins/MagicPlayer/src/types/index.d.ts +1 -0
  89. package/dist/plugins/MagicScroll/src/components/MagicScrollCollision.vue +2 -2
  90. package/dist/plugins/MagicScroll/src/components/MagicScrollMotion.vue +13 -1
  91. package/dist/plugins/MagicScroll/src/components/MagicScrollScene.vue +9 -5
  92. package/dist/plugins/MagicScroll/src/composables/private/useCollisionDetection.mjs +2 -1
  93. package/dist/plugins/MagicToast/src/components/MagicToastProvider.vue +2 -11
  94. package/dist/plugins/MagicToast/src/components/MagicToastView.vue +1 -0
  95. package/dist/plugins/MagicToast/src/composables/private/useToastDrag.mjs +18 -15
  96. package/dist/plugins/MagicToast/src/composables/private/useToastScrollLock.d.ts +2 -4
  97. package/dist/plugins/MagicToast/src/composables/private/useToastScrollLock.mjs +11 -49
  98. package/dist/plugins/MagicToast/src/composables/private/useToastState.d.ts +2 -3
  99. package/dist/plugins/MagicToast/src/composables/private/useToastState.mjs +35 -12
  100. package/dist/plugins/MagicToast/src/types/index.d.ts +1 -0
  101. package/dist/utils/index.d.ts +8 -1
  102. package/dist/utils/index.js +56497 -0
  103. package/dist/utils/index.js.map +1 -1
  104. package/package.json +1 -1
  105. package/dist/plugins/MagicError/src/MagicError.d.ts +0 -0
  106. package/dist/plugins/MagicError/src/MagicError.mjs +0 -0
@@ -6,10 +6,7 @@ type UseMenuCallbackArgs = {
6
6
  viewId: string;
7
7
  innerActive: Ref<boolean>;
8
8
  wrapperActive: Ref<boolean>;
9
- lockScroll: () => void;
10
- unlockScroll: () => void;
11
- addScrollLockPadding: () => void;
12
- removeScrollLockPadding: () => void;
9
+ parentTree: string[];
13
10
  };
14
11
  export declare function useMenuCallback(args: UseMenuCallbackArgs): {
15
12
  onBeforeEnter: () => void;
@@ -1,19 +1,11 @@
1
1
  import { toValue } from "vue";
2
2
  import { useMagicEmitter } from "@maas/vue-equipment/plugins/MagicEmitter";
3
+ import { useMenuDOM } from "./useMenuDOM.mjs";
3
4
  import { ModeScrollLock } from "../../utils/modeScrollLockDefaults.mjs";
4
5
  export function useMenuCallback(args) {
5
- const {
6
- state,
7
- instanceId,
8
- viewId,
9
- innerActive,
10
- wrapperActive,
11
- lockScroll,
12
- unlockScroll,
13
- addScrollLockPadding,
14
- removeScrollLockPadding
15
- } = args;
6
+ const { state, instanceId, viewId, innerActive, wrapperActive, parentTree } = args;
16
7
  const emitter = useMagicEmitter();
8
+ const { lockScroll, unlockScroll } = useMenuDOM();
17
9
  function onBeforeEnter() {
18
10
  emitter.emit("beforeEnter", { id: toValue(instanceId), viewId });
19
11
  }
@@ -23,11 +15,8 @@ export function useMenuCallback(args) {
23
15
  function onAfterEnter() {
24
16
  emitter.emit("afterEnter", { id: toValue(instanceId), viewId });
25
17
  const scrollLock = state.options.scrollLock ?? ModeScrollLock[state.options.mode].value;
26
- if (scrollLock) {
27
- if (typeof scrollLock === "object" && scrollLock.padding) {
28
- addScrollLockPadding();
29
- }
30
- lockScroll();
18
+ if (scrollLock && parentTree.length === 2) {
19
+ lockScroll(typeof scrollLock === "object" && scrollLock.padding);
31
20
  }
32
21
  }
33
22
  function onBeforeLeave() {
@@ -39,11 +28,8 @@ export function useMenuCallback(args) {
39
28
  function onAfterLeave() {
40
29
  emitter.emit("afterLeave", { id: toValue(instanceId), viewId });
41
30
  const scrollLock = state.options.scrollLock ?? ModeScrollLock[state.options.mode].value;
42
- if (scrollLock) {
43
- unlockScroll();
44
- if (typeof scrollLock === "object" && scrollLock.padding) {
45
- removeScrollLockPadding();
46
- }
31
+ if (scrollLock && parentTree.length === 2) {
32
+ unlockScroll(typeof scrollLock === "object" && scrollLock.padding);
47
33
  }
48
34
  if (!innerActive.value) {
49
35
  wrapperActive.value = false;
@@ -1,4 +1,4 @@
1
- import { ref, shallowRef } from "vue";
1
+ import { onScopeDispose, ref, shallowRef } from "vue";
2
2
  import { useEventListener } from "@vueuse/core";
3
3
  export function useMenuCursor(view, debug = false) {
4
4
  let cancelListener = new AbortController();
@@ -116,6 +116,9 @@ export function useMenuCursor(view, debug = false) {
116
116
  break;
117
117
  }
118
118
  }
119
+ if (!sidePoints[0] || !sidePoints[1]) {
120
+ return [];
121
+ }
119
122
  const [a, b, c] = extendTriangle(
120
123
  [centerPoint, sidePoints[0], sidePoints[1]],
121
124
  16
@@ -124,6 +127,9 @@ export function useMenuCursor(view, debug = false) {
124
127
  }
125
128
  function triangleOverlap(cursor, fromBounding, toBounding) {
126
129
  const [a, b, c] = getTriangle(fromBounding, toBounding);
130
+ if (!a || !b || !c) {
131
+ return false;
132
+ }
127
133
  return isPointInTriangle({
128
134
  p: cursor,
129
135
  a,
@@ -167,6 +173,9 @@ export function useMenuCursor(view, debug = false) {
167
173
  from.forEach((trigger) => {
168
174
  const fromBounding = trigger.getBoundingClientRect();
169
175
  const [a, b, c] = getTriangle(fromBounding, toBounding);
176
+ if (!a || !b || !c) {
177
+ return;
178
+ }
170
179
  allCoords.push(a, b, c);
171
180
  });
172
181
  coords.value = allCoords;
@@ -187,6 +196,9 @@ export function useMenuCursor(view, debug = false) {
187
196
  isInsideTriangle.value = false;
188
197
  cancelListener.abort();
189
198
  }
199
+ onScopeDispose(() => {
200
+ destroy();
201
+ });
190
202
  return {
191
203
  coords,
192
204
  isInsideFrom,
@@ -1,6 +1,4 @@
1
1
  export declare function useMenuDOM(): {
2
- lockScroll: () => void;
3
- unlockScroll: () => void;
4
- addScrollLockPadding: () => void;
5
- removeScrollLockPadding: () => void;
2
+ lockScroll: (padding?: boolean) => void;
3
+ unlockScroll: (padding?: boolean) => void;
6
4
  };
@@ -1,63 +1,25 @@
1
- import { ref, shallowRef } from "vue";
1
+ import { shallowRef } from "vue";
2
2
  import { useScrollLock } from "@vueuse/core";
3
- import {
4
- matchClass,
5
- scrollbarGutterSupport,
6
- scrollbarWidth
7
- } from "@maas/vue-equipment/utils";
3
+ import { useScrollLockPadding } from "@maas/vue-equipment/composables/useScrollLockPadding";
8
4
  const scrollLock = typeof window !== "undefined" ? useScrollLock(document?.documentElement) : shallowRef(false);
5
+ const { add, remove } = useScrollLockPadding({
6
+ exclude: /magic-menu/
7
+ });
9
8
  export function useMenuDOM() {
10
- const positionFixedElements = ref([]);
11
- function lockScroll() {
9
+ function lockScroll(padding) {
10
+ if (padding) {
11
+ add();
12
+ }
12
13
  scrollLock.value = true;
13
14
  }
14
- function unlockScroll() {
15
+ function unlockScroll(padding) {
15
16
  scrollLock.value = false;
16
- }
17
- function addScrollLockPadding() {
18
- if (typeof window === "undefined") {
19
- return;
17
+ if (padding) {
18
+ remove();
20
19
  }
21
- const exclude = new RegExp(/magic-menu/);
22
- document.body.style.setProperty(
23
- "--scrollbar-width",
24
- `${scrollbarWidth()}px`
25
- );
26
- positionFixedElements.value = [
27
- ...document.body.getElementsByTagName("*")
28
- ].filter(
29
- (x) => getComputedStyle(x, null).getPropertyValue("position") === "fixed" && getComputedStyle(x, null).getPropertyValue("right") === "0px" && !matchClass(x, exclude)
30
- );
31
- switch (scrollbarGutterSupport()) {
32
- case true:
33
- document.documentElement.style.scrollbarGutter = "stable";
34
- positionFixedElements.value.forEach((elem) => {
35
- elem.style.scrollbarGutter = "stable";
36
- elem.style.overflow = "auto";
37
- });
38
- break;
39
- case false:
40
- document.body.style.paddingRight = "var(--scrollbar-width)";
41
- positionFixedElements.value.forEach(
42
- (elem) => elem.style.paddingRight = "var(--scrollbar-width)"
43
- );
44
- break;
45
- }
46
- }
47
- function removeScrollLockPadding() {
48
- document.documentElement.style.scrollbarGutter = "";
49
- document.body.style.removeProperty("--scrollbar-width");
50
- document.body.style.paddingRight = "";
51
- positionFixedElements.value.forEach((elem) => {
52
- elem.style.paddingRight = "";
53
- elem.style.scrollbarGutter = "";
54
- elem.style.overflow = "";
55
- });
56
20
  }
57
21
  return {
58
22
  lockScroll,
59
- unlockScroll,
60
- addScrollLockPadding,
61
- removeScrollLockPadding
23
+ unlockScroll
62
24
  };
63
25
  }
@@ -1,7 +1,6 @@
1
- import { type Ref, type MaybeRef } from 'vue';
1
+ import { type MaybeRef } from 'vue';
2
2
  import type { MenuState, MagicMenuOptions } from '../../types/index.js';
3
3
  export declare function useMenuState(instanceId: MaybeRef<string>): {
4
4
  initializeState: (options?: MagicMenuOptions) => MenuState;
5
- deleteState: () => void;
6
- menuStateStore: Ref<MenuState[], MenuState[]>;
5
+ menuStateStore: import("vue").Ref<MenuState[], MenuState[]>;
7
6
  };
@@ -1,11 +1,15 @@
1
- import { ref, reactive, toValue } from "vue";
1
+ import { reactive, toValue, onScopeDispose } from "vue";
2
2
  import { defu } from "defu";
3
+ import { createStateStore } from "@maas/vue-equipment/utils";
3
4
  import { defaultOptions } from "../../utils/defaultOptions.mjs";
4
- const menuStateStore = ref([]);
5
+ const getMenuStateStore = createStateStore("MagicMenu", () => []);
5
6
  export function useMenuState(instanceId) {
7
+ const menuStateStore = getMenuStateStore();
8
+ let scopeCounted = false;
6
9
  function createState(id) {
7
10
  const state = {
8
11
  id,
12
+ refCount: 0,
9
13
  options: { ...defaultOptions },
10
14
  views: [],
11
15
  active: false,
@@ -22,12 +26,21 @@ export function useMenuState(instanceId) {
22
26
  menuStateStore.value = [...menuStateStore.value, state];
23
27
  return state;
24
28
  }
29
+ function deleteState() {
30
+ const currentId = toValue(instanceId);
31
+ menuStateStore.value = menuStateStore.value.filter(
32
+ (x) => x.id !== currentId
33
+ );
34
+ }
25
35
  function initializeState(options) {
26
- let state = menuStateStore.value.find((entry) => {
27
- return entry.id === toValue(instanceId);
28
- });
36
+ const currentId = toValue(instanceId);
37
+ let state = menuStateStore.value.find((entry) => entry.id === currentId);
29
38
  if (!state) {
30
- state = addState(toValue(instanceId));
39
+ state = addState(currentId);
40
+ }
41
+ if (!scopeCounted) {
42
+ state.refCount++;
43
+ scopeCounted = true;
31
44
  }
32
45
  if (options) {
33
46
  const mappedOptions = defu(options, defaultOptions);
@@ -35,14 +48,21 @@ export function useMenuState(instanceId) {
35
48
  }
36
49
  return state;
37
50
  }
38
- function deleteState() {
39
- menuStateStore.value = menuStateStore.value.filter(
40
- (x) => x.id !== toValue(instanceId)
41
- );
42
- }
51
+ onScopeDispose(() => {
52
+ if (!scopeCounted) {
53
+ return;
54
+ }
55
+ const currentId = toValue(instanceId);
56
+ const state = menuStateStore.value.find((entry) => entry.id === currentId);
57
+ if (state) {
58
+ state.refCount--;
59
+ if (state.refCount <= 0) {
60
+ deleteState();
61
+ }
62
+ }
63
+ });
43
64
  return {
44
65
  initializeState,
45
- deleteState,
46
66
  menuStateStore
47
67
  };
48
68
  }
@@ -80,7 +80,7 @@ export function useMenuTrigger(args) {
80
80
  if (mappedTrigger.value.includes("right-click") && viewId) {
81
81
  e.preventDefault();
82
82
  e.stopPropagation();
83
- if (control.value || shift.value) {
83
+ if (control?.value || shift?.value) {
84
84
  onRightClick(
85
85
  new MouseEvent(e.type, {
86
86
  ...e,
@@ -68,6 +68,7 @@ export interface MenuView {
68
68
  }
69
69
  export interface MenuState {
70
70
  id: string;
71
+ refCount: number;
71
72
  active: boolean;
72
73
  views: MenuView[];
73
74
  options: CombinedMagicMenuOptions;
@@ -81,14 +81,7 @@ const { id, options = {} } = defineProps({
81
81
  const mappedOptions = customDefu(options, defaultOptions);
82
82
  const mappedId = toValue(id);
83
83
  const modalRef = useTemplateRef("modal");
84
- const {
85
- trapFocus,
86
- releaseFocus,
87
- lockScroll,
88
- unlockScroll,
89
- addScrollLockPadding,
90
- removeScrollLockPadding
91
- } = useModalDOM({
84
+ const { trapFocus, releaseFocus, unlockScroll } = useModalDOM({
92
85
  focusTarget: modalRef,
93
86
  focusTrap: mappedOptions.focusTrap
94
87
  });
@@ -105,10 +98,6 @@ const {
105
98
  } = useModalCallback({
106
99
  id,
107
100
  mappedOptions,
108
- addScrollLockPadding,
109
- removeScrollLockPadding,
110
- lockScroll,
111
- unlockScroll,
112
101
  trapFocus,
113
102
  releaseFocus,
114
103
  wrapperActive
@@ -139,10 +128,9 @@ onBeforeUnmount(() => {
139
128
  });
140
129
  onUnmounted(() => {
141
130
  if (mappedOptions.scrollLock) {
142
- unlockScroll();
143
- if (typeof mappedOptions.scrollLock === "object" && mappedOptions.scrollLock.padding) {
144
- removeScrollLockPadding();
145
- }
131
+ unlockScroll(
132
+ typeof mappedOptions.scrollLock === "object" && mappedOptions.scrollLock.padding
133
+ );
146
134
  }
147
135
  if (mappedOptions.focusTrap) {
148
136
  releaseFocus();
@@ -3,10 +3,6 @@ import type { MagicModalOptions } from '../../types/index.js';
3
3
  type UseModalCallbackArgs = {
4
4
  id: MaybeRef<string>;
5
5
  mappedOptions: MagicModalOptions;
6
- addScrollLockPadding: () => void;
7
- removeScrollLockPadding: () => void;
8
- lockScroll: () => void;
9
- unlockScroll: () => void;
10
6
  trapFocus: () => void;
11
7
  releaseFocus: () => void;
12
8
  wrapperActive: Ref<boolean>;
@@ -1,25 +1,16 @@
1
1
  import { toValue, nextTick } from "vue";
2
2
  import { useMagicEmitter } from "@maas/vue-equipment/plugins/MagicEmitter";
3
+ import { useModalDOM } from "./useModalDOM.mjs";
3
4
  export function useModalCallback(args) {
4
- const {
5
- id,
6
- mappedOptions,
7
- addScrollLockPadding,
8
- removeScrollLockPadding,
9
- lockScroll,
10
- unlockScroll,
11
- trapFocus,
12
- releaseFocus,
13
- wrapperActive
14
- } = args;
5
+ const { id, mappedOptions, trapFocus, releaseFocus, wrapperActive } = args;
15
6
  const emitter = useMagicEmitter();
7
+ const { lockScroll, unlockScroll } = useModalDOM();
16
8
  function onBeforeEnter() {
17
9
  emitter.emit("beforeEnter", toValue(id));
18
10
  if (mappedOptions.scrollLock) {
19
- if (typeof mappedOptions.scrollLock === "object" && mappedOptions.scrollLock.padding) {
20
- addScrollLockPadding();
21
- }
22
- lockScroll();
11
+ lockScroll(
12
+ typeof mappedOptions.scrollLock === "object" && mappedOptions.scrollLock.padding
13
+ );
23
14
  }
24
15
  }
25
16
  function onEnter() {
@@ -41,10 +32,9 @@ export function useModalCallback(args) {
41
32
  function onAfterLeave() {
42
33
  emitter.emit("afterLeave", toValue(id));
43
34
  if (mappedOptions.scrollLock) {
44
- unlockScroll();
45
- if (typeof mappedOptions.scrollLock === "object" && mappedOptions.scrollLock.padding) {
46
- removeScrollLockPadding();
47
- }
35
+ unlockScroll(
36
+ typeof mappedOptions.scrollLock === "object" && mappedOptions.scrollLock.padding
37
+ );
48
38
  }
49
39
  if (mappedOptions.focusTrap) {
50
40
  releaseFocus();
@@ -6,8 +6,6 @@ export type useModalDOMArgs = Pick<MagicModalOptions, 'scrollLock' | 'focusTrap'
6
6
  export declare function useModalDOM(args?: useModalDOMArgs): {
7
7
  trapFocus: () => void;
8
8
  releaseFocus: () => void;
9
- lockScroll: () => void;
10
- unlockScroll: () => void;
11
- addScrollLockPadding: () => void;
12
- removeScrollLockPadding: () => void;
9
+ lockScroll: (padding?: boolean) => void;
10
+ unlockScroll: (padding?: boolean) => void;
13
11
  };
@@ -1,20 +1,17 @@
1
- import { ref, shallowRef } from "vue";
1
+ import { shallowRef } from "vue";
2
2
  import { defu } from "defu";
3
3
  import { useScrollLock } from "@vueuse/core";
4
4
  import { useFocusTrap } from "@vueuse/integrations/useFocusTrap";
5
- import {
6
- matchClass,
7
- scrollbarGutterSupport,
8
- scrollbarWidth
9
- } from "@maas/vue-equipment/utils";
5
+ import { useScrollLockPadding } from "@maas/vue-equipment/composables/useScrollLockPadding";
10
6
  const defaultOptions = {
11
7
  focusTrap: false,
12
- focusTarget: void 0,
13
- scrollLock: true
8
+ focusTarget: void 0
14
9
  };
15
10
  const scrollLock = typeof window !== "undefined" ? useScrollLock(document?.documentElement) : shallowRef(false);
11
+ const { add, remove } = useScrollLockPadding({
12
+ exclude: /magic-modal(__backdrop)?/
13
+ });
16
14
  export function useModalDOM(args) {
17
- const positionFixedElements = ref([]);
18
15
  const mappedOptions = defu(args, defaultOptions);
19
16
  const focusTrap = mappedOptions.focusTarget ? typeof mappedOptions.focusTrap === "boolean" ? useFocusTrap(mappedOptions.focusTarget) : useFocusTrap(mappedOptions.focusTarget, mappedOptions.focusTrap) : void 0;
20
17
  function trapFocus() {
@@ -27,62 +24,22 @@ export function useModalDOM(args) {
27
24
  focusTrap.deactivate();
28
25
  }
29
26
  }
30
- function lockScroll() {
31
- if (mappedOptions.scrollLock) {
32
- scrollLock.value = true;
27
+ function lockScroll(padding) {
28
+ if (padding) {
29
+ add();
33
30
  }
31
+ scrollLock.value = true;
34
32
  }
35
- function unlockScroll() {
36
- if (mappedOptions.scrollLock) {
37
- scrollLock.value = false;
33
+ function unlockScroll(padding) {
34
+ scrollLock.value = false;
35
+ if (padding) {
36
+ remove();
38
37
  }
39
38
  }
40
- function addScrollLockPadding() {
41
- if (typeof window === "undefined") {
42
- return;
43
- }
44
- const exclude = new RegExp(/magic-modal(__backdrop)?/);
45
- document.body.style.setProperty(
46
- "--scrollbar-width",
47
- `${scrollbarWidth()}px`
48
- );
49
- positionFixedElements.value = [
50
- ...document.body.getElementsByTagName("*")
51
- ].filter(
52
- (x) => getComputedStyle(x, null).getPropertyValue("position") === "fixed" && getComputedStyle(x, null).getPropertyValue("right") === "0px" && !matchClass(x, exclude)
53
- );
54
- switch (scrollbarGutterSupport()) {
55
- case true:
56
- document.documentElement.style.scrollbarGutter = "stable";
57
- positionFixedElements.value.forEach((elem) => {
58
- elem.style.scrollbarGutter = "stable";
59
- elem.style.overflow = "auto";
60
- });
61
- break;
62
- case false:
63
- document.body.style.paddingRight = "var(--scrollbar-width)";
64
- positionFixedElements.value.forEach(
65
- (elem) => elem.style.paddingRight = "var(--scrollbar-width)"
66
- );
67
- break;
68
- }
69
- }
70
- function removeScrollLockPadding() {
71
- document.documentElement.style.scrollbarGutter = "";
72
- document.body.style.removeProperty("--scrollbar-width");
73
- document.body.style.paddingRight = "";
74
- positionFixedElements.value.forEach((elem) => {
75
- elem.style.paddingRight = "";
76
- elem.style.scrollbarGutter = "";
77
- elem.style.overflow = "";
78
- });
79
- }
80
39
  return {
81
40
  trapFocus,
82
41
  releaseFocus,
83
42
  lockScroll,
84
- unlockScroll,
85
- addScrollLockPadding,
86
- removeScrollLockPadding
43
+ unlockScroll
87
44
  };
88
45
  }
@@ -0,0 +1,6 @@
1
+ import { type MaybeRef } from 'vue';
2
+ import type { ModalState } from '../../types/index.js';
3
+ export declare function useModalState(id: MaybeRef<string>): {
4
+ initializeState: () => ModalState;
5
+ modalStateStore: import("vue").Ref<ModalState[], ModalState[]>;
6
+ };
@@ -0,0 +1,58 @@
1
+ import { reactive, toValue, onScopeDispose } from "vue";
2
+ import { createStateStore } from "@maas/vue-equipment/utils";
3
+ const getModalStateStore = createStateStore(
4
+ "MagicModal",
5
+ () => []
6
+ );
7
+ export function useModalState(id) {
8
+ const modalStateStore = getModalStateStore();
9
+ let scopeCounted = false;
10
+ function createState(id2) {
11
+ const state = {
12
+ id: id2,
13
+ refCount: 0,
14
+ active: false
15
+ };
16
+ return reactive(state);
17
+ }
18
+ function addState(id2) {
19
+ const state = createState(id2);
20
+ modalStateStore.value = [...modalStateStore.value, state];
21
+ return state;
22
+ }
23
+ function deleteState() {
24
+ const currentId = toValue(id);
25
+ modalStateStore.value = modalStateStore.value.filter(
26
+ (x) => x.id !== currentId
27
+ );
28
+ }
29
+ function initializeState() {
30
+ const currentId = toValue(id);
31
+ let state = modalStateStore.value.find((entry) => entry.id === currentId);
32
+ if (!state) {
33
+ state = addState(currentId);
34
+ }
35
+ if (!scopeCounted) {
36
+ state.refCount++;
37
+ scopeCounted = true;
38
+ }
39
+ return state;
40
+ }
41
+ onScopeDispose(() => {
42
+ if (!scopeCounted) {
43
+ return;
44
+ }
45
+ const currentId = toValue(id);
46
+ const state = modalStateStore.value.find((entry) => entry.id === currentId);
47
+ if (state) {
48
+ state.refCount--;
49
+ if (state.refCount <= 0) {
50
+ deleteState();
51
+ }
52
+ }
53
+ });
54
+ return {
55
+ initializeState,
56
+ modalStateStore
57
+ };
58
+ }
@@ -1,5 +1 @@
1
- export declare function useModalStore(): {
2
- modalStore: import("vue").Ref<string[], string[]>;
3
- addInstance: (id: string) => void;
4
- removeInstance: (id: string) => void;
5
- };
1
+ export { useModalState } from './useModalState.js';
@@ -1,15 +1 @@
1
- import { ref } from "vue";
2
- const modalStore = ref([]);
3
- export function useModalStore() {
4
- function addInstance(id) {
5
- modalStore.value.push(id);
6
- }
7
- function removeInstance(id) {
8
- modalStore.value = modalStore.value.filter((x) => x !== id);
9
- }
10
- return {
11
- modalStore,
12
- addInstance,
13
- removeInstance
14
- };
15
- }
1
+ export { useModalState } from "./useModalState.mjs";
@@ -1,13 +1,14 @@
1
- import { computed, toValue } from "vue";
2
- import { useModalStore } from "./private/useModalStore.mjs";
1
+ import { computed } from "vue";
2
+ import { useModalState } from "./private/useModalState.mjs";
3
3
  export function useMagicModal(id) {
4
- const { modalStore, addInstance, removeInstance } = useModalStore();
5
- const isActive = computed(() => modalStore.value.includes(toValue(id)));
4
+ const { initializeState } = useModalState(id);
5
+ const state = initializeState();
6
+ const isActive = computed(() => state.active);
6
7
  function open() {
7
- addInstance(toValue(id));
8
+ state.active = true;
8
9
  }
9
10
  function close() {
10
- removeInstance(toValue(id));
11
+ state.active = false;
11
12
  }
12
13
  return {
13
14
  isActive,
@@ -26,3 +26,8 @@ export interface ModalEvents {
26
26
  leave: string;
27
27
  afterLeave: string;
28
28
  }
29
+ export interface ModalState {
30
+ id: string;
31
+ refCount: number;
32
+ active: boolean;
33
+ }
@@ -8,7 +8,13 @@
8
8
  </template>
9
9
 
10
10
  <script setup>
11
- import { onMounted, onUnmounted, watch, useTemplateRef } from "vue";
11
+ import {
12
+ onMounted,
13
+ onUnmounted,
14
+ watch,
15
+ useTemplateRef,
16
+ onBeforeUnmount
17
+ } from "vue";
12
18
  import { useResizeObserver, useDebounceFn } from "@vueuse/core";
13
19
  import { useNoiseApi } from "../composables/private/useNoiseApi";
14
20
  const { pause = false, options } = defineProps({
@@ -30,7 +36,10 @@ const {
30
36
  throttledRotateAndTransfer,
31
37
  isReady
32
38
  } = noiseApi;
33
- useResizeObserver(canvasRef, useDebounceFn(initialize, 100));
39
+ const resizeObserver = useResizeObserver(
40
+ canvasRef,
41
+ useDebounceFn(initialize, 100)
42
+ );
34
43
  watch(
35
44
  () => pause,
36
45
  (pause2) => {
@@ -47,6 +56,9 @@ onMounted(() => {
47
56
  throttledDraw();
48
57
  throttledRotateAndTransfer();
49
58
  });
59
+ onBeforeUnmount(() => {
60
+ resizeObserver.stop();
61
+ });
50
62
  onUnmounted(() => {
51
63
  isReady.value = false;
52
64
  transferControls.value?.pause();