@mantou/gem 2.2.10 → 2.2.12
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/dist/gem.js +4 -4
- package/dist/gem.mjs +4 -4
- package/elements/base/gesture.d.ts +15 -1
- package/elements/base/gesture.d.ts.map +1 -1
- package/elements/base/gesture.js +90 -39
- package/elements/base/gesture.js.map +1 -1
- package/helper/theme.d.ts.map +1 -1
- package/helper/theme.js +12 -2
- package/helper/theme.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +1 -1
- package/src/elements/base/gesture.ts +113 -40
- package/src/helper/theme.ts +15 -2
- package/src/lib/version.ts +1 -1
- package/src/test/elements/gesture.test.ts +347 -0
- package/src/test/gem-element/decorators.test.ts +67 -0
- package/src/test/utils.ts +1 -1
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
import type { EndEventDetail, GemGestureElement, SwipeEventDetail } from '../../elements/gesture';
|
|
2
|
+
import { html } from '../../lib/element';
|
|
3
|
+
import { aTimeout, expect, fixture } from '../utils';
|
|
4
|
+
|
|
5
|
+
import '../../elements/gesture';
|
|
6
|
+
|
|
7
|
+
type Sample = [timeStamp: number, clientX: number, clientY?: number];
|
|
8
|
+
|
|
9
|
+
function pointer(type: string, [timeStamp, clientX, clientY = 0]: Sample, pointerId = 1) {
|
|
10
|
+
const event = new PointerEvent(type, {
|
|
11
|
+
bubbles: true,
|
|
12
|
+
pointerType: 'touch',
|
|
13
|
+
isPrimary: pointerId === 1,
|
|
14
|
+
pointerId,
|
|
15
|
+
clientX,
|
|
16
|
+
clientY,
|
|
17
|
+
});
|
|
18
|
+
// timeStamp 是只读属性,PointerEventInit 不接受它。
|
|
19
|
+
Object.defineProperty(event, 'timeStamp', { value: timeStamp });
|
|
20
|
+
return event;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function setupGesture(touchAction = '') {
|
|
24
|
+
const el: GemGestureElement = await fixture(html`<gem-gesture touch-action=${touchAction}></gem-gesture>`);
|
|
25
|
+
const captured = new Set<number>();
|
|
26
|
+
el.setPointerCapture = (id) => captured.add(id);
|
|
27
|
+
el.releasePointerCapture = (id) => captured.delete(id);
|
|
28
|
+
el.hasPointerCapture = (id) => captured.has(id);
|
|
29
|
+
const swipes: SwipeEventDetail[] = [];
|
|
30
|
+
const events: string[] = [];
|
|
31
|
+
el.addEventListener('swipe', (evt: CustomEvent<SwipeEventDetail>) => {
|
|
32
|
+
swipes.push(evt.detail);
|
|
33
|
+
events.push('swipe');
|
|
34
|
+
});
|
|
35
|
+
el.addEventListener('end', () => events.push('end'));
|
|
36
|
+
const dispatch = (type: string, sample: Sample, id = 1) => el.dispatchEvent(pointer(type, sample, id));
|
|
37
|
+
return { el, swipes, events, dispatch };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
describe('GemGestureElement end', () => {
|
|
41
|
+
for (const type of ['pointerup', 'pointercancel', 'pointerleave']) {
|
|
42
|
+
it(`includes the original ${type} event and resets pressed for the next gesture`, async () => {
|
|
43
|
+
const { el, dispatch } = await setupGesture();
|
|
44
|
+
const ends: EndEventDetail[] = [];
|
|
45
|
+
el.addEventListener('end', (evt: CustomEvent<EndEventDetail>) => ends.push(evt.detail));
|
|
46
|
+
const pressed = new Promise((resolve) => el.addEventListener('press', resolve, { once: true }));
|
|
47
|
+
dispatch('pointerdown', [0, 0]);
|
|
48
|
+
await pressed;
|
|
49
|
+
const event = pointer(type, [300, 10, 20]);
|
|
50
|
+
el.dispatchEvent(event);
|
|
51
|
+
await Promise.resolve();
|
|
52
|
+
expect(ends).to.have.lengthOf(1);
|
|
53
|
+
expect(ends[0].event).to.equal(event);
|
|
54
|
+
expect(ends[0].pressed).to.equal(true);
|
|
55
|
+
|
|
56
|
+
dispatch('pointerdown', [400, 0]);
|
|
57
|
+
dispatch('pointerup', [450, 0]);
|
|
58
|
+
await Promise.resolve();
|
|
59
|
+
expect(ends).to.have.lengthOf(2);
|
|
60
|
+
expect(ends[1].pressed).to.equal(false);
|
|
61
|
+
expect(ends[0].pressed).to.equal(true);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
it('sets pressed before a press handler synchronously ends the gesture', async () => {
|
|
66
|
+
const { el, dispatch } = await setupGesture();
|
|
67
|
+
const ended = new Promise<EndEventDetail>((resolve) => {
|
|
68
|
+
el.addEventListener('end', (evt: CustomEvent<EndEventDetail>) => resolve(evt.detail), { once: true });
|
|
69
|
+
});
|
|
70
|
+
el.addEventListener('press', () => dispatch('pointerup', [300, 0]), { once: true });
|
|
71
|
+
dispatch('pointerdown', [0, 0]);
|
|
72
|
+
expect((await ended).pressed).to.equal(true);
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
describe('GemGestureElement swipe', () => {
|
|
77
|
+
for (const [direction, x, y] of [
|
|
78
|
+
['right', 60, 0],
|
|
79
|
+
['left', -60, 0],
|
|
80
|
+
['bottom', 0, 60],
|
|
81
|
+
['top', 0, -60],
|
|
82
|
+
] as const) {
|
|
83
|
+
it(`emits ${direction} with release speed before end`, async () => {
|
|
84
|
+
const { el, swipes, events, dispatch } = await setupGesture();
|
|
85
|
+
dispatch('pointerdown', [0, 100, 100]);
|
|
86
|
+
dispatch('pointermove', [50, 100 + x, 100 + y]);
|
|
87
|
+
let movesAtEnd = 0;
|
|
88
|
+
el.addEventListener('end', () => {
|
|
89
|
+
movesAtEnd = el.movesMap.get(1)!.length;
|
|
90
|
+
expect(el.grabbing).to.equal(false);
|
|
91
|
+
});
|
|
92
|
+
dispatch('pointerup', [60, 100 + x, 100 + y]);
|
|
93
|
+
await Promise.resolve();
|
|
94
|
+
expect(swipes).to.deep.equal([{ direction, speed: 1 }]);
|
|
95
|
+
expect(events).to.deep.equal(['swipe', 'end']);
|
|
96
|
+
expect(movesAtEnd).to.equal(1);
|
|
97
|
+
await Promise.resolve();
|
|
98
|
+
expect(el.movesMap.size).to.equal(0);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
for (const frequency of [30, 60, 120, 240]) {
|
|
103
|
+
it(`samples the same release velocity at ${frequency} Hz`, async () => {
|
|
104
|
+
const { swipes, dispatch } = await setupGesture();
|
|
105
|
+
dispatch('pointerdown', [0, 0]);
|
|
106
|
+
for (let time = 1000 / frequency; time < 250; time += 1000 / frequency) {
|
|
107
|
+
dispatch('pointermove', [time, time <= 100 ? time * 0.2 : 20 + (time - 100) * 0.8]);
|
|
108
|
+
}
|
|
109
|
+
dispatch('pointerup', [250, 140]);
|
|
110
|
+
await Promise.resolve();
|
|
111
|
+
expect(swipes).to.have.lengthOf(1);
|
|
112
|
+
expect(swipes[0].direction).to.equal('right');
|
|
113
|
+
expect(swipes[0].speed).to.be.closeTo(0.8, 0.000001);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
it('interpolates the window boundary instead of including stale movement', async () => {
|
|
118
|
+
const { swipes, dispatch } = await setupGesture();
|
|
119
|
+
dispatch('pointerdown', [0, 0]);
|
|
120
|
+
dispatch('pointermove', [50, 5]);
|
|
121
|
+
dispatch('pointermove', [150, 105]);
|
|
122
|
+
dispatch('pointerup', [180, 135]);
|
|
123
|
+
await Promise.resolve();
|
|
124
|
+
expect(swipes).to.deep.equal([{ direction: 'right', speed: 1 }]);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('includes movement delivered only on pointerup', async () => {
|
|
128
|
+
const { swipes, dispatch } = await setupGesture();
|
|
129
|
+
dispatch('pointerdown', [0, 0]);
|
|
130
|
+
dispatch('pointerup', [50, 50]);
|
|
131
|
+
await Promise.resolve();
|
|
132
|
+
expect(swipes).to.deep.equal([{ direction: 'right', speed: 1 }]);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('reduces velocity when the finger pauses briefly before release', async () => {
|
|
136
|
+
const { swipes, dispatch } = await setupGesture();
|
|
137
|
+
dispatch('pointerdown', [0, 0]);
|
|
138
|
+
dispatch('pointermove', [40, 40]);
|
|
139
|
+
dispatch('pointerup', [80, 40]);
|
|
140
|
+
await Promise.resolve();
|
|
141
|
+
expect(swipes).to.deep.equal([{ direction: 'right', speed: 0.5 }]);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
for (const [name, samples] of [
|
|
145
|
+
[
|
|
146
|
+
'slow drag',
|
|
147
|
+
[
|
|
148
|
+
[0, 0],
|
|
149
|
+
[150, 30],
|
|
150
|
+
[180, 35],
|
|
151
|
+
],
|
|
152
|
+
],
|
|
153
|
+
[
|
|
154
|
+
'tap jitter',
|
|
155
|
+
[
|
|
156
|
+
[0, 0],
|
|
157
|
+
[10, 8],
|
|
158
|
+
[20, 7],
|
|
159
|
+
],
|
|
160
|
+
],
|
|
161
|
+
[
|
|
162
|
+
'paused drag',
|
|
163
|
+
[
|
|
164
|
+
[0, 0],
|
|
165
|
+
[40, 80],
|
|
166
|
+
[140, 80],
|
|
167
|
+
],
|
|
168
|
+
],
|
|
169
|
+
[
|
|
170
|
+
'diagonal without a dominant axis',
|
|
171
|
+
[
|
|
172
|
+
[0, 0],
|
|
173
|
+
[40, 40, 40],
|
|
174
|
+
[50, 50, 50],
|
|
175
|
+
],
|
|
176
|
+
],
|
|
177
|
+
[
|
|
178
|
+
'zero duration',
|
|
179
|
+
[
|
|
180
|
+
[0, 0],
|
|
181
|
+
[0, 50],
|
|
182
|
+
[0, 80],
|
|
183
|
+
],
|
|
184
|
+
],
|
|
185
|
+
[
|
|
186
|
+
'short reversal',
|
|
187
|
+
[
|
|
188
|
+
[0, 0],
|
|
189
|
+
[30, 100],
|
|
190
|
+
[60, 85],
|
|
191
|
+
],
|
|
192
|
+
],
|
|
193
|
+
] satisfies [string, Sample[]][]) {
|
|
194
|
+
it(`does not swipe on ${name}`, async () => {
|
|
195
|
+
const { swipes, dispatch } = await setupGesture();
|
|
196
|
+
dispatch('pointerdown', samples[0]);
|
|
197
|
+
dispatch('pointermove', samples[1]);
|
|
198
|
+
dispatch('pointerup', samples[2]);
|
|
199
|
+
await Promise.resolve();
|
|
200
|
+
expect(swipes).to.deep.equal([]);
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
it('uses the final flick direction after reversing a drag', async () => {
|
|
205
|
+
const { swipes, dispatch } = await setupGesture();
|
|
206
|
+
dispatch('pointerdown', [0, 0]);
|
|
207
|
+
dispatch('pointermove', [40, 100]);
|
|
208
|
+
dispatch('pointermove', [60, 80]);
|
|
209
|
+
dispatch('pointerup', [80, 60]);
|
|
210
|
+
await Promise.resolve();
|
|
211
|
+
expect(swipes).to.deep.equal([{ direction: 'left', speed: 1 }]);
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('ignores a small backwards jitter at release', async () => {
|
|
215
|
+
const { swipes, dispatch } = await setupGesture();
|
|
216
|
+
dispatch('pointerdown', [0, 0]);
|
|
217
|
+
dispatch('pointermove', [50, 60]);
|
|
218
|
+
dispatch('pointerup', [60, 58]);
|
|
219
|
+
await Promise.resolve();
|
|
220
|
+
expect(swipes).to.have.lengthOf(1);
|
|
221
|
+
expect(swipes[0].direction).to.equal('right');
|
|
222
|
+
expect(swipes[0].speed).to.be.closeTo(58 / 60, 0.000001);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
for (const [touchAction, x, y] of [
|
|
226
|
+
['pan-x', 50, 0],
|
|
227
|
+
['pan-y', 0, 50],
|
|
228
|
+
['pan-right', 50, 0],
|
|
229
|
+
['pan-left', -50, 0],
|
|
230
|
+
['pan-down', 0, 50],
|
|
231
|
+
['pan-up', 0, -50],
|
|
232
|
+
] as const) {
|
|
233
|
+
it(`respects touch-action=${touchAction}`, async () => {
|
|
234
|
+
const { swipes, dispatch } = await setupGesture(touchAction);
|
|
235
|
+
dispatch('pointerdown', [0, 0]);
|
|
236
|
+
dispatch('pointermove', [40, x, y]);
|
|
237
|
+
dispatch('pointerup', [50, x, y]);
|
|
238
|
+
await Promise.resolve();
|
|
239
|
+
expect(swipes).to.deep.equal([]);
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
it('allows horizontal flicks with touch-action=pan-y', async () => {
|
|
244
|
+
const { swipes, dispatch } = await setupGesture('pan-y');
|
|
245
|
+
dispatch('pointerdown', [0, 0]);
|
|
246
|
+
dispatch('pointermove', [40, 50, 2]);
|
|
247
|
+
dispatch('pointerup', [50, 50, 2]);
|
|
248
|
+
await Promise.resolve();
|
|
249
|
+
expect(swipes).to.deep.equal([{ direction: 'right', speed: 1 }]);
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
for (const type of ['pointercancel', 'pointerleave']) {
|
|
253
|
+
it(`does not swipe on ${type} or duplicate end events`, async () => {
|
|
254
|
+
const { swipes, events, dispatch } = await setupGesture();
|
|
255
|
+
dispatch('pointerdown', [0, 0]);
|
|
256
|
+
dispatch('pointermove', [40, 50]);
|
|
257
|
+
dispatch(type, [50, 50]);
|
|
258
|
+
dispatch('pointerup', [50, 50]);
|
|
259
|
+
await Promise.resolve();
|
|
260
|
+
expect(swipes).to.deep.equal([]);
|
|
261
|
+
expect(events).to.deep.equal(['end']);
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
it('ignores end events from pointers outside the gesture', async () => {
|
|
266
|
+
const { el, events, dispatch } = await setupGesture();
|
|
267
|
+
dispatch('pointerdown', [0, 0]);
|
|
268
|
+
dispatch('pointerleave', [10, 0], 2);
|
|
269
|
+
expect(events).to.deep.equal([]);
|
|
270
|
+
expect(el.grabbing).to.equal(true);
|
|
271
|
+
dispatch('pointercancel', [20, 0]);
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
it('does not swipe after losing pointer capture', async () => {
|
|
275
|
+
const { el, swipes, dispatch } = await setupGesture();
|
|
276
|
+
dispatch('pointerdown', [0, 0]);
|
|
277
|
+
dispatch('pointermove', [40, 50]);
|
|
278
|
+
el.releasePointerCapture(1);
|
|
279
|
+
dispatch('pointerup', [50, 50]);
|
|
280
|
+
await Promise.resolve();
|
|
281
|
+
expect(swipes).to.deep.equal([]);
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
it('suppresses both fingers of a multitouch gesture and resets for the next gesture', async () => {
|
|
285
|
+
const { el, swipes, events, dispatch } = await setupGesture();
|
|
286
|
+
dispatch('pointerdown', [0, 0]);
|
|
287
|
+
dispatch('pointerdown', [10, 100], 2);
|
|
288
|
+
dispatch('pointermove', [30, 30]);
|
|
289
|
+
dispatch('pointerup', [40, 40]);
|
|
290
|
+
await Promise.resolve();
|
|
291
|
+
expect(el.grabbing).to.equal(true);
|
|
292
|
+
expect(events).to.deep.equal([]);
|
|
293
|
+
await Promise.resolve();
|
|
294
|
+
dispatch('pointermove', [60, 150], 2);
|
|
295
|
+
dispatch('pointerup', [80, 170], 2);
|
|
296
|
+
await Promise.resolve();
|
|
297
|
+
expect(swipes).to.deep.equal([]);
|
|
298
|
+
expect(events).to.deep.equal(['end']);
|
|
299
|
+
dispatch('pointerdown', [100, 0]);
|
|
300
|
+
dispatch('pointermove', [140, 50]);
|
|
301
|
+
dispatch('pointerup', [150, 50]);
|
|
302
|
+
await Promise.resolve();
|
|
303
|
+
expect(swipes).to.deep.equal([{ direction: 'right', speed: 1 }]);
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
it('does not swipe after a long press', async () => {
|
|
307
|
+
const { el, swipes, dispatch } = await setupGesture();
|
|
308
|
+
const pressed = new Promise((resolve) => el.addEventListener('press', resolve, { once: true }));
|
|
309
|
+
dispatch('pointerdown', [0, 0]);
|
|
310
|
+
await pressed;
|
|
311
|
+
dispatch('pointermove', [300, 0]);
|
|
312
|
+
dispatch('pointermove', [340, 60]);
|
|
313
|
+
dispatch('pointerup', [350, 60]);
|
|
314
|
+
await Promise.resolve();
|
|
315
|
+
expect(swipes).to.deep.equal([]);
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
it('handles coalesced samples and the empty-list fallback', async () => {
|
|
319
|
+
const { el, swipes, dispatch } = await setupGesture();
|
|
320
|
+
dispatch('pointerdown', [0, 0]);
|
|
321
|
+
const coalesced = pointer('pointermove', [50, 50]);
|
|
322
|
+
Object.defineProperty(coalesced, 'getCoalescedEvents', {
|
|
323
|
+
value: () => [pointer('pointermove', [25, 25]), pointer('pointermove', [50, 50])],
|
|
324
|
+
});
|
|
325
|
+
el.dispatchEvent(coalesced);
|
|
326
|
+
const empty = pointer('pointermove', [75, 75]);
|
|
327
|
+
Object.defineProperty(empty, 'getCoalescedEvents', { value: () => [] });
|
|
328
|
+
el.dispatchEvent(empty);
|
|
329
|
+
expect(el.movesMap.get(1)).to.have.lengthOf(3);
|
|
330
|
+
dispatch('pointerup', [100, 100]);
|
|
331
|
+
await Promise.resolve();
|
|
332
|
+
expect(swipes).to.deep.equal([{ direction: 'right', speed: 1 }]);
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
it('preserves a new gesture started by an end handler', async () => {
|
|
336
|
+
const { el, dispatch } = await setupGesture();
|
|
337
|
+
el.addEventListener('end', () => dispatch('pointerdown', [100, 0]), { once: true });
|
|
338
|
+
dispatch('pointerdown', [0, 0]);
|
|
339
|
+
dispatch('pointermove', [40, 50]);
|
|
340
|
+
dispatch('pointerup', [50, 50]);
|
|
341
|
+
await Promise.resolve();
|
|
342
|
+
await aTimeout();
|
|
343
|
+
expect(el.grabbing).to.equal(true);
|
|
344
|
+
expect(el.movesMap.has(1)).to.equal(true);
|
|
345
|
+
dispatch('pointercancel', [110, 0]);
|
|
346
|
+
});
|
|
347
|
+
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createDecoratorTheme } from '../../helper/theme';
|
|
1
2
|
import type { Emitter } from '../../lib/decorators';
|
|
2
3
|
import {
|
|
3
4
|
adoptedStyle,
|
|
@@ -18,6 +19,51 @@ import { css, GemElement, html } from '../../lib/element';
|
|
|
18
19
|
import { createStore } from '../../lib/store';
|
|
19
20
|
import { expect, fixture } from '../utils';
|
|
20
21
|
|
|
22
|
+
const elemTheme = createDecoratorTheme({ color: 'rgb(255, 0, 0)' });
|
|
23
|
+
|
|
24
|
+
const themeDemoStyle = css`
|
|
25
|
+
:host {
|
|
26
|
+
color: ${elemTheme.color};
|
|
27
|
+
}
|
|
28
|
+
`;
|
|
29
|
+
|
|
30
|
+
@customElement('decorator-theme-demo')
|
|
31
|
+
@adoptedStyle(themeDemoStyle)
|
|
32
|
+
@shadow()
|
|
33
|
+
class DecoratorThemeDemo extends GemElement {
|
|
34
|
+
@boolattribute active: boolean;
|
|
35
|
+
|
|
36
|
+
@elemTheme((i) => [i.active])
|
|
37
|
+
#theme = () => ({
|
|
38
|
+
color: this.active ? 'rgb(0, 0, 255)' : 'rgb(255, 0, 0)',
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
render() {
|
|
42
|
+
return html`Theme Demo`;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const lightThemeDemoStyle = css`
|
|
47
|
+
:scope {
|
|
48
|
+
color: ${elemTheme.color};
|
|
49
|
+
}
|
|
50
|
+
`;
|
|
51
|
+
|
|
52
|
+
@customElement('decorator-theme-light-demo')
|
|
53
|
+
@adoptedStyle(lightThemeDemoStyle)
|
|
54
|
+
class DecoratorThemeLightDemo extends GemElement {
|
|
55
|
+
@boolattribute active: boolean;
|
|
56
|
+
|
|
57
|
+
@elemTheme((i) => [i.active])
|
|
58
|
+
#theme = () => ({
|
|
59
|
+
color: this.active ? 'rgb(0, 0, 255)' : 'rgb(255, 0, 0)',
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
render() {
|
|
63
|
+
return html`<span>Light Theme Demo</span>`;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
21
67
|
const store = createStore({
|
|
22
68
|
a: 1,
|
|
23
69
|
});
|
|
@@ -106,4 +152,25 @@ describe('装饰器', () => {
|
|
|
106
152
|
expect(el.renderCount).to.equal(3);
|
|
107
153
|
expect(a).to.equal(2);
|
|
108
154
|
});
|
|
155
|
+
|
|
156
|
+
it('createDecoratorTheme 响应式更新及多实例隔离', async () => {
|
|
157
|
+
const el1: DecoratorThemeDemo = await fixture(html`<decorator-theme-demo></decorator-theme-demo>`);
|
|
158
|
+
const el2: DecoratorThemeDemo = await fixture(html`<decorator-theme-demo active></decorator-theme-demo>`);
|
|
159
|
+
|
|
160
|
+
expect(getComputedStyle(el1).color).to.equal('rgb(255, 0, 0)');
|
|
161
|
+
expect(getComputedStyle(el2).color).to.equal('rgb(0, 0, 255)');
|
|
162
|
+
|
|
163
|
+
el1.active = true;
|
|
164
|
+
await Promise.resolve();
|
|
165
|
+
expect(getComputedStyle(el1).color).to.equal('rgb(0, 0, 255)');
|
|
166
|
+
expect(getComputedStyle(el2).color).to.equal('rgb(0, 0, 255)');
|
|
167
|
+
|
|
168
|
+
const elLight: DecoratorThemeLightDemo = await fixture(
|
|
169
|
+
html`<decorator-theme-light-demo></decorator-theme-light-demo>`,
|
|
170
|
+
);
|
|
171
|
+
expect(getComputedStyle(elLight).color).to.equal('rgb(255, 0, 0)');
|
|
172
|
+
elLight.active = true;
|
|
173
|
+
await Promise.resolve();
|
|
174
|
+
expect(getComputedStyle(elLight).color).to.equal('rgb(0, 0, 255)');
|
|
175
|
+
});
|
|
109
176
|
});
|
package/src/test/utils.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { assert, expect, should } from 'chai';
|
|
|
3
3
|
import type { TemplateResult } from '../lib/element';
|
|
4
4
|
import { render } from '../lib/element';
|
|
5
5
|
|
|
6
|
-
export { expect, should
|
|
6
|
+
export { assert, expect, should };
|
|
7
7
|
|
|
8
8
|
export function nextFrame() {
|
|
9
9
|
return new Promise((resolve) => requestAnimationFrame(() => resolve(null)));
|