@thinkpixellab-public/px-vue 3.0.65 → 3.0.67
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/components/PxBaseMobileAware.vue +7 -0
- package/components/PxSticky.vue +113 -0
- package/package.json +1 -1
- package/utils/cssStr.js +8 -0
- package/utils/drag.js +0 -1
- package/utils/utils.js +44 -0
|
@@ -49,11 +49,18 @@
|
|
|
49
49
|
-->
|
|
50
50
|
|
|
51
51
|
<script>
|
|
52
|
+
import utils from '../utils/utils.js';
|
|
53
|
+
|
|
52
54
|
export default {
|
|
53
55
|
data() {
|
|
54
56
|
return { isMobile: null };
|
|
55
57
|
},
|
|
56
58
|
mounted() {
|
|
59
|
+
if (utils.getQueryBool('alwaysMobile')) {
|
|
60
|
+
this.isMobile = true;
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
57
64
|
if (this.$globalOn) {
|
|
58
65
|
this.$globalOn('mobile-changed', isMobile => {
|
|
59
66
|
this.isMobile = isMobile;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
A simple position:stickky container that adds stuck / unstuck events and classes as the item
|
|
3
|
+
becomes stuck / unstuck.
|
|
4
|
+
-->
|
|
5
|
+
<template>
|
|
6
|
+
<div
|
|
7
|
+
:class="[bem({ disabled: !enabled }), stuck ? stuckClass : unstuckClass]"
|
|
8
|
+
:style="enabled ? { top: cssPx(top), position: 'sticky', zIndex: z } : null"
|
|
9
|
+
>
|
|
10
|
+
<div
|
|
11
|
+
v-show="enabled"
|
|
12
|
+
ref="sentinel"
|
|
13
|
+
:class="bem('sentinel')"
|
|
14
|
+
:style="enabled ? { top: cssPx(-(top + overlap)), height: cssPx(top + overlap) } : null"
|
|
15
|
+
></div>
|
|
16
|
+
<slot :stuck="stuck" />
|
|
17
|
+
</div>
|
|
18
|
+
</template>
|
|
19
|
+
|
|
20
|
+
<script>
|
|
21
|
+
export default {
|
|
22
|
+
name: 'px-sticky',
|
|
23
|
+
props: {
|
|
24
|
+
enabled: { type: Boolean, default: true },
|
|
25
|
+
top: { type: Number, default: 0 },
|
|
26
|
+
overlap: { type: Number, default: 1 },
|
|
27
|
+
z: { type: Number, default: 1 },
|
|
28
|
+
stuckClass: { type: String, default: '' },
|
|
29
|
+
unstuckClass: { type: String, default: '' },
|
|
30
|
+
},
|
|
31
|
+
data() {
|
|
32
|
+
return {
|
|
33
|
+
stuck: false,
|
|
34
|
+
stuckScrollY: null,
|
|
35
|
+
};
|
|
36
|
+
},
|
|
37
|
+
watch: {
|
|
38
|
+
enabled() {
|
|
39
|
+
this.updateConnections();
|
|
40
|
+
},
|
|
41
|
+
stuck(nv) {
|
|
42
|
+
if (nv) {
|
|
43
|
+
this.$emit('stuck');
|
|
44
|
+
} else {
|
|
45
|
+
this.$emit('unstuck');
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
mounted() {
|
|
50
|
+
this.updateConnections();
|
|
51
|
+
},
|
|
52
|
+
beforeDestroy() {
|
|
53
|
+
this.tryDisconnect();
|
|
54
|
+
},
|
|
55
|
+
methods: {
|
|
56
|
+
updateConnections() {
|
|
57
|
+
if (this.enabled) {
|
|
58
|
+
this.tryConnect();
|
|
59
|
+
} else {
|
|
60
|
+
this.tryDisconnect();
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
tryConnect() {
|
|
64
|
+
if (!this.observer) {
|
|
65
|
+
try {
|
|
66
|
+
this.observer = new IntersectionObserver(
|
|
67
|
+
([e]) => {
|
|
68
|
+
this.stuck = e.intersectionRatio < 1;
|
|
69
|
+
},
|
|
70
|
+
{ threshold: [1] }
|
|
71
|
+
);
|
|
72
|
+
this.observer.observe(this.$refs.sentinel);
|
|
73
|
+
} catch (e) {
|
|
74
|
+
console.warn('Cound not create css sticky detector.');
|
|
75
|
+
console.warn(e);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
tryDisconnect() {
|
|
80
|
+
this.stuck = false;
|
|
81
|
+
if (this.observer) {
|
|
82
|
+
this.observer.disconnect();
|
|
83
|
+
this.observer = null;
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
</script>
|
|
89
|
+
|
|
90
|
+
<style lang="scss">
|
|
91
|
+
@import '@/styles/include.scss';
|
|
92
|
+
.px-sticky {
|
|
93
|
+
position: relative;
|
|
94
|
+
|
|
95
|
+
&:not(.px-sticky--disabled) {
|
|
96
|
+
position: sticky !important;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
&__sentinel {
|
|
100
|
+
position: absolute;
|
|
101
|
+
left: 0;
|
|
102
|
+
right: 0; /* needs dimensions */
|
|
103
|
+
visibility: hidden;
|
|
104
|
+
opacity: 0;
|
|
105
|
+
|
|
106
|
+
// DEBUG
|
|
107
|
+
// visibility: visible;
|
|
108
|
+
// opacity: 0.9;
|
|
109
|
+
// background-color: lime;
|
|
110
|
+
// z-index: 10000000;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
</style>
|
package/package.json
CHANGED
package/utils/cssStr.js
CHANGED
|
@@ -190,6 +190,13 @@ function cssEmFallback(val, allowNumberless = false) {
|
|
|
190
190
|
return cssUnitFallback(val, 'em', allowNumberless);
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
+
/*
|
|
194
|
+
Px version of cssUnitFallback
|
|
195
|
+
*/
|
|
196
|
+
function cssPxFallback(val, allowNumberless = false) {
|
|
197
|
+
return cssUnitFallback(val, 'px', allowNumberless);
|
|
198
|
+
}
|
|
199
|
+
|
|
193
200
|
export {
|
|
194
201
|
cssPx,
|
|
195
202
|
cssEm,
|
|
@@ -201,4 +208,5 @@ export {
|
|
|
201
208
|
cssUnit,
|
|
202
209
|
cssUnitFallback,
|
|
203
210
|
cssEmFallback,
|
|
211
|
+
cssPxFallback,
|
|
204
212
|
};
|
package/utils/drag.js
CHANGED
package/utils/utils.js
CHANGED
|
@@ -116,6 +116,38 @@ export default {
|
|
|
116
116
|
return chunks;
|
|
117
117
|
},
|
|
118
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Returns an array containing any elements that are in arrA not in arrB (e.g. arrA - arrB)
|
|
121
|
+
* @param {} arrA The source array
|
|
122
|
+
* @param {} arrB The comparison array
|
|
123
|
+
*
|
|
124
|
+
* @expample arrMinus([1,2,3], [3,4,5]) ==> [1,2]
|
|
125
|
+
*/
|
|
126
|
+
arrMinus: function (arrA, arrB) {
|
|
127
|
+
return arrA.filter(item => !arrB.includes(item));
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Returns an object like {added: [...], removed: [...]} containing the delta between arrOld and
|
|
132
|
+
* arrNew such that removed are elements in arrOld but not in arrNew and added are elements in
|
|
133
|
+
* arrNew but not in arrOld.
|
|
134
|
+
* @param {} arrOld The source array
|
|
135
|
+
* @param {} arrNew The comparison array
|
|
136
|
+
*/
|
|
137
|
+
arrDelta: function (arrOld, arrNew) {
|
|
138
|
+
return {
|
|
139
|
+
added: this.arrMinus(arrNew, arrOld),
|
|
140
|
+
removed: this.arrMinus(arrOld, arrNew),
|
|
141
|
+
};
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Returns an array of all elements found in both arrA and arrB.
|
|
146
|
+
*/
|
|
147
|
+
arrIntersect: function (arrA, arrB) {
|
|
148
|
+
return arrA.filter(value => arrB.includes(value));
|
|
149
|
+
},
|
|
150
|
+
|
|
119
151
|
/**
|
|
120
152
|
* Returns an object representing the current query string parameters.
|
|
121
153
|
*/
|
|
@@ -260,4 +292,16 @@ export default {
|
|
|
260
292
|
setTimeout(resolve, ms);
|
|
261
293
|
});
|
|
262
294
|
},
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Generate a 6 letter random sequence of letters and numbers, based on this:
|
|
298
|
+
* https://stackoverflow.com/questions/6248666/how-to-generate-short-uid-like-ax4j9z-in-js
|
|
299
|
+
*/
|
|
300
|
+
|
|
301
|
+
uniqueId() {
|
|
302
|
+
return (
|
|
303
|
+
('000' + ((Math.random() * 46656) | 0).toString(36)).slice(-3) +
|
|
304
|
+
('000' + ((Math.random() * 46656) | 0).toString(36)).slice(-3)
|
|
305
|
+
);
|
|
306
|
+
},
|
|
263
307
|
};
|