ember-nav-stack 4.3.1 → 5.0.0
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/.prettierignore +21 -0
- package/.prettierrc.js +5 -0
- package/CHANGELOG.md +12 -0
- package/README.md +27 -1
- package/addon/components/nav-stack/component.js +173 -92
- package/addon/components/to-nav-stack.js +2 -1
- package/addon/helpers/nav-layer-indices.js +2 -2
- package/addon/mixins/stackable-route.js +10 -7
- package/addon/services/gesture.js +3 -1
- package/addon/services/nav-stacks.js +18 -13
- package/addon/utils/animation.js +12 -7
- package/addon/utils/back-swipe-recognizer.js +33 -14
- package/addon/utils/component.js +32 -15
- package/addon-test-support/in-viewport.js +7 -4
- package/app/styles/nav-stack.scss +10 -6
- package/config/deploy.js +2 -2
- package/config/environment.js +2 -2
- package/index.js +4 -4
- package/package.json +59 -39
package/.prettierignore
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# unconventional js
|
|
2
|
+
/blueprints/*/files/
|
|
3
|
+
/vendor/
|
|
4
|
+
|
|
5
|
+
# compiled output
|
|
6
|
+
/dist/
|
|
7
|
+
/tmp/
|
|
8
|
+
|
|
9
|
+
# dependencies
|
|
10
|
+
/bower_components/
|
|
11
|
+
/node_modules/
|
|
12
|
+
|
|
13
|
+
# misc
|
|
14
|
+
/coverage/
|
|
15
|
+
!.*
|
|
16
|
+
.eslintcache
|
|
17
|
+
|
|
18
|
+
# ember-try
|
|
19
|
+
/.node_modules.ember-try/
|
|
20
|
+
/bower.json.ember-try
|
|
21
|
+
/package.json.ember-try
|
package/.prettierrc.js
ADDED
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## v5.0.0 (2023-09-19)
|
|
2
|
+
|
|
3
|
+
#### :rocket: Enhancement
|
|
4
|
+
* [#70](https://github.com/yapplabs/ember-nav-stack/pull/70) Update to ember 3.24 ([@lukemelia](https://github.com/lukemelia))
|
|
5
|
+
|
|
6
|
+
#### Committers: 1
|
|
7
|
+
- Luke Melia ([@lukemelia](https://github.com/lukemelia))
|
|
8
|
+
|
|
9
|
+
## v4.3.3 (2021-02-08)
|
|
10
|
+
|
|
11
|
+
## v4.3.2 (2021-02-05)
|
|
12
|
+
|
|
1
13
|
## v4.3.1 (2020-10-21)
|
|
2
14
|
|
|
3
15
|
## v4.3.0 (2020-06-16)
|
package/README.md
CHANGED
|
@@ -4,7 +4,33 @@ This addon is used by Yapp to blend mobile-style stack navigation with Ember rou
|
|
|
4
4
|
|
|
5
5
|
This addon's current status is "opensource, but unpolished". It lacks tests, docs, and other niceties of a well-maintained Ember addon.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Compatibility
|
|
8
|
+
------------------------------------------------------------------------------
|
|
9
|
+
|
|
10
|
+
* Ember.js v3.16 or above
|
|
11
|
+
* Ember CLI v2.13 or above
|
|
12
|
+
* Node.js v10 or above
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
Installation
|
|
16
|
+
------------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
ember install ember-nav-stack
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
Usage
|
|
24
|
+
------------------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
[Longer description of how to use the addon in apps.]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
Contributing
|
|
30
|
+
------------------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
See the [Contributing](CONTRIBUTING.md) guide for details.
|
|
33
|
+
|
|
8
34
|
|
|
9
35
|
License
|
|
10
36
|
------------------------------------------------------------------------------
|
|
@@ -14,7 +14,7 @@ import { setTransform } from 'ember-nav-stack/utils/animation';
|
|
|
14
14
|
import { inject as service } from '@ember/service';
|
|
15
15
|
import { bool, mapBy, reads } from 'macro-decorators';
|
|
16
16
|
import { guidFor } from '@ember/object/internals';
|
|
17
|
-
import { extractComponentKey } from 'ember-nav-stack/utils/component'
|
|
17
|
+
import { extractComponentKey } from 'ember-nav-stack/utils/component';
|
|
18
18
|
|
|
19
19
|
function currentTransitionPercentage(fromValue, toValue, currentValue) {
|
|
20
20
|
if (fromValue === undefined || fromValue === toValue) {
|
|
@@ -27,7 +27,12 @@ function currentTransitionPercentage(fromValue, toValue, currentValue) {
|
|
|
27
27
|
return percentage;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
function styleHeaderElements(
|
|
30
|
+
function styleHeaderElements(
|
|
31
|
+
transitionRatio,
|
|
32
|
+
isForward,
|
|
33
|
+
currentHeaderElement,
|
|
34
|
+
otherHeaderElement,
|
|
35
|
+
) {
|
|
31
36
|
let startingOffset = 60;
|
|
32
37
|
if (!isForward) {
|
|
33
38
|
transitionRatio = 1 - transitionRatio;
|
|
@@ -36,7 +41,10 @@ function styleHeaderElements(transitionRatio, isForward, currentHeaderElement, o
|
|
|
36
41
|
let xOffset = transitionRatio * -1 * startingOffset;
|
|
37
42
|
if (currentHeaderElement) {
|
|
38
43
|
currentHeaderElement.style.opacity = transitionRatio;
|
|
39
|
-
setTransform(
|
|
44
|
+
setTransform(
|
|
45
|
+
currentHeaderElement,
|
|
46
|
+
`translateX(${startingOffset + xOffset}px)`,
|
|
47
|
+
);
|
|
40
48
|
}
|
|
41
49
|
if (otherHeaderElement) {
|
|
42
50
|
otherHeaderElement.style.opacity = 1 - transitionRatio;
|
|
@@ -59,6 +67,8 @@ export default class NavStack extends Component {
|
|
|
59
67
|
return this.args.birdsEyeDebugging || false;
|
|
60
68
|
}
|
|
61
69
|
|
|
70
|
+
element;
|
|
71
|
+
|
|
62
72
|
get elementId() {
|
|
63
73
|
return guidFor(this);
|
|
64
74
|
}
|
|
@@ -98,7 +108,7 @@ export default class NavStack extends Component {
|
|
|
98
108
|
return this.stackItems[this.stackItems.length - 2].headerComponent;
|
|
99
109
|
}
|
|
100
110
|
|
|
101
|
-
get stackItems(){
|
|
111
|
+
get stackItems() {
|
|
102
112
|
return get(this.navStacksService, `stacks.layer${this.args.layer}`) || [];
|
|
103
113
|
}
|
|
104
114
|
|
|
@@ -111,7 +121,10 @@ export default class NavStack extends Component {
|
|
|
111
121
|
get suppressAnimation() {
|
|
112
122
|
if (this._suppressAnimation === undefined) {
|
|
113
123
|
const config = getOwner(this).resolveRegistration('config:environment');
|
|
114
|
-
|
|
124
|
+
// eslint-disable-next-line ember/no-side-effects
|
|
125
|
+
this._suppressAnimation =
|
|
126
|
+
config['ember-nav-stack'] &&
|
|
127
|
+
config['ember-nav-stack'].suppressAnimation;
|
|
115
128
|
}
|
|
116
129
|
return this._suppressAnimation;
|
|
117
130
|
}
|
|
@@ -119,20 +132,23 @@ export default class NavStack extends Component {
|
|
|
119
132
|
clones = {
|
|
120
133
|
stackItems: [],
|
|
121
134
|
headers: [],
|
|
122
|
-
elements: []
|
|
123
|
-
}
|
|
135
|
+
elements: [],
|
|
136
|
+
};
|
|
124
137
|
|
|
125
138
|
@action
|
|
126
139
|
setupHammer(el) {
|
|
127
140
|
this.element = el;
|
|
128
141
|
this.hammer = new Hammer.Manager(this.element, {
|
|
129
142
|
inputClass: Hammer.TouchMouseInput,
|
|
130
|
-
recognizers: [
|
|
131
|
-
[BackSwipeRecognizer]
|
|
132
|
-
]
|
|
143
|
+
recognizers: [[BackSwipeRecognizer]],
|
|
133
144
|
});
|
|
134
145
|
let isInitialRender = this.navStacksService.isInitialRender;
|
|
135
|
-
scheduleOnce(
|
|
146
|
+
scheduleOnce(
|
|
147
|
+
'afterRender',
|
|
148
|
+
this,
|
|
149
|
+
this.handleStackDepthChange,
|
|
150
|
+
isInitialRender,
|
|
151
|
+
);
|
|
136
152
|
this._setupPanHandlerContext();
|
|
137
153
|
|
|
138
154
|
let { hammer, gesture } = this;
|
|
@@ -141,7 +157,7 @@ export default class NavStack extends Component {
|
|
|
141
157
|
}
|
|
142
158
|
|
|
143
159
|
@action
|
|
144
|
-
tearDownHammer(){
|
|
160
|
+
tearDownHammer() {
|
|
145
161
|
let { hammer, gesture } = this;
|
|
146
162
|
gesture.unregister(this, hammer.get('pan'));
|
|
147
163
|
hammer.off('pan');
|
|
@@ -156,30 +172,28 @@ export default class NavStack extends Component {
|
|
|
156
172
|
let stackItems = this.stackItems || [];
|
|
157
173
|
let stackDepth = stackItems.length;
|
|
158
174
|
let rootComponentRef = stackItems[0] && stackItems[0].component;
|
|
159
|
-
let rootComponentKey = this.args.extractComponentKey
|
|
175
|
+
let rootComponentKey = this.args.extractComponentKey
|
|
176
|
+
? this.args.extractComponentKey(rootComponentRef)
|
|
177
|
+
: extractComponentKey(rootComponentRef);
|
|
160
178
|
|
|
161
179
|
let layer = this.args.layer;
|
|
162
180
|
if (isInitialRender) {
|
|
163
181
|
this.schedule(this.cut);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
|
|
182
|
+
} else if (
|
|
183
|
+
(layer > 0 && stackDepth > 0 && this._stackDepth === 0) ||
|
|
184
|
+
this._stackDepth === undefined
|
|
185
|
+
) {
|
|
167
186
|
this.schedule(this.slideUp);
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
else if (layer > 0 && stackDepth === 0 && this._stackDepth > 0) {
|
|
187
|
+
} else if (layer > 0 && stackDepth === 0 && this._stackDepth > 0) {
|
|
171
188
|
this.cloneElement();
|
|
172
189
|
this.element.style.display = 'none';
|
|
173
190
|
this.schedule(this.slideDown);
|
|
174
|
-
|
|
175
191
|
} else if (rootComponentKey !== this._rootComponentKey) {
|
|
176
192
|
this.schedule(this.cut);
|
|
177
|
-
|
|
178
193
|
} else if (stackDepth < this._stackDepth) {
|
|
179
194
|
this.cloneLastStackItem();
|
|
180
195
|
this.cloneHeader();
|
|
181
196
|
this.schedule(this.slideBack);
|
|
182
|
-
|
|
183
197
|
} else if (stackDepth > this._stackDepth) {
|
|
184
198
|
this.cloneHeader();
|
|
185
199
|
this.schedule(this.slideForward);
|
|
@@ -198,7 +212,9 @@ export default class NavStack extends Component {
|
|
|
198
212
|
if (stackDepth === 0) {
|
|
199
213
|
return 0;
|
|
200
214
|
}
|
|
201
|
-
let currentStackItemElement = this.element.querySelector(
|
|
215
|
+
let currentStackItemElement = this.element.querySelector(
|
|
216
|
+
'.NavStack-item:last-child',
|
|
217
|
+
);
|
|
202
218
|
if (!currentStackItemElement) {
|
|
203
219
|
return 0;
|
|
204
220
|
}
|
|
@@ -210,7 +226,9 @@ export default class NavStack extends Component {
|
|
|
210
226
|
|
|
211
227
|
@action
|
|
212
228
|
repositionX() {
|
|
213
|
-
let itemContainerElement = this.element.querySelector(
|
|
229
|
+
let itemContainerElement = this.element.querySelector(
|
|
230
|
+
'.NavStack-itemContainer',
|
|
231
|
+
);
|
|
214
232
|
let newX = this.computeXPosition();
|
|
215
233
|
setTransform(itemContainerElement, `translateX(${newX}px)`);
|
|
216
234
|
}
|
|
@@ -218,14 +236,14 @@ export default class NavStack extends Component {
|
|
|
218
236
|
cut() {
|
|
219
237
|
this.horizontalTransition({
|
|
220
238
|
toValue: this.computeXPosition(),
|
|
221
|
-
animate: false
|
|
239
|
+
animate: false,
|
|
222
240
|
});
|
|
223
241
|
|
|
224
|
-
if (this.args.layer > 0 & this.stackDepth > 0) {
|
|
242
|
+
if ((this.args.layer > 0) & (this.stackDepth > 0)) {
|
|
225
243
|
this.verticalTransition({
|
|
226
244
|
element: this.element,
|
|
227
245
|
toValue: 0,
|
|
228
|
-
animate: false
|
|
246
|
+
animate: false,
|
|
229
247
|
});
|
|
230
248
|
}
|
|
231
249
|
}
|
|
@@ -235,7 +253,7 @@ export default class NavStack extends Component {
|
|
|
235
253
|
toValue: this.computeXPosition(),
|
|
236
254
|
finishCallback: () => {
|
|
237
255
|
this.removeClonedHeader();
|
|
238
|
-
}
|
|
256
|
+
},
|
|
239
257
|
});
|
|
240
258
|
}
|
|
241
259
|
|
|
@@ -245,7 +263,7 @@ export default class NavStack extends Component {
|
|
|
245
263
|
finishCallback: () => {
|
|
246
264
|
this.removeClonedStackItem();
|
|
247
265
|
this.removeClonedHeader();
|
|
248
|
-
}
|
|
266
|
+
},
|
|
249
267
|
});
|
|
250
268
|
}
|
|
251
269
|
|
|
@@ -254,7 +272,7 @@ export default class NavStack extends Component {
|
|
|
254
272
|
this.verticalTransition({
|
|
255
273
|
element: this.element,
|
|
256
274
|
toValue: 0,
|
|
257
|
-
fromValue: debug ? 480 : this.element.getBoundingClientRect().height
|
|
275
|
+
fromValue: debug ? 480 : this.element.getBoundingClientRect().height,
|
|
258
276
|
});
|
|
259
277
|
}
|
|
260
278
|
|
|
@@ -268,15 +286,26 @@ export default class NavStack extends Component {
|
|
|
268
286
|
toValue: y,
|
|
269
287
|
finishCallback: () => {
|
|
270
288
|
this.removeClonedElement();
|
|
271
|
-
}
|
|
289
|
+
},
|
|
272
290
|
});
|
|
273
291
|
});
|
|
274
292
|
}
|
|
275
293
|
|
|
276
|
-
horizontalTransition({
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
294
|
+
horizontalTransition({
|
|
295
|
+
toValue,
|
|
296
|
+
fromValue,
|
|
297
|
+
animate = !this.suppressAnimation,
|
|
298
|
+
finishCallback,
|
|
299
|
+
}) {
|
|
300
|
+
let itemContainerElement = this.element.querySelector(
|
|
301
|
+
'.NavStack-itemContainer',
|
|
302
|
+
);
|
|
303
|
+
let currentHeaderElement = this.element.querySelector(
|
|
304
|
+
'.NavStack-currentHeaderContainer',
|
|
305
|
+
);
|
|
306
|
+
let clonedHeaderElement = this.element.querySelector(
|
|
307
|
+
'.NavStack-clonedHeaderContainer',
|
|
308
|
+
);
|
|
280
309
|
|
|
281
310
|
this.transitionDidBegin();
|
|
282
311
|
this.notifyTransitionStart();
|
|
@@ -286,7 +315,7 @@ export default class NavStack extends Component {
|
|
|
286
315
|
currentTransitionPercentage(fromValue, toValue, toValue),
|
|
287
316
|
fromValue === undefined || fromValue > toValue,
|
|
288
317
|
currentHeaderElement,
|
|
289
|
-
clonedHeaderElement
|
|
318
|
+
clonedHeaderElement,
|
|
290
319
|
);
|
|
291
320
|
this.notifyTransitionEnd();
|
|
292
321
|
this.transitionDidEnd();
|
|
@@ -301,23 +330,32 @@ export default class NavStack extends Component {
|
|
|
301
330
|
return;
|
|
302
331
|
}
|
|
303
332
|
let spring = this._createSpring({ fromValue, toValue });
|
|
304
|
-
spring
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
333
|
+
spring
|
|
334
|
+
.onUpdate((s) => {
|
|
335
|
+
setTransform(itemContainerElement, `translateX(${s.currentValue}px)`);
|
|
336
|
+
styleHeaderElements(
|
|
337
|
+
currentTransitionPercentage(fromValue, toValue, s.currentValue),
|
|
338
|
+
fromValue > toValue,
|
|
339
|
+
currentHeaderElement,
|
|
340
|
+
clonedHeaderElement,
|
|
341
|
+
);
|
|
342
|
+
})
|
|
343
|
+
.onStop(() => {
|
|
344
|
+
run(finish);
|
|
345
|
+
})
|
|
346
|
+
.start();
|
|
315
347
|
return;
|
|
316
348
|
}
|
|
317
349
|
run(finish);
|
|
318
350
|
}
|
|
319
351
|
|
|
320
|
-
verticalTransition({
|
|
352
|
+
verticalTransition({
|
|
353
|
+
element,
|
|
354
|
+
toValue,
|
|
355
|
+
fromValue,
|
|
356
|
+
animate = !this.suppressAnimation,
|
|
357
|
+
finishCallback,
|
|
358
|
+
}) {
|
|
321
359
|
this.transitionDidBegin();
|
|
322
360
|
this.notifyTransitionStart();
|
|
323
361
|
let finish = () => {
|
|
@@ -335,24 +373,27 @@ export default class NavStack extends Component {
|
|
|
335
373
|
return;
|
|
336
374
|
}
|
|
337
375
|
let spring = this._createSpring({ fromValue, toValue });
|
|
338
|
-
spring
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
376
|
+
spring
|
|
377
|
+
.onUpdate((s) => {
|
|
378
|
+
setTransform(element, `translateY(${s.currentValue}px)`);
|
|
379
|
+
})
|
|
380
|
+
.onStop(() => {
|
|
381
|
+
run(finish);
|
|
382
|
+
})
|
|
383
|
+
.start();
|
|
343
384
|
return;
|
|
344
385
|
}
|
|
345
386
|
run(finish);
|
|
346
387
|
}
|
|
347
388
|
|
|
348
|
-
_createSpring({ initialVelocity=0, fromValue, toValue }) {
|
|
389
|
+
_createSpring({ initialVelocity = 0, fromValue, toValue }) {
|
|
349
390
|
return new Spring({
|
|
350
391
|
initialVelocity,
|
|
351
392
|
fromValue,
|
|
352
393
|
toValue,
|
|
353
394
|
stiffness: 1000,
|
|
354
395
|
damping: 500,
|
|
355
|
-
mass: 3
|
|
396
|
+
mass: 3,
|
|
356
397
|
});
|
|
357
398
|
}
|
|
358
399
|
|
|
@@ -360,12 +401,12 @@ export default class NavStack extends Component {
|
|
|
360
401
|
this.hammer.get('pan').set({ enable: false });
|
|
361
402
|
}
|
|
362
403
|
|
|
363
|
-
transitionDidBegin(){
|
|
404
|
+
transitionDidBegin() {
|
|
364
405
|
this.disablePanRecognizer();
|
|
365
406
|
}
|
|
366
407
|
|
|
367
|
-
transitionDidEnd(){
|
|
368
|
-
if (this._currentStackItemElement)
|
|
408
|
+
transitionDidEnd() {
|
|
409
|
+
if (this._currentStackItemElement) {
|
|
369
410
|
this.disablePanRecognizer();
|
|
370
411
|
}
|
|
371
412
|
if (!this.element || this.stackDepth <= 1) {
|
|
@@ -383,11 +424,18 @@ export default class NavStack extends Component {
|
|
|
383
424
|
}
|
|
384
425
|
|
|
385
426
|
_setupPanHandlerContext() {
|
|
386
|
-
this.containerElement = this.element.querySelector(
|
|
387
|
-
|
|
388
|
-
|
|
427
|
+
this.containerElement = this.element.querySelector(
|
|
428
|
+
'.NavStack-itemContainer',
|
|
429
|
+
);
|
|
430
|
+
this.currentHeaderElement = this.element.querySelector(
|
|
431
|
+
'.NavStack-currentHeaderContainer',
|
|
432
|
+
);
|
|
433
|
+
this.parentHeaderElement = this.element.querySelector(
|
|
434
|
+
'.NavStack-parentItemHeaderContainer',
|
|
435
|
+
);
|
|
389
436
|
this.startingX = this.getX(this.containerElement);
|
|
390
|
-
let currentStackItemElement = this._currentStackItemElement =
|
|
437
|
+
let currentStackItemElement = (this._currentStackItemElement =
|
|
438
|
+
this.element.querySelector('.NavStack-item:last-child'));
|
|
391
439
|
if (!currentStackItemElement) {
|
|
392
440
|
return;
|
|
393
441
|
}
|
|
@@ -403,15 +451,26 @@ export default class NavStack extends Component {
|
|
|
403
451
|
if (this._activeSpring) {
|
|
404
452
|
return;
|
|
405
453
|
}
|
|
406
|
-
setTransform(
|
|
454
|
+
setTransform(
|
|
455
|
+
this.containerElement,
|
|
456
|
+
`translateX(${this.startingX + ev.deltaX}px)`,
|
|
457
|
+
);
|
|
407
458
|
styleHeaderElements(
|
|
408
|
-
currentTransitionPercentage(
|
|
459
|
+
currentTransitionPercentage(
|
|
460
|
+
this.startingX,
|
|
461
|
+
this.backX,
|
|
462
|
+
this.startingX + ev.deltaX,
|
|
463
|
+
),
|
|
409
464
|
true,
|
|
410
465
|
this.currentHeaderElement,
|
|
411
|
-
this.parentHeaderElement
|
|
466
|
+
this.parentHeaderElement,
|
|
412
467
|
);
|
|
413
468
|
|
|
414
|
-
let transitionRatio = currentTransitionPercentage(
|
|
469
|
+
let transitionRatio = currentTransitionPercentage(
|
|
470
|
+
this.startingX,
|
|
471
|
+
this.backX,
|
|
472
|
+
this.startingX + ev.deltaX,
|
|
473
|
+
);
|
|
415
474
|
if (this.currentHeaderElement) {
|
|
416
475
|
this.currentHeaderElement.style.opacity = transitionRatio;
|
|
417
476
|
}
|
|
@@ -424,7 +483,8 @@ export default class NavStack extends Component {
|
|
|
424
483
|
}
|
|
425
484
|
|
|
426
485
|
handlePanEnd(ev) {
|
|
427
|
-
let shouldNavigateBack =
|
|
486
|
+
let shouldNavigateBack =
|
|
487
|
+
this.adjustX(ev.center.x) >= this.thresholdX && this.canNavigateBack;
|
|
428
488
|
let initialVelocity = ev.velocityX;
|
|
429
489
|
let fromValue = this.startingX + ev.deltaX;
|
|
430
490
|
let toValue = shouldNavigateBack ? this.backX : this.startingX;
|
|
@@ -435,16 +495,20 @@ export default class NavStack extends Component {
|
|
|
435
495
|
currentTransitionPercentage(this.startingX, this.backX, this.backX),
|
|
436
496
|
false,
|
|
437
497
|
this.parentHeaderElement,
|
|
438
|
-
this.currentHeaderElement
|
|
498
|
+
this.currentHeaderElement,
|
|
439
499
|
);
|
|
440
500
|
run(this.args, this.args.back);
|
|
441
501
|
} else {
|
|
442
502
|
setTransform(this.containerElement, `translateX(${this.startingX}px)`);
|
|
443
503
|
styleHeaderElements(
|
|
444
|
-
currentTransitionPercentage(
|
|
504
|
+
currentTransitionPercentage(
|
|
505
|
+
this.startingX,
|
|
506
|
+
this.backX,
|
|
507
|
+
this.startingX,
|
|
508
|
+
),
|
|
445
509
|
false,
|
|
446
510
|
this.parentHeaderElement,
|
|
447
|
-
this.currentHeaderElement
|
|
511
|
+
this.currentHeaderElement,
|
|
448
512
|
);
|
|
449
513
|
}
|
|
450
514
|
if (this.currentHeaderElement) {
|
|
@@ -464,27 +528,39 @@ export default class NavStack extends Component {
|
|
|
464
528
|
}
|
|
465
529
|
let spring = this._createSpring({ initialVelocity, fromValue, toValue });
|
|
466
530
|
this._activeSpring = spring;
|
|
467
|
-
spring
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
531
|
+
spring
|
|
532
|
+
.onUpdate((s) => {
|
|
533
|
+
setTransform(this.containerElement, `translateX(${s.currentValue}px)`);
|
|
534
|
+
styleHeaderElements(
|
|
535
|
+
currentTransitionPercentage(
|
|
536
|
+
this.startingX,
|
|
537
|
+
this.backX,
|
|
538
|
+
s.currentValue,
|
|
539
|
+
),
|
|
540
|
+
false,
|
|
541
|
+
this.parentHeaderElement,
|
|
542
|
+
this.currentHeaderElement,
|
|
543
|
+
);
|
|
544
|
+
if (
|
|
545
|
+
!shouldNavigateBack &&
|
|
546
|
+
s.currentValue >= this.startingX + this.thresholdX
|
|
547
|
+
) {
|
|
548
|
+
shouldNavigateBack = true;
|
|
549
|
+
spring.updateConfig({
|
|
550
|
+
toValue: this.backX,
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
})
|
|
554
|
+
.onStop(() => {
|
|
555
|
+
finalize();
|
|
556
|
+
})
|
|
557
|
+
.start();
|
|
484
558
|
}
|
|
485
559
|
|
|
486
560
|
cloneLastStackItem() {
|
|
487
|
-
let clone = this.element
|
|
561
|
+
let clone = this.element
|
|
562
|
+
.querySelector('.NavStack-item:last-child')
|
|
563
|
+
.cloneNode(true);
|
|
488
564
|
this.clones.stackItems.push(clone);
|
|
489
565
|
clone.setAttribute('id', `${this.elementId}_clonedStackItem`);
|
|
490
566
|
this.attachClonedStackItem(clone);
|
|
@@ -492,7 +568,9 @@ export default class NavStack extends Component {
|
|
|
492
568
|
|
|
493
569
|
cloneHeader() {
|
|
494
570
|
this.removeClonedHeader();
|
|
495
|
-
let liveHeader = this.element.querySelector(
|
|
571
|
+
let liveHeader = this.element.querySelector(
|
|
572
|
+
'.NavStack-currentHeaderContainer',
|
|
573
|
+
);
|
|
496
574
|
if (!liveHeader) {
|
|
497
575
|
return;
|
|
498
576
|
}
|
|
@@ -527,21 +605,24 @@ export default class NavStack extends Component {
|
|
|
527
605
|
|
|
528
606
|
removeClonedHeader() {
|
|
529
607
|
var clonedHeader;
|
|
530
|
-
while (clonedHeader = this.clones.headers.pop()) {
|
|
608
|
+
while ((clonedHeader = this.clones.headers.pop())) {
|
|
609
|
+
//eslint-disable-line no-cond-assign
|
|
531
610
|
clonedHeader.parentNode.removeChild(clonedHeader);
|
|
532
611
|
}
|
|
533
612
|
}
|
|
534
613
|
|
|
535
614
|
removeClonedStackItem() {
|
|
536
615
|
var clonedStackItem;
|
|
537
|
-
while (clonedStackItem = this.clones.stackItems.pop()) {
|
|
616
|
+
while ((clonedStackItem = this.clones.stackItems.pop())) {
|
|
617
|
+
//eslint-disable-line no-cond-assign
|
|
538
618
|
clonedStackItem.parentNode.removeChild(clonedStackItem);
|
|
539
619
|
}
|
|
540
620
|
}
|
|
541
621
|
|
|
542
622
|
removeClonedElement() {
|
|
543
623
|
var clonedElement;
|
|
544
|
-
while (clonedElement = this.clones.elements.pop()) {
|
|
624
|
+
while ((clonedElement = this.clones.elements.pop())) {
|
|
625
|
+
//eslint-disable-line no-cond-assign
|
|
545
626
|
clonedElement.parentNode.removeChild(clonedElement);
|
|
546
627
|
}
|
|
547
628
|
}
|
|
@@ -21,11 +21,12 @@ export default class ToNavStack extends Component {
|
|
|
21
21
|
guidFor(this),
|
|
22
22
|
this.args.layer,
|
|
23
23
|
this.args.item,
|
|
24
|
-
this.args.header
|
|
24
|
+
this.args.header,
|
|
25
25
|
);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
willDestroy() {
|
|
29
|
+
super.willDestroy(...arguments);
|
|
29
30
|
this.service.removeItem(guidFor(this));
|
|
30
31
|
}
|
|
31
32
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
/* eslint-disable ember/no-computed-properties-in-native-classes */
|
|
1
2
|
/* eslint-disable ember/no-observers */
|
|
2
3
|
import Helper from '@ember/component/helper';
|
|
3
4
|
import { computed } from '@ember/object';
|
|
4
5
|
import { observes } from '@ember-decorators/object';
|
|
5
6
|
import { inject as service } from '@ember/service';
|
|
6
7
|
export default class NavLayerIndices extends Helper {
|
|
7
|
-
|
|
8
8
|
@service
|
|
9
9
|
navStacks;
|
|
10
10
|
|
|
@@ -18,7 +18,7 @@ export default class NavLayerIndices extends Helper {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
@computed('navStacks.stacks')
|
|
21
|
-
get layerCount(){
|
|
21
|
+
get layerCount() {
|
|
22
22
|
return Object.keys(this.navStacks.stacks).length;
|
|
23
23
|
}
|
|
24
24
|
|
|
@@ -3,13 +3,14 @@ import Mixin from '@ember/object/mixin';
|
|
|
3
3
|
import { computed } from '@ember/object';
|
|
4
4
|
|
|
5
5
|
export function getParentRoute(router, route) {
|
|
6
|
+
// eslint-disable-next-line ember/no-private-routing-service
|
|
6
7
|
let routerMicroLib = router._routerMicrolib;
|
|
7
8
|
let { routeInfos, handlerInfos } = routerMicroLib.state;
|
|
8
9
|
routeInfos = routeInfos || handlerInfos; // routeInfos is in newer Ember versions
|
|
9
10
|
if (!routeInfos) {
|
|
10
11
|
return;
|
|
11
12
|
}
|
|
12
|
-
let routes = routeInfos.map(hi => hi._handler || hi._route);
|
|
13
|
+
let routes = routeInfos.map((hi) => hi._handler || hi._route);
|
|
13
14
|
let routeIndex = routes.indexOf(route);
|
|
14
15
|
if (routeIndex > 0) {
|
|
15
16
|
return routes[routes.indexOf(route) - 1];
|
|
@@ -19,16 +20,18 @@ export function getParentRoute(router, route) {
|
|
|
19
20
|
export default Mixin.create({
|
|
20
21
|
templateName: 'stackable',
|
|
21
22
|
getRouteComponent(/* model */) {
|
|
22
|
-
return `routable-components/${(
|
|
23
|
+
return `routable-components/${(
|
|
24
|
+
this.routableTemplateName || this.routeName
|
|
25
|
+
).replace(/\./g, '/')}`;
|
|
23
26
|
},
|
|
24
27
|
getHeaderComponent(model) {
|
|
25
28
|
return `${this.getRouteComponent(model)}/header`;
|
|
26
29
|
},
|
|
27
|
-
layerIndex: computed(function() {
|
|
30
|
+
layerIndex: computed('_router', 'newLayer', function () {
|
|
28
31
|
let parentRoute = getParentRoute(this._router, this);
|
|
29
32
|
let parentRouteLayerIndex = parentRoute.get('layerIndex');
|
|
30
33
|
let currentLayerIndex = parentRouteLayerIndex || 0;
|
|
31
|
-
if (this.
|
|
34
|
+
if (this.newLayer === true) {
|
|
32
35
|
return currentLayerIndex + 1;
|
|
33
36
|
}
|
|
34
37
|
return currentLayerIndex;
|
|
@@ -39,7 +42,7 @@ export default Mixin.create({
|
|
|
39
42
|
layerIndex: this.layerIndex,
|
|
40
43
|
routeComponent: this.getRouteComponent(model),
|
|
41
44
|
headerComponent: this.getHeaderComponent(model),
|
|
42
|
-
routeName: this.routeName
|
|
45
|
+
routeName: this.routeName,
|
|
43
46
|
});
|
|
44
47
|
},
|
|
45
48
|
getParentRouteName() {
|
|
@@ -48,6 +51,6 @@ export default Mixin.create({
|
|
|
48
51
|
actions: {
|
|
49
52
|
back() {
|
|
50
53
|
this.transitionTo(this.getParentRouteName());
|
|
51
|
-
}
|
|
52
|
-
}
|
|
54
|
+
},
|
|
55
|
+
},
|
|
53
56
|
});
|
|
@@ -20,7 +20,9 @@ export default class extends Service {
|
|
|
20
20
|
|
|
21
21
|
unregister(component, recognizer) {
|
|
22
22
|
let registry = this.#registry;
|
|
23
|
-
let registerable = registry.find(
|
|
23
|
+
let registerable = registry.find(
|
|
24
|
+
(r) => r.component === component && r.recognizer === recognizer,
|
|
25
|
+
);
|
|
24
26
|
if (registerable) {
|
|
25
27
|
registry.splice(registry.indexOf(registerable), 1);
|
|
26
28
|
}
|
|
@@ -3,23 +3,21 @@ import Service from '@ember/service';
|
|
|
3
3
|
import { run, next } from '@ember/runloop';
|
|
4
4
|
import EmberObject from '@ember/object';
|
|
5
5
|
import { Promise as EmberPromise } from 'rsvp';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { buildWaiter } from '@ember/test-waiters';
|
|
7
|
+
import { set } from '@ember/object';
|
|
8
|
+
let waiter = buildWaiter('ember-nav-stack:transition-waiter');
|
|
8
9
|
|
|
9
10
|
export default class NavStacks extends Service {
|
|
11
|
+
waiterToken;
|
|
12
|
+
|
|
10
13
|
constructor() {
|
|
11
14
|
super(...arguments);
|
|
12
|
-
|
|
15
|
+
set(this, 'stacks', EmberObject.create());
|
|
13
16
|
this._listeners = A([]);
|
|
14
17
|
this._itemsById = {};
|
|
15
18
|
this._counter = 1;
|
|
16
19
|
this._runningTransitions = 0;
|
|
17
20
|
this.isInitialRender = true;
|
|
18
|
-
if (DEBUG) {
|
|
19
|
-
registerWaiter(this, function() {
|
|
20
|
-
return this._runningTransitions === 0;
|
|
21
|
-
});
|
|
22
|
-
}
|
|
23
21
|
}
|
|
24
22
|
|
|
25
23
|
pushItem(sourceId, layer, component, headerComponent) {
|
|
@@ -27,7 +25,7 @@ export default class NavStacks extends Service {
|
|
|
27
25
|
layer,
|
|
28
26
|
component,
|
|
29
27
|
headerComponent,
|
|
30
|
-
order: this._counter
|
|
28
|
+
order: this._counter++,
|
|
31
29
|
};
|
|
32
30
|
this._schedule();
|
|
33
31
|
}
|
|
@@ -47,10 +45,17 @@ export default class NavStacks extends Service {
|
|
|
47
45
|
|
|
48
46
|
notifyTransitionStart() {
|
|
49
47
|
this._runningTransitions++;
|
|
48
|
+
if (this._runningTransitions === 1) {
|
|
49
|
+
this.waiterToken = waiter.beginAsync();
|
|
50
|
+
}
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
notifyTransitionEnd() {
|
|
53
54
|
this._runningTransitions--;
|
|
55
|
+
if (this._runningTransitions === 0) {
|
|
56
|
+
waiter.endAsync(this.waiterToken);
|
|
57
|
+
this.waiterToken = undefined;
|
|
58
|
+
}
|
|
54
59
|
next(() => {
|
|
55
60
|
this._maybeResolveIdle();
|
|
56
61
|
});
|
|
@@ -64,12 +69,12 @@ export default class NavStacks extends Service {
|
|
|
64
69
|
if (this._waitingPromise) {
|
|
65
70
|
return this._waitingPromise;
|
|
66
71
|
}
|
|
67
|
-
return this._waitingPromise = new EmberPromise((resolve) => {
|
|
72
|
+
return (this._waitingPromise = new EmberPromise((resolve) => {
|
|
68
73
|
this._resolveWaiting = resolve;
|
|
69
74
|
next(() => {
|
|
70
75
|
this._maybeResolveIdle();
|
|
71
76
|
});
|
|
72
|
-
});
|
|
77
|
+
}));
|
|
73
78
|
}
|
|
74
79
|
|
|
75
80
|
didUpdate() {} // hook
|
|
@@ -102,7 +107,7 @@ export default class NavStacks extends Service {
|
|
|
102
107
|
for (var layerName in newStacks) {
|
|
103
108
|
newStacks[layerName] = newStacks[layerName].sortBy('order');
|
|
104
109
|
}
|
|
105
|
-
|
|
110
|
+
set(this, 'stacks', EmberObject.create(newStacks));
|
|
106
111
|
if (this.isInitialRender === true) {
|
|
107
112
|
run.next(this, this._clearIsInitialRender);
|
|
108
113
|
}
|
|
@@ -114,6 +119,6 @@ export default class NavStacks extends Service {
|
|
|
114
119
|
if (this.isDestroyed || this.isDestroying) {
|
|
115
120
|
return;
|
|
116
121
|
}
|
|
117
|
-
|
|
122
|
+
set(this, 'isInitialRender', false);
|
|
118
123
|
}
|
|
119
124
|
}
|
package/addon/utils/animation.js
CHANGED
|
@@ -20,7 +20,7 @@ const TICK = 17;
|
|
|
20
20
|
*/
|
|
21
21
|
function rAF(cb) {
|
|
22
22
|
if (Ember.testing || !window.requestAnimationFrame) {
|
|
23
|
-
return run.later(cb, TICK);
|
|
23
|
+
return run.later(cb, TICK);
|
|
24
24
|
} else {
|
|
25
25
|
return window.requestAnimationFrame(cb);
|
|
26
26
|
}
|
|
@@ -52,7 +52,7 @@ export function computeTimeout(element) {
|
|
|
52
52
|
transitionDelay,
|
|
53
53
|
animationDuration,
|
|
54
54
|
animationDelay,
|
|
55
|
-
animationIterationCount
|
|
55
|
+
animationIterationCount,
|
|
56
56
|
} = window.getComputedStyle(element);
|
|
57
57
|
|
|
58
58
|
// `getComputedStyle` returns durations and delays in the Xs format.
|
|
@@ -60,21 +60,26 @@ export function computeTimeout(element) {
|
|
|
60
60
|
// numeral (0-9), a decimal point, or an exponent, it returns the value up to that point
|
|
61
61
|
// and ignores that character and all succeeding characters.
|
|
62
62
|
|
|
63
|
-
let maxDelay = Math.max(
|
|
64
|
-
|
|
65
|
-
parseFloat(
|
|
63
|
+
let maxDelay = Math.max(
|
|
64
|
+
parseFloat(animationDelay),
|
|
65
|
+
parseFloat(transitionDelay),
|
|
66
|
+
);
|
|
67
|
+
let maxDuration = Math.max(
|
|
68
|
+
parseFloat(animationDuration) * parseFloat(animationIterationCount),
|
|
69
|
+
parseFloat(transitionDuration),
|
|
70
|
+
);
|
|
66
71
|
|
|
67
72
|
return (maxDelay + maxDuration) * 1000;
|
|
68
73
|
}
|
|
69
74
|
|
|
70
75
|
let setTransformImpl = function setTransformFunc(element, value) {
|
|
71
76
|
element.style.transform = value;
|
|
72
|
-
}
|
|
77
|
+
};
|
|
73
78
|
// Android <= 4.x does not support element.style.transform
|
|
74
79
|
if (document.body.style.transform === undefined) {
|
|
75
80
|
setTransformImpl = function setTransformFunc(element, value) {
|
|
76
81
|
element.style.webkitTransform = value;
|
|
77
|
-
}
|
|
82
|
+
};
|
|
78
83
|
}
|
|
79
84
|
|
|
80
85
|
export let setTransform = setTransformImpl;
|
|
@@ -12,8 +12,12 @@ export default class BackSwipeRecognizer extends Hammer.Pan {
|
|
|
12
12
|
this.options = Object.assign({}, this.defaults, options || {});
|
|
13
13
|
this.captureClick = (ev) => {
|
|
14
14
|
ev.stopPropagation(); // Stop the click from being propagated.
|
|
15
|
-
this.manager.element.removeEventListener(
|
|
16
|
-
|
|
15
|
+
this.manager.element.removeEventListener(
|
|
16
|
+
'click',
|
|
17
|
+
this.captureClick,
|
|
18
|
+
true,
|
|
19
|
+
);
|
|
20
|
+
};
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
defaults = {
|
|
@@ -22,14 +26,16 @@ export default class BackSwipeRecognizer extends Hammer.Pan {
|
|
|
22
26
|
threshold: 10,
|
|
23
27
|
pointers: 1,
|
|
24
28
|
direction: DIRECTION_RIGHT,
|
|
25
|
-
validLeftAreaPercent: 33
|
|
29
|
+
validLeftAreaPercent: 33,
|
|
26
30
|
};
|
|
27
31
|
|
|
28
32
|
recognize(inputData) {
|
|
29
33
|
if (inputData.isFirst) {
|
|
30
|
-
this.isInitialTouchInValidArea =
|
|
34
|
+
this.isInitialTouchInValidArea =
|
|
35
|
+
this.checkInitialTouchInValidArea(inputData);
|
|
31
36
|
}
|
|
32
|
-
let isOverElementThatPreventsScrollingInteraction =
|
|
37
|
+
let isOverElementThatPreventsScrollingInteraction =
|
|
38
|
+
this.shouldPreventScrollingInteraction(inputData);
|
|
33
39
|
if (isOverElementThatPreventsScrollingInteraction) {
|
|
34
40
|
this.manager.stop();
|
|
35
41
|
return;
|
|
@@ -45,17 +51,25 @@ export default class BackSwipeRecognizer extends Hammer.Pan {
|
|
|
45
51
|
|
|
46
52
|
shouldPreventScrollingInteraction(inputData) {
|
|
47
53
|
let { target } = inputData;
|
|
48
|
-
return
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
54
|
+
return (
|
|
55
|
+
inputData.isFirst &&
|
|
56
|
+
((target && target.tagName.match(FIELD_REGEXP)) ||
|
|
57
|
+
(target && target.hasAttribute('data-prevent-scrolling')))
|
|
58
|
+
);
|
|
52
59
|
}
|
|
53
60
|
|
|
54
61
|
captureGhostClickIfNeeded(inputData) {
|
|
55
|
-
if (
|
|
62
|
+
if (
|
|
63
|
+
inputData.srcEvent.type === 'mouseup' &&
|
|
64
|
+
this.state & Hammer.STATE_BEGAN
|
|
65
|
+
) {
|
|
56
66
|
this.manager.element.addEventListener('click', this.captureClick, true);
|
|
57
67
|
setTimeout(() => {
|
|
58
|
-
this.manager.element.removeEventListener(
|
|
68
|
+
this.manager.element.removeEventListener(
|
|
69
|
+
'click',
|
|
70
|
+
this.captureClick,
|
|
71
|
+
true,
|
|
72
|
+
);
|
|
59
73
|
}, 0);
|
|
60
74
|
}
|
|
61
75
|
}
|
|
@@ -73,11 +87,16 @@ export default class BackSwipeRecognizer extends Hammer.Pan {
|
|
|
73
87
|
let testingEl = document.querySelector('#ember-testing');
|
|
74
88
|
if (testingEl) {
|
|
75
89
|
let minValidX = testingEl.getBoundingClientRect().left;
|
|
76
|
-
let maxValidX =
|
|
77
|
-
|
|
90
|
+
let maxValidX =
|
|
91
|
+
minValidX +
|
|
92
|
+
testingEl.clientWidth * (this.options.validLeftAreaPercent / 100);
|
|
93
|
+
return (
|
|
94
|
+
inputData.center.x >= minValidX && inputData.center.x <= maxValidX
|
|
95
|
+
);
|
|
78
96
|
}
|
|
79
97
|
}
|
|
80
|
-
let maxValidX =
|
|
98
|
+
let maxValidX =
|
|
99
|
+
window.innerWidth * (this.options.validLeftAreaPercent / 100);
|
|
81
100
|
return inputData.center.x <= maxValidX;
|
|
82
101
|
}
|
|
83
102
|
}
|
package/addon/utils/component.js
CHANGED
|
@@ -1,23 +1,40 @@
|
|
|
1
|
-
import { get } from '@ember/object';
|
|
2
|
-
|
|
3
1
|
export function extractComponentKey(componentRef) {
|
|
4
2
|
if (!componentRef) {
|
|
5
3
|
return 'none';
|
|
6
4
|
}
|
|
7
|
-
let result = componentRef
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
5
|
+
let result = getComponentRefName(componentRef);
|
|
6
|
+
let modelId = getComponentRefModelId(componentRef);
|
|
7
|
+
if (modelId) {
|
|
8
|
+
result += `:${modelId}`;
|
|
9
|
+
}
|
|
10
|
+
return result;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function getComponentRefName(componentRef) {
|
|
14
|
+
let componentRefInner =
|
|
15
|
+
componentRef.inner?.name ||
|
|
16
|
+
componentRef[
|
|
17
|
+
Object.getOwnPropertySymbols(componentRef).find(
|
|
18
|
+
(s) => s.description === 'INNER',
|
|
19
|
+
)
|
|
20
|
+
];
|
|
21
|
+
let result = componentRef.name || componentRefInner?.name;
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function getComponentRefModelId(componentRef) {
|
|
26
|
+
let componentRefArgs =
|
|
27
|
+
componentRef.args ||
|
|
28
|
+
componentRef[
|
|
29
|
+
Object.getOwnPropertySymbols(componentRef).find(
|
|
30
|
+
(s) => s.description === 'ARGS',
|
|
31
|
+
)
|
|
32
|
+
];
|
|
33
|
+
if (componentRefArgs.named.has && componentRefArgs.named.has('model')) {
|
|
34
|
+
let model = componentRefArgs.named.get('model').value();
|
|
15
35
|
if (model) {
|
|
16
|
-
|
|
17
|
-
if (modelId) {
|
|
18
|
-
result += `:${modelId}`;
|
|
19
|
-
}
|
|
36
|
+
return model.id;
|
|
20
37
|
}
|
|
21
38
|
}
|
|
22
|
-
return
|
|
39
|
+
return;
|
|
23
40
|
}
|
|
@@ -16,14 +16,17 @@ export function getElementInViewportRatio(selectorOrElement) {
|
|
|
16
16
|
let elementRect = element.getBoundingClientRect();
|
|
17
17
|
let viewportRect = viewportEl.getBoundingClientRect();
|
|
18
18
|
let topOutOfViewport = Math.max(0, viewportRect.top - elementRect.top);
|
|
19
|
-
let bottomOutOfViewport = Math.max(
|
|
19
|
+
let bottomOutOfViewport = Math.max(
|
|
20
|
+
0,
|
|
21
|
+
elementRect.bottom - viewportRect.bottom,
|
|
22
|
+
);
|
|
20
23
|
let leftOutOfViewport = Math.max(0, viewportRect.left - elementRect.left);
|
|
21
24
|
let rightOutOfViewport = Math.max(0, elementRect.right - viewportRect.right);
|
|
22
|
-
let totalArea =
|
|
25
|
+
let totalArea = elementRect.width * elementRect.height;
|
|
23
26
|
let outOfViewportXAmount = leftOutOfViewport + rightOutOfViewport;
|
|
24
27
|
let outOfViewportYAmount = topOutOfViewport + bottomOutOfViewport;
|
|
25
28
|
let areaOutside =
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
outOfViewportXAmount * elementRect.height +
|
|
30
|
+
outOfViewportYAmount * (elementRect.width - outOfViewportXAmount);
|
|
28
31
|
return (totalArea - areaOutside) / totalArea;
|
|
29
32
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
:root {
|
|
2
|
+
--nav-stack-header-height: 44px;
|
|
3
|
+
--nav-stack-footer-height: 50px;
|
|
4
|
+
}
|
|
3
5
|
|
|
4
6
|
$easing: cubic-bezier(.23, 1, .32, 1);
|
|
5
7
|
|
|
@@ -26,14 +28,14 @@ $easing: cubic-bezier(.23, 1, .32, 1);
|
|
|
26
28
|
}
|
|
27
29
|
&-itemContainer {
|
|
28
30
|
position: absolute;
|
|
29
|
-
top:
|
|
31
|
+
top: var(--nav-stack-header-height);
|
|
30
32
|
bottom: 0;
|
|
31
33
|
left: 0;
|
|
32
34
|
width: 500%;
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
&--withFooter &-itemContainer {
|
|
36
|
-
bottom:
|
|
38
|
+
bottom: var(--nav-stack-footer-height);
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
&-item {
|
|
@@ -63,7 +65,8 @@ $easing: cubic-bezier(.23, 1, .32, 1);
|
|
|
63
65
|
|
|
64
66
|
&-header {
|
|
65
67
|
position: absolute;
|
|
66
|
-
height:
|
|
68
|
+
height: var(--nav-stack-header-height);
|
|
69
|
+
box-sizing: content-box;
|
|
67
70
|
top: 0;
|
|
68
71
|
left: 0;
|
|
69
72
|
right: 0;
|
|
@@ -93,7 +96,8 @@ $easing: cubic-bezier(.23, 1, .32, 1);
|
|
|
93
96
|
&-footer {
|
|
94
97
|
position: absolute;
|
|
95
98
|
bottom: 0;
|
|
96
|
-
height:
|
|
99
|
+
height: var(--nav-stack-footer-height);
|
|
100
|
+
box-sizing: content-box;
|
|
97
101
|
left: 0;
|
|
98
102
|
right: 0;
|
|
99
103
|
background: rgba(0,0,0,.2);
|
package/config/deploy.js
CHANGED
package/config/environment.js
CHANGED
package/index.js
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
module.exports = {
|
|
4
4
|
name: require('./package').name,
|
|
5
5
|
options: {
|
|
6
|
-
autoImport:{
|
|
7
|
-
exclude: ['wobble']
|
|
8
|
-
}
|
|
6
|
+
autoImport: {
|
|
7
|
+
exclude: ['wobble'],
|
|
8
|
+
},
|
|
9
9
|
},
|
|
10
10
|
included(app) {
|
|
11
11
|
this._super.included.apply(this, arguments);
|
|
12
12
|
app.import('vendor/wobble-shim.js');
|
|
13
13
|
app.import('node_modules/wobble/dist/wobble.browser.js');
|
|
14
|
-
}
|
|
14
|
+
},
|
|
15
15
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ember-nav-stack",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"description": "The default blueprint for ember-cli addons.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ember-addon"
|
|
@@ -17,62 +17,78 @@
|
|
|
17
17
|
},
|
|
18
18
|
"scripts": {
|
|
19
19
|
"build": "ember build --environment=production",
|
|
20
|
-
"lint
|
|
20
|
+
"lint": "npm-run-all --aggregate-output --continue-on-error --parallel 'lint:!(fix)'",
|
|
21
|
+
"lint:fix": "npm-run-all --aggregate-output --continue-on-error --parallel lint:*:fix",
|
|
22
|
+
"lint:hbs:fix": "ember-template-lint . --fix",
|
|
23
|
+
"lint:js": "eslint . --cache",
|
|
21
24
|
"release": "release-it",
|
|
25
|
+
"lint:js:fix": "eslint . --fix",
|
|
22
26
|
"start": "ember serve",
|
|
23
|
-
"test": "
|
|
24
|
-
"test:
|
|
27
|
+
"test": "npm-run-all lint test:*",
|
|
28
|
+
"test:ember": "ember test",
|
|
29
|
+
"test:ember-compatibility": "ember try:each"
|
|
25
30
|
},
|
|
26
31
|
"dependencies": {
|
|
27
|
-
"@
|
|
28
|
-
"ember-
|
|
29
|
-
"ember-
|
|
30
|
-
"ember-cli-
|
|
32
|
+
"@babel/core": "^7.0.0",
|
|
33
|
+
"@ember/render-modifiers": "^2.1.0",
|
|
34
|
+
"ember-auto-import": "^2.6.3",
|
|
35
|
+
"ember-cli-babel": "^7.26.11",
|
|
36
|
+
"ember-cli-htmlbars": "^6.3.0",
|
|
31
37
|
"ember-decorators": "6.1.1",
|
|
32
|
-
"ember-math-helpers": "^
|
|
33
|
-
"ember-truth-helpers": "^3.
|
|
38
|
+
"ember-math-helpers": "^3.0.0",
|
|
39
|
+
"ember-truth-helpers": "^3.1.1",
|
|
34
40
|
"hammerjs": "^2.0.8",
|
|
35
41
|
"macro-decorators": "^0.1.2",
|
|
42
|
+
"webpack": "5",
|
|
36
43
|
"wobble": "^1.5.1"
|
|
37
44
|
},
|
|
38
45
|
"devDependencies": {
|
|
39
|
-
"@
|
|
40
|
-
"@ember/
|
|
41
|
-
"@
|
|
42
|
-
"@glimmer/
|
|
43
|
-
"
|
|
46
|
+
"@ember/optional-features": "^2.0.0",
|
|
47
|
+
"@ember/test-helpers": "^2.4.0",
|
|
48
|
+
"@ember/test-waiters": "^3.0.2",
|
|
49
|
+
"@glimmer/component": "^1.1.2",
|
|
50
|
+
"@glimmer/tracking": "^1.1.2",
|
|
51
|
+
"babel-eslint": "^10.1.0",
|
|
44
52
|
"broccoli-asset-rev": "^3.0.0",
|
|
45
|
-
"ember-cli": "~3.
|
|
46
|
-
"ember-cli-dependency-checker": "^3.2
|
|
47
|
-
"ember-cli-deploy": "^
|
|
48
|
-
"ember-cli-deploy-build": "^
|
|
49
|
-
"ember-cli-deploy-git": "^1.3.
|
|
50
|
-
"ember-cli-
|
|
51
|
-
"ember-cli-inject-live-reload": "^2.0
|
|
52
|
-
"ember-cli-sass": "^
|
|
53
|
+
"ember-cli": "~3.24.0",
|
|
54
|
+
"ember-cli-dependency-checker": "^3.3.2",
|
|
55
|
+
"ember-cli-deploy": "^2.0.0",
|
|
56
|
+
"ember-cli-deploy-build": "^3.0.0",
|
|
57
|
+
"ember-cli-deploy-git": "^1.3.4",
|
|
58
|
+
"ember-cli-deprecation-workflow": "^2.1.0",
|
|
59
|
+
"ember-cli-inject-live-reload": "^2.1.0",
|
|
60
|
+
"ember-cli-sass": "^11.0.1",
|
|
53
61
|
"ember-cli-sri": "^2.1.1",
|
|
54
|
-
"ember-cli-
|
|
62
|
+
"ember-cli-terser": "^4.0.2",
|
|
55
63
|
"ember-disable-prototype-extensions": "^1.1.3",
|
|
56
64
|
"ember-export-application-global": "^2.0.1",
|
|
57
|
-
"ember-load-initializers": "^2.1.
|
|
58
|
-
"ember-maybe-import-regenerator": "^0.
|
|
59
|
-
"ember-
|
|
60
|
-
"ember-
|
|
65
|
+
"ember-load-initializers": "^2.1.2",
|
|
66
|
+
"ember-maybe-import-regenerator": "^1.0.0",
|
|
67
|
+
"ember-page-title": "^8.0.0",
|
|
68
|
+
"ember-qunit": "^5.1.5",
|
|
69
|
+
"ember-resolver": "^11.0.1",
|
|
61
70
|
"ember-route-action-helper": "^2.0.8",
|
|
62
|
-
"ember-simulant-test-helpers": "^0.3.
|
|
63
|
-
"ember-source": "~3.
|
|
64
|
-
"ember-source-channel-url": "^
|
|
65
|
-
"ember-
|
|
66
|
-
"
|
|
67
|
-
"eslint
|
|
68
|
-
"eslint-
|
|
71
|
+
"ember-simulant-test-helpers": "^0.3.2",
|
|
72
|
+
"ember-source": "~3.24.0",
|
|
73
|
+
"ember-source-channel-url": "^3.0.0",
|
|
74
|
+
"ember-template-lint": "^5.11.2",
|
|
75
|
+
"ember-try": "^3.0.0",
|
|
76
|
+
"eslint": "^7.26.0",
|
|
77
|
+
"eslint-config-prettier": "^9.0.0",
|
|
78
|
+
"eslint-plugin-ember": "^10.4.2",
|
|
79
|
+
"eslint-plugin-node": "^11.1.0",
|
|
80
|
+
"eslint-plugin-prettier": "^5.0.0",
|
|
69
81
|
"loader.js": "^4.7.0",
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
82
|
+
"npm-run-all": "^4.1.5",
|
|
83
|
+
"prettier": "^3.0.2",
|
|
84
|
+
"qunit": "^2.19.4",
|
|
85
|
+
"qunit-dom": "^2.0.0",
|
|
86
|
+
"release-it": "^13.7.2",
|
|
87
|
+
"release-it-lerna-changelog": "^2.4.0",
|
|
88
|
+
"sass": "^1.66.1"
|
|
73
89
|
},
|
|
74
90
|
"engines": {
|
|
75
|
-
"node": "
|
|
91
|
+
"node": ">= 14"
|
|
76
92
|
},
|
|
77
93
|
"publishConfig": {
|
|
78
94
|
"registry": "https://registry.npmjs.org"
|
|
@@ -98,5 +114,9 @@
|
|
|
98
114
|
"release": true,
|
|
99
115
|
"tokenRef": "GITHUB_AUTH"
|
|
100
116
|
}
|
|
117
|
+
},
|
|
118
|
+
"volta": {
|
|
119
|
+
"node": "16.20.2",
|
|
120
|
+
"yarn": "1.22.10"
|
|
101
121
|
}
|
|
102
122
|
}
|