Skip to content

Commit c46dfec

Browse files
committed
Dynamic tags
1 parent 52458c8 commit c46dfec

File tree

10 files changed

+103
-24
lines changed

10 files changed

+103
-24
lines changed

README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,33 @@ There are additional props you can use:
3939

4040
- `typeField` to customize which field is used on the items to get their type and use the corresponding definition in the `renderers` map. The default is `'type'`.
4141
- `keyField` to customize which field is used on the items to set their `key` special attribute (see [the documation](https://vuejs.org/v2/api/#key)). The default is `'id'`.
42+
- `mainTag` to change the DOM tag of the component root element. The default is `'div'`.
43+
- `containerTag` to change the DOM tag of the element simulating the height. The default is `'div'`.
44+
- `contentTag` to change the DOM tag of the element containing the items. The default is `'div'`. For example, you can change this to `'table'`.
45+
46+
The component template is structured like this:
47+
48+
```html
49+
<main>
50+
<container>
51+
<content>
52+
<!-- Your items here -->
53+
</content>
54+
</container>
55+
</main>
56+
```
57+
58+
If you set `contentTag` to `'table'`, the actual result in the DOM will bu the following:
59+
60+
```html
61+
<div>
62+
<div>
63+
<table>
64+
<!-- Your items here -->
65+
</table>
66+
</div>
67+
</div>
68+
```
4269

4370
The `renderers` map is an object containing a component definition for each possible value of the item type. **The component definition must have an `item` prop, that will get the item object to render in the scroller.**
4471

dist/vue-virtual-scroller.css

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
}
55
.item-container[data-v-5594e8c4] {
66
box-sizing: border-box;
7+
width: 100%;
8+
overflow: hidden;
9+
}
10+
.items[data-v-5594e8c4] {
11+
width: 100%;
712
}
813

914
.resize-observer[data-v-c7b3205a] {

dist/vue-virtual-scroller.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs-src/src/App.vue

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,13 @@
1111
Virtual scroller update: {{ updateTime }} ms
1212
</span>
1313
<span>
14-
<button @click="showScroller = !showScroller">Toggle scroller</button>
14+
<button @mousedown="showScroller = !showScroller">Toggle scroller</button>
1515
</span>
1616
</div>
1717
<div class="content" v-if="showScroller">
18-
<virtual-scroller class="scroller" :items="items" :renderers="renderers" item-height="42" type-field="type" key-field="index"></virtual-scroller>
18+
<div class="wrapper">
19+
<virtual-scroller class="scroller" :items="items" :renderers="renderers" item-height="42" type-field="type" key-field="index" main-tag="section" content-tag="table"></virtual-scroller>
20+
</div>
1921
</div>
2022
</div>
2123
</template>
@@ -130,22 +132,26 @@ body {
130132
position: relative;
131133
}
132134
133-
.scroller {
134-
overflow: auto;
135+
.wrapper {
136+
overflow: hidden;
135137
position: absolute;
136138
top: 0;
137139
bottom: 0;
138140
left: 0;
139141
right: 0;
140142
}
141143
144+
.scroller {
145+
width: 100%;
146+
height: 100%;
147+
}
148+
142149
.item-container {
143150
box-sizing: border-box;
144151
}
145152
146153
.item {
147154
height: 42px;
148-
padding: 12px;
149155
box-sizing: border-box;
150156
cursor: pointer;
151157
user-select: none;
@@ -165,9 +171,16 @@ body {
165171
}
166172
167173
.index {
168-
display: inline-block;
169174
color: rgba(0, 0, 0, 0.2);
170175
width: 55px;
171176
text-align: right;
172177
}
178+
179+
table {
180+
border-collapse: collapse;
181+
}
182+
183+
td {
184+
padding: 12px;
185+
}
173186
</style>

docs-src/src/Item.vue

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
<template>
2-
<div class="person" @click="edit"><span class="index">{{item.index}}</span> {{item.value.name}}</div>
2+
<tr class="person" @click="edit">
3+
<td class="index">
4+
{{item.index}}
5+
</td>
6+
<td>
7+
{{item.value.name}}
8+
</td>
9+
</tr>
310
</template>
411

512
<script>

docs-src/src/Letter.vue

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
<template>
2-
<div class="letter"><span class="index">{{item.index}}</span> {{item.value}}</div>
2+
<tr class="letter">
3+
<td class="index">
4+
{{item.index}}
5+
</td>
6+
<td>
7+
{{item.value}}
8+
</td>
9+
</tr>
310
</template>
411

512
<script>

docs/build.js

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/build.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "vue-virtual-scroller",
33
"description": "Smooth scrolling for any amount of data",
4-
"version": "0.1.0",
4+
"version": "0.2.0",
55
"author": {
66
"name": "Guillaume Chau",
77
"email": "[email protected]"

src/components/VirtualScroller.vue

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
<template>
2-
<div class="virtual-scroller" @scroll="updateVisibleItems">
3-
<div class="item-container" :style="itemContainerStyle">
4-
<div class="items">
2+
<component :is="mainTag" class="virtual-scroller" @scroll="updateVisibleItems">
3+
<component :is="containerTag" class="item-container" :style="itemContainerStyle">
4+
<component :is="contentTag" class="items" :style="itemsStyle">
55
<component class="item" v-for="item in visibleItems" :key="item[keyField]" :is="renderers[item[typeField]]" :item="item"></component>
6-
</div>
7-
</div>
8-
6+
</component>
7+
</component>
98
<resize-observer @notify="updateVisibleItems" />
10-
</div>
9+
</component>
1110
</template>
1211

1312
<script>
@@ -40,11 +39,24 @@ export default {
4039
type: String,
4140
default: 'id',
4241
},
42+
mainTag: {
43+
type: String,
44+
default: 'div',
45+
},
46+
containerTag: {
47+
type: String,
48+
default: 'div',
49+
},
50+
contentTag: {
51+
type: String,
52+
default: 'div',
53+
},
4354
},
4455
4556
data: () => ({
4657
visibleItems: [],
4758
itemContainerStyle: null,
59+
itemsStyle: null,
4860
}),
4961
5062
watch: {
@@ -74,7 +86,9 @@ export default {
7486
this.visibleItems = this.items.slice(startIndex, endIndex)
7587
this.itemContainerStyle = {
7688
height: l * this.itemHeight + 'px',
77-
paddingTop: startIndex * this.itemHeight + 'px',
89+
}
90+
this.itemsStyle = {
91+
marginTop: startIndex * this.itemHeight + 'px',
7892
}
7993
this.$forceUpdate()
8094
},
@@ -97,5 +111,11 @@ export default {
97111
98112
.item-container {
99113
box-sizing: border-box;
114+
width: 100%;
115+
overflow: hidden;
116+
}
117+
118+
.items {
119+
width: 100%;
100120
}
101121
</style>

0 commit comments

Comments
 (0)