@v-c/virtual-list 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,127 +0,0 @@
1
- <script setup lang="ts">
2
- import VirtualList from '../src'
3
-
4
- interface Item {
5
- id: number
6
- height: number
7
- }
8
-
9
- const data: Item[] = []
10
- for (let i = 0; i < 100; i += 1) {
11
- data.push({
12
- id: i,
13
- height: 30 + (i % 2 ? 20 : 0),
14
- })
15
- }
16
- </script>
17
-
18
- <template>
19
- <div>
20
- <h2>Not Data</h2>
21
- <VirtualList
22
- :data="null"
23
- :item-height="30"
24
- :height="100"
25
- item-key="id"
26
- :style="{
27
- border: '1px solid red',
28
- boxSizing: 'border-box',
29
- }"
30
- >
31
- <template #default="{ item }">
32
- <span
33
- :style="{
34
- border: '1px solid gray',
35
- padding: '0 16px',
36
- height: `${item.height}px`,
37
- lineHeight: '30px',
38
- boxSizing: 'border-box',
39
- display: 'inline-block',
40
- }"
41
- >
42
- {{ item.id }}
43
- </span>
44
- </template>
45
- </VirtualList>
46
-
47
- <h2>Less Count</h2>
48
- <VirtualList
49
- :data="data.slice(0, 1)"
50
- :item-height="30"
51
- :height="100"
52
- item-key="id"
53
- :style="{
54
- border: '1px solid red',
55
- boxSizing: 'border-box',
56
- }"
57
- >
58
- <template #default="{ item }">
59
- <span
60
- :style="{
61
- border: '1px solid gray',
62
- padding: '0 16px',
63
- height: `${item.height}px`,
64
- lineHeight: '30px',
65
- boxSizing: 'border-box',
66
- display: 'inline-block',
67
- }"
68
- >
69
- {{ item.id }}
70
- </span>
71
- </template>
72
- </VirtualList>
73
-
74
- <h2>Less Item Height</h2>
75
- <VirtualList
76
- :data="data.slice(0, 10)"
77
- :item-height="1"
78
- :height="100"
79
- item-key="id"
80
- :style="{
81
- border: '1px solid red',
82
- boxSizing: 'border-box',
83
- }"
84
- >
85
- <template #default="{ item }">
86
- <span
87
- :style="{
88
- border: '1px solid gray',
89
- padding: '0 16px',
90
- height: `${item.height}px`,
91
- lineHeight: '30px',
92
- boxSizing: 'border-box',
93
- display: 'inline-block',
94
- }"
95
- >
96
- {{ item.id }}
97
- </span>
98
- </template>
99
- </VirtualList>
100
-
101
- <h2>Without Height</h2>
102
- <VirtualList
103
- :data="data"
104
- :item-height="30"
105
- item-key="id"
106
- :style="{
107
- border: '1px solid red',
108
- boxSizing: 'border-box',
109
- }"
110
- >
111
- <template #default="{ item }">
112
- <span
113
- :style="{
114
- border: '1px solid gray',
115
- padding: '0 16px',
116
- height: `${item.height}px`,
117
- lineHeight: '30px',
118
- boxSizing: 'border-box',
119
- display: 'inline-block',
120
- }"
121
- >
122
- {{ item.id }}
123
- </span>
124
- </template>
125
- </VirtualList>
126
- </div>
127
- </template>
package/docs/switch.vue DELETED
@@ -1,102 +0,0 @@
1
- <script setup lang="ts">
2
- import type { ListRef } from '../src'
3
- import { ref } from 'vue'
4
- import VirtualList from '../src'
5
-
6
- interface Item {
7
- id: number
8
- }
9
-
10
- function getData(count: number): Item[] {
11
- const result: Item[] = []
12
- for (let i = 0; i < count; i += 1) {
13
- result.push({ id: i })
14
- }
15
- return result
16
- }
17
-
18
- const height = ref(200)
19
- const data = ref(getData(20))
20
- const fullHeight = ref(true)
21
- const listRef = ref<ListRef>()
22
-
23
- function setDataCount(count: number) {
24
- data.value = getData(count)
25
- }
26
-
27
- function showScrollbar() {
28
- listRef.value?.scrollTo(null)
29
- }
30
- </script>
31
-
32
- <template>
33
- <div style="height: 150vh">
34
- <h2>Switch</h2>
35
- <div style="margin-bottom: 16px">
36
- <span>
37
- Data:
38
- <label><input type="radio" name="data" value="0" @change="() => setDataCount(0)"> 0</label>
39
- <label><input type="radio" name="data" value="2" @change="() => setDataCount(2)"> 2</label>
40
- <label><input type="radio" name="data" value="20" checked @change="() => setDataCount(20)"> 20</label>
41
- <label><input type="radio" name="data" value="100" @change="() => setDataCount(100)"> 100</label>
42
- <label><input type="radio" name="data" value="200" @change="() => setDataCount(200)"> 200</label>
43
- <label><input type="radio" name="data" value="1000" @change="() => setDataCount(1000)"> 1000</label>
44
- <button type="button" @click="showScrollbar">
45
- Show scrollbar
46
- </button>
47
- </span>
48
- <br>
49
- <span>
50
- Height:
51
- <label><input type="radio" name="height" value="0" @change="() => height = 0"> 0</label>
52
- <label><input type="radio" name="height" value="100" @change="() => height = 100"> 100</label>
53
- <label><input type="radio" name="height" value="200" checked @change="() => height = 200"> 200</label>
54
- </span>
55
- <span style="margin-left: 16px">
56
- <button @click="fullHeight = !fullHeight">
57
- Full Height: {{ fullHeight }}
58
- </button>
59
- </span>
60
- </div>
61
-
62
- <VirtualList
63
- ref="listRef"
64
- :data="data"
65
- :height="height"
66
- :item-height="10"
67
- item-key="id"
68
- :full-height="fullHeight"
69
- :style="{
70
- border: '1px solid red',
71
- boxSizing: 'border-box',
72
- }"
73
- >
74
- <template #default="{ item }">
75
- <span
76
- :style="{
77
- border: '1px solid gray',
78
- padding: '0 16px',
79
- height: '30px',
80
- lineHeight: '30px',
81
- boxSizing: 'border-box',
82
- display: 'inline-block',
83
- }"
84
- >
85
- {{ item.id }}
86
- </span>
87
- </template>
88
- </VirtualList>
89
- </div>
90
- </template>
91
-
92
- <style scoped>
93
- label {
94
- margin-left: 8px;
95
- }
96
-
97
- button {
98
- margin-left: 8px;
99
- padding: 4px 8px;
100
- cursor: pointer;
101
- }
102
- </style>
@@ -1,35 +0,0 @@
1
- <script setup lang="ts">
2
- import Animate from './animate.vue'
3
- import Basic from './basic.vue'
4
- import Height from './height.vue'
5
- import Nest from './nest.vue'
6
- import NoVirtual from './no-virtual.vue'
7
- import Switch from './switch.vue'
8
- </script>
9
-
10
- <template>
11
- <Story title="Virtual List">
12
- <Variant title="Basic">
13
- <Basic />
14
- </Variant>
15
- <Variant title="Animate">
16
- <Animate />
17
- </Variant>
18
-
19
- <Variant title="Dynamic Height">
20
- <Height />
21
- </Variant>
22
-
23
- <Variant title="No Virtual">
24
- <NoVirtual />
25
- </Variant>
26
-
27
- <Variant title="Switch Data">
28
- <Switch />
29
- </Variant>
30
-
31
- <Variant title="Nested">
32
- <Nest />
33
- </Variant>
34
- </Story>
35
- </template>
package/src/Filler.tsx DELETED
@@ -1,73 +0,0 @@
1
- import type { CSSProperties, PropType, VNode } from 'vue'
2
- import ResizeObserver from '@v-c/resize-observer'
3
- import { defineComponent } from 'vue'
4
-
5
- export interface InnerProps {
6
- role?: string
7
- id?: string
8
- }
9
-
10
- export default defineComponent({
11
- name: 'Filler',
12
- props: {
13
- prefixCls: String,
14
- /** Virtual filler height. Should be `count * itemMinHeight` */
15
- height: Number,
16
- /** Set offset of visible items. Should be the top of start item position */
17
- offsetY: Number,
18
- offsetX: Number,
19
- scrollWidth: Number,
20
- onInnerResize: Function as PropType<() => void>,
21
- innerProps: Object as PropType<InnerProps>,
22
- rtl: Boolean,
23
- extra: Object as PropType<VNode>,
24
- },
25
- setup(props, { slots }) {
26
- return () => {
27
- let outerStyle: CSSProperties = {}
28
- let innerStyle: CSSProperties = {
29
- display: 'flex',
30
- flexDirection: 'column',
31
- }
32
-
33
- if (props.offsetY !== undefined) {
34
- outerStyle = {
35
- height: `${props.height}px`,
36
- position: 'relative',
37
- overflow: 'hidden',
38
- }
39
-
40
- innerStyle = {
41
- ...innerStyle,
42
- transform: `translateY(${props.offsetY}px)`,
43
- [props.rtl ? 'marginRight' : 'marginLeft']: `-${props.offsetX || 0}px`,
44
- position: 'absolute',
45
- left: 0,
46
- right: 0,
47
- top: 0,
48
- }
49
- }
50
-
51
- return (
52
- <div style={outerStyle}>
53
- <ResizeObserver
54
- onResize={({ offsetHeight }) => {
55
- if (offsetHeight && props.onInnerResize) {
56
- props.onInnerResize()
57
- }
58
- }}
59
- >
60
- <div
61
- style={innerStyle}
62
- class={props.prefixCls ? `${props.prefixCls}-holder-inner` : undefined}
63
- {...props.innerProps}
64
- >
65
- {slots.default?.()}
66
- {props.extra}
67
- </div>
68
- </ResizeObserver>
69
- </div>
70
- )
71
- }
72
- },
73
- })
package/src/Item.tsx DELETED
@@ -1,35 +0,0 @@
1
- import type { PropType } from 'vue'
2
- import { filterEmpty } from '@v-c/util/dist/props-util'
3
- import { cloneVNode, defineComponent, shallowRef } from 'vue'
4
-
5
- export interface ItemProps {
6
- setRef: (element: HTMLElement | null) => void
7
- }
8
-
9
- export default defineComponent({
10
- name: 'Item',
11
- props: {
12
- setRef: {
13
- type: Function as PropType<(element: HTMLElement | null) => void>,
14
- required: true,
15
- },
16
- },
17
- setup(props, { slots }) {
18
- // Store the ref callback to avoid recreating it on each render
19
- const currentElement = shallowRef<HTMLElement | null>(null)
20
- const refFunc = (node: any) => {
21
- if (currentElement.value !== node) {
22
- currentElement.value = node
23
- props.setRef(node)
24
- }
25
- }
26
-
27
- return () => {
28
- const child = filterEmpty(slots.default?.() ?? [])[0]
29
- if (!child)
30
- return null
31
-
32
- return cloneVNode(child, { ref: refFunc })
33
- }
34
- },
35
- })