adminforth 3.31.17 → 3.31.18

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.
@@ -41,21 +41,24 @@
41
41
  <div>
42
42
  <button
43
43
  ref="dropdownUserButton"
44
- type="button" class=" hover:scale-110 transition-transform duration-200 flex text-sm bg- rounded-full focus:ring-4 focus:ring-lightSidebarDevider dark:focus:ring-darkSidebarDevider dark:bg-" aria-expanded="false" data-dropdown-toggle="dropdown-user">
44
+ type="button" class="flex text-sm bg- rounded-full focus:ring-4 focus:ring-lightSidebarDevider dark:focus:ring-darkSidebarDevider dark:bg-" aria-expanded="false">
45
45
  <span class="sr-only">{{ $t('Open user menu') }}</span>
46
- <img
46
+ <!-- hover scale lives on the inner span: popper measures the button with transforms, so scaling it would shift the popup -->
47
+ <span class="flex hover:scale-110 transition-transform duration-200">
48
+ <img
47
49
  v-if="coreStore.userAvatarUrl"
48
- class="w-8 h-8 rounded-full object-cover"
49
- :src="coreStore.userAvatarUrl"
50
+ class="w-8 h-8 rounded-full object-cover"
51
+ :src="coreStore.userAvatarUrl"
50
52
  alt="user photo"
51
53
  />
52
- <svg v-else class="w-8 h-8 text-lightNavbarIcons dark:text-darkNavbarIcons" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 24 24">
53
- <path fill-rule="evenodd" d="M12 20a7.966 7.966 0 0 1-5.002-1.756l.002.001v-.683c0-1.794 1.492-3.25 3.333-3.25h3.334c1.84 0 3.333 1.456 3.333 3.25v.683A7.966 7.966 0 0 1 12 20ZM2 12C2 6.477 6.477 2 12 2s10 4.477 10 10c0 5.5-4.44 9.963-9.932 10h-.138C6.438 21.962 2 17.5 2 12Zm10-5c-1.84 0-3.333 1.455-3.333 3.25S10.159 13.5 12 13.5c1.84 0 3.333-1.455 3.333-3.25S13.841 7 12 7Z" clip-rule="evenodd"/>
54
- </svg>
54
+ <svg v-else class="w-8 h-8 text-lightNavbarIcons dark:text-darkNavbarIcons" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 24 24">
55
+ <path fill-rule="evenodd" d="M12 20a7.966 7.966 0 0 1-5.002-1.756l.002.001v-.683c0-1.794 1.492-3.25 3.333-3.25h3.334c1.84 0 3.333 1.456 3.333 3.25v.683A7.966 7.966 0 0 1 12 20ZM2 12C2 6.477 6.477 2 12 2s10 4.477 10 10c0 5.5-4.44 9.963-9.932 10h-.138C6.438 21.962 2 17.5 2 12Zm10-5c-1.84 0-3.333 1.455-3.333 3.25S10.159 13.5 12 13.5c1.84 0 3.333-1.455 3.333-3.25S13.841 7 12 7Z" clip-rule="evenodd"/>
56
+ </svg>
57
+ </span>
55
58
  </button>
56
59
  </div>
57
60
  <Teleport to="body">
58
- <div class="af-settings-popup z-50 hidden my-4 text-base list-none bg-lightUserMenuBackground divide-y divide-lightUserMenuBorder text-lightUserMenuText rounded-default shadow dark:shadow-black dark:bg-darkUserMenuBackground dark:divide-darkUserMenuBorder text-darkUserMenuText dark:shadow-black" id="dropdown-user">
61
+ <div class="af-settings-popup z-50 hidden my-4 max-h-[calc(100dvh-5rem)] overflow-y-auto overscroll-contain text-base list-none bg-lightUserMenuBackground divide-y divide-lightUserMenuBorder text-lightUserMenuText rounded-default shadow dark:shadow-black dark:bg-darkUserMenuBackground dark:divide-darkUserMenuBorder text-darkUserMenuText dark:shadow-black" id="dropdown-user">
59
62
  <div class="px-4 py-3" role="none">
60
63
  <p class="text-sm text-gray-900 dark:text-darkNavbarText" role="none" v-if="coreStore.userFullname">
61
64
  {{ coreStore.userFullname }}
@@ -350,11 +353,17 @@ watch(dropdownUserButton, async (dropdownUserButton) => {
350
353
  if (dropdownUserButton) {
351
354
  await nextTick();
352
355
  const dropdownUser = document.querySelector('#dropdown-user') as HTMLElement;
353
- const dropdownUserTrigger = document.querySelector('[data-dropdown-toggle="dropdown-user"]') as HTMLElement;
356
+ // trigger is passed by ref without data-dropdown-toggle: flowbite auto-inits such triggers on window load
357
+ // with default 'bottom' placement, and that second popper overrides our positioning
354
358
  const dd = new Dropdown(
355
359
  dropdownUser,
356
- dropdownUserTrigger,
360
+ dropdownUserButton,
361
+ { placement: 'bottom-end' },
357
362
  );
363
+ // trigger lives in the fixed header, so fixed strategy keeps popup in place while the page scrolls
364
+ dd._popperInstance.setOptions({ strategy: 'fixed' });
365
+ // keep popup anchored to the right edge when its content size changes (e.g. async user menu components)
366
+ new ResizeObserver(() => dd._popperInstance.update()).observe(dropdownUser);
358
367
  closeUserMenuDropdown = () => {
359
368
  dd.hide();
360
369
  }
@@ -13,8 +13,9 @@
13
13
  />
14
14
  </div>
15
15
 
16
- <div v-if="showDropdown" >
17
-
16
+ <!-- collapsed submenu stays in layout with zero height, so popup width already fits its widest item and does not jump on expand -->
17
+ <div :class="{ 'h-0 overflow-hidden invisible': !showDropdown }">
18
+
18
19
  <router-link class="cursor-pointer flex items-center gap-1 block px-4 py-1 text-sm
19
20
  bg-lightUserMenuItemBackground hover:bg-lightUserMenuItemBackgroundHover text-lightUserMenuItemText
20
21
  hover:text-lightUserMenuItemText dark:bg-darkUserMenuItemBackground dark:hover:bg-darkUserMenuItemBackgroundHover
@@ -27,8 +27,6 @@ import { ref, onMounted, watch } from 'vue';
27
27
  import { useRouter } from 'vue-router';
28
28
  import { useCoreStore } from '@/stores/core';
29
29
  import { getCustomComponent, getIcon } from '@/utils';
30
- import { Dropdown } from 'flowbite';
31
- import { useAdminforth } from '@/adminforth';
32
30
  import { VerticalTabs } from '@/afcl'
33
31
  import { useRoute } from 'vue-router'
34
32
 
@@ -36,10 +34,8 @@ const route = useRoute()
36
34
  const coreStore = useCoreStore();
37
35
  const router = useRouter();
38
36
 
39
- let { closeUserMenuDropdown } = useAdminforth();
40
37
  const routerIsReady = ref(false);
41
38
  const loginRedirectCheckIsReady = ref(false);
42
- const dropdownUserButton = ref<HTMLElement | null>(null);
43
39
  const VerticalTabsRef = ref();
44
40
  const activeTab = ref('');
45
41
  const initialTabSet = ref(false);
@@ -53,16 +49,6 @@ async function initRouter() {
53
49
  routerIsReady.value = true;
54
50
  }
55
51
 
56
- watch(dropdownUserButton, (el) => {
57
- if (el) {
58
- const dd = new Dropdown(
59
- document.querySelector('#dropdown-user') as HTMLElement,
60
- document.querySelector('[data-dropdown-toggle="dropdown-user"]') as HTMLElement,
61
- );
62
- closeUserMenuDropdown = () => dd.hide();
63
- }
64
- });
65
-
66
52
  onMounted(async () => {
67
53
  if (coreStore.adminUser) {
68
54
  await loadMenu();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adminforth",
3
- "version": "3.31.17",
3
+ "version": "3.31.18",
4
4
  "description": "OpenSource Agent-Native forth-generation admin panel",
5
5
  "keywords": [
6
6
  "adminforth",