From 8e8de96143c806ed9feecd981ac35e588c7207df Mon Sep 17 00:00:00 2001 From: Chris Jung Date: Fri, 27 Jun 2025 11:34:58 +0200 Subject: [PATCH 1/2] fix: route aria-label* attributes to aside element (fix #18058) --- .../layout/layout-container-drawer-loop.vue | 2 + .../src/pages/layout/layout-drawer-loop.vue | 2 + ui/src/components/drawer/QDrawer.js | 959 ++++++++++-------- 3 files changed, 523 insertions(+), 440 deletions(-) diff --git a/ui/playground/src/pages/layout/layout-container-drawer-loop.vue b/ui/playground/src/pages/layout/layout-container-drawer-loop.vue index e48dacc0749..e58c9bc28a4 100644 --- a/ui/playground/src/pages/layout/layout-container-drawer-loop.vue +++ b/ui/playground/src/pages/layout/layout-container-drawer-loop.vue @@ -30,6 +30,8 @@ side="right" v-model="drawer" bordered + aria-label="This is an ARIA-Label" + test-attribute="This is an Test attribute" >
Drawer {{ n }} / {{ contentSize * 2 + 5 }} diff --git a/ui/playground/src/pages/layout/layout-drawer-loop.vue b/ui/playground/src/pages/layout/layout-drawer-loop.vue index 9d200c22dd7..086e3eea0d5 100644 --- a/ui/playground/src/pages/layout/layout-drawer-loop.vue +++ b/ui/playground/src/pages/layout/layout-drawer-loop.vue @@ -18,6 +18,8 @@ side="right" v-model="drawer" bordered + aria-label="This is an ARIA-Label" + test-attribute="This is an Test attribute" >
Drawer {{ n }} / {{ contentSize }} diff --git a/ui/src/components/drawer/QDrawer.js b/ui/src/components/drawer/QDrawer.js index 725db89ea77..17412f3591a 100644 --- a/ui/src/components/drawer/QDrawer.js +++ b/ui/src/components/drawer/QDrawer.js @@ -1,22 +1,41 @@ -import { h, withDirectives, ref, computed, watch, onMounted, onBeforeUnmount, nextTick, inject, getCurrentInstance } from 'vue' - -import useHistory from '../../composables/private.use-history/use-history.js' -import useModelToggle, { useModelToggleProps, useModelToggleEmits } from '../../composables/private.use-model-toggle/use-model-toggle.js' -import usePreventScroll from '../../composables/private.use-prevent-scroll/use-prevent-scroll.js' -import useTimeout from '../../composables/use-timeout/use-timeout.js' -import useDark, { useDarkProps } from '../../composables/private.use-dark/use-dark.js' - -import TouchPan from '../../directives/touch-pan/TouchPan.js' - -import { createComponent } from '../../utils/private.create/create.js' -import { between } from '../../utils/format/format.js' -import { hSlot, hDir } from '../../utils/private.render/render.js' -import { layoutKey, emptyRenderFn } from '../../utils/private.symbols/symbols.js' - -const duration = 150 +import { + h, + withDirectives, + ref, + computed, + watch, + onMounted, + onBeforeUnmount, + nextTick, + inject, + getCurrentInstance, +} from "vue"; + +import useHistory from "../../composables/private.use-history/use-history.js"; +import useModelToggle, { + useModelToggleProps, + useModelToggleEmits, +} from "../../composables/private.use-model-toggle/use-model-toggle.js"; +import usePreventScroll from "../../composables/private.use-prevent-scroll/use-prevent-scroll.js"; +import useTimeout from "../../composables/use-timeout/use-timeout.js"; +import useDark, { + useDarkProps, +} from "../../composables/private.use-dark/use-dark.js"; + +import TouchPan from "../../directives/touch-pan/TouchPan.js"; + +import { createComponent } from "../../utils/private.create/create.js"; +import { between } from "../../utils/format/format.js"; +import { hSlot, hDir } from "../../utils/private.render/render.js"; +import { + layoutKey, + emptyRenderFn, +} from "../../utils/private.symbols/symbols.js"; + +const duration = 150; export default createComponent({ - name: 'QDrawer', + name: "QDrawer", inheritAttrs: false, @@ -26,33 +45,33 @@ export default createComponent({ side: { type: String, - default: 'left', - validator: v => [ 'left', 'right' ].includes(v) + default: "left", + validator: (v) => ["left", "right"].includes(v), }, width: { type: Number, - default: 300 + default: 300, }, mini: Boolean, miniToOverlay: Boolean, miniWidth: { type: Number, - default: 57 + default: 57, }, noMiniAnimation: Boolean, breakpoint: { type: Number, - default: 1023 + default: 1023, }, showIfAbove: Boolean, behavior: { type: String, - validator: v => [ 'default', 'desktop', 'mobile' ].includes(v), - default: 'default' + validator: (v) => ["default", "desktop", "mobile"].includes(v), + default: "default", }, bordered: Boolean, @@ -62,97 +81,98 @@ export default createComponent({ persistent: Boolean, noSwipeOpen: Boolean, noSwipeClose: Boolean, - noSwipeBackdrop: Boolean + noSwipeBackdrop: Boolean, }, - emits: [ - ...useModelToggleEmits, - 'onLayout', 'miniState' - ], + emits: [...useModelToggleEmits, "onLayout", "miniState"], - setup (props, { slots, emit, attrs }) { - const vm = getCurrentInstance() - const { proxy: { $q } } = vm + setup(props, { slots, emit, attrs }) { + const vm = getCurrentInstance(); + const { + proxy: { $q }, + } = vm; - const isDark = useDark(props, $q) - const { preventBodyScroll } = usePreventScroll() - const { registerTimeout, removeTimeout } = useTimeout() + const isDark = useDark(props, $q); + const { preventBodyScroll } = usePreventScroll(); + const { registerTimeout, removeTimeout } = useTimeout(); - const $layout = inject(layoutKey, emptyRenderFn) + const $layout = inject(layoutKey, emptyRenderFn); if ($layout === emptyRenderFn) { - console.error('QDrawer needs to be child of QLayout') - return emptyRenderFn + console.error("QDrawer needs to be child of QLayout"); + return emptyRenderFn; } - let lastDesktopState, timerMini = null, layoutTotalWidthWatcher + let lastDesktopState, + timerMini = null, + layoutTotalWidthWatcher; const belowBreakpoint = ref( - props.behavior === 'mobile' - || (props.behavior !== 'desktop' && $layout.totalWidth.value <= props.breakpoint) - ) + props.behavior === "mobile" || + (props.behavior !== "desktop" && + $layout.totalWidth.value <= props.breakpoint), + ); - const isMini = computed(() => - props.mini === true && belowBreakpoint.value !== true - ) + const isMini = computed( + () => props.mini === true && belowBreakpoint.value !== true, + ); - const size = computed(() => ( - isMini.value === true - ? props.miniWidth - : props.width - )) + const size = computed(() => + isMini.value === true ? props.miniWidth : props.width, + ); const showing = ref( props.showIfAbove === true && belowBreakpoint.value === false ? true - : props.modelValue === true - ) + : props.modelValue === true, + ); - const hideOnRouteChange = computed(() => - props.persistent !== true - && (belowBreakpoint.value === true || onScreenOverlay.value === true) - ) + const hideOnRouteChange = computed( + () => + props.persistent !== true && + (belowBreakpoint.value === true || onScreenOverlay.value === true), + ); - function handleShow (evt, noEvent) { - addToHistory() + function handleShow(evt, noEvent) { + addToHistory(); - evt !== false && $layout.animate() - applyPosition(0) + evt !== false && $layout.animate(); + applyPosition(0); if (belowBreakpoint.value === true) { - const otherInstance = $layout.instances[ otherSide.value ] + const otherInstance = $layout.instances[otherSide.value]; if (otherInstance?.belowBreakpoint === true) { - otherInstance.hide(false) + otherInstance.hide(false); } - applyBackdrop(1) - $layout.isContainer.value !== true && preventBodyScroll(true) - } - else { - applyBackdrop(0) - evt !== false && setScrollable(false) + applyBackdrop(1); + $layout.isContainer.value !== true && preventBodyScroll(true); + } else { + applyBackdrop(0); + evt !== false && setScrollable(false); } registerTimeout(() => { - evt !== false && setScrollable(true) - noEvent !== true && emit('show', evt) - }, duration) + evt !== false && setScrollable(true); + noEvent !== true && emit("show", evt); + }, duration); } - function handleHide (evt, noEvent) { - removeFromHistory() + function handleHide(evt, noEvent) { + removeFromHistory(); - evt !== false && $layout.animate() + evt !== false && $layout.animate(); - applyBackdrop(0) - applyPosition(stateDirection.value * size.value) + applyBackdrop(0); + applyPosition(stateDirection.value * size.value); - cleanup() + cleanup(); if (noEvent !== true) { - registerTimeout(() => { emit('hide', evt) }, duration) - } - else { - removeTimeout() + registerTimeout(() => { + emit("hide", evt); + }, duration); + } else { + removeTimeout(); } } @@ -160,551 +180,610 @@ export default createComponent({ showing, hideOnRouteChange, handleShow, - handleHide - }) + handleHide, + }); - const { addToHistory, removeFromHistory } = useHistory(showing, hide, hideOnRouteChange) + const { addToHistory, removeFromHistory } = useHistory( + showing, + hide, + hideOnRouteChange, + ); const instance = { belowBreakpoint, - hide - } - - const rightSide = computed(() => props.side === 'right') - - const stateDirection = computed(() => - ($q.lang.rtl === true ? -1 : 1) * (rightSide.value === true ? 1 : -1) - ) - - const flagBackdropBg = ref(0) - const flagPanning = ref(false) - const flagMiniAnimate = ref(false) - const flagContentPosition = ref( // starting with "hidden" for SSR - size.value * stateDirection.value - ) - - const otherSide = computed(() => (rightSide.value === true ? 'left' : 'right')) - const offset = computed(() => ( - showing.value === true && belowBreakpoint.value === false && props.overlay === false - ? (props.miniToOverlay === true ? props.miniWidth : size.value) - : 0 - )) - - const fixed = computed(() => - props.overlay === true - || props.miniToOverlay === true - || $layout.view.value.indexOf(rightSide.value ? 'R' : 'L') !== -1 - || ($q.platform.is.ios === true && $layout.isContainer.value === true) - ) - - const onLayout = computed(() => + hide, + }; + + const rightSide = computed(() => props.side === "right"); + + const stateDirection = computed( + () => + ($q.lang.rtl === true ? -1 : 1) * (rightSide.value === true ? 1 : -1), + ); + + const flagBackdropBg = ref(0); + const flagPanning = ref(false); + const flagMiniAnimate = ref(false); + const flagContentPosition = ref( + // starting with "hidden" for SSR + size.value * stateDirection.value, + ); + + const otherSide = computed(() => + rightSide.value === true ? "left" : "right", + ); + const offset = computed(() => + showing.value === true && + belowBreakpoint.value === false && props.overlay === false - && showing.value === true - && belowBreakpoint.value === false - ) - - const onScreenOverlay = computed(() => - props.overlay === true - && showing.value === true - && belowBreakpoint.value === false - ) - - const backdropClass = computed(() => - 'fullscreen q-drawer__backdrop' - + (showing.value === false && flagPanning.value === false ? ' hidden' : '') - ) + ? props.miniToOverlay === true + ? props.miniWidth + : size.value + : 0, + ); + + const fixed = computed( + () => + props.overlay === true || + props.miniToOverlay === true || + $layout.view.value.indexOf(rightSide.value ? "R" : "L") !== -1 || + ($q.platform.is.ios === true && $layout.isContainer.value === true), + ); + + const onLayout = computed( + () => + props.overlay === false && + showing.value === true && + belowBreakpoint.value === false, + ); + + const onScreenOverlay = computed( + () => + props.overlay === true && + showing.value === true && + belowBreakpoint.value === false, + ); + + const backdropClass = computed( + () => + "fullscreen q-drawer__backdrop" + + (showing.value === false && flagPanning.value === false + ? " hidden" + : ""), + ); const backdropStyle = computed(() => ({ - backgroundColor: `rgba(0,0,0,${ flagBackdropBg.value * 0.4 })` - })) + backgroundColor: `rgba(0,0,0,${flagBackdropBg.value * 0.4})`, + })); - const headerSlot = computed(() => ( + const headerSlot = computed(() => rightSide.value === true - ? $layout.rows.value.top[ 2 ] === 'r' - : $layout.rows.value.top[ 0 ] === 'l' - )) + ? $layout.rows.value.top[2] === "r" + : $layout.rows.value.top[0] === "l", + ); - const footerSlot = computed(() => ( + const footerSlot = computed(() => rightSide.value === true - ? $layout.rows.value.bottom[ 2 ] === 'r' - : $layout.rows.value.bottom[ 0 ] === 'l' - )) + ? $layout.rows.value.bottom[2] === "r" + : $layout.rows.value.bottom[0] === "l", + ); const aboveStyle = computed(() => { - const css = {} + const css = {}; if ($layout.header.space === true && headerSlot.value === false) { if (fixed.value === true) { - css.top = `${ $layout.header.offset }px` - } - else if ($layout.header.space === true) { - css.top = `${ $layout.header.size }px` + css.top = `${$layout.header.offset}px`; + } else if ($layout.header.space === true) { + css.top = `${$layout.header.size}px`; } } if ($layout.footer.space === true && footerSlot.value === false) { if (fixed.value === true) { - css.bottom = `${ $layout.footer.offset }px` - } - else if ($layout.footer.space === true) { - css.bottom = `${ $layout.footer.size }px` + css.bottom = `${$layout.footer.offset}px`; + } else if ($layout.footer.space === true) { + css.bottom = `${$layout.footer.size}px`; } } - return css - }) + return css; + }); const style = computed(() => { const style = { - width: `${ size.value }px`, - transform: `translateX(${ flagContentPosition.value }px)` - } + width: `${size.value}px`, + transform: `translateX(${flagContentPosition.value}px)`, + }; return belowBreakpoint.value === true ? style - : Object.assign(style, aboveStyle.value) - }) - - const contentClass = computed(() => - 'q-drawer__content fit ' - + ($layout.isContainer.value !== true ? 'scroll' : 'overflow-auto') - ) - - const classes = computed(() => - `q-drawer q-drawer--${ props.side }` - + (flagMiniAnimate.value === true ? ' q-drawer--mini-animate' : '') - + (props.bordered === true ? ' q-drawer--bordered' : '') - + (isDark.value === true ? ' q-drawer--dark q-dark' : '') - + ( - flagPanning.value === true - ? ' no-transition' - : (showing.value === true ? '' : ' q-layout--prevent-focus') - ) - + ( - belowBreakpoint.value === true - ? ' fixed q-drawer--on-top q-drawer--mobile q-drawer--top-padding' - : ` q-drawer--${ isMini.value === true ? 'mini' : 'standard' }` - + (fixed.value === true || onLayout.value !== true ? ' fixed' : '') - + (props.overlay === true || props.miniToOverlay === true ? ' q-drawer--on-top' : '') - + (headerSlot.value === true ? ' q-drawer--top-padding' : '') - ) - ) + : Object.assign(style, aboveStyle.value); + }); + + const contentClass = computed( + () => + "q-drawer__content fit " + + ($layout.isContainer.value !== true ? "scroll" : "overflow-auto"), + ); + + const classes = computed( + () => + `q-drawer q-drawer--${props.side}` + + (flagMiniAnimate.value === true ? " q-drawer--mini-animate" : "") + + (props.bordered === true ? " q-drawer--bordered" : "") + + (isDark.value === true ? " q-drawer--dark q-dark" : "") + + (flagPanning.value === true + ? " no-transition" + : showing.value === true + ? "" + : " q-layout--prevent-focus") + + (belowBreakpoint.value === true + ? " fixed q-drawer--on-top q-drawer--mobile q-drawer--top-padding" + : ` q-drawer--${isMini.value === true ? "mini" : "standard"}` + + (fixed.value === true || onLayout.value !== true ? " fixed" : "") + + (props.overlay === true || props.miniToOverlay === true + ? " q-drawer--on-top" + : "") + + (headerSlot.value === true ? " q-drawer--top-padding" : "")), + ); const openDirective = computed(() => { // if props.noSwipeOpen !== true - const dir = $q.lang.rtl === true ? props.side : otherSide.value - - return [ [ - TouchPan, - onOpenPan, - void 0, - { - [ dir ]: true, - mouse: true - } - ] ] - }) + const dir = $q.lang.rtl === true ? props.side : otherSide.value; + + return [ + [ + TouchPan, + onOpenPan, + void 0, + { + [dir]: true, + mouse: true, + }, + ], + ]; + }); const contentCloseDirective = computed(() => { // if belowBreakpoint.value === true && props.noSwipeClose !== true - const dir = $q.lang.rtl === true ? otherSide.value : props.side - - return [ [ - TouchPan, - onClosePan, - void 0, - { - [ dir ]: true, - mouse: true - } - ] ] - }) + const dir = $q.lang.rtl === true ? otherSide.value : props.side; + + return [ + [ + TouchPan, + onClosePan, + void 0, + { + [dir]: true, + mouse: true, + }, + ], + ]; + }); const backdropCloseDirective = computed(() => { // if showing.value === true && props.noSwipeBackdrop !== true - const dir = $q.lang.rtl === true ? otherSide.value : props.side - - return [ [ - TouchPan, - onClosePan, - void 0, - { - [ dir ]: true, - mouse: true, - mouseAllDir: true - } - ] ] - }) - - function updateBelowBreakpoint () { - updateLocal(belowBreakpoint, ( - props.behavior === 'mobile' - || (props.behavior !== 'desktop' && $layout.totalWidth.value <= props.breakpoint) - )) + const dir = $q.lang.rtl === true ? otherSide.value : props.side; + + return [ + [ + TouchPan, + onClosePan, + void 0, + { + [dir]: true, + mouse: true, + mouseAllDir: true, + }, + ], + ]; + }); + + function updateBelowBreakpoint() { + updateLocal( + belowBreakpoint, + props.behavior === "mobile" || + (props.behavior !== "desktop" && + $layout.totalWidth.value <= props.breakpoint), + ); } - watch(belowBreakpoint, val => { - if (val === true) { // from lg to xs - lastDesktopState = showing.value - showing.value === true && hide(false) - } - else if ( - props.overlay === false - && props.behavior !== 'mobile' - && lastDesktopState !== false - ) { // from xs to lg + watch(belowBreakpoint, (val) => { + if (val === true) { + // from lg to xs + lastDesktopState = showing.value; + showing.value === true && hide(false); + } else if ( + props.overlay === false && + props.behavior !== "mobile" && + lastDesktopState !== false + ) { + // from xs to lg if (showing.value === true) { - applyPosition(0) - applyBackdrop(0) - cleanup() - } - else { - show(false) + applyPosition(0); + applyBackdrop(0); + cleanup(); + } else { + show(false); } } - }) + }); - watch(() => props.side, (newSide, oldSide) => { - if ($layout.instances[ oldSide ] === instance) { - $layout.instances[ oldSide ] = void 0 - $layout[ oldSide ].space = false - $layout[ oldSide ].offset = 0 - } + watch( + () => props.side, + (newSide, oldSide) => { + if ($layout.instances[oldSide] === instance) { + $layout.instances[oldSide] = void 0; + $layout[oldSide].space = false; + $layout[oldSide].offset = 0; + } - $layout.instances[ newSide ] = instance - $layout[ newSide ].size = size.value - $layout[ newSide ].space = onLayout.value - $layout[ newSide ].offset = offset.value - }) + $layout.instances[newSide] = instance; + $layout[newSide].size = size.value; + $layout[newSide].space = onLayout.value; + $layout[newSide].offset = offset.value; + }, + ); watch($layout.totalWidth, () => { - if ($layout.isContainer.value === true || document.qScrollPrevented !== true) { - updateBelowBreakpoint() + if ( + $layout.isContainer.value === true || + document.qScrollPrevented !== true + ) { + updateBelowBreakpoint(); } - }) + }); - watch( - () => props.behavior + props.breakpoint, - updateBelowBreakpoint - ) + watch(() => props.behavior + props.breakpoint, updateBelowBreakpoint); - watch($layout.isContainer, val => { - showing.value === true && preventBodyScroll(val !== true) - val === true && updateBelowBreakpoint() - }) + watch($layout.isContainer, (val) => { + showing.value === true && preventBodyScroll(val !== true); + val === true && updateBelowBreakpoint(); + }); watch($layout.scrollbarWidth, () => { - applyPosition(showing.value === true ? 0 : void 0) - }) + applyPosition(showing.value === true ? 0 : void 0); + }); - watch(offset, val => { updateLayout('offset', val) }) + watch(offset, (val) => { + updateLayout("offset", val); + }); - watch(onLayout, val => { - emit('onLayout', val) - updateLayout('space', val) - }) + watch(onLayout, (val) => { + emit("onLayout", val); + updateLayout("space", val); + }); - watch(rightSide, () => { applyPosition() }) + watch(rightSide, () => { + applyPosition(); + }); - watch(size, val => { - applyPosition() - updateSizeOnLayout(props.miniToOverlay, val) - }) + watch(size, (val) => { + applyPosition(); + updateSizeOnLayout(props.miniToOverlay, val); + }); - watch(() => props.miniToOverlay, val => { - updateSizeOnLayout(val, size.value) - }) + watch( + () => props.miniToOverlay, + (val) => { + updateSizeOnLayout(val, size.value); + }, + ); - watch(() => $q.lang.rtl, () => { applyPosition() }) + watch( + () => $q.lang.rtl, + () => { + applyPosition(); + }, + ); - watch(() => props.mini, () => { - if (props.noMiniAnimation) return - if (props.modelValue === true) { - animateMini() - $layout.animate() - } - }) + watch( + () => props.mini, + () => { + if (props.noMiniAnimation) return; + if (props.modelValue === true) { + animateMini(); + $layout.animate(); + } + }, + ); - watch(isMini, val => { emit('miniState', val) }) + watch(isMini, (val) => { + emit("miniState", val); + }); - function applyPosition (position) { + function applyPosition(position) { if (position === void 0) { nextTick(() => { - position = showing.value === true ? 0 : size.value - applyPosition(stateDirection.value * position) - }) - } - else { + position = showing.value === true ? 0 : size.value; + applyPosition(stateDirection.value * position); + }); + } else { if ( - $layout.isContainer.value === true - && rightSide.value === true - && (belowBreakpoint.value === true || Math.abs(position) === size.value) + $layout.isContainer.value === true && + rightSide.value === true && + (belowBreakpoint.value === true || Math.abs(position) === size.value) ) { - position += stateDirection.value * $layout.scrollbarWidth.value + position += stateDirection.value * $layout.scrollbarWidth.value; } - flagContentPosition.value = position + flagContentPosition.value = position; } } - function applyBackdrop (x) { - flagBackdropBg.value = x + function applyBackdrop(x) { + flagBackdropBg.value = x; } - function setScrollable (v) { - const action = v === true - ? 'remove' - : ($layout.isContainer.value !== true ? 'add' : '') + function setScrollable(v) { + const action = + v === true ? "remove" : $layout.isContainer.value !== true ? "add" : ""; - action !== '' && document.body.classList[ action ]('q-body--drawer-toggle') + action !== "" && document.body.classList[action]("q-body--drawer-toggle"); } - function animateMini () { - timerMini !== null && clearTimeout(timerMini) + function animateMini() { + timerMini !== null && clearTimeout(timerMini); if (vm.proxy && vm.proxy.$el) { // need to speed it up and apply it immediately, // even faster than Vue's nextTick! - vm.proxy.$el.classList.add('q-drawer--mini-animate') + vm.proxy.$el.classList.add("q-drawer--mini-animate"); } - flagMiniAnimate.value = true + flagMiniAnimate.value = true; timerMini = setTimeout(() => { - timerMini = null - flagMiniAnimate.value = false - vm?.proxy?.$el?.classList.remove('q-drawer--mini-animate') - }, 150) + timerMini = null; + flagMiniAnimate.value = false; + vm?.proxy?.$el?.classList.remove("q-drawer--mini-animate"); + }, 150); } - function onOpenPan (evt) { + function onOpenPan(evt) { if (showing.value !== false) { // some browsers might capture and trigger this // even if Drawer has just been opened (but animation is still pending) - return + return; } - const - width = size.value, - position = between(evt.distance.x, 0, width) + const width = size.value, + position = between(evt.distance.x, 0, width); if (evt.isFinal === true) { - const opened = position >= Math.min(75, width) + const opened = position >= Math.min(75, width); if (opened === true) { - show() - } - else { - $layout.animate() - applyBackdrop(0) - applyPosition(stateDirection.value * width) + show(); + } else { + $layout.animate(); + applyBackdrop(0); + applyPosition(stateDirection.value * width); } - flagPanning.value = false - return + flagPanning.value = false; + return; } applyPosition( ($q.lang.rtl === true ? rightSide.value !== true : rightSide.value) ? Math.max(width - position, 0) - : Math.min(0, position - width) - ) - applyBackdrop( - between(position / width, 0, 1) - ) + : Math.min(0, position - width), + ); + applyBackdrop(between(position / width, 0, 1)); if (evt.isFirst === true) { - flagPanning.value = true + flagPanning.value = true; } } - function onClosePan (evt) { + function onClosePan(evt) { if (showing.value !== true) { // some browsers might capture and trigger this // even if Drawer has just been closed (but animation is still pending) - return + return; } - const - width = size.value, + const width = size.value, dir = evt.direction === props.side, position = ($q.lang.rtl === true ? dir !== true : dir) ? between(evt.distance.x, 0, width) - : 0 + : 0; if (evt.isFinal === true) { - const opened = Math.abs(position) < Math.min(75, width) + const opened = Math.abs(position) < Math.min(75, width); if (opened === true) { - $layout.animate() - applyBackdrop(1) - applyPosition(0) - } - else { - hide() + $layout.animate(); + applyBackdrop(1); + applyPosition(0); + } else { + hide(); } - flagPanning.value = false - return + flagPanning.value = false; + return; } - applyPosition(stateDirection.value * position) - applyBackdrop(between(1 - position / width, 0, 1)) + applyPosition(stateDirection.value * position); + applyBackdrop(between(1 - position / width, 0, 1)); if (evt.isFirst === true) { - flagPanning.value = true + flagPanning.value = true; } } - function cleanup () { - preventBodyScroll(false) - setScrollable(true) + function cleanup() { + preventBodyScroll(false); + setScrollable(true); } - function updateLayout (prop, val) { - $layout.update(props.side, prop, val) + function updateLayout(prop, val) { + $layout.update(props.side, prop, val); } - function updateLocal (prop, val) { + function updateLocal(prop, val) { if (prop.value !== val) { - prop.value = val + prop.value = val; } } - function updateSizeOnLayout (miniToOverlay, size) { - updateLayout('size', miniToOverlay === true ? props.miniWidth : size) + function updateSizeOnLayout(miniToOverlay, size) { + updateLayout("size", miniToOverlay === true ? props.miniWidth : size); } - $layout.instances[ props.side ] = instance - updateSizeOnLayout(props.miniToOverlay, size.value) - updateLayout('space', onLayout.value) - updateLayout('offset', offset.value) + $layout.instances[props.side] = instance; + updateSizeOnLayout(props.miniToOverlay, size.value); + updateLayout("space", onLayout.value); + updateLayout("offset", offset.value); if ( - props.showIfAbove === true - && props.modelValue !== true - && showing.value === true - && props[ 'onUpdate:modelValue' ] !== void 0 + props.showIfAbove === true && + props.modelValue !== true && + showing.value === true && + props["onUpdate:modelValue"] !== void 0 ) { - emit('update:modelValue', true) + emit("update:modelValue", true); } onMounted(() => { - emit('onLayout', onLayout.value) - emit('miniState', isMini.value) + emit("onLayout", onLayout.value); + emit("miniState", isMini.value); - lastDesktopState = props.showIfAbove === true + lastDesktopState = props.showIfAbove === true; const fn = () => { - const action = showing.value === true ? handleShow : handleHide - action(false, true) - } + const action = showing.value === true ? handleShow : handleHide; + action(false, true); + }; if ($layout.totalWidth.value !== 0) { // make sure that all computed properties // have been updated before calling handleShow/handleHide() - nextTick(fn) - return + nextTick(fn); + return; } layoutTotalWidthWatcher = watch($layout.totalWidth, () => { - layoutTotalWidthWatcher() - layoutTotalWidthWatcher = void 0 + layoutTotalWidthWatcher(); + layoutTotalWidthWatcher = void 0; - if (showing.value === false && props.showIfAbove === true && belowBreakpoint.value === false) { - show(false) - } - else { - fn() + if ( + showing.value === false && + props.showIfAbove === true && + belowBreakpoint.value === false + ) { + show(false); + } else { + fn(); } - }) - }) + }); + }); onBeforeUnmount(() => { - layoutTotalWidthWatcher?.() + layoutTotalWidthWatcher?.(); if (timerMini !== null) { - clearTimeout(timerMini) - timerMini = null + clearTimeout(timerMini); + timerMini = null; } - showing.value === true && cleanup() + showing.value === true && cleanup(); - if ($layout.instances[ props.side ] === instance) { - $layout.instances[ props.side ] = void 0 - updateLayout('size', 0) - updateLayout('offset', 0) - updateLayout('space', false) + if ($layout.instances[props.side] === instance) { + $layout.instances[props.side] = void 0; + updateLayout("size", 0); + updateLayout("offset", 0); + updateLayout("space", false); } - }) + }); return () => { - const child = [] + const child = []; if (belowBreakpoint.value === true) { - props.noSwipeOpen === false && child.push( - withDirectives( - h('div', { - key: 'open', - class: `q-drawer__opener fixed-${ props.side }`, - 'aria-hidden': 'true' - }), - openDirective.value - ) - ) + props.noSwipeOpen === false && + child.push( + withDirectives( + h("div", { + key: "open", + class: `q-drawer__opener fixed-${props.side}`, + "aria-hidden": "true", + }), + openDirective.value, + ), + ); child.push( hDir( - 'div', + "div", { - ref: 'backdrop', + ref: "backdrop", class: backdropClass.value, style: backdropStyle.value, - 'aria-hidden': 'true', - onClick: hide + "aria-hidden": "true", + onClick: hide, }, void 0, - 'backdrop', + "backdrop", props.noSwipeBackdrop !== true && showing.value === true, - () => backdropCloseDirective.value - ) - ) + () => backdropCloseDirective.value, + ), + ); } - const mini = isMini.value === true && slots.mini !== void 0 + const mini = isMini.value === true && slots.mini !== void 0; + + const sortedAttrs = Object.entries(attrs).reduce( + (acc, [key, value]) => { + if (key.startsWith("aria-label")) { + acc.labelAttibutes[key] = value; + } else { + acc.other[key] = value; + } + return acc; + }, + { labelAttibutes: {}, other: {} }, + ); + const content = [ - h('div', { - ...attrs, - key: '' + mini, // required otherwise Vue will not diff correctly - class: [ - contentClass.value, - attrs.class - ] - }, mini === true - ? slots.mini() - : hSlot(slots.default) - ) - ] + h( + "div", + { + ...sortedAttrs.other, + key: "" + mini, // required otherwise Vue will not diff correctly + class: [contentClass.value, attrs.class], + }, + mini === true ? slots.mini() : hSlot(slots.default), + ), + ]; if (props.elevated === true && showing.value === true) { content.push( - h('div', { - class: 'q-layout__shadow absolute-full overflow-hidden no-pointer-events' - }) - ) + h("div", { + class: + "q-layout__shadow absolute-full overflow-hidden no-pointer-events", + }), + ); } child.push( hDir( - 'aside', - { ref: 'content', class: classes.value, style: style.value }, + "aside", + { + ref: "content", + class: classes.value, + style: style.value, + ...sortedAttrs.labelAttibutes, + }, content, - 'contentclose', + "contentclose", props.noSwipeClose !== true && belowBreakpoint.value === true, - () => contentCloseDirective.value - ) - ) + () => contentCloseDirective.value, + ), + ); - return h('div', { class: 'q-drawer-container' }, child) - } - } -}) + return h("div", { class: "q-drawer-container" }, child); + }; + }, +}); From a281733537130551666253af42d66992f451f96e Mon Sep 17 00:00:00 2001 From: Chris Jung Date: Fri, 27 Jun 2025 15:06:37 +0200 Subject: [PATCH 2/2] chore: apply codestyles --- ui/src/components/drawer/QDrawer.js | 963 +++++++++++++--------------- 1 file changed, 449 insertions(+), 514 deletions(-) diff --git a/ui/src/components/drawer/QDrawer.js b/ui/src/components/drawer/QDrawer.js index 17412f3591a..25982ef4907 100644 --- a/ui/src/components/drawer/QDrawer.js +++ b/ui/src/components/drawer/QDrawer.js @@ -1,41 +1,22 @@ -import { - h, - withDirectives, - ref, - computed, - watch, - onMounted, - onBeforeUnmount, - nextTick, - inject, - getCurrentInstance, -} from "vue"; - -import useHistory from "../../composables/private.use-history/use-history.js"; -import useModelToggle, { - useModelToggleProps, - useModelToggleEmits, -} from "../../composables/private.use-model-toggle/use-model-toggle.js"; -import usePreventScroll from "../../composables/private.use-prevent-scroll/use-prevent-scroll.js"; -import useTimeout from "../../composables/use-timeout/use-timeout.js"; -import useDark, { - useDarkProps, -} from "../../composables/private.use-dark/use-dark.js"; - -import TouchPan from "../../directives/touch-pan/TouchPan.js"; - -import { createComponent } from "../../utils/private.create/create.js"; -import { between } from "../../utils/format/format.js"; -import { hSlot, hDir } from "../../utils/private.render/render.js"; -import { - layoutKey, - emptyRenderFn, -} from "../../utils/private.symbols/symbols.js"; - -const duration = 150; +import { h, withDirectives, ref, computed, watch, onMounted, onBeforeUnmount, nextTick, inject, getCurrentInstance } from 'vue' + +import useHistory from '../../composables/private.use-history/use-history.js' +import useModelToggle, { useModelToggleProps, useModelToggleEmits } from '../../composables/private.use-model-toggle/use-model-toggle.js' +import usePreventScroll from '../../composables/private.use-prevent-scroll/use-prevent-scroll.js' +import useTimeout from '../../composables/use-timeout/use-timeout.js' +import useDark, { useDarkProps } from '../../composables/private.use-dark/use-dark.js' + +import TouchPan from '../../directives/touch-pan/TouchPan.js' + +import { createComponent } from '../../utils/private.create/create.js' +import { between } from '../../utils/format/format.js' +import { hSlot, hDir } from '../../utils/private.render/render.js' +import { layoutKey, emptyRenderFn } from '../../utils/private.symbols/symbols.js' + +const duration = 150 export default createComponent({ - name: "QDrawer", + name: 'QDrawer', inheritAttrs: false, @@ -45,33 +26,33 @@ export default createComponent({ side: { type: String, - default: "left", - validator: (v) => ["left", "right"].includes(v), + default: 'left', + validator: v => [ 'left', 'right' ].includes(v) }, width: { type: Number, - default: 300, + default: 300 }, mini: Boolean, miniToOverlay: Boolean, miniWidth: { type: Number, - default: 57, + default: 57 }, noMiniAnimation: Boolean, breakpoint: { type: Number, - default: 1023, + default: 1023 }, showIfAbove: Boolean, behavior: { type: String, - validator: (v) => ["default", "desktop", "mobile"].includes(v), - default: "default", + validator: v => [ 'default', 'desktop', 'mobile' ].includes(v), + default: 'default' }, bordered: Boolean, @@ -81,98 +62,97 @@ export default createComponent({ persistent: Boolean, noSwipeOpen: Boolean, noSwipeClose: Boolean, - noSwipeBackdrop: Boolean, + noSwipeBackdrop: Boolean }, - emits: [...useModelToggleEmits, "onLayout", "miniState"], + emits: [ + ...useModelToggleEmits, + 'onLayout', 'miniState' + ], - setup(props, { slots, emit, attrs }) { - const vm = getCurrentInstance(); - const { - proxy: { $q }, - } = vm; + setup (props, { slots, emit, attrs }) { + const vm = getCurrentInstance() + const { proxy: { $q } } = vm - const isDark = useDark(props, $q); - const { preventBodyScroll } = usePreventScroll(); - const { registerTimeout, removeTimeout } = useTimeout(); + const isDark = useDark(props, $q) + const { preventBodyScroll } = usePreventScroll() + const { registerTimeout, removeTimeout } = useTimeout() - const $layout = inject(layoutKey, emptyRenderFn); + const $layout = inject(layoutKey, emptyRenderFn) if ($layout === emptyRenderFn) { - console.error("QDrawer needs to be child of QLayout"); - return emptyRenderFn; + console.error('QDrawer needs to be child of QLayout') + return emptyRenderFn } - let lastDesktopState, - timerMini = null, - layoutTotalWidthWatcher; + let lastDesktopState, timerMini = null, layoutTotalWidthWatcher const belowBreakpoint = ref( - props.behavior === "mobile" || - (props.behavior !== "desktop" && - $layout.totalWidth.value <= props.breakpoint), - ); + props.behavior === 'mobile' + || (props.behavior !== 'desktop' && $layout.totalWidth.value <= props.breakpoint) + ) - const isMini = computed( - () => props.mini === true && belowBreakpoint.value !== true, - ); + const isMini = computed(() => + props.mini === true && belowBreakpoint.value !== true + ) - const size = computed(() => - isMini.value === true ? props.miniWidth : props.width, - ); + const size = computed(() => ( + isMini.value === true + ? props.miniWidth + : props.width + )) const showing = ref( props.showIfAbove === true && belowBreakpoint.value === false ? true - : props.modelValue === true, - ); + : props.modelValue === true + ) - const hideOnRouteChange = computed( - () => - props.persistent !== true && - (belowBreakpoint.value === true || onScreenOverlay.value === true), - ); + const hideOnRouteChange = computed(() => + props.persistent !== true + && (belowBreakpoint.value === true || onScreenOverlay.value === true) + ) - function handleShow(evt, noEvent) { - addToHistory(); + function handleShow (evt, noEvent) { + addToHistory() - evt !== false && $layout.animate(); - applyPosition(0); + evt !== false && $layout.animate() + applyPosition(0) if (belowBreakpoint.value === true) { - const otherInstance = $layout.instances[otherSide.value]; + const otherInstance = $layout.instances[ otherSide.value ] if (otherInstance?.belowBreakpoint === true) { - otherInstance.hide(false); + otherInstance.hide(false) } - applyBackdrop(1); - $layout.isContainer.value !== true && preventBodyScroll(true); - } else { - applyBackdrop(0); - evt !== false && setScrollable(false); + applyBackdrop(1) + $layout.isContainer.value !== true && preventBodyScroll(true) + } + else { + applyBackdrop(0) + evt !== false && setScrollable(false) } registerTimeout(() => { - evt !== false && setScrollable(true); - noEvent !== true && emit("show", evt); - }, duration); + evt !== false && setScrollable(true) + noEvent !== true && emit('show', evt) + }, duration) } - function handleHide(evt, noEvent) { - removeFromHistory(); + function handleHide (evt, noEvent) { + removeFromHistory() - evt !== false && $layout.animate(); + evt !== false && $layout.animate() - applyBackdrop(0); - applyPosition(stateDirection.value * size.value); + applyBackdrop(0) + applyPosition(stateDirection.value * size.value) - cleanup(); + cleanup() if (noEvent !== true) { - registerTimeout(() => { - emit("hide", evt); - }, duration); - } else { - removeTimeout(); + registerTimeout(() => { emit('hide', evt) }, duration) + } + else { + removeTimeout() } } @@ -180,610 +160,565 @@ export default createComponent({ showing, hideOnRouteChange, handleShow, - handleHide, - }); + handleHide + }) - const { addToHistory, removeFromHistory } = useHistory( - showing, - hide, - hideOnRouteChange, - ); + const { addToHistory, removeFromHistory } = useHistory(showing, hide, hideOnRouteChange) const instance = { belowBreakpoint, - hide, - }; - - const rightSide = computed(() => props.side === "right"); - - const stateDirection = computed( - () => - ($q.lang.rtl === true ? -1 : 1) * (rightSide.value === true ? 1 : -1), - ); - - const flagBackdropBg = ref(0); - const flagPanning = ref(false); - const flagMiniAnimate = ref(false); - const flagContentPosition = ref( - // starting with "hidden" for SSR - size.value * stateDirection.value, - ); - - const otherSide = computed(() => - rightSide.value === true ? "left" : "right", - ); - const offset = computed(() => - showing.value === true && - belowBreakpoint.value === false && + hide + } + + const rightSide = computed(() => props.side === 'right') + + const stateDirection = computed(() => + ($q.lang.rtl === true ? -1 : 1) * (rightSide.value === true ? 1 : -1) + ) + + const flagBackdropBg = ref(0) + const flagPanning = ref(false) + const flagMiniAnimate = ref(false) + const flagContentPosition = ref( // starting with "hidden" for SSR + size.value * stateDirection.value + ) + + const otherSide = computed(() => (rightSide.value === true ? 'left' : 'right')) + const offset = computed(() => ( + showing.value === true && belowBreakpoint.value === false && props.overlay === false + ? (props.miniToOverlay === true ? props.miniWidth : size.value) + : 0 + )) + + const fixed = computed(() => + props.overlay === true + || props.miniToOverlay === true + || $layout.view.value.indexOf(rightSide.value ? 'R' : 'L') !== -1 + || ($q.platform.is.ios === true && $layout.isContainer.value === true) + ) + + const onLayout = computed(() => props.overlay === false - ? props.miniToOverlay === true - ? props.miniWidth - : size.value - : 0, - ); - - const fixed = computed( - () => - props.overlay === true || - props.miniToOverlay === true || - $layout.view.value.indexOf(rightSide.value ? "R" : "L") !== -1 || - ($q.platform.is.ios === true && $layout.isContainer.value === true), - ); - - const onLayout = computed( - () => - props.overlay === false && - showing.value === true && - belowBreakpoint.value === false, - ); - - const onScreenOverlay = computed( - () => - props.overlay === true && - showing.value === true && - belowBreakpoint.value === false, - ); - - const backdropClass = computed( - () => - "fullscreen q-drawer__backdrop" + - (showing.value === false && flagPanning.value === false - ? " hidden" - : ""), - ); + && showing.value === true + && belowBreakpoint.value === false + ) + + const onScreenOverlay = computed(() => + props.overlay === true + && showing.value === true + && belowBreakpoint.value === false + ) + + const backdropClass = computed(() => + 'fullscreen q-drawer__backdrop' + + (showing.value === false && flagPanning.value === false ? ' hidden' : '') + ) const backdropStyle = computed(() => ({ - backgroundColor: `rgba(0,0,0,${flagBackdropBg.value * 0.4})`, - })); + backgroundColor: `rgba(0,0,0,${ flagBackdropBg.value * 0.4 })` + })) - const headerSlot = computed(() => + const headerSlot = computed(() => ( rightSide.value === true - ? $layout.rows.value.top[2] === "r" - : $layout.rows.value.top[0] === "l", - ); + ? $layout.rows.value.top[ 2 ] === 'r' + : $layout.rows.value.top[ 0 ] === 'l' + )) - const footerSlot = computed(() => + const footerSlot = computed(() => ( rightSide.value === true - ? $layout.rows.value.bottom[2] === "r" - : $layout.rows.value.bottom[0] === "l", - ); + ? $layout.rows.value.bottom[ 2 ] === 'r' + : $layout.rows.value.bottom[ 0 ] === 'l' + )) const aboveStyle = computed(() => { - const css = {}; + const css = {} if ($layout.header.space === true && headerSlot.value === false) { if (fixed.value === true) { - css.top = `${$layout.header.offset}px`; - } else if ($layout.header.space === true) { - css.top = `${$layout.header.size}px`; + css.top = `${ $layout.header.offset }px` + } + else if ($layout.header.space === true) { + css.top = `${ $layout.header.size }px` } } if ($layout.footer.space === true && footerSlot.value === false) { if (fixed.value === true) { - css.bottom = `${$layout.footer.offset}px`; - } else if ($layout.footer.space === true) { - css.bottom = `${$layout.footer.size}px`; + css.bottom = `${ $layout.footer.offset }px` + } + else if ($layout.footer.space === true) { + css.bottom = `${ $layout.footer.size }px` } } - return css; - }); + return css + }) const style = computed(() => { const style = { - width: `${size.value}px`, - transform: `translateX(${flagContentPosition.value}px)`, - }; + width: `${ size.value }px`, + transform: `translateX(${ flagContentPosition.value }px)` + } return belowBreakpoint.value === true ? style - : Object.assign(style, aboveStyle.value); - }); - - const contentClass = computed( - () => - "q-drawer__content fit " + - ($layout.isContainer.value !== true ? "scroll" : "overflow-auto"), - ); - - const classes = computed( - () => - `q-drawer q-drawer--${props.side}` + - (flagMiniAnimate.value === true ? " q-drawer--mini-animate" : "") + - (props.bordered === true ? " q-drawer--bordered" : "") + - (isDark.value === true ? " q-drawer--dark q-dark" : "") + - (flagPanning.value === true - ? " no-transition" - : showing.value === true - ? "" - : " q-layout--prevent-focus") + - (belowBreakpoint.value === true - ? " fixed q-drawer--on-top q-drawer--mobile q-drawer--top-padding" - : ` q-drawer--${isMini.value === true ? "mini" : "standard"}` + - (fixed.value === true || onLayout.value !== true ? " fixed" : "") + - (props.overlay === true || props.miniToOverlay === true - ? " q-drawer--on-top" - : "") + - (headerSlot.value === true ? " q-drawer--top-padding" : "")), - ); + : Object.assign(style, aboveStyle.value) + }) + + const contentClass = computed(() => + 'q-drawer__content fit ' + + ($layout.isContainer.value !== true ? 'scroll' : 'overflow-auto') + ) + + const classes = computed(() => + `q-drawer q-drawer--${ props.side }` + + (flagMiniAnimate.value === true ? ' q-drawer--mini-animate' : '') + + (props.bordered === true ? ' q-drawer--bordered' : '') + + (isDark.value === true ? ' q-drawer--dark q-dark' : '') + + ( + flagPanning.value === true + ? ' no-transition' + : (showing.value === true ? '' : ' q-layout--prevent-focus') + ) + + ( + belowBreakpoint.value === true + ? ' fixed q-drawer--on-top q-drawer--mobile q-drawer--top-padding' + : ` q-drawer--${ isMini.value === true ? 'mini' : 'standard' }` + + (fixed.value === true || onLayout.value !== true ? ' fixed' : '') + + (props.overlay === true || props.miniToOverlay === true ? ' q-drawer--on-top' : '') + + (headerSlot.value === true ? ' q-drawer--top-padding' : '') + ) + ) const openDirective = computed(() => { // if props.noSwipeOpen !== true - const dir = $q.lang.rtl === true ? props.side : otherSide.value; - - return [ - [ - TouchPan, - onOpenPan, - void 0, - { - [dir]: true, - mouse: true, - }, - ], - ]; - }); + const dir = $q.lang.rtl === true ? props.side : otherSide.value + + return [ [ + TouchPan, + onOpenPan, + void 0, + { + [ dir ]: true, + mouse: true + } + ] ] + }) const contentCloseDirective = computed(() => { // if belowBreakpoint.value === true && props.noSwipeClose !== true - const dir = $q.lang.rtl === true ? otherSide.value : props.side; - - return [ - [ - TouchPan, - onClosePan, - void 0, - { - [dir]: true, - mouse: true, - }, - ], - ]; - }); + const dir = $q.lang.rtl === true ? otherSide.value : props.side + + return [ [ + TouchPan, + onClosePan, + void 0, + { + [ dir ]: true, + mouse: true + } + ] ] + }) const backdropCloseDirective = computed(() => { // if showing.value === true && props.noSwipeBackdrop !== true - const dir = $q.lang.rtl === true ? otherSide.value : props.side; - - return [ - [ - TouchPan, - onClosePan, - void 0, - { - [dir]: true, - mouse: true, - mouseAllDir: true, - }, - ], - ]; - }); - - function updateBelowBreakpoint() { - updateLocal( - belowBreakpoint, - props.behavior === "mobile" || - (props.behavior !== "desktop" && - $layout.totalWidth.value <= props.breakpoint), - ); + const dir = $q.lang.rtl === true ? otherSide.value : props.side + + return [ [ + TouchPan, + onClosePan, + void 0, + { + [ dir ]: true, + mouse: true, + mouseAllDir: true + } + ] ] + }) + + function updateBelowBreakpoint () { + updateLocal(belowBreakpoint, ( + props.behavior === 'mobile' + || (props.behavior !== 'desktop' && $layout.totalWidth.value <= props.breakpoint) + )) } - watch(belowBreakpoint, (val) => { - if (val === true) { - // from lg to xs - lastDesktopState = showing.value; - showing.value === true && hide(false); - } else if ( - props.overlay === false && - props.behavior !== "mobile" && - lastDesktopState !== false - ) { - // from xs to lg + watch(belowBreakpoint, val => { + if (val === true) { // from lg to xs + lastDesktopState = showing.value + showing.value === true && hide(false) + } + else if ( + props.overlay === false + && props.behavior !== 'mobile' + && lastDesktopState !== false + ) { // from xs to lg if (showing.value === true) { - applyPosition(0); - applyBackdrop(0); - cleanup(); - } else { - show(false); + applyPosition(0) + applyBackdrop(0) + cleanup() + } + else { + show(false) } } - }); + }) - watch( - () => props.side, - (newSide, oldSide) => { - if ($layout.instances[oldSide] === instance) { - $layout.instances[oldSide] = void 0; - $layout[oldSide].space = false; - $layout[oldSide].offset = 0; - } + watch(() => props.side, (newSide, oldSide) => { + if ($layout.instances[ oldSide ] === instance) { + $layout.instances[ oldSide ] = void 0 + $layout[ oldSide ].space = false + $layout[ oldSide ].offset = 0 + } - $layout.instances[newSide] = instance; - $layout[newSide].size = size.value; - $layout[newSide].space = onLayout.value; - $layout[newSide].offset = offset.value; - }, - ); + $layout.instances[ newSide ] = instance + $layout[ newSide ].size = size.value + $layout[ newSide ].space = onLayout.value + $layout[ newSide ].offset = offset.value + }) watch($layout.totalWidth, () => { - if ( - $layout.isContainer.value === true || - document.qScrollPrevented !== true - ) { - updateBelowBreakpoint(); + if ($layout.isContainer.value === true || document.qScrollPrevented !== true) { + updateBelowBreakpoint() } - }); + }) - watch(() => props.behavior + props.breakpoint, updateBelowBreakpoint); + watch( + () => props.behavior + props.breakpoint, + updateBelowBreakpoint + ) - watch($layout.isContainer, (val) => { - showing.value === true && preventBodyScroll(val !== true); - val === true && updateBelowBreakpoint(); - }); + watch($layout.isContainer, val => { + showing.value === true && preventBodyScroll(val !== true) + val === true && updateBelowBreakpoint() + }) watch($layout.scrollbarWidth, () => { - applyPosition(showing.value === true ? 0 : void 0); - }); + applyPosition(showing.value === true ? 0 : void 0) + }) - watch(offset, (val) => { - updateLayout("offset", val); - }); + watch(offset, val => { updateLayout('offset', val) }) - watch(onLayout, (val) => { - emit("onLayout", val); - updateLayout("space", val); - }); + watch(onLayout, val => { + emit('onLayout', val) + updateLayout('space', val) + }) - watch(rightSide, () => { - applyPosition(); - }); + watch(rightSide, () => { applyPosition() }) - watch(size, (val) => { - applyPosition(); - updateSizeOnLayout(props.miniToOverlay, val); - }); + watch(size, val => { + applyPosition() + updateSizeOnLayout(props.miniToOverlay, val) + }) - watch( - () => props.miniToOverlay, - (val) => { - updateSizeOnLayout(val, size.value); - }, - ); + watch(() => props.miniToOverlay, val => { + updateSizeOnLayout(val, size.value) + }) - watch( - () => $q.lang.rtl, - () => { - applyPosition(); - }, - ); + watch(() => $q.lang.rtl, () => { applyPosition() }) - watch( - () => props.mini, - () => { - if (props.noMiniAnimation) return; - if (props.modelValue === true) { - animateMini(); - $layout.animate(); - } - }, - ); + watch(() => props.mini, () => { + if (props.noMiniAnimation) return + if (props.modelValue === true) { + animateMini() + $layout.animate() + } + }) - watch(isMini, (val) => { - emit("miniState", val); - }); + watch(isMini, val => { emit('miniState', val) }) - function applyPosition(position) { + function applyPosition (position) { if (position === void 0) { nextTick(() => { - position = showing.value === true ? 0 : size.value; - applyPosition(stateDirection.value * position); - }); - } else { + position = showing.value === true ? 0 : size.value + applyPosition(stateDirection.value * position) + }) + } + else { if ( - $layout.isContainer.value === true && - rightSide.value === true && - (belowBreakpoint.value === true || Math.abs(position) === size.value) + $layout.isContainer.value === true + && rightSide.value === true + && (belowBreakpoint.value === true || Math.abs(position) === size.value) ) { - position += stateDirection.value * $layout.scrollbarWidth.value; + position += stateDirection.value * $layout.scrollbarWidth.value } - flagContentPosition.value = position; + flagContentPosition.value = position } } - function applyBackdrop(x) { - flagBackdropBg.value = x; + function applyBackdrop (x) { + flagBackdropBg.value = x } - function setScrollable(v) { - const action = - v === true ? "remove" : $layout.isContainer.value !== true ? "add" : ""; + function setScrollable (v) { + const action = v === true + ? 'remove' + : ($layout.isContainer.value !== true ? 'add' : '') - action !== "" && document.body.classList[action]("q-body--drawer-toggle"); + action !== '' && document.body.classList[ action ]('q-body--drawer-toggle') } - function animateMini() { - timerMini !== null && clearTimeout(timerMini); + function animateMini () { + timerMini !== null && clearTimeout(timerMini) if (vm.proxy && vm.proxy.$el) { // need to speed it up and apply it immediately, // even faster than Vue's nextTick! - vm.proxy.$el.classList.add("q-drawer--mini-animate"); + vm.proxy.$el.classList.add('q-drawer--mini-animate') } - flagMiniAnimate.value = true; + flagMiniAnimate.value = true timerMini = setTimeout(() => { - timerMini = null; - flagMiniAnimate.value = false; - vm?.proxy?.$el?.classList.remove("q-drawer--mini-animate"); - }, 150); + timerMini = null + flagMiniAnimate.value = false + vm?.proxy?.$el?.classList.remove('q-drawer--mini-animate') + }, 150) } - function onOpenPan(evt) { + function onOpenPan (evt) { if (showing.value !== false) { // some browsers might capture and trigger this // even if Drawer has just been opened (but animation is still pending) - return; + return } - const width = size.value, - position = between(evt.distance.x, 0, width); + const + width = size.value, + position = between(evt.distance.x, 0, width) if (evt.isFinal === true) { - const opened = position >= Math.min(75, width); + const opened = position >= Math.min(75, width) if (opened === true) { - show(); - } else { - $layout.animate(); - applyBackdrop(0); - applyPosition(stateDirection.value * width); + show() + } + else { + $layout.animate() + applyBackdrop(0) + applyPosition(stateDirection.value * width) } - flagPanning.value = false; - return; + flagPanning.value = false + return } applyPosition( ($q.lang.rtl === true ? rightSide.value !== true : rightSide.value) ? Math.max(width - position, 0) - : Math.min(0, position - width), - ); - applyBackdrop(between(position / width, 0, 1)); + : Math.min(0, position - width) + ) + applyBackdrop( + between(position / width, 0, 1) + ) if (evt.isFirst === true) { - flagPanning.value = true; + flagPanning.value = true } } - function onClosePan(evt) { + function onClosePan (evt) { if (showing.value !== true) { // some browsers might capture and trigger this // even if Drawer has just been closed (but animation is still pending) - return; + return } - const width = size.value, + const + width = size.value, dir = evt.direction === props.side, position = ($q.lang.rtl === true ? dir !== true : dir) ? between(evt.distance.x, 0, width) - : 0; + : 0 if (evt.isFinal === true) { - const opened = Math.abs(position) < Math.min(75, width); + const opened = Math.abs(position) < Math.min(75, width) if (opened === true) { - $layout.animate(); - applyBackdrop(1); - applyPosition(0); - } else { - hide(); + $layout.animate() + applyBackdrop(1) + applyPosition(0) + } + else { + hide() } - flagPanning.value = false; - return; + flagPanning.value = false + return } - applyPosition(stateDirection.value * position); - applyBackdrop(between(1 - position / width, 0, 1)); + applyPosition(stateDirection.value * position) + applyBackdrop(between(1 - position / width, 0, 1)) if (evt.isFirst === true) { - flagPanning.value = true; + flagPanning.value = true } } - function cleanup() { - preventBodyScroll(false); - setScrollable(true); + function cleanup () { + preventBodyScroll(false) + setScrollable(true) } - function updateLayout(prop, val) { - $layout.update(props.side, prop, val); + function updateLayout (prop, val) { + $layout.update(props.side, prop, val) } - function updateLocal(prop, val) { + function updateLocal (prop, val) { if (prop.value !== val) { - prop.value = val; + prop.value = val } } - function updateSizeOnLayout(miniToOverlay, size) { - updateLayout("size", miniToOverlay === true ? props.miniWidth : size); + function updateSizeOnLayout (miniToOverlay, size) { + updateLayout('size', miniToOverlay === true ? props.miniWidth : size) } - $layout.instances[props.side] = instance; - updateSizeOnLayout(props.miniToOverlay, size.value); - updateLayout("space", onLayout.value); - updateLayout("offset", offset.value); + $layout.instances[ props.side ] = instance + updateSizeOnLayout(props.miniToOverlay, size.value) + updateLayout('space', onLayout.value) + updateLayout('offset', offset.value) if ( - props.showIfAbove === true && - props.modelValue !== true && - showing.value === true && - props["onUpdate:modelValue"] !== void 0 + props.showIfAbove === true + && props.modelValue !== true + && showing.value === true + && props[ 'onUpdate:modelValue' ] !== void 0 ) { - emit("update:modelValue", true); + emit('update:modelValue', true) } onMounted(() => { - emit("onLayout", onLayout.value); - emit("miniState", isMini.value); + emit('onLayout', onLayout.value) + emit('miniState', isMini.value) - lastDesktopState = props.showIfAbove === true; + lastDesktopState = props.showIfAbove === true const fn = () => { - const action = showing.value === true ? handleShow : handleHide; - action(false, true); - }; + const action = showing.value === true ? handleShow : handleHide + action(false, true) + } if ($layout.totalWidth.value !== 0) { // make sure that all computed properties // have been updated before calling handleShow/handleHide() - nextTick(fn); - return; + nextTick(fn) + return } layoutTotalWidthWatcher = watch($layout.totalWidth, () => { - layoutTotalWidthWatcher(); - layoutTotalWidthWatcher = void 0; + layoutTotalWidthWatcher() + layoutTotalWidthWatcher = void 0 - if ( - showing.value === false && - props.showIfAbove === true && - belowBreakpoint.value === false - ) { - show(false); - } else { - fn(); + if (showing.value === false && props.showIfAbove === true && belowBreakpoint.value === false) { + show(false) } - }); - }); + else { + fn() + } + }) + }) onBeforeUnmount(() => { - layoutTotalWidthWatcher?.(); + layoutTotalWidthWatcher?.() if (timerMini !== null) { - clearTimeout(timerMini); - timerMini = null; + clearTimeout(timerMini) + timerMini = null } - showing.value === true && cleanup(); + showing.value === true && cleanup() - if ($layout.instances[props.side] === instance) { - $layout.instances[props.side] = void 0; - updateLayout("size", 0); - updateLayout("offset", 0); - updateLayout("space", false); + if ($layout.instances[ props.side ] === instance) { + $layout.instances[ props.side ] = void 0 + updateLayout('size', 0) + updateLayout('offset', 0) + updateLayout('space', false) } - }); + }) return () => { - const child = []; + const child = [] if (belowBreakpoint.value === true) { - props.noSwipeOpen === false && - child.push( - withDirectives( - h("div", { - key: "open", - class: `q-drawer__opener fixed-${props.side}`, - "aria-hidden": "true", - }), - openDirective.value, - ), - ); + props.noSwipeOpen === false && child.push( + withDirectives( + h('div', { + key: 'open', + class: `q-drawer__opener fixed-${ props.side }`, + 'aria-hidden': 'true' + }), + openDirective.value + ) + ) child.push( hDir( - "div", + 'div', { - ref: "backdrop", + ref: 'backdrop', class: backdropClass.value, style: backdropStyle.value, - "aria-hidden": "true", - onClick: hide, + 'aria-hidden': 'true', + onClick: hide }, void 0, - "backdrop", + 'backdrop', props.noSwipeBackdrop !== true && showing.value === true, - () => backdropCloseDirective.value, - ), - ); + () => backdropCloseDirective.value + ) + ) } - const mini = isMini.value === true && slots.mini !== void 0; + const mini = isMini.value === true && slots.mini !== void 0 const sortedAttrs = Object.entries(attrs).reduce( - (acc, [key, value]) => { - if (key.startsWith("aria-label")) { - acc.labelAttibutes[key] = value; - } else { - acc.other[key] = value; + (acc, [ key, value ]) => { + if (key.startsWith('aria-label')) { + acc.labelAttibutes[ key ] = value + } + else { + acc.other[ key ] = value } - return acc; + return acc }, - { labelAttibutes: {}, other: {} }, - ); + { labelAttibutes: {}, other: {} } + ) const content = [ - h( - "div", - { - ...sortedAttrs.other, - key: "" + mini, // required otherwise Vue will not diff correctly - class: [contentClass.value, attrs.class], - }, - mini === true ? slots.mini() : hSlot(slots.default), - ), - ]; + h('div', { + ...sortedAttrs.other, + key: '' + mini, // required otherwise Vue will not diff correctly + class: [ + contentClass.value, + attrs.class + ] + }, mini === true + ? slots.mini() + : hSlot(slots.default) + ) + ] if (props.elevated === true && showing.value === true) { content.push( - h("div", { - class: - "q-layout__shadow absolute-full overflow-hidden no-pointer-events", - }), - ); + h('div', { + class: 'q-layout__shadow absolute-full overflow-hidden no-pointer-events' + }) + ) } child.push( hDir( - "aside", - { - ref: "content", - class: classes.value, - style: style.value, - ...sortedAttrs.labelAttibutes, - }, + 'aside', + { ref: 'content', class: classes.value, style: style.value, ...sortedAttrs.labelAttributes }, content, - "contentclose", + 'contentclose', props.noSwipeClose !== true && belowBreakpoint.value === true, - () => contentCloseDirective.value, - ), - ); + () => contentCloseDirective.value + ) + ) - return h("div", { class: "q-drawer-container" }, child); - }; - }, -}); + return h('div', { class: 'q-drawer-container' }, child) + } + } +})