fix resize issue when nav menu collapsed

This commit is contained in:
pa
2026-01-07 19:27:08 +09:00
committed by Natsumi
parent 7e4de15ef2
commit 738d22461e
2 changed files with 62 additions and 18 deletions

View File

@@ -1,4 +1,4 @@
import { computed, nextTick, onMounted, ref, watch } from 'vue';
import { computed, nextTick, onMounted, onUnmounted, ref, watch } from 'vue';
import { storeToRefs } from 'pinia';
import { useAppearanceSettingsStore } from '../stores';
@@ -15,15 +15,18 @@ export function useAuthenticatedLayoutResizable() {
const { asideWidth, isNavCollapsed, isSideBarTabShow, navWidth } =
storeToRefs(appearanceStore);
const panelGroupRef = ref(null);
const navPanelRef = ref(null);
const navExpandedSize = ref(null);
const fallbackWidth =
typeof window !== 'undefined' && window.innerWidth
? window.innerWidth
: 1200;
const panelGroupRef = ref(null);
const navPanelRef = ref(null);
const navExpandedSize = ref(null);
const groupWidth = ref(fallbackWidth);
let resizeObserver = null;
let windowResizeHandler = null;
const getGroupWidth = () => {
const element = panelGroupRef.value?.$el ?? panelGroupRef.value;
const width = element?.getBoundingClientRect?.().width;
@@ -42,7 +45,9 @@ export function useAuthenticatedLayoutResizable() {
layout.length >= 3 &&
layout[layout.length - 1] <= 1;
const navCollapsedSize = computed(() => pxToPercent(navCollapsedPx));
const navCollapsedSize = computed(() =>
pxToPercent(navCollapsedPx, groupWidth.value)
);
const navExpandedPx = computed(() => navWidth.value || navDefaultPx);
const navDefaultSize = computed(() =>
@@ -75,15 +80,15 @@ export function useAuthenticatedLayoutResizable() {
return;
}
const groupWidth = getGroupWidth();
if (!Number.isFinite(groupWidth) || groupWidth <= 0) {
const width = getGroupWidth();
if (!Number.isFinite(width) || width <= 0) {
return;
}
const navSize = sizes[0];
if (!isNavCollapsed.value && Number.isFinite(navSize) && navSize > 0) {
navExpandedSize.value = navSize;
setNavWidth(Math.round(percentToPx(navSize, groupWidth)));
setNavWidth(Math.round(percentToPx(navSize, width)));
}
if (!isSideBarTabShow.value || sizes.length < 3) {
@@ -100,12 +105,19 @@ export function useAuthenticatedLayoutResizable() {
return;
}
setAsideWidth(Math.round(percentToPx(asideSize, groupWidth)));
setAsideWidth(Math.round(percentToPx(asideSize, width)));
};
const resizeNavPanel = (targetSize) =>
navPanelRef.value?.resize?.(targetSize);
const updateGroupWidth = () => {
groupWidth.value = getGroupWidth();
if (isNavCollapsed.value) {
resizeNavPanel(navCollapsedSize.value);
}
};
watch(isNavCollapsed, async (collapsed) => {
await nextTick();
if (collapsed) {
@@ -119,6 +131,7 @@ export function useAuthenticatedLayoutResizable() {
onMounted(async () => {
await nextTick();
updateGroupWidth();
let panelSize = null;
panelSize = navPanelRef.value?.getSize?.() ?? null;
@@ -126,6 +139,26 @@ export function useAuthenticatedLayoutResizable() {
if (isNavCollapsed.value) {
resizeNavPanel(navCollapsedSize.value);
}
const element = panelGroupRef.value?.$el ?? panelGroupRef.value;
if (element && typeof ResizeObserver !== 'undefined') {
resizeObserver = new ResizeObserver(updateGroupWidth);
resizeObserver.observe(element);
} else if (typeof window !== 'undefined') {
windowResizeHandler = updateGroupWidth;
window.addEventListener('resize', windowResizeHandler);
}
});
onUnmounted(() => {
if (resizeObserver) {
resizeObserver.disconnect();
resizeObserver = null;
}
if (windowResizeHandler && typeof window !== 'undefined') {
window.removeEventListener('resize', windowResizeHandler);
windowResizeHandler = null;
}
});
return {