edvoyui-component-library-test-flight 0.0.201 → 0.0.203

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.
@@ -20,6 +20,7 @@ declare function __VLS_template(): {
20
20
  };
21
21
  refs: {
22
22
  dropdownButton: HTMLButtonElement;
23
+ dropdownMenu: HTMLDivElement;
23
24
  };
24
25
  rootEl: HTMLDivElement;
25
26
  };
@@ -124,6 +125,7 @@ declare const __VLS_component: import('vue').DefineComponent<import('vue').Extra
124
125
  menuItems: MenuItem[];
125
126
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {
126
127
  dropdownButton: HTMLButtonElement;
128
+ dropdownMenu: HTMLDivElement;
127
129
  }, HTMLDivElement>;
128
130
  declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
129
131
  export default _default;
@@ -21,6 +21,7 @@
21
21
  <!-- Menu lists -->
22
22
  <div
23
23
  v-if="isOpen && menuItems.length"
24
+ ref="dropdownMenu"
24
25
  :class="[
25
26
  'absolute z-50 p-2 transition-all duration-300 ease-in-out bg-white border border-gray-200 border-solid rounded-lg shadow-2xl shadow-gray-300 min-w-32 max-w-64 w-max',
26
27
  mainDropdownClasses,
@@ -91,7 +92,16 @@
91
92
  </template>
92
93
 
93
94
  <script setup lang="ts">
94
- import { ref, defineProps, PropType, computed } from "vue";
95
+ import {
96
+ ref,
97
+ PropType,
98
+ computed,
99
+ nextTick,
100
+ watch,
101
+ onMounted,
102
+ onBeforeUnmount,
103
+ defineProps
104
+ } from "vue";
95
105
  import { onClickOutside } from "@vueuse/core";
96
106
  import ChevronDownStroke from "../../assets/svg/ChevronDownStroke.vue";
97
107
  import ChevronDownStrokeSolid from "../../assets/svg/ChevronDownStrokeSolid.vue";
@@ -151,6 +161,10 @@ const props = defineProps({
151
161
  const isOpen = ref(false);
152
162
  const activeMenuItem = ref<string | null>(null);
153
163
  const dropdownButton = ref<HTMLElement | null>(null);
164
+ const dropdownMenu = ref<HTMLElement | null>(null);
165
+ const resolvedPlacement = ref<"top" | "bottom" | "left" | "right">(
166
+ props.placement
167
+ );
154
168
 
155
169
  defineEmits(["subMenuItem", "menuItem", "actionItem"]);
156
170
 
@@ -170,8 +184,61 @@ onClickOutside(dropdownButton, () => {
170
184
  isOpen.value = false;
171
185
  });
172
186
 
187
+ const updateDropdownPlacement = () => {
188
+ if (!isOpen.value || !dropdownButton.value || !dropdownMenu.value) return;
189
+
190
+ if (props.placement === "left" || props.placement === "right") {
191
+ resolvedPlacement.value = props.placement;
192
+ return;
193
+ }
194
+
195
+ const buttonRect = dropdownButton.value.getBoundingClientRect();
196
+ const menuRect = dropdownMenu.value.getBoundingClientRect();
197
+ const menuHeight = menuRect.height || 240;
198
+ const spaceBelow = window.innerHeight - buttonRect.bottom;
199
+ const spaceAbove = buttonRect.top;
200
+
201
+ if (props.placement === "top") {
202
+ resolvedPlacement.value =
203
+ spaceAbove < menuHeight && spaceBelow > spaceAbove ? "bottom" : "top";
204
+ return;
205
+ }
206
+
207
+ resolvedPlacement.value =
208
+ spaceBelow < menuHeight && spaceAbove > spaceBelow ? "top" : "bottom";
209
+ };
210
+
211
+ watch(
212
+ () => isOpen.value,
213
+ async (open) => {
214
+ if (!open) return;
215
+ await nextTick();
216
+ updateDropdownPlacement();
217
+ }
218
+ );
219
+
220
+ watch(
221
+ () => props.placement,
222
+ () => {
223
+ resolvedPlacement.value = props.placement;
224
+ if (isOpen.value) {
225
+ nextTick(() => updateDropdownPlacement());
226
+ }
227
+ }
228
+ );
229
+
230
+ onMounted(() => {
231
+ window.addEventListener("resize", updateDropdownPlacement);
232
+ window.addEventListener("scroll", updateDropdownPlacement, true);
233
+ });
234
+
235
+ onBeforeUnmount(() => {
236
+ window.removeEventListener("resize", updateDropdownPlacement);
237
+ window.removeEventListener("scroll", updateDropdownPlacement, true);
238
+ });
239
+
173
240
  const mainDropdownClasses = computed(() => {
174
- switch (props.placement) {
241
+ switch (resolvedPlacement.value) {
175
242
  case 'top':
176
243
  return 'bottom-full left-0 mb-1';
177
244
  case 'left':
@@ -491,7 +491,7 @@ watch(() => tableContainer.value?.clientWidth, checkOverflow);
491
491
  tbody {
492
492
  @apply snap-y snap-mandatory snap-always;
493
493
  tr:not(.norecords) {
494
- @apply text-gray-500 transition-all duration-300 rounded-xl bg-white snap-start ease-in-out snap-x snap-mandatory will-change-transform;
494
+ @apply text-gray-500 transition-all duration-300 rounded-xl bg-white snap-start ease-in-out snap-x snap-mandatory;
495
495
  &:hover {
496
496
  @apply shadow-[1px_2px_40px_0px_#03022912] ring-1 ring-gray-100 ring-inset z-30;
497
497
  }