From e5984ea029b3fa4249e8c7a405aa2f69ed248215 Mon Sep 17 00:00:00 2001 From: inokawa <48897392+inokawa@users.noreply.github.com> Date: Wed, 26 Jun 2024 00:30:16 +0900 Subject: [PATCH] Add as and item props to Vue Virtualizer --- src/vue/ListItem.tsx | 16 +++++++++++++--- src/vue/Virtualizer.tsx | 18 ++++++++++++++++-- src/vue/WindowVirtualizer.tsx | 21 ++++++++++++++++++--- 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/vue/ListItem.tsx b/src/vue/ListItem.tsx index 5f04393c8..0de28c4ed 100644 --- a/src/vue/ListItem.tsx +++ b/src/vue/ListItem.tsx @@ -1,5 +1,13 @@ /** @jsxImportSource vue */ -import { ref, defineComponent, watch, StyleValue, PropType, VNode } from "vue"; +import { + ref, + defineComponent, + watch, + StyleValue, + PropType, + VNode, + NativeElements, +} from "vue"; import { ItemResizeObserver } from "../core/resizer"; import { isRTLDocument } from "../core/environment"; @@ -18,6 +26,7 @@ export const ListItem = /*#__PURE__*/ defineComponent({ _hide: { type: Boolean }, _isHorizontal: { type: Boolean }, _isSSR: { type: Boolean }, + _as: { type: String as PropType, required: true }, }, setup(props) { const elementRef = ref(); @@ -40,6 +49,7 @@ export const ListItem = /*#__PURE__*/ defineComponent({ _hide: hide, _isHorizontal: isHorizontal, _isSSR: isSSR, + _as: Element, } = props; const style: StyleValue = { @@ -57,9 +67,9 @@ export const ListItem = /*#__PURE__*/ defineComponent({ } return ( -
+ {children} -
+ ); }; }, diff --git a/src/vue/Virtualizer.tsx b/src/vue/Virtualizer.tsx index c44ad42c7..d31d90473 100644 --- a/src/vue/Virtualizer.tsx +++ b/src/vue/Virtualizer.tsx @@ -11,6 +11,7 @@ import { ComponentOptionsWithObjectProps, ComponentObjectPropsOptions, PropType, + NativeElements, } from "vue"; import { SCROLL_IDLE, @@ -103,6 +104,16 @@ const props = { * Reference to the scrollable element. The default will get the parent element of virtualizer. */ scrollRef: Object as PropType, + /** + * Component or element type for container element. + * @defaultValue "div" + */ + as: { type: String as PropType, default: "div" }, + /** + * Component or element type for item element. + * @defaultValue "div" + */ + item: { type: String as PropType, default: "div" }, } satisfies ComponentObjectPropsOptions; export const Virtualizer = /*#__PURE__*/ defineComponent({ @@ -215,6 +226,8 @@ export const Virtualizer = /*#__PURE__*/ defineComponent({ return () => { rerender.value; + const Element = props.as; + const ItemElement = props.item; const count = props.data.length; const [startIndex, endIndex] = store._getRange(); @@ -244,12 +257,13 @@ export const Virtualizer = /*#__PURE__*/ defineComponent({ _children={e} _isHorizontal={isHorizontal} _isSSR={isSSR} + _as={ItemElement} /> ); } return ( -
{items} -
+ ); }; }, diff --git a/src/vue/WindowVirtualizer.tsx b/src/vue/WindowVirtualizer.tsx index fc11e7466..a8b10f7da 100644 --- a/src/vue/WindowVirtualizer.tsx +++ b/src/vue/WindowVirtualizer.tsx @@ -10,6 +10,8 @@ import { SlotsType, ComponentOptionsWithObjectProps, ComponentObjectPropsOptions, + PropType, + NativeElements, } from "vue"; import { SCROLL_IDLE, @@ -49,6 +51,16 @@ const props = { * If true, rendered as a horizontally scrollable list. Otherwise rendered as a vertically scrollable list. */ horizontal: Boolean, + /** + * Component or element type for container element. + * @defaultValue "div" + */ + as: { type: String as PropType, default: "div" }, + /** + * Component or element type for item element. + * @defaultValue "div" + */ + item: { type: String as PropType, default: "div" }, } satisfies ComponentObjectPropsOptions; export const WindowVirtualizer = /*#__PURE__*/ defineComponent({ @@ -121,7 +133,9 @@ export const WindowVirtualizer = /*#__PURE__*/ defineComponent({ return () => { rerender.value; - + + const Element = props.as; + const ItemElement = props.item; const count = props.data.length; const [startIndex, endIndex] = store._getRange(); @@ -150,12 +164,13 @@ export const WindowVirtualizer = /*#__PURE__*/ defineComponent({ _hide={store._isUnmeasuredItem(i)} _children={e} _isHorizontal={isHorizontal} + _as={ItemElement} /> ); } return ( -
{items} -
+ ); }; },