@mixd-id/web-scaffold 0.1.230406357 → 0.1.230406359
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.
- package/package.json +1 -1
- package/src/components/Datepicker.vue +8 -6
- package/src/components/List.vue +9 -13
- package/src/components/VirtualGrid.vue +201 -210
package/package.json
CHANGED
|
@@ -266,7 +266,7 @@ export default{
|
|
|
266
266
|
.datepicker {
|
|
267
267
|
@apply min-h-[var(--h-cp)];
|
|
268
268
|
@apply flex items-center rounded-lg overflow-hidden cursor-pointer relative;
|
|
269
|
-
@apply border-[1px] border-text-200;
|
|
269
|
+
@apply border-[1px] border-text-200 bg-base-500 rounded-lg;
|
|
270
270
|
@apply cursor-pointer;
|
|
271
271
|
}
|
|
272
272
|
.datepicker:not(.readonly){
|
|
@@ -290,12 +290,18 @@ export default{
|
|
|
290
290
|
.button{
|
|
291
291
|
@apply rounded-full aspect-square;
|
|
292
292
|
}
|
|
293
|
+
.button:hover{
|
|
294
|
+
@apply bg-primary-200;
|
|
295
|
+
}
|
|
296
|
+
.button.selected{
|
|
297
|
+
@apply bg-primary text-white;
|
|
298
|
+
}
|
|
293
299
|
.button.otherMonth{
|
|
294
300
|
@apply text-text-300;
|
|
295
301
|
}
|
|
296
302
|
|
|
297
303
|
.arrow{
|
|
298
|
-
@apply absolute right-0 pointer-events-none
|
|
304
|
+
@apply absolute right-0 pointer-events-none px-2;
|
|
299
305
|
top: 50%;
|
|
300
306
|
transform: translate3d(0, -50%, 0);
|
|
301
307
|
}
|
|
@@ -303,10 +309,6 @@ export default{
|
|
|
303
309
|
@apply block fill-text-300;
|
|
304
310
|
}
|
|
305
311
|
|
|
306
|
-
.selected{
|
|
307
|
-
@apply bg-primary;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
312
|
.mode-calendar{
|
|
311
313
|
@apply p-2 h-auto;
|
|
312
314
|
}
|
package/src/components/List.vue
CHANGED
|
@@ -368,7 +368,6 @@ export default{
|
|
|
368
368
|
itemsPerPage: this.data.itemsPerPage,
|
|
369
369
|
})
|
|
370
370
|
.then(data => {
|
|
371
|
-
console.log(data)
|
|
372
371
|
generatePivotColumns(this.preset, data.items)
|
|
373
372
|
generateTotalColumns(this.preset, data.items)
|
|
374
373
|
this.loadEnums(data.items)
|
|
@@ -388,8 +387,6 @@ export default{
|
|
|
388
387
|
((this.data ?? {}).hasNext !== false) &&
|
|
389
388
|
!(this.preset.pivot ?? {}).enabled) {
|
|
390
389
|
|
|
391
|
-
//console.log('last id', this.dataItems[this.dataItems.length - 1].id)
|
|
392
|
-
|
|
393
390
|
this.readyState = 4
|
|
394
391
|
this.socket.send(this.src, {
|
|
395
392
|
...this.preset,
|
|
@@ -397,7 +394,6 @@ export default{
|
|
|
397
394
|
afterItem: this.data.items[this.data.items.length - 1],
|
|
398
395
|
})
|
|
399
396
|
.then(data => {
|
|
400
|
-
//console.log('next id', data.items[0].id)
|
|
401
397
|
|
|
402
398
|
this.data.items.push(...data.items)
|
|
403
399
|
this.loadEnums(data.items)
|
|
@@ -505,10 +501,10 @@ export default{
|
|
|
505
501
|
],
|
|
506
502
|
pivot: null
|
|
507
503
|
})
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
504
|
+
.then((res) => {
|
|
505
|
+
this.data.extItems = res.items
|
|
506
|
+
})
|
|
507
|
+
.finally(_ => this.readyState = 1)
|
|
512
508
|
},
|
|
513
509
|
|
|
514
510
|
loadExtNext(){
|
|
@@ -600,12 +596,12 @@ export default{
|
|
|
600
596
|
...this.preset,
|
|
601
597
|
[key]: items.map(item => item[key])
|
|
602
598
|
})
|
|
603
|
-
|
|
604
|
-
|
|
599
|
+
.then(({ items:nextItems }) => {
|
|
600
|
+
nextItems.forEach(item => this.$util.unshift(this.data.items, item, { highlight: true }))
|
|
605
601
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
602
|
+
const destroyedItems = items.filter(_ => !nextItems.find(i => i[key] === _[key]))
|
|
603
|
+
this.$util.remove(this.data.items, destroyedItems)
|
|
604
|
+
})
|
|
609
605
|
break
|
|
610
606
|
}
|
|
611
607
|
|
|
@@ -1,44 +1,37 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
<div ref="
|
|
5
|
-
<div
|
|
6
|
-
<div
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
<slot name="item" :item="item" :index="index">
|
|
10
|
-
{{ item }}
|
|
11
|
-
</slot>
|
|
12
|
-
</div>
|
|
13
|
-
<slot name="end"></slot>
|
|
2
|
+
<div :class="$style.virtualGrid" @click="resize">
|
|
3
|
+
|
|
4
|
+
<div ref="scroller" :class="$style.scroller" :style="scrollerStyle">
|
|
5
|
+
<div :class="spacerClass" ref="spacer" :style="spacerStyle">
|
|
6
|
+
<div v-for="(item, index) in visibleItems" :key="item" :data-id="item.id"
|
|
7
|
+
@click="">
|
|
8
|
+
<slot name="item" :item="item" :index="index"></slot>
|
|
14
9
|
</div>
|
|
15
10
|
</div>
|
|
16
11
|
</div>
|
|
17
12
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
</div>
|
|
13
|
+
<div :class="$style.calc" v-if="items && items.length > 0" ref="calc">
|
|
14
|
+
<slot name="item" :item="items[0]" :index="0"></slot>
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
<Teleport v-if="optBar" :to="optBar">
|
|
18
|
+
<div class="flex flex-row gap-2 items-center">
|
|
19
|
+
<small class="text-text-400">Column</small>
|
|
20
|
+
<select v-model="config.gridColumn"
|
|
21
|
+
class="appearance-none outline-none text-text-400 w-[20px] bg-transparent border-[1px] border-text-100 text-center">
|
|
22
|
+
<option v-for="i in 8" :value="i">{{ i }}</option>
|
|
23
|
+
</select>
|
|
24
|
+
</div>
|
|
25
|
+
<div class="flex flex-row gap-2 items-center">
|
|
26
|
+
<small class="text-text-400">Gap</small>
|
|
27
|
+
<select v-model="config.gridGap"
|
|
28
|
+
class="appearance-none outline-none text-text-400 w-[20px] bg-transparent border-[1px] border-text-100 text-center">
|
|
29
|
+
<option v-for="i in 8" :value="`gap-${i}`">{{ i }}</option>
|
|
30
|
+
</select>
|
|
31
|
+
</div>
|
|
32
|
+
</Teleport>
|
|
33
|
+
|
|
34
|
+
</div>
|
|
42
35
|
</template>
|
|
43
36
|
|
|
44
37
|
<script>
|
|
@@ -47,202 +40,200 @@ import throttle from "lodash/throttle";
|
|
|
47
40
|
|
|
48
41
|
export default{
|
|
49
42
|
|
|
50
|
-
|
|
43
|
+
emits: [ 'scroll-end' ],
|
|
51
44
|
|
|
52
|
-
|
|
45
|
+
props: {
|
|
53
46
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
47
|
+
column: {
|
|
48
|
+
type: [ Number, String ],
|
|
49
|
+
default: 1
|
|
50
|
+
},
|
|
58
51
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
52
|
+
gap: {
|
|
53
|
+
type: [ String ],
|
|
54
|
+
default: 'gap-0'
|
|
55
|
+
},
|
|
63
56
|
|
|
64
57
|
containerClass: String,
|
|
65
58
|
|
|
66
|
-
|
|
59
|
+
items: Array,
|
|
67
60
|
|
|
68
|
-
|
|
61
|
+
pinned: Function,
|
|
69
62
|
|
|
70
|
-
|
|
63
|
+
optBar: String,
|
|
71
64
|
|
|
72
|
-
|
|
65
|
+
config: Object
|
|
73
66
|
|
|
74
|
-
|
|
67
|
+
},
|
|
75
68
|
|
|
76
|
-
|
|
69
|
+
methods: {
|
|
77
70
|
|
|
78
|
-
|
|
79
|
-
|
|
71
|
+
handleScroll: throttle(function(){
|
|
72
|
+
this.scrollTop = this.$el.scrollTop
|
|
80
73
|
|
|
81
|
-
|
|
74
|
+
if(this.scrollTop > this.$refs.scroller.offsetHeight - this.$el.clientHeight - this.itemHeight){
|
|
75
|
+
if(!this.isOnEndScroll){
|
|
76
|
+
this.$emit('scroll-end')
|
|
77
|
+
this.isOnEndScroll = true
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else{
|
|
81
|
+
if(this.isOnEndScroll){
|
|
82
|
+
this.isOnEndScroll = false
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}, 16),
|
|
82
86
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
else{
|
|
90
|
-
if(this.isOnEndScroll){
|
|
91
|
-
this.isOnEndScroll = false
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
}, 16),
|
|
87
|
+
init(){
|
|
88
|
+
this.$el.addEventListener(
|
|
89
|
+
"scroll",
|
|
90
|
+
this.handleScroll,
|
|
91
|
+
this.passiveScrollSupported() ? { passive: true } : false
|
|
92
|
+
)
|
|
95
93
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
"scroll",
|
|
99
|
-
this.handleScroll,
|
|
100
|
-
this.passiveScrollSupported() ? { passive: true } : false
|
|
101
|
-
)
|
|
94
|
+
this.resize()
|
|
95
|
+
},
|
|
102
96
|
|
|
103
|
-
|
|
104
|
-
|
|
97
|
+
passiveScrollSupported() {
|
|
98
|
+
let passiveSupported = false;
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
const options = {
|
|
102
|
+
get passive() {
|
|
103
|
+
passiveSupported = true;
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
window.addEventListener("test", null, options);
|
|
108
|
+
window.removeEventListener("test", null, options);
|
|
109
|
+
} catch (err) {
|
|
110
|
+
passiveSupported = false;
|
|
111
|
+
}
|
|
112
|
+
return passiveSupported;
|
|
113
|
+
},
|
|
105
114
|
|
|
106
|
-
|
|
107
|
-
|
|
115
|
+
resetState(){
|
|
116
|
+
this.state = 1
|
|
117
|
+
},
|
|
108
118
|
|
|
109
|
-
|
|
110
|
-
const options = {
|
|
111
|
-
get passive() {
|
|
112
|
-
passiveSupported = true;
|
|
113
|
-
return false;
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
window.addEventListener("test", null, options);
|
|
117
|
-
window.removeEventListener("test", null, options);
|
|
118
|
-
} catch (err) {
|
|
119
|
-
passiveSupported = false;
|
|
120
|
-
}
|
|
121
|
-
return passiveSupported;
|
|
122
|
-
},
|
|
119
|
+
async resize(){
|
|
123
120
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
121
|
+
this.$nextTick(() => {
|
|
122
|
+
if(this.$refs.calc){
|
|
123
|
+
const elHeight = parseInt(window.getComputedStyle(this.$el).height !== '0px' ?
|
|
124
|
+
window.getComputedStyle(this.$el).height :
|
|
125
|
+
window.getComputedStyle(this.$el).maxHeight)
|
|
127
126
|
|
|
128
|
-
|
|
127
|
+
if(isNaN(elHeight)) return
|
|
129
128
|
|
|
130
|
-
|
|
131
|
-
if(this.$refs.calc){
|
|
132
|
-
const elHeight = parseInt(window.getComputedStyle(this.$refs.container).height !== '0px' ?
|
|
133
|
-
window.getComputedStyle(this.$refs.container).height :
|
|
134
|
-
window.getComputedStyle(this.$refs.container).maxHeight)
|
|
129
|
+
this.itemHeight = parseFloat(window.getComputedStyle(this.$refs.calc).height.replace('px', ''))
|
|
135
130
|
|
|
136
|
-
|
|
131
|
+
this.itemGap = parseFloat(window.getComputedStyle(this.$refs.spacer)['row-gap'].replace('px', ''));
|
|
137
132
|
|
|
138
|
-
|
|
133
|
+
this.maxVisibleItems = elHeight > 0 ? (Math.ceil(elHeight / this.itemHeight) * this.column) : this.items.length
|
|
139
134
|
|
|
140
|
-
|
|
135
|
+
if(this.itemHeight <= 0){
|
|
136
|
+
console.error('Unable to calculate virtual grid item height, async component not supported.')
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
})
|
|
141
140
|
|
|
142
|
-
|
|
141
|
+
},
|
|
143
142
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
})
|
|
143
|
+
setState(state){
|
|
144
|
+
this.state = state
|
|
145
|
+
}
|
|
149
146
|
|
|
150
|
-
|
|
147
|
+
},
|
|
151
148
|
|
|
152
|
-
|
|
153
|
-
this.state = state
|
|
154
|
-
}
|
|
149
|
+
computed: {
|
|
155
150
|
|
|
156
|
-
|
|
151
|
+
scrollerStyle(){
|
|
152
|
+
if(!this.items || this.items.length < 1)
|
|
153
|
+
return {}
|
|
157
154
|
|
|
158
|
-
|
|
155
|
+
const rowCount = Math.ceil((this.items.length / this.column))
|
|
156
|
+
const height = (rowCount * this.itemHeight) + (this.itemGap * (rowCount - 1))
|
|
159
157
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
158
|
+
return {
|
|
159
|
+
height: height + 'px'
|
|
160
|
+
}
|
|
161
|
+
},
|
|
163
162
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
]
|
|
189
|
-
}
|
|
190
|
-
return this.items
|
|
191
|
-
},
|
|
192
|
-
|
|
193
|
-
spacerClass(){
|
|
194
|
-
return [
|
|
195
|
-
this.$style.spacer,
|
|
163
|
+
sortedItems(){
|
|
164
|
+
if(!Array.isArray(this.items)) return []
|
|
165
|
+
|
|
166
|
+
if(typeof this.pinned === 'function'){
|
|
167
|
+
const pinnedItems = []
|
|
168
|
+
const unpinnedItems = []
|
|
169
|
+
this.items.forEach((item) => {
|
|
170
|
+
if(this.pinned(item))
|
|
171
|
+
pinnedItems.push(item)
|
|
172
|
+
else
|
|
173
|
+
unpinnedItems.push(item)
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
return [
|
|
177
|
+
...pinnedItems,
|
|
178
|
+
...unpinnedItems
|
|
179
|
+
]
|
|
180
|
+
}
|
|
181
|
+
return this.items
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
spacerClass(){
|
|
185
|
+
return [
|
|
186
|
+
this.$style.spacer,
|
|
196
187
|
this.containerClass,
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
188
|
+
this.gap
|
|
189
|
+
]
|
|
190
|
+
.join(' ')
|
|
191
|
+
},
|
|
192
|
+
|
|
193
|
+
spacerStyle(){
|
|
194
|
+
return {
|
|
195
|
+
transform: "translateY(" + (this.visibleStartIndex * (this.itemHeight + this.itemGap)) + "px)",
|
|
196
|
+
'grid-template-columns': `repeat(${this.column}, minmax(0, 1fr))`,
|
|
197
|
+
gap: this.gap
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
|
|
201
|
+
visibleItems(){
|
|
202
|
+
if(this.itemHeight <= 0) return []
|
|
203
|
+
return this.sortedItems.slice(this.visibleStartIndex * this.column, (this.visibleStartIndex * this.column) + this.maxVisibleItems)
|
|
204
|
+
},
|
|
205
|
+
|
|
206
|
+
visibleStartIndex(){
|
|
207
|
+
return Math.floor((this.scrollTop < 0 ? 0 : this.scrollTop) / (this.itemHeight + this.itemGap))
|
|
208
|
+
},
|
|
209
|
+
|
|
210
|
+
},
|
|
211
|
+
|
|
212
|
+
data(){
|
|
213
|
+
return {
|
|
214
|
+
scrollTop: 0,
|
|
215
|
+
itemHeight: 0,
|
|
216
|
+
itemGap: 0,
|
|
217
|
+
maxVisibleItems: 0,
|
|
218
|
+
isOnEndScroll: false,
|
|
219
|
+
selectedIndex: -1,
|
|
220
|
+
state: 1,
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
|
|
224
|
+
mounted() {
|
|
225
|
+
this.init()
|
|
226
|
+
},
|
|
227
|
+
|
|
228
|
+
watch: {
|
|
229
|
+
|
|
230
|
+
column(to){
|
|
231
|
+
this.resize()
|
|
232
|
+
},
|
|
233
|
+
|
|
234
|
+
gap(to){
|
|
235
|
+
this.resize()
|
|
236
|
+
},
|
|
246
237
|
|
|
247
238
|
items: {
|
|
248
239
|
deep: true,
|
|
@@ -255,7 +246,7 @@ export default{
|
|
|
255
246
|
}
|
|
256
247
|
},
|
|
257
248
|
|
|
258
|
-
|
|
249
|
+
}
|
|
259
250
|
|
|
260
251
|
}
|
|
261
252
|
|
|
@@ -264,25 +255,25 @@ export default{
|
|
|
264
255
|
<style module>
|
|
265
256
|
|
|
266
257
|
.virtualGrid{
|
|
267
|
-
|
|
258
|
+
@apply flex-1 overflow-y-auto;
|
|
268
259
|
}
|
|
269
260
|
|
|
270
261
|
.scroller{
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
262
|
+
position: relative;
|
|
263
|
+
overflow: hidden;
|
|
264
|
+
will-change: auto;
|
|
265
|
+
@apply min-w-full;
|
|
275
266
|
}
|
|
276
267
|
|
|
277
268
|
.spacer{
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
269
|
+
will-change: auto;
|
|
270
|
+
position: relative;
|
|
271
|
+
@apply grid;
|
|
281
272
|
}
|
|
282
273
|
|
|
283
274
|
.calc{
|
|
284
|
-
|
|
285
|
-
|
|
275
|
+
@apply absolute invisible max-w-full;
|
|
276
|
+
top: -10000px;
|
|
286
277
|
|
|
287
278
|
}
|
|
288
279
|
|