From 027490cd4f5455f13ead0eec079880813bcf25c0 Mon Sep 17 00:00:00 2001 From: Yuchao Wu Date: Thu, 2 May 2024 00:52:00 +1000 Subject: [PATCH 1/7] fix(VVirtualScrollItem): pass dynamic template ref function for itemRef fixes #19713 --- .../src/components/VVirtualScroll/VVirtualScrollItem.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vuetify/src/components/VVirtualScroll/VVirtualScrollItem.tsx b/packages/vuetify/src/components/VVirtualScroll/VVirtualScrollItem.tsx index 28cb31df9ca..65571002e67 100644 --- a/packages/vuetify/src/components/VVirtualScroll/VVirtualScrollItem.tsx +++ b/packages/vuetify/src/components/VVirtualScroll/VVirtualScrollItem.tsx @@ -45,7 +45,7 @@ export const VVirtualScrollItem = genericComponent props.renderless ? ( <> - { slots.default?.({ itemRef: resizeRef }) } + { slots.default?.({ itemRef: el => resizeRef.value = el }) } ) : (
Date: Thu, 2 May 2024 11:17:44 +1000 Subject: [PATCH 2/7] chore: fix build error --- .../vuetify/src/components/VDataTable/VDataTableVirtual.tsx | 4 ++-- .../src/components/VVirtualScroll/VVirtualScrollItem.tsx | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/vuetify/src/components/VDataTable/VDataTableVirtual.tsx b/packages/vuetify/src/components/VDataTable/VDataTableVirtual.tsx index dc2c3b1941a..a73685ce406 100644 --- a/packages/vuetify/src/components/VDataTable/VDataTableVirtual.tsx +++ b/packages/vuetify/src/components/VDataTable/VDataTableVirtual.tsx @@ -23,7 +23,7 @@ import { computed, shallowRef, toRef } from 'vue' import { convertToUnit, genericComponent, propsFactory, useRender } from '@/util' // Types -import type { Ref } from 'vue' +import type { ComponentPublicInstance } from 'vue' import type { VDataTableSlotProps } from './VDataTable' import type { VDataTableHeadersSlots } from './VDataTableHeaders' import type { VDataTableRowsSlots } from './VDataTableRows' @@ -46,7 +46,7 @@ export type VDataTableVirtualSlots = VDataTableRowsSlots & VDataTableHeade 'body.prepend': VDataTableVirtualSlotProps 'body.append': VDataTableVirtualSlotProps item: { - itemRef: Ref + itemRef: (ref: Element | ComponentPublicInstance | null) => void } } diff --git a/packages/vuetify/src/components/VVirtualScroll/VVirtualScrollItem.tsx b/packages/vuetify/src/components/VVirtualScroll/VVirtualScrollItem.tsx index 65571002e67..7e735e928f5 100644 --- a/packages/vuetify/src/components/VVirtualScroll/VVirtualScrollItem.tsx +++ b/packages/vuetify/src/components/VVirtualScroll/VVirtualScrollItem.tsx @@ -7,7 +7,7 @@ import { watch } from 'vue' import { genericComponent, propsFactory, useRender } from '@/util' // Types -import type { Ref } from 'vue' +import type { ComponentPublicInstance } from 'vue' import type { GenericProps } from '@/util' export const makeVVirtualScrollItemProps = propsFactory({ @@ -22,7 +22,7 @@ export const VVirtualScrollItem = genericComponent + itemRef: (ref: Element | ComponentPublicInstance | null) => void } : never } ) => GenericProps>()({ @@ -45,7 +45,7 @@ export const VVirtualScrollItem = genericComponent props.renderless ? ( <> - { slots.default?.({ itemRef: el => resizeRef.value = el }) } + { slots.default?.({ itemRef: el => resizeRef.value = el as HTMLElement }) } ) : (
Date: Thu, 2 May 2024 12:57:02 +1000 Subject: [PATCH 3/7] chore: make shared FunctionVNodeRef type --- .../vuetify/src/components/VDataTable/VDataTableVirtual.tsx | 5 ++--- .../src/components/VVirtualScroll/VVirtualScrollItem.tsx | 5 ++--- packages/vuetify/src/util/defineComponent.tsx | 2 ++ 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/vuetify/src/components/VDataTable/VDataTableVirtual.tsx b/packages/vuetify/src/components/VDataTable/VDataTableVirtual.tsx index a73685ce406..6def31b0d6c 100644 --- a/packages/vuetify/src/components/VDataTable/VDataTableVirtual.tsx +++ b/packages/vuetify/src/components/VDataTable/VDataTableVirtual.tsx @@ -23,12 +23,11 @@ import { computed, shallowRef, toRef } from 'vue' import { convertToUnit, genericComponent, propsFactory, useRender } from '@/util' // Types -import type { ComponentPublicInstance } from 'vue' import type { VDataTableSlotProps } from './VDataTable' import type { VDataTableHeadersSlots } from './VDataTableHeaders' import type { VDataTableRowsSlots } from './VDataTableRows' import type { CellProps, RowProps } from '@/components/VDataTable/types' -import type { GenericProps, SelectItemKey } from '@/util' +import type { FunctionVNodeRef, GenericProps, SelectItemKey } from '@/util' type VDataTableVirtualSlotProps = Omit< VDataTableSlotProps, @@ -46,7 +45,7 @@ export type VDataTableVirtualSlots = VDataTableRowsSlots & VDataTableHeade 'body.prepend': VDataTableVirtualSlotProps 'body.append': VDataTableVirtualSlotProps item: { - itemRef: (ref: Element | ComponentPublicInstance | null) => void + itemRef: FunctionVNodeRef } } diff --git a/packages/vuetify/src/components/VVirtualScroll/VVirtualScrollItem.tsx b/packages/vuetify/src/components/VVirtualScroll/VVirtualScrollItem.tsx index 7e735e928f5..59e85e7e24e 100644 --- a/packages/vuetify/src/components/VVirtualScroll/VVirtualScrollItem.tsx +++ b/packages/vuetify/src/components/VVirtualScroll/VVirtualScrollItem.tsx @@ -7,8 +7,7 @@ import { watch } from 'vue' import { genericComponent, propsFactory, useRender } from '@/util' // Types -import type { ComponentPublicInstance } from 'vue' -import type { GenericProps } from '@/util' +import type { FunctionVNodeRef, GenericProps } from '@/util' export const makeVVirtualScrollItemProps = propsFactory({ renderless: Boolean, @@ -22,7 +21,7 @@ export const VVirtualScrollItem = genericComponent void + itemRef: FunctionVNodeRef } : never } ) => GenericProps>()({ diff --git a/packages/vuetify/src/util/defineComponent.tsx b/packages/vuetify/src/util/defineComponent.tsx index fee604b39f4..f8477722b37 100644 --- a/packages/vuetify/src/util/defineComponent.tsx +++ b/packages/vuetify/src/util/defineComponent.tsx @@ -327,3 +327,5 @@ export type ComponentInstance = T extends { new (): ComponentPublicInstance = E extends Record ? { [K in keyof E]: (...args: E[K]) => any; } : E; + +export type FunctionVNodeRef = (ref: Element | ComponentPublicInstance | null, refs: Record) => void From ad9d6808bd982027826eaecfad49dc8e72d903f3 Mon Sep 17 00:00:00 2001 From: Yuchao Wu Date: Sat, 4 May 2024 17:52:24 +1000 Subject: [PATCH 4/7] fix(VOverlay): assign function ref to activator template ref --- packages/vuetify/src/components/VOverlay/VOverlay.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vuetify/src/components/VOverlay/VOverlay.tsx b/packages/vuetify/src/components/VOverlay/VOverlay.tsx index 1f8f910efcf..9c627a809c2 100644 --- a/packages/vuetify/src/components/VOverlay/VOverlay.tsx +++ b/packages/vuetify/src/components/VOverlay/VOverlay.tsx @@ -276,7 +276,7 @@ export const VOverlay = genericComponent()({ isActive: isActive.value, targetRef, props: mergeProps({ - ref: activatorRef, + ref: el => activatorRef.value = el as HTMLElement, }, activatorEvents.value, props.activatorProps), })} From 04e9b02c9e382265712f931d50b27c524e271efc Mon Sep 17 00:00:00 2001 From: Yuchao Wu Date: Sat, 4 May 2024 20:29:45 +1000 Subject: [PATCH 5/7] fix(VDatePickerYear): assign function ref to year slot ref --- .../src/components/VDatePicker/VDatePickerYears.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/vuetify/src/components/VDatePicker/VDatePickerYears.tsx b/packages/vuetify/src/components/VDatePicker/VDatePickerYears.tsx index d596f29ab92..05feb1b5c10 100644 --- a/packages/vuetify/src/components/VDatePicker/VDatePickerYears.tsx +++ b/packages/vuetify/src/components/VDatePicker/VDatePickerYears.tsx @@ -13,7 +13,8 @@ import { computed, nextTick, onMounted, ref, watchEffect } from 'vue' import { convertToUnit, createRange, genericComponent, propsFactory, useRender } from '@/util' // Types -import type { PropType } from 'vue' +import type { ComponentPublicInstance, PropType } from 'vue' +import type { FunctionVNodeRef } from '@/util' // Types export type VDatePickerYearsSlots = { @@ -87,7 +88,10 @@ export const VDatePickerYears = genericComponent()({ model.value = model.value ?? adapter.getYear(adapter.date()) }) - const yearRef = ref() + const yearRef = ref() + + const yearRefFunction: FunctionVNodeRef = el => yearRef.value = el as ComponentPublicInstance + onMounted(async () => { await nextTick() yearRef.value?.$el.scrollIntoView({ block: 'center' }) @@ -103,7 +107,7 @@ export const VDatePickerYears = genericComponent()({
{ years.value.map((year, i) => { const btnProps = { - ref: model.value === year.value ? yearRef : undefined, + ref: model.value === year.value ? yearRefFunction : undefined, active: model.value === year.value, color: model.value === year.value ? props.color : undefined, rounded: true, From d60255b6a72e84164075d2a556200ad34538762b Mon Sep 17 00:00:00 2001 From: Kael Date: Tue, 7 May 2024 17:21:18 +1000 Subject: [PATCH 6/7] create reusable function --- packages/api-generator/src/types.ts | 1 + .../VDataTable/VDataTableVirtual.tsx | 4 ++-- .../VDatePicker/VDatePickerYears.tsx | 15 +++++------- .../src/components/VOverlay/VOverlay.tsx | 10 ++++---- .../src/components/VOverlay/useActivator.tsx | 10 ++++---- .../VVirtualScroll/VVirtualScrollItem.tsx | 6 ++--- .../vuetify/src/composables/resizeObserver.ts | 13 ++++++----- packages/vuetify/src/util/defineComponent.tsx | 2 -- packages/vuetify/src/util/helpers.ts | 23 +++++++++++++++++++ 9 files changed, 51 insertions(+), 33 deletions(-) diff --git a/packages/api-generator/src/types.ts b/packages/api-generator/src/types.ts index 76c410b852a..818d8dc273f 100644 --- a/packages/api-generator/src/types.ts +++ b/packages/api-generator/src/types.ts @@ -325,6 +325,7 @@ const allowedRefs = [ 'SelectStrategyFn', 'SortItem', 'SubmitEventPromise', + 'TemplateRef', 'TouchHandlers', 'ValidationRule', ] diff --git a/packages/vuetify/src/components/VDataTable/VDataTableVirtual.tsx b/packages/vuetify/src/components/VDataTable/VDataTableVirtual.tsx index 6def31b0d6c..bee0fb23013 100644 --- a/packages/vuetify/src/components/VDataTable/VDataTableVirtual.tsx +++ b/packages/vuetify/src/components/VDataTable/VDataTableVirtual.tsx @@ -27,7 +27,7 @@ import type { VDataTableSlotProps } from './VDataTable' import type { VDataTableHeadersSlots } from './VDataTableHeaders' import type { VDataTableRowsSlots } from './VDataTableRows' import type { CellProps, RowProps } from '@/components/VDataTable/types' -import type { FunctionVNodeRef, GenericProps, SelectItemKey } from '@/util' +import type { GenericProps, SelectItemKey, TemplateRef } from '@/util' type VDataTableVirtualSlotProps = Omit< VDataTableSlotProps, @@ -45,7 +45,7 @@ export type VDataTableVirtualSlots = VDataTableRowsSlots & VDataTableHeade 'body.prepend': VDataTableVirtualSlotProps 'body.append': VDataTableVirtualSlotProps item: { - itemRef: FunctionVNodeRef + itemRef: TemplateRef } } diff --git a/packages/vuetify/src/components/VDatePicker/VDatePickerYears.tsx b/packages/vuetify/src/components/VDatePicker/VDatePickerYears.tsx index 05feb1b5c10..4910d073cd2 100644 --- a/packages/vuetify/src/components/VDatePicker/VDatePickerYears.tsx +++ b/packages/vuetify/src/components/VDatePicker/VDatePickerYears.tsx @@ -9,12 +9,11 @@ import { useDate } from '@/composables/date' import { useProxiedModel } from '@/composables/proxiedModel' // Utilities -import { computed, nextTick, onMounted, ref, watchEffect } from 'vue' -import { convertToUnit, createRange, genericComponent, propsFactory, useRender } from '@/util' +import { computed, nextTick, onMounted, watchEffect } from 'vue' +import { convertToUnit, createRange, genericComponent, propsFactory, templateRef, useRender } from '@/util' // Types -import type { ComponentPublicInstance, PropType } from 'vue' -import type { FunctionVNodeRef } from '@/util' +import type { PropType } from 'vue' // Types export type VDatePickerYearsSlots = { @@ -88,13 +87,11 @@ export const VDatePickerYears = genericComponent()({ model.value = model.value ?? adapter.getYear(adapter.date()) }) - const yearRef = ref() - - const yearRefFunction: FunctionVNodeRef = el => yearRef.value = el as ComponentPublicInstance + const yearRef = templateRef() onMounted(async () => { await nextTick() - yearRef.value?.$el.scrollIntoView({ block: 'center' }) + yearRef.el?.scrollIntoView({ block: 'center' }) }) useRender(() => ( @@ -107,7 +104,7 @@ export const VDatePickerYears = genericComponent()({
{ years.value.map((year, i) => { const btnProps = { - ref: model.value === year.value ? yearRefFunction : undefined, + ref: model.value === year.value ? yearRef : undefined, active: model.value === year.value, color: model.value === year.value ? props.color : undefined, rounded: true, diff --git a/packages/vuetify/src/components/VOverlay/VOverlay.tsx b/packages/vuetify/src/components/VOverlay/VOverlay.tsx index 0ba65d37e77..75da73ed33b 100644 --- a/packages/vuetify/src/components/VOverlay/VOverlay.tsx +++ b/packages/vuetify/src/components/VOverlay/VOverlay.tsx @@ -46,11 +46,9 @@ import { } from '@/util' // Types -import type { - ComponentPublicInstance, PropType, - Ref, -} from 'vue' +import type { PropType, Ref } from 'vue' import type { BackgroundColorData } from '@/composables/color' +import type { TemplateRef } from '@/util' interface ScrimProps { [key: string]: unknown @@ -77,7 +75,7 @@ function Scrim (props: ScrimProps) { export type OverlaySlots = { default: { isActive: Ref } - activator: { isActive: boolean, props: Record, targetRef: Ref | HTMLElement> } + activator: { isActive: boolean, props: Record, targetRef: TemplateRef } } export const makeVOverlayProps = propsFactory({ @@ -273,7 +271,7 @@ export const VOverlay = genericComponent()({ isActive: isActive.value, targetRef, props: mergeProps({ - ref: el => activatorRef.value = el as HTMLElement, + ref: activatorRef, }, activatorEvents.value, props.activatorProps), })} diff --git a/packages/vuetify/src/components/VOverlay/useActivator.tsx b/packages/vuetify/src/components/VOverlay/useActivator.tsx index b1555ee3c48..0bf11e5ac86 100644 --- a/packages/vuetify/src/components/VOverlay/useActivator.tsx +++ b/packages/vuetify/src/components/VOverlay/useActivator.tsx @@ -22,7 +22,7 @@ import { IN_BROWSER, matchesSelector, propsFactory, - refElement, + templateRef, unbindProps, } from '@/util' @@ -228,19 +228,19 @@ export function useActivator ( } }, { flush: 'post' }) - const activatorRef = ref() + const activatorRef = templateRef() watchEffect(() => { if (!activatorRef.value) return nextTick(() => { - activatorEl.value = refElement(activatorRef.value) + activatorEl.value = activatorRef.el }) }) - const targetRef = ref | HTMLElement>() + const targetRef = templateRef() const target = computed(() => { if (props.target === 'cursor' && cursorTarget.value) return cursorTarget.value - if (targetRef.value) return refElement(targetRef.value) + if (targetRef.value) return targetRef.el return getTarget(props.target, vm) || activatorEl.value }) const targetEl = computed(() => { diff --git a/packages/vuetify/src/components/VVirtualScroll/VVirtualScrollItem.tsx b/packages/vuetify/src/components/VVirtualScroll/VVirtualScrollItem.tsx index 59e85e7e24e..a7327248cf0 100644 --- a/packages/vuetify/src/components/VVirtualScroll/VVirtualScrollItem.tsx +++ b/packages/vuetify/src/components/VVirtualScroll/VVirtualScrollItem.tsx @@ -7,7 +7,7 @@ import { watch } from 'vue' import { genericComponent, propsFactory, useRender } from '@/util' // Types -import type { FunctionVNodeRef, GenericProps } from '@/util' +import type { GenericProps, TemplateRef } from '@/util' export const makeVVirtualScrollItemProps = propsFactory({ renderless: Boolean, @@ -21,7 +21,7 @@ export const VVirtualScrollItem = genericComponent GenericProps>()({ @@ -44,7 +44,7 @@ export const VVirtualScrollItem = genericComponent props.renderless ? ( <> - { slots.default?.({ itemRef: el => resizeRef.value = el as HTMLElement }) } + { slots.default?.({ itemRef: resizeRef }) } ) : (
+ resizeRef: TemplateRef contentRect: DeepReadonly> } export function useResizeObserver (callback?: ResizeObserverCallback, box: 'content' | 'border' = 'content'): ResizeState { - const resizeRef = ref() + const resizeRef = templateRef() const contentRect = ref() if (IN_BROWSER) { @@ -32,13 +33,13 @@ export function useResizeObserver (callback?: ResizeObserverCallback, box: 'cont observer.disconnect() }) - watch(resizeRef, (newValue, oldValue) => { + watch(() => resizeRef.el, (newValue, oldValue) => { if (oldValue) { - observer.unobserve(refElement(oldValue) as Element) + observer.unobserve(oldValue) contentRect.value = undefined } - if (newValue) observer.observe(refElement(newValue) as Element) + if (newValue) observer.observe(newValue) }, { flush: 'post', }) diff --git a/packages/vuetify/src/util/defineComponent.tsx b/packages/vuetify/src/util/defineComponent.tsx index f8477722b37..fee604b39f4 100644 --- a/packages/vuetify/src/util/defineComponent.tsx +++ b/packages/vuetify/src/util/defineComponent.tsx @@ -327,5 +327,3 @@ export type ComponentInstance = T extends { new (): ComponentPublicInstance = E extends Record ? { [K in keyof E]: (...args: E[K]) => any; } : E; - -export type FunctionVNodeRef = (ref: Element | ComponentPublicInstance | null, refs: Record) => void diff --git a/packages/vuetify/src/util/helpers.ts b/packages/vuetify/src/util/helpers.ts index cb60134d49a..6343d5e23ba 100644 --- a/packages/vuetify/src/util/helpers.ts +++ b/packages/vuetify/src/util/helpers.ts @@ -735,3 +735,26 @@ export function isClickInsideElement (event: MouseEvent, targetDiv: HTMLElement) return mouseX >= divLeft && mouseX <= divRight && mouseY >= divTop && mouseY <= divBottom } + +export type TemplateRef = { + (target: Element | ComponentPublicInstance | null): void + value: HTMLElement | ComponentPublicInstance | null | undefined + readonly el: HTMLElement | undefined +} +export function templateRef () { + const el = shallowRef() + const fn = (target: HTMLElement | ComponentPublicInstance | null) => { + el.value = target + } + Object.defineProperty(fn, 'value', { + enumerable: true, + get: () => el.value, + set: val => el.value = val, + }) + Object.defineProperty(fn, 'el', { + enumerable: true, + get: () => refElement(el.value), + }) + + return el as any as TemplateRef +} From 6cf976b984944a764ad700f5f6437d956c95ee4f Mon Sep 17 00:00:00 2001 From: Kael Date: Tue, 7 May 2024 21:53:46 +1000 Subject: [PATCH 7/7] update useResizeObserver downstream --- .../VColorPicker/VColorPickerCanvas.tsx | 2 +- .../components/VSlideGroup/VSlideGroup.tsx | 50 +++++++++---------- packages/vuetify/src/util/helpers.ts | 2 +- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/packages/vuetify/src/components/VColorPicker/VColorPickerCanvas.tsx b/packages/vuetify/src/components/VColorPicker/VColorPickerCanvas.tsx index 5b76f1fb410..fa3f6e32a04 100644 --- a/packages/vuetify/src/components/VColorPicker/VColorPickerCanvas.tsx +++ b/packages/vuetify/src/components/VColorPicker/VColorPickerCanvas.tsx @@ -80,7 +80,7 @@ export const VColorPickerCanvas = defineComponent({ }) const { resizeRef } = useResizeObserver(entries => { - if (!resizeRef.value?.offsetParent) return + if (!resizeRef.el?.offsetParent) return const { width, height } = entries[0].contentRect diff --git a/packages/vuetify/src/components/VSlideGroup/VSlideGroup.tsx b/packages/vuetify/src/components/VSlideGroup/VSlideGroup.tsx index 0fa926635c9..dee0b516718 100644 --- a/packages/vuetify/src/components/VSlideGroup/VSlideGroup.tsx +++ b/packages/vuetify/src/components/VSlideGroup/VSlideGroup.tsx @@ -116,7 +116,7 @@ export const VSlideGroup = genericComponent( const goTo = useGoTo() const goToOptions = computed>(() => { return { - container: containerRef.value, + container: containerRef.el, duration: 200, easing: 'easeOutQuart', } @@ -148,9 +148,9 @@ export const VSlideGroup = genericComponent( isOverflowing.value = containerSize.value + 1 < contentSize.value } - if (firstSelectedIndex.value >= 0 && contentRef.value) { + if (firstSelectedIndex.value >= 0 && contentRef.el) { // TODO: Is this too naive? Should we store element references in group composable? - const selectedElement = contentRef.value.children[lastSelectedIndex.value] as HTMLElement + const selectedElement = contentRef.el.children[lastSelectedIndex.value] as HTMLElement scrollToChildren(selectedElement, props.centerActive) } @@ -165,13 +165,13 @@ export const VSlideGroup = genericComponent( if (center) { target = calculateCenteredTarget({ - containerElement: containerRef.value!, + containerElement: containerRef.el!, isHorizontal: isHorizontal.value, selectedElement: children, }) } else { target = calculateUpdatedTarget({ - containerElement: containerRef.value!, + containerElement: containerRef.el!, isHorizontal: isHorizontal.value, isRtl: isRtl.value, selectedElement: children, @@ -182,11 +182,11 @@ export const VSlideGroup = genericComponent( } function scrollToPosition (newPosition: number) { - if (!IN_BROWSER || !containerRef.value) return + if (!IN_BROWSER || !containerRef.el) return - const offsetSize = getOffsetSize(isHorizontal.value, containerRef.value) - const scrollPosition = getScrollPosition(isHorizontal.value, isRtl.value, containerRef.value) - const scrollSize = getScrollSize(isHorizontal.value, containerRef.value) + const offsetSize = getOffsetSize(isHorizontal.value, containerRef.el) + const scrollPosition = getScrollPosition(isHorizontal.value, isRtl.value, containerRef.el) + const scrollSize = getScrollSize(isHorizontal.value, containerRef.el) if ( scrollSize <= offsetSize || @@ -194,8 +194,8 @@ export const VSlideGroup = genericComponent( Math.abs(newPosition - scrollPosition) < 16 ) return - if (isHorizontal.value && isRtl.value && containerRef.value) { - const { scrollWidth, offsetWidth: containerWidth } = containerRef.value! + if (isHorizontal.value && isRtl.value && containerRef.el) { + const { scrollWidth, offsetWidth: containerWidth } = containerRef.el! newPosition = (scrollWidth - containerWidth) - newPosition } @@ -216,12 +216,12 @@ export const VSlideGroup = genericComponent( function onFocusin (e: FocusEvent) { isFocused.value = true - if (!isOverflowing.value || !contentRef.value) return + if (!isOverflowing.value || !contentRef.el) return // Focused element is likely to be the root of an item, so a // breadth-first search will probably find it in the first iteration for (const el of e.composedPath()) { - for (const item of contentRef.value.children) { + for (const item of contentRef.el.children) { if (item === el) { scrollToChildren(item as HTMLElement) return @@ -240,7 +240,7 @@ export const VSlideGroup = genericComponent( if ( !ignoreFocusEvent && !isFocused.value && - !(e.relatedTarget && contentRef.value?.contains(e.relatedTarget as Node)) + !(e.relatedTarget && contentRef.el?.contains(e.relatedTarget as Node)) ) focus() ignoreFocusEvent = false @@ -251,7 +251,7 @@ export const VSlideGroup = genericComponent( } function onKeydown (e: KeyboardEvent) { - if (!contentRef.value) return + if (!contentRef.el) return function toFocus (location: Parameters[0]) { e.preventDefault() @@ -280,25 +280,25 @@ export const VSlideGroup = genericComponent( } function focus (location?: 'next' | 'prev' | 'first' | 'last') { - if (!contentRef.value) return + if (!contentRef.el) return let el: HTMLElement | undefined if (!location) { - const focusable = focusableChildren(contentRef.value) + const focusable = focusableChildren(contentRef.el) el = focusable[0] } else if (location === 'next') { - el = contentRef.value.querySelector(':focus')?.nextElementSibling as HTMLElement | undefined + el = contentRef.el.querySelector(':focus')?.nextElementSibling as HTMLElement | undefined if (!el) return focus('first') } else if (location === 'prev') { - el = contentRef.value.querySelector(':focus')?.previousElementSibling as HTMLElement | undefined + el = contentRef.el.querySelector(':focus')?.previousElementSibling as HTMLElement | undefined if (!el) return focus('last') } else if (location === 'first') { - el = (contentRef.value.firstElementChild as HTMLElement) + el = (contentRef.el.firstElementChild as HTMLElement) } else if (location === 'last') { - el = (contentRef.value.lastElementChild as HTMLElement) + el = (contentRef.el.lastElementChild as HTMLElement) } if (el) { @@ -314,8 +314,8 @@ export const VSlideGroup = genericComponent( let newPosition = scrollOffset.value + offsetStep // TODO: improve it - if (isHorizontal.value && isRtl.value && containerRef.value) { - const { scrollWidth, offsetWidth: containerWidth } = containerRef.value! + if (isHorizontal.value && isRtl.value && containerRef.el) { + const { scrollWidth, offsetWidth: containerWidth } = containerRef.el! newPosition += scrollWidth - containerWidth } @@ -366,8 +366,8 @@ export const VSlideGroup = genericComponent( const hasNext = computed(() => { if (!containerRef.value) return false - const scrollSize = getScrollSize(isHorizontal.value, containerRef.value) - const clientSize = getClientSize(isHorizontal.value, containerRef.value) + const scrollSize = getScrollSize(isHorizontal.value, containerRef.el) + const clientSize = getClientSize(isHorizontal.value, containerRef.el) const scrollSizeMax = scrollSize - clientSize diff --git a/packages/vuetify/src/util/helpers.ts b/packages/vuetify/src/util/helpers.ts index 6343d5e23ba..cfff79aa004 100644 --- a/packages/vuetify/src/util/helpers.ts +++ b/packages/vuetify/src/util/helpers.ts @@ -756,5 +756,5 @@ export function templateRef () { get: () => refElement(el.value), }) - return el as any as TemplateRef + return fn as TemplateRef }