atharv-mandlavdiya 1.2.0 → 1.2.2
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/atharvmandlavdiya.js +187 -70
- package/package.json +1 -1
- package/prefabs/progress/progress.css +9 -5
- package/test/progress-card.test.js +0 -213
package/atharvmandlavdiya.js
CHANGED
|
@@ -19,42 +19,44 @@ const progressCardStyles = `
|
|
|
19
19
|
|
|
20
20
|
.progress-wrapper {
|
|
21
21
|
position: relative;
|
|
22
|
-
min-height: 1024px;
|
|
23
22
|
width: 100%;
|
|
24
23
|
box-sizing: border-box;
|
|
25
|
-
overflow: visible;
|
|
26
24
|
}
|
|
27
25
|
|
|
28
26
|
progress-card {
|
|
29
27
|
display: block;
|
|
30
28
|
position: sticky;
|
|
31
|
-
top:
|
|
32
|
-
height:
|
|
29
|
+
top: 30vh;
|
|
30
|
+
height: 40vh;
|
|
33
31
|
width: 100%;
|
|
34
|
-
|
|
32
|
+
margin-bottom: 30vh;
|
|
33
|
+
overflow: hidden;
|
|
35
34
|
scale: calc(0.5 + var(--progress) * 0.5);
|
|
36
35
|
clip-path: rect(
|
|
37
|
-
calc(20% - var(--progress) * 20%)
|
|
38
|
-
calc(90% + var(--progress) * 10%)
|
|
39
|
-
calc(80% + var(--progress) * 20%)
|
|
36
|
+
calc(20% - var(--progress) * 20%)
|
|
37
|
+
calc(90% + var(--progress) * 10%)
|
|
38
|
+
calc(80% + var(--progress) * 20%)
|
|
40
39
|
calc(10% - var(--progress) * 10%)
|
|
41
|
-
round calc(2.441rem - var(--progress) *
|
|
40
|
+
round calc(2.441rem - var(--progress) * 2.441rem)
|
|
42
41
|
);
|
|
43
|
-
|
|
42
|
+
transform: translateZ(0);
|
|
43
|
+
will-change: clip-path, scale;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
@media (min-width: 1024px) {
|
|
47
47
|
progress-card {
|
|
48
|
-
|
|
48
|
+
top: 15vh;
|
|
49
|
+
height: 70vh;
|
|
49
50
|
width: 70%;
|
|
50
51
|
margin-left: auto;
|
|
51
52
|
margin-right: auto;
|
|
53
|
+
margin-bottom: 15vh;
|
|
52
54
|
clip-path: rect(
|
|
53
|
-
calc(20% - var(--progress) * 20%)
|
|
54
|
-
calc(70% + var(--progress) * 30%)
|
|
55
|
+
calc(20% - var(--progress) * 20%)
|
|
56
|
+
calc(70% + var(--progress) * 30%)
|
|
55
57
|
calc(80% + var(--progress) * 20%)
|
|
56
|
-
calc(30% - var(--progress) * 30%)
|
|
57
|
-
round calc(2.441rem - var(--progress) *
|
|
58
|
+
calc(30% - var(--progress) * 30%)
|
|
59
|
+
round calc(2.441rem - var(--progress) * 2.441rem)
|
|
58
60
|
);
|
|
59
61
|
}
|
|
60
62
|
}
|
|
@@ -70,7 +72,8 @@ progress-card > div {
|
|
|
70
72
|
`;
|
|
71
73
|
|
|
72
74
|
function injectProgressCardStyles(root) {
|
|
73
|
-
if (!root.document
|
|
75
|
+
if (!root.document) return;
|
|
76
|
+
if (root.document.getElementById('atharv-progress-card-styles')) return;
|
|
74
77
|
|
|
75
78
|
const style = root.document.createElement('style');
|
|
76
79
|
style.id = 'atharv-progress-card-styles';
|
|
@@ -78,11 +81,14 @@ function injectProgressCardStyles(root) {
|
|
|
78
81
|
(root.document.head || root.document.documentElement).appendChild(style);
|
|
79
82
|
}
|
|
80
83
|
|
|
84
|
+
function clamp(value, min, max) {
|
|
85
|
+
return Math.min(max, Math.max(min, value));
|
|
86
|
+
}
|
|
87
|
+
|
|
81
88
|
function isScrollable(element, root) {
|
|
82
89
|
const style = root.getComputedStyle(element);
|
|
83
90
|
const overflow = `${style.overflow} ${style.overflowY}`;
|
|
84
|
-
return /(auto|scroll|overlay)/.test(overflow)
|
|
85
|
-
(element.scrollHeight > element.clientHeight || /(auto|scroll|overlay)/.test(overflow));
|
|
91
|
+
return /(auto|scroll|overlay)/.test(overflow);
|
|
86
92
|
}
|
|
87
93
|
|
|
88
94
|
function findScrollContainer(element, root) {
|
|
@@ -95,84 +101,138 @@ function findScrollContainer(element, root) {
|
|
|
95
101
|
}
|
|
96
102
|
|
|
97
103
|
function getScrollPosition(container, root) {
|
|
98
|
-
|
|
104
|
+
if (container !== root) return container.scrollTop;
|
|
105
|
+
return root.scrollY || root.pageYOffset || 0;
|
|
99
106
|
}
|
|
100
107
|
|
|
101
108
|
function getViewportHeight(container, root) {
|
|
102
|
-
|
|
109
|
+
if (container !== root) return container.clientHeight;
|
|
110
|
+
return root.innerHeight;
|
|
103
111
|
}
|
|
104
112
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if (container === root) return wrapperRect.top + getScrollPosition(container, root);
|
|
113
|
+
const cards = new Set();
|
|
114
|
+
let frameQueued = false;
|
|
108
115
|
|
|
109
|
-
|
|
110
|
-
|
|
116
|
+
function queueFrame() {
|
|
117
|
+
if (frameQueued) return;
|
|
118
|
+
frameQueued = true;
|
|
119
|
+
requestAnimationFrame(runFrame);
|
|
111
120
|
}
|
|
112
121
|
|
|
113
|
-
function
|
|
114
|
-
|
|
122
|
+
function runFrame() {
|
|
123
|
+
frameQueued = false;
|
|
124
|
+
for (const card of cards) {
|
|
125
|
+
if (card.dirty) card.measure();
|
|
126
|
+
}
|
|
127
|
+
for (const card of cards) card.render();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function markAllDirty() {
|
|
131
|
+
for (const card of cards) card.dirty = true;
|
|
132
|
+
queueFrame();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function releaseContainer(container) {
|
|
136
|
+
for (const card of cards) {
|
|
137
|
+
if (card.container === container) return;
|
|
138
|
+
}
|
|
139
|
+
container.removeEventListener('scroll', queueFrame);
|
|
115
140
|
}
|
|
116
141
|
|
|
117
142
|
function defineProgressCard(root) {
|
|
118
|
-
if (!root.document || !root.customElements
|
|
143
|
+
if (!root.document || !root.customElements) return;
|
|
144
|
+
if (root.customElements.get('progress-card')) return;
|
|
145
|
+
|
|
146
|
+
root.addEventListener('resize', markAllDirty, { passive: true });
|
|
119
147
|
|
|
120
148
|
root.customElements.define('progress-card', class extends root.HTMLElement {
|
|
121
149
|
constructor() {
|
|
122
150
|
super();
|
|
123
|
-
this.
|
|
124
|
-
this.
|
|
125
|
-
this.
|
|
126
|
-
this.
|
|
151
|
+
this.wrapper = null;
|
|
152
|
+
this.container = null;
|
|
153
|
+
this.observer = null;
|
|
154
|
+
this.mounting = false;
|
|
155
|
+
this.dirty = true;
|
|
156
|
+
this.start = 0;
|
|
157
|
+
this.range = 1;
|
|
158
|
+
this.last = -1;
|
|
127
159
|
}
|
|
128
160
|
|
|
129
161
|
connectedCallback() {
|
|
130
|
-
if (
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
162
|
+
if (this.mounting) return;
|
|
163
|
+
if (!this.wrapper) this.mount();
|
|
164
|
+
|
|
165
|
+
this.container = findScrollContainer(this, root);
|
|
166
|
+
this.container.addEventListener('scroll', queueFrame, { passive: true });
|
|
167
|
+
|
|
168
|
+
if (root.ResizeObserver && !this.observer) {
|
|
169
|
+
this.observer = new root.ResizeObserver(markAllDirty);
|
|
170
|
+
this.observer.observe(this.wrapper);
|
|
138
171
|
}
|
|
139
172
|
|
|
140
|
-
|
|
141
|
-
this.
|
|
142
|
-
|
|
143
|
-
this._updateProgress();
|
|
173
|
+
cards.add(this);
|
|
174
|
+
this.dirty = true;
|
|
175
|
+
queueFrame();
|
|
144
176
|
}
|
|
145
177
|
|
|
146
178
|
disconnectedCallback() {
|
|
147
|
-
if (this.
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
179
|
+
if (this.mounting) return;
|
|
180
|
+
cards.delete(this);
|
|
181
|
+
|
|
182
|
+
if (this.observer) this.observer.disconnect();
|
|
183
|
+
this.observer = null;
|
|
184
|
+
|
|
185
|
+
if (this.container) releaseContainer(this.container);
|
|
186
|
+
this.container = null;
|
|
187
|
+
|
|
188
|
+
const wrapper = this.wrapper;
|
|
189
|
+
this.wrapper = null;
|
|
190
|
+
if (!wrapper || !wrapper.parentNode) return;
|
|
191
|
+
if (wrapper.contains(this)) return;
|
|
192
|
+
wrapper.parentNode.removeChild(wrapper);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
mount() {
|
|
196
|
+
const length = Number.parseFloat(this.dataset.scrollLength) || 300;
|
|
197
|
+
const wrapper = root.document.createElement('div');
|
|
198
|
+
wrapper.className = 'progress-wrapper';
|
|
199
|
+
wrapper.style.minHeight = `${length}vh`;
|
|
200
|
+
|
|
201
|
+
this.wrapper = wrapper;
|
|
202
|
+
this.mounting = true;
|
|
203
|
+
this.parentNode.insertBefore(wrapper, this);
|
|
204
|
+
wrapper.appendChild(this);
|
|
205
|
+
this.mounting = false;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
measure() {
|
|
209
|
+
const container = this.container;
|
|
210
|
+
if (!container || !this.wrapper) return;
|
|
211
|
+
|
|
212
|
+
const viewport = getViewportHeight(container, root);
|
|
213
|
+
const rect = this.wrapper.getBoundingClientRect();
|
|
214
|
+
const scroll = getScrollPosition(container, root);
|
|
215
|
+
|
|
216
|
+
let top = rect.top + scroll;
|
|
217
|
+
if (container !== root) {
|
|
218
|
+
top = rect.top - container.getBoundingClientRect().top + scroll;
|
|
154
219
|
}
|
|
155
|
-
|
|
220
|
+
|
|
221
|
+
this.start = top;
|
|
222
|
+
this.range = Math.max(1, rect.height - viewport);
|
|
223
|
+
this.dirty = false;
|
|
156
224
|
}
|
|
157
225
|
|
|
158
|
-
|
|
159
|
-
if (!this.
|
|
160
|
-
|
|
161
|
-
const
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
? (scrollPosition >= sectionEnd ? 1 : 0)
|
|
169
|
-
: clamp(
|
|
170
|
-
(scrollPosition - sectionStart) / (sectionEnd - sectionStart),
|
|
171
|
-
0,
|
|
172
|
-
1
|
|
173
|
-
);
|
|
174
|
-
|
|
175
|
-
this.style.setProperty('--progress', String(progress));
|
|
226
|
+
render() {
|
|
227
|
+
if (!this.container) return;
|
|
228
|
+
|
|
229
|
+
const scroll = getScrollPosition(this.container, root);
|
|
230
|
+
const raw = (scroll - this.start) / this.range;
|
|
231
|
+
const value = Math.round(clamp(raw, 0, 1) * 1e4) / 1e4;
|
|
232
|
+
|
|
233
|
+
if (value === this.last) return;
|
|
234
|
+
this.last = value;
|
|
235
|
+
this.style.setProperty('--progress', String(value));
|
|
176
236
|
}
|
|
177
237
|
});
|
|
178
238
|
}
|
|
@@ -186,6 +246,63 @@ export function progressCard() {
|
|
|
186
246
|
defineProgressCard(globalThis);
|
|
187
247
|
}
|
|
188
248
|
|
|
249
|
+
export function smoothScroll(options = {}) {
|
|
250
|
+
const root = globalThis;
|
|
251
|
+
if (!root.document || !root.matchMedia) return;
|
|
252
|
+
if (root.matchMedia('(pointer: coarse)').matches) return;
|
|
253
|
+
|
|
254
|
+
const speed = options.speed ?? 0.09;
|
|
255
|
+
const accel = options.accel ?? 0.42;
|
|
256
|
+
const multiplier = options.multiplier ?? 1.1;
|
|
257
|
+
const maxDelta = options.maxDelta ?? 2400;
|
|
258
|
+
const stop = options.stop ?? 0.08;
|
|
259
|
+
|
|
260
|
+
let delta = 0;
|
|
261
|
+
let target = 0;
|
|
262
|
+
let current = 0;
|
|
263
|
+
let running = false;
|
|
264
|
+
|
|
265
|
+
function limit() {
|
|
266
|
+
const doc = root.document.documentElement;
|
|
267
|
+
return Math.max(0, doc.scrollHeight - root.innerHeight);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function step() {
|
|
271
|
+
if (delta === 0) {
|
|
272
|
+
running = false;
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
delta = clamp(delta, -maxDelta, maxDelta);
|
|
277
|
+
target = clamp(target + delta * accel, 0, limit());
|
|
278
|
+
|
|
279
|
+
const lerped = (target - current) * speed;
|
|
280
|
+
current += lerped;
|
|
281
|
+
delta *= 1 - accel;
|
|
282
|
+
|
|
283
|
+
if (Math.abs(lerped) < stop) {
|
|
284
|
+
current = Math.round(target);
|
|
285
|
+
delta = 0;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
root.scrollTo(0, current);
|
|
289
|
+
requestAnimationFrame(step);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
root.addEventListener('wheel', (event) => {
|
|
293
|
+
event.preventDefault();
|
|
294
|
+
|
|
295
|
+
if (!running) {
|
|
296
|
+
target = getScrollPosition(root, root);
|
|
297
|
+
current = target;
|
|
298
|
+
running = true;
|
|
299
|
+
requestAnimationFrame(step);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
delta += event.deltaY * multiplier;
|
|
303
|
+
}, { passive: false });
|
|
304
|
+
}
|
|
305
|
+
|
|
189
306
|
const _svg = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 650 200" width="650" height="200">
|
|
190
307
|
<defs>
|
|
191
308
|
<linearGradient id="pathGradient" x1="0%" y1="0%" x2="100%" y2="0%">
|
package/package.json
CHANGED
|
@@ -15,33 +15,37 @@
|
|
|
15
15
|
progress-card {
|
|
16
16
|
display: block;
|
|
17
17
|
position: sticky;
|
|
18
|
-
top:
|
|
19
|
-
height:
|
|
18
|
+
top: 30vh;
|
|
19
|
+
height: 40vh;
|
|
20
20
|
width: 100%;
|
|
21
21
|
max-width: 100%;
|
|
22
|
+
margin-bottom: 30vh;
|
|
22
23
|
scale: calc(0.5 + var(--progress) * 0.5);
|
|
23
24
|
clip-path: rect(
|
|
24
25
|
calc(20% - var(--progress) * 20%)
|
|
25
26
|
calc(90% + var(--progress) * 10%)
|
|
26
27
|
calc(80% + var(--progress) * 20%)
|
|
27
28
|
calc(10% - var(--progress) * 10%)
|
|
28
|
-
round calc(2.441rem - var(--progress) *
|
|
29
|
+
round calc(2.441rem - var(--progress) * 2.441rem)
|
|
29
30
|
);
|
|
31
|
+
transform: translateZ(0);
|
|
30
32
|
overflow: hidden;
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
@media (min-width: 1024px) {
|
|
34
36
|
progress-card {
|
|
35
|
-
|
|
37
|
+
top: 15vh;
|
|
38
|
+
height: 70vh;
|
|
36
39
|
width: 70%;
|
|
37
40
|
margin-left: auto;
|
|
38
41
|
margin-right: auto;
|
|
42
|
+
margin-bottom: 15vh;
|
|
39
43
|
clip-path: rect(
|
|
40
44
|
calc(20% - var(--progress) * 20%)
|
|
41
45
|
calc(70% + var(--progress) * 30%)
|
|
42
46
|
calc(80% + var(--progress) * 20%)
|
|
43
47
|
calc(30% - var(--progress) * 30%)
|
|
44
|
-
round calc(2.441rem - var(--progress) *
|
|
48
|
+
round calc(2.441rem - var(--progress) * 2.441rem)
|
|
45
49
|
);
|
|
46
50
|
}
|
|
47
51
|
}
|
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
import test, { afterEach } from 'node:test';
|
|
2
|
-
import assert from 'node:assert/strict';
|
|
3
|
-
|
|
4
|
-
class FakeStyle {
|
|
5
|
-
setProperty(name, value) {
|
|
6
|
-
this[name] = value;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
getPropertyValue(name) {
|
|
10
|
-
return this[name] || '';
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
class FakeElement {
|
|
15
|
-
constructor() {
|
|
16
|
-
this.children = [];
|
|
17
|
-
this.attributes = new Map();
|
|
18
|
-
this.style = new FakeStyle();
|
|
19
|
-
this.listeners = new Map();
|
|
20
|
-
this.parentElement = null;
|
|
21
|
-
this._rect = { top: 0, height: 0 };
|
|
22
|
-
this._height = 0;
|
|
23
|
-
this.clientHeight = 0;
|
|
24
|
-
this.scrollHeight = 0;
|
|
25
|
-
this.scrollTop = 0;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
get parentNode() {
|
|
29
|
-
return this.parentElement;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
get dataset() {
|
|
33
|
-
return Object.fromEntries([...this.attributes]
|
|
34
|
-
.filter(([name]) => name.startsWith('data-'))
|
|
35
|
-
.map(([name, value]) => [
|
|
36
|
-
name.slice(5).replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()),
|
|
37
|
-
value
|
|
38
|
-
]));
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
get offsetHeight() {
|
|
42
|
-
return this._height;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
set className(value) {
|
|
46
|
-
this.attributes.set('class', value);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
get className() {
|
|
50
|
-
return this.attributes.get('class') || '';
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
setAttribute(name, value) {
|
|
54
|
-
this.attributes.set(name, String(value));
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
hasAttribute(name) {
|
|
58
|
-
return this.attributes.has(name);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
appendChild(child) {
|
|
62
|
-
child.parentElement = this;
|
|
63
|
-
this.children.push(child);
|
|
64
|
-
return child;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
insertBefore(child, reference) {
|
|
68
|
-
child.parentElement = this;
|
|
69
|
-
const index = this.children.indexOf(reference);
|
|
70
|
-
this.children.splice(index < 0 ? this.children.length : index, 0, child);
|
|
71
|
-
return child;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
removeChild(child) {
|
|
75
|
-
this.children.splice(this.children.indexOf(child), 1);
|
|
76
|
-
child.parentElement = null;
|
|
77
|
-
return child;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
contains(child) {
|
|
81
|
-
return this.children.includes(child) || this.children.some((item) => item.contains(child));
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
getBoundingClientRect() {
|
|
85
|
-
return this._rect;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
addEventListener(type, listener) {
|
|
89
|
-
if (!this.listeners.has(type)) this.listeners.set(type, new Set());
|
|
90
|
-
this.listeners.get(type).add(listener);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
removeEventListener(type, listener) {
|
|
94
|
-
this.listeners.get(type)?.delete(listener);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
class FakeHTMLElement extends FakeElement {}
|
|
99
|
-
|
|
100
|
-
const body = new FakeElement();
|
|
101
|
-
const head = new FakeElement();
|
|
102
|
-
const documentElement = new FakeElement();
|
|
103
|
-
globalThis.HTMLElement = FakeHTMLElement;
|
|
104
|
-
globalThis.document = {
|
|
105
|
-
body,
|
|
106
|
-
head,
|
|
107
|
-
documentElement,
|
|
108
|
-
createElement: () => new FakeElement(),
|
|
109
|
-
getElementById(id) {
|
|
110
|
-
return [head, ...head.children].find((element) => element.attributes.get('id') === id) || null;
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
globalThis.customElements = {
|
|
114
|
-
registry: new Map(),
|
|
115
|
-
define(name, constructor) {
|
|
116
|
-
this.registry.set(name, constructor);
|
|
117
|
-
},
|
|
118
|
-
get(name) {
|
|
119
|
-
return this.registry.get(name);
|
|
120
|
-
}
|
|
121
|
-
};
|
|
122
|
-
globalThis.innerHeight = 1000;
|
|
123
|
-
globalThis.pageYOffset = 0;
|
|
124
|
-
globalThis.scrollY = 0;
|
|
125
|
-
globalThis.listeners = new Map();
|
|
126
|
-
globalThis.addEventListener = (type, listener) => {
|
|
127
|
-
if (!globalThis.listeners.has(type)) globalThis.listeners.set(type, new Set());
|
|
128
|
-
globalThis.listeners.get(type).add(listener);
|
|
129
|
-
};
|
|
130
|
-
globalThis.removeEventListener = (type, listener) => globalThis.listeners.get(type)?.delete(listener);
|
|
131
|
-
globalThis.getComputedStyle = (element) => ({
|
|
132
|
-
overflow: element._overflow || 'visible',
|
|
133
|
-
overflowY: element._overflowY || 'visible'
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
await import('../atharvmandlavdiya.js');
|
|
137
|
-
|
|
138
|
-
const ProgressCard = customElements.get('progress-card');
|
|
139
|
-
const createdCards = [];
|
|
140
|
-
|
|
141
|
-
afterEach(() => {
|
|
142
|
-
for (const card of createdCards.splice(0)) {
|
|
143
|
-
card.parentElement?.removeChild(card);
|
|
144
|
-
card.disconnectedCallback();
|
|
145
|
-
}
|
|
146
|
-
globalThis.pageYOffset = 0;
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
function createCard(parent = body, scrollLength = '300') {
|
|
150
|
-
const card = new ProgressCard();
|
|
151
|
-
card.setAttribute('data-scroll-length', scrollLength);
|
|
152
|
-
parent.appendChild(card);
|
|
153
|
-
card.connectedCallback();
|
|
154
|
-
createdCards.push(card);
|
|
155
|
-
const wrapper = card.parentElement;
|
|
156
|
-
wrapper._height = 3000;
|
|
157
|
-
wrapper._rect = { top: 0, height: 3000 };
|
|
158
|
-
card._onScroll();
|
|
159
|
-
return { card, wrapper };
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
test('registers automatically, injects CSS, and needs no StringTune', () => {
|
|
163
|
-
assert.equal(typeof ProgressCard, 'function');
|
|
164
|
-
assert.match(head.children[0].textContent || head.children[0].style?.textContent || '', /progress-wrapper/);
|
|
165
|
-
assert.equal(globalThis.StringTune, undefined);
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
test('uses the window scroll range and clamps at both ends', () => {
|
|
169
|
-
const { card } = createCard();
|
|
170
|
-
assert.equal(card.style.getPropertyValue('--progress'), '0');
|
|
171
|
-
globalThis.pageYOffset = 1000;
|
|
172
|
-
card.parentElement._rect = { top: -1000, height: 3000 };
|
|
173
|
-
card._onScroll();
|
|
174
|
-
assert.equal(card.style.getPropertyValue('--progress'), '0.5');
|
|
175
|
-
globalThis.pageYOffset = 2000;
|
|
176
|
-
card.parentElement._rect = { top: -2000, height: 3000 };
|
|
177
|
-
card._onScroll();
|
|
178
|
-
assert.equal(card.style.getPropertyValue('--progress'), '1');
|
|
179
|
-
globalThis.pageYOffset = 2500;
|
|
180
|
-
card.parentElement._rect = { top: -2500, height: 3000 };
|
|
181
|
-
card._onScroll();
|
|
182
|
-
assert.equal(card.style.getPropertyValue('--progress'), '1');
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
test('uses the nearest nested scroll container', () => {
|
|
186
|
-
globalThis.pageYOffset = 0;
|
|
187
|
-
const brand = new FakeElement();
|
|
188
|
-
brand._overflowY = 'auto';
|
|
189
|
-
brand.clientHeight = 500;
|
|
190
|
-
brand.scrollHeight = 2000;
|
|
191
|
-
brand._rect = { top: 10, height: 500 };
|
|
192
|
-
body.appendChild(brand);
|
|
193
|
-
const { card, wrapper } = createCard(brand);
|
|
194
|
-
wrapper._height = 1500;
|
|
195
|
-
wrapper._rect = { top: 10, height: 1500 };
|
|
196
|
-
brand.scrollTop = 500;
|
|
197
|
-
wrapper._rect = { top: -490, height: 1500 };
|
|
198
|
-
card._onScroll();
|
|
199
|
-
assert.equal(card.style.getPropertyValue('--progress'), '0.5');
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
test('keeps cards independent and removes listeners on disconnect', () => {
|
|
203
|
-
const first = createCard();
|
|
204
|
-
const second = createCard();
|
|
205
|
-
assert.notEqual(first.card, second.card);
|
|
206
|
-
assert.equal(globalThis.listeners.get('resize').size >= 2, true);
|
|
207
|
-
first.card.parentElement.removeChild(first.card);
|
|
208
|
-
first.card.disconnectedCallback();
|
|
209
|
-
assert.equal(globalThis.listeners.get('resize').size >= 1, true);
|
|
210
|
-
second.card.parentElement.removeChild(second.card);
|
|
211
|
-
second.card.disconnectedCallback();
|
|
212
|
-
assert.equal(globalThis.listeners.get('resize').size, 0);
|
|
213
|
-
});
|