@html-next/vertical-collection 4.0.2 → 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.
Files changed (39) hide show
  1. package/package.json +64 -79
  2. package/{addon → src}/-private/data-view/elements/occluded-content.js +1 -1
  3. package/{addon/-private/data-view → src/-private/data-view/elements}/viewport-container.js +35 -25
  4. package/{addon → src}/-private/data-view/elements/virtual-component.js +13 -5
  5. package/{addon → src}/-private/data-view/radar/dynamic-radar.js +41 -40
  6. package/{addon → src}/-private/data-view/radar/radar.js +211 -112
  7. package/{addon → src}/-private/data-view/radar/static-radar.js +19 -7
  8. package/{addon → src}/-private/data-view/skip-list.js +20 -21
  9. package/{addon → src}/-private/data-view/utils/insert-range-before.js +6 -1
  10. package/{addon → src}/-private/data-view/utils/mutation-checkers.js +12 -4
  11. package/src/-private/data-view/utils/object-at.js +10 -0
  12. package/{addon → src}/-private/data-view/utils/scroll-handler.js +19 -9
  13. package/{addon → src}/-private/data-view/utils/supports-passive.js +2 -2
  14. package/{addon/-private/data-view/elements → src/-private/data-view}/viewport-container.js +35 -25
  15. package/{addon → src}/-private/ember-internals/key-for-item.js +9 -3
  16. package/{addon → src}/-private/index.js +8 -8
  17. package/{addon → src}/-private/utils/element/closest.js +8 -2
  18. package/{addon → src}/-private/utils/element/estimate-element-height.js +11 -5
  19. package/{addon/components/vertical-collection/component.js → src/components/vertical-collection.gjs} +155 -71
  20. package/src/index.js +3 -0
  21. package/{addon/styles/app.css → src/occluded-content.css} +11 -1
  22. package/.github/workflows/ci.yml +0 -102
  23. package/CHANGELOG.md +0 -176
  24. package/README.md +0 -122
  25. package/RELEASE.md +0 -74
  26. package/addon/-private/data-view/utils/object-at.js +0 -7
  27. package/addon/components/vertical-collection/template.hbs +0 -13
  28. package/app/components/vertical-collection.js +0 -1
  29. package/bin/restore-env.sh +0 -1
  30. package/bin/run-tests-with-retry.sh +0 -24
  31. package/bin/stash-env.sh +0 -1
  32. package/config/ember-cli-toolbelts.json +0 -1
  33. package/config/environment.js +0 -5
  34. package/index.js +0 -157
  35. package/vendor/debug.css +0 -62
  36. /package/{addon → src}/-private/data-view/utils/round-to.js +0 -0
  37. /package/{addon → src}/-private/ember-internals/identity.js +0 -0
  38. /package/{addon → src}/-private/utils/document-shim.js +0 -0
  39. /package/{addon → src}/-private/utils/element/get-scaled-client-rect.js +0 -0
@@ -1,22 +1,30 @@
1
1
  import { DEBUG } from '@glimmer/env';
2
2
  import { assert } from '@ember/debug';
3
3
 
4
+ /*
5
+ * This lint rule is incorrectly trigged by the presence of native
6
+ * classes in this file. Computed properties are not actually used
7
+ * as part of the native classes.
8
+ *
9
+ * This disable can likely be removed once the base component is
10
+ * refactored to a native class (and likely Glimmer component).
11
+ */
12
+ /* eslint-disable ember/no-computed-properties-in-native-classes, ember/no-component-lifecycle-hooks */
4
13
  import { empty, readOnly } from '@ember/object/computed';
5
14
 
6
15
  import Component from '@ember/component';
7
16
  import { get, computed } from '@ember/object';
8
17
  import { run } from '@ember/runloop';
9
- import layout from './template';
10
- import { ViewportContainer } from '../../-private';
11
18
 
12
19
  import { scheduler, Token } from 'ember-raf-scheduler';
13
20
 
14
21
  import {
15
22
  keyForItem,
23
+ ViewportContainer,
16
24
  DynamicRadar,
17
25
  StaticRadar,
18
- objectAt
19
- } from '../../-private';
26
+ objectAt,
27
+ } from '../-private/index.js';
20
28
 
21
29
  /*
22
30
  * BEGIN DEBUG HELPERS
@@ -84,7 +92,10 @@ class Visualization {
84
92
  const { _scrollContainer } = this.radar;
85
93
  this.container.style.height = `${_scrollContainer.getBoundingClientRect().height}px`;
86
94
 
87
- applyVerticalStyles(this.scrollContainer, _scrollContainer.getBoundingClientRect());
95
+ applyVerticalStyles(
96
+ this.scrollContainer,
97
+ _scrollContainer.getBoundingClientRect(),
98
+ );
88
99
  applyVerticalStyles(this.screen, ViewportContainer.getBoundingClientRect());
89
100
  }
90
101
 
@@ -113,7 +124,7 @@ class Visualization {
113
124
  totalBefore,
114
125
  totalAfter,
115
126
  skipList,
116
- _calculatedEstimateHeight
127
+ _calculatedEstimateHeight,
117
128
  } = this.radar;
118
129
 
119
130
  const isDynamic = !!skipList;
@@ -136,10 +147,16 @@ class Visualization {
136
147
  }
137
148
  }
138
149
 
139
- for (let itemIndex = firstVisualizedIndex, i = 0; itemIndex <= lastVisualizedIndex; itemIndex++, i++) {
150
+ for (
151
+ let itemIndex = firstVisualizedIndex, i = 0;
152
+ itemIndex <= lastVisualizedIndex;
153
+ itemIndex++, i++
154
+ ) {
140
155
  const element = sats[i];
141
156
 
142
- const itemHeight = isDynamic ? itemHeights[itemIndex] : _calculatedEstimateHeight;
157
+ const itemHeight = isDynamic
158
+ ? itemHeights[itemIndex]
159
+ : _calculatedEstimateHeight;
143
160
 
144
161
  element.style.height = `${itemHeight}px`;
145
162
  element.setAttribute('index', String(itemIndex));
@@ -178,9 +195,7 @@ class Visualization {
178
195
  * END DEBUG HELPERS
179
196
  */
180
197
 
181
- const VerticalCollection = Component.extend({
182
- layout,
183
-
198
+ class VerticalCollection extends Component.extend({
184
199
  tagName: '',
185
200
 
186
201
  /**
@@ -316,21 +331,27 @@ const VerticalCollection = Component.extend({
316
331
  isEmpty: empty('items'),
317
332
  shouldYieldToInverse: readOnly('isEmpty'),
318
333
 
319
- virtualComponents: computed('items.[]', 'renderAll', 'estimateHeight', 'bufferSize', function() {
320
- const { _radar } = this;
334
+ virtualComponents: computed(
335
+ 'items.[]',
336
+ 'renderAll',
337
+ 'estimateHeight',
338
+ 'bufferSize',
339
+ function () {
340
+ const { _radar } = this;
321
341
 
322
- const items = this.items;
342
+ const items = this.items;
323
343
 
324
- _radar.items = items === null || items === undefined ? [] : items;
325
- _radar.estimateHeight = this.estimateHeight;
326
- _radar.renderAll = this.renderAll;
327
- _radar.bufferSize = this.bufferSize;
344
+ _radar.items = items === null || items === undefined ? [] : items;
345
+ _radar.estimateHeight = this.estimateHeight;
346
+ _radar.renderAll = this.renderAll;
347
+ _radar.bufferSize = this.bufferSize;
328
348
 
329
- _radar.scheduleUpdate(true);
330
- this._clearScheduledActions();
349
+ _radar.scheduleUpdate(true);
350
+ this._clearScheduledActions();
331
351
 
332
- return _radar.virtualComponents;
333
- }),
352
+ return _radar.virtualComponents;
353
+ },
354
+ ),
334
355
 
335
356
  schedule(queueName, job) {
336
357
  return scheduler.schedule(queueName, job, this.token);
@@ -384,13 +405,14 @@ const VerticalCollection = Component.extend({
384
405
  _radar._prevFirstVisibleIndex = _radar._prevFirstItemIndex = index;
385
406
  // Components will be rendered after schedule 'measure' inside 'update' method.
386
407
  // In our case, we need to focus the element after component is rendered. So passing the promise.
387
- return new Promise ((resolve) => {
408
+ return new Promise((resolve) => {
388
409
  _radar.scheduleUpdate(false, resolve);
389
410
  });
390
411
  },
391
412
 
392
413
  // –––––––––––––– Setup/Teardown
393
414
  didInsertElement() {
415
+ this._super();
394
416
  this.schedule('sync', () => {
395
417
  this._radar.start();
396
418
  });
@@ -407,11 +429,12 @@ const VerticalCollection = Component.extend({
407
429
 
408
430
  if (DEBUG) {
409
431
  if (this.__visualization) {
410
- console.info('destroying visualization'); // eslint-disable-line no-console
432
+ console.info('destroying visualization');
411
433
  this.__visualization.destroy();
412
434
  this.__visualization = null;
413
435
  }
414
436
  }
437
+ this._super();
415
438
  },
416
439
 
417
440
  init() {
@@ -432,28 +455,30 @@ const VerticalCollection = Component.extend({
432
455
  shouldRecycle,
433
456
  occlusionTagName,
434
457
  idForFirstItem,
435
- key
458
+ key,
436
459
  } = this;
437
460
 
438
- const startingIndex = calculateStartingIndex(items, idForFirstItem, key, renderFromLast);
439
-
440
- this._radar = new RadarClass(
441
- this.token,
442
- {
443
- bufferSize,
444
- containerSelector,
445
- estimateHeight,
446
- initialRenderCount,
447
- items,
448
- key,
449
- renderAll,
450
- renderFromLast,
451
- shouldRecycle,
452
- startingIndex,
453
- occlusionTagName
454
- }
461
+ const startingIndex = calculateStartingIndex(
462
+ items,
463
+ idForFirstItem,
464
+ key,
465
+ renderFromLast,
455
466
  );
456
467
 
468
+ this._radar = new RadarClass(this.token, {
469
+ bufferSize,
470
+ containerSelector,
471
+ estimateHeight,
472
+ initialRenderCount,
473
+ items,
474
+ key,
475
+ renderAll,
476
+ renderFromLast,
477
+ shouldRecycle,
478
+ startingIndex,
479
+ occlusionTagName,
480
+ });
481
+
457
482
  this._prevItemsLength = 0;
458
483
  this._prevFirstKey = null;
459
484
  this._prevLastKey = null;
@@ -473,7 +498,7 @@ const VerticalCollection = Component.extend({
473
498
  lastReached: a,
474
499
  firstReached: b,
475
500
  lastVisibleChanged: c,
476
- firstVisibleChanged: d
501
+ firstVisibleChanged: d,
477
502
  };
478
503
 
479
504
  this._radar.sendAction = (action, index) => {
@@ -484,27 +509,27 @@ const VerticalCollection = Component.extend({
484
509
  }
485
510
 
486
511
  /* Public methods to Expose to parent
487
-
512
+
488
513
  Usage:
489
514
 
490
515
  Template:
491
516
 
492
- <VerticalCollection @registerAPI={{action "registerAPI"}} />
517
+ <VerticalCollection @registerAPI={{this.registerAPI}} />
493
518
 
494
519
  Component:
495
-
496
- export default Component.extend({
497
- actions: {
498
- registerAPI(api) {
499
- this.set('collectionAPI', api);
500
- }
501
- },
502
- scrollToItem() {
503
- let collectionAPI = this.collectionAPI;
504
- collectionAPI.scrollToItem(index);
520
+
521
+ export default class extends Component {
522
+ @action
523
+ registerAPI(api) {
524
+ this.collectionAPI = api;
505
525
  }
506
- });
507
-
526
+
527
+ @action
528
+ scrollToItem(index) {
529
+ this.collectionAPI.scrollToItem(index);
530
+ }
531
+ }
532
+
508
533
  Need to pass this property in the vertical-collection template
509
534
  Listen in the component actions and do your custom logic
510
535
  This API will have below methods.
@@ -515,7 +540,7 @@ const VerticalCollection = Component.extend({
515
540
  if (registerAPI) {
516
541
  /* List of methods to be exposed to public should be added here */
517
542
  let publicAPI = {
518
- scrollToItem: this.scrollToItem.bind(this)
543
+ scrollToItem: this.scrollToItem.bind(this),
519
544
  };
520
545
  registerAPI(publicAPI);
521
546
  }
@@ -523,7 +548,6 @@ const VerticalCollection = Component.extend({
523
548
  if (DEBUG) {
524
549
  this.__visualization = null;
525
550
  this._radar._debugDidUpdate = () => {
526
-
527
551
  // Update visualization
528
552
  //
529
553
  // This debugging mode can be controlled via the argument
@@ -531,7 +555,7 @@ const VerticalCollection = Component.extend({
531
555
  //
532
556
  if (this.debugVis !== true) {
533
557
  if (this.__visualization !== null) {
534
- console.info('tearing down existing visualization'); // eslint-disable-line no-console
558
+ console.info('tearing down existing visualization');
535
559
  this.__visualization.destroy();
536
560
  this.__visualization = null;
537
561
  }
@@ -563,34 +587,94 @@ const VerticalCollection = Component.extend({
563
587
  styles = window.getComputedStyle(document.body);
564
588
  }
565
589
 
566
- assert(`scrollContainer cannot be inline.`, styleIsOneOf(styles, 'display', ['block', 'inline-block', 'flex', 'inline-flex']));
567
- assert(`scrollContainer must define position`, styleIsOneOf(styles, 'position', ['static', 'relative', 'absolute']));
568
- assert(`scrollContainer must define height or max-height`, hasStyleWithNonZeroValue(styles, 'height') || hasStyleWithNonZeroValue(styles, 'max-height'));
590
+ assert(
591
+ `scrollContainer cannot be inline.`,
592
+ styleIsOneOf(styles, 'display', [
593
+ 'block',
594
+ 'inline-block',
595
+ 'flex',
596
+ 'inline-flex',
597
+ ]),
598
+ );
599
+ assert(
600
+ `scrollContainer must define position`,
601
+ styleIsOneOf(styles, 'position', ['static', 'relative', 'absolute']),
602
+ );
603
+ assert(
604
+ `scrollContainer must define height or max-height`,
605
+ hasStyleWithNonZeroValue(styles, 'height') ||
606
+ hasStyleWithNonZeroValue(styles, 'max-height'),
607
+ );
569
608
 
570
609
  // conditional perf check for non-body scrolling
571
610
  if (radar.scrollContainer !== ViewportContainer) {
572
- assert(`scrollContainer must define overflow-y`, hasStyleValue(styles, 'overflow-y', 'scroll') || hasStyleValue(styles, 'overflow', 'scroll'));
611
+ assert(
612
+ `scrollContainer must define overflow-y`,
613
+ hasStyleValue(styles, 'overflow-y', 'scroll') ||
614
+ hasStyleValue(styles, 'overflow', 'scroll'),
615
+ );
573
616
  }
574
617
 
575
618
  // check itemContainer
576
619
  styles = window.getComputedStyle(radar.itemContainer);
577
620
 
578
- assert(`itemContainer cannot be inline.`, styleIsOneOf(styles, 'display', ['block', 'inline-block', 'flex', 'inline-flex']));
579
- assert(`itemContainer must define position`, styleIsOneOf(styles, 'position', ['static', 'relative', 'absolute']));
621
+ assert(
622
+ `itemContainer cannot be inline.`,
623
+ styleIsOneOf(styles, 'display', [
624
+ 'block',
625
+ 'inline-block',
626
+ 'flex',
627
+ 'inline-flex',
628
+ ]),
629
+ );
630
+ assert(
631
+ `itemContainer must define position`,
632
+ styleIsOneOf(styles, 'position', ['static', 'relative', 'absolute']),
633
+ );
580
634
 
581
635
  // check item defaults
582
- assert(`You must supply at least one item to the collection to debug it's CSS.`, this.items.length);
636
+ assert(
637
+ `You must supply at least one item to the collection to debug it's CSS.`,
638
+ this.items.length,
639
+ );
583
640
 
584
641
  let element = radar._itemContainer.firstElementChild;
585
642
 
586
643
  styles = window.getComputedStyle(element);
587
644
 
588
- assert(`Item cannot be inline.`, styleIsOneOf(styles, 'display', ['block', 'inline-block', 'flex', 'inline-flex']));
589
- assert(`Item must define position`, styleIsOneOf(styles, 'position', ['static', 'relative', 'absolute']));
645
+ assert(
646
+ `Item cannot be inline.`,
647
+ styleIsOneOf(styles, 'display', [
648
+ 'block',
649
+ 'inline-block',
650
+ 'flex',
651
+ 'inline-flex',
652
+ ]),
653
+ );
654
+ assert(
655
+ `Item must define position`,
656
+ styleIsOneOf(styles, 'position', ['static', 'relative', 'absolute']),
657
+ );
590
658
  };
591
659
  }
592
- }
593
- });
660
+ },
661
+ }) {
662
+ <template>
663
+ {{#each this.virtualComponents key="id" as |virtualComponent|~}}
664
+ {{~unbound virtualComponent.upperBound~}}
665
+ {{~#if virtualComponent.isOccludedContent~}}
666
+ {{{unbound virtualComponent.element}}}
667
+ {{~else~}}
668
+ {{~yield virtualComponent.content virtualComponent.index~}}
669
+ {{~/if~}}
670
+ {{~unbound virtualComponent.lowerBound~}}
671
+ {{~/each}}
672
+
673
+ {{#if this.shouldYieldToInverse}}
674
+ {{yield to="inverse"}}
675
+ {{/if}}
676
+ </template>
677
+ }
594
678
 
595
679
  function calculateStartingIndex(items, idForFirstItem, key, renderFromLast) {
596
680
  const totalItems = get(items, 'length');
package/src/index.js ADDED
@@ -0,0 +1,3 @@
1
+ import './occluded-content.css';
2
+
3
+ export { default as VerticalCollection } from './components/vertical-collection.gjs';
@@ -7,7 +7,17 @@
7
7
  min-height: 0.01px;
8
8
 
9
9
  /* hides text visually while still being readable by screen readers */
10
- color: rgba(0,0,0,0);
10
+ color: rgb(0 0 0 / 0%);
11
+
12
+ /*
13
+ * Prevents the debug text ("And X items before/after") from affecting
14
+ * the element's layout height. Without this, inherited line-height values
15
+ * can cause the text to create a line box that inflates the element's
16
+ * actual height above its inline style height, especially when used
17
+ * inside tables with display: table-row.
18
+ */
19
+ font-size: 0;
20
+ line-height: 0;
11
21
  }
12
22
 
13
23
  table .occluded-content,
@@ -1,102 +0,0 @@
1
- name: Vertical Collection CI
2
- on:
3
- pull_request:
4
- types: [opened, synchronize, reopened, ready_for_review]
5
-
6
- jobs:
7
- test:
8
- name: Run Tests
9
- runs-on: ubuntu-latest
10
- timeout-minutes: 12
11
-
12
- steps:
13
- - name: Checkout
14
- uses: actions/checkout@v3
15
-
16
- - name: Use Volta
17
- uses: volta-cli/action@v1
18
-
19
- - name: Node Modules Cache
20
- id: cache-npm
21
- uses: actions/cache@v3
22
- with:
23
- path: '**/node_modules'
24
- key: ci-yarn-${{ hashFiles('yarn.lock') }}
25
-
26
- - name: Install Dependencies
27
- if: steps.cache-npm.outputs.cache-hit != 'true'
28
- run: yarn install --frozen-lockfile
29
-
30
- - name: Lint
31
- run: yarn lint
32
-
33
- - name: Run Build
34
- run: . bin/restore-env.sh && yarn run ember build
35
-
36
- - name: Run Tests
37
- uses: nick-fields/retry@v2
38
- with:
39
- timeout_minutes: 2
40
- max_attempts: 5
41
- command: . bin/restore-env.sh && CI=true yarn run ember test --path=dist
42
-
43
- test-ember-try:
44
- name: Run Tests
45
- runs-on: ubuntu-latest
46
- timeout-minutes: 12
47
-
48
- strategy:
49
- fail-fast: false
50
- matrix:
51
- ember-version:
52
- [
53
- ember-lts-3.12,
54
- ember-lts-3.16,
55
- ember-lts-3.20,
56
- ember-lts-3.28,
57
- ember-lts-4.4,
58
- ember-release,
59
- ember-beta,
60
- ember-canary,
61
- ]
62
-
63
- steps:
64
- - name: Checkout
65
- uses: actions/checkout@v3
66
-
67
- - name: Use Volta
68
- uses: volta-cli/action@v1
69
-
70
- - name: Stash yarn.lock for cache key
71
- run: cp yarn.lock __cache-key
72
-
73
- - name: Node Modules Cache
74
- id: cache-npm
75
- uses: actions/cache@v3
76
- with:
77
- path: |
78
- node_modules
79
- package.json
80
- yarn.lock
81
- __env
82
- key: ci-yarn-v3-${{ matrix.ember-version }}-${{ hashFiles('config/ember-try.js', '__cache-key') }}
83
- restore-keys: |
84
- ci-yarn-${{ hashFiles('yarn.lock') }}
85
-
86
- - name: Install Dependencies
87
- if: steps.cache-npm.outputs.cache-hit != 'true'
88
- run: yarn install --frozen-lockfile
89
-
90
- - name: Ember-Try Setup
91
- if: steps.cache-npm.outputs.cache-hit != 'true'
92
- run: node_modules/.bin/ember try:one ${{ matrix.ember-version }} --skip-cleanup --- bin/stash-env.sh
93
-
94
- - name: Run Build
95
- run: . bin/restore-env.sh && yarn run ember build
96
-
97
- - name: Run Tests
98
- uses: nick-fields/retry@v2
99
- with:
100
- timeout_minutes: 2
101
- max_attempts: 5
102
- command: . bin/restore-env.sh && CI=true yarn run ember test --path=dist
package/CHANGELOG.md DELETED
@@ -1,176 +0,0 @@
1
- Changelog
2
- =========
3
-
4
-
5
-
6
-
7
- ## v4.0.2 (2022-11-17)
8
-
9
- #### :bug: Bug Fix
10
- * [#396](https://github.com/html-next/vertical-collection/pull/396) Fix build for ember-source 4.0+ ([@wagenet](https://github.com/wagenet))
11
-
12
- #### Committers: 1
13
- - Peter Wagenet ([@wagenet](https://github.com/wagenet))
14
-
15
- ## v4.0.1 (2022-11-07)
16
-
17
- #### :memo: Documentation
18
- * [#381](https://github.com/html-next/vertical-collection/pull/381) Fix README ([@runspired](https://github.com/runspired))
19
-
20
- #### Committers: 4
21
- - Alex Navasardyan ([@twokul](https://github.com/twokul))
22
- - Chris Thoburn ([@runspired](https://github.com/runspired))
23
- - Matthew Beale ([@mixonic](https://github.com/mixonic))
24
- - [@Atrue](https://github.com/Atrue)
25
-
26
-
27
- ## v4.0.0 (2022-09-12)
28
-
29
- * Drops support for Ember < 3.12-LTS.
30
- * Drops support for Ember CLI 2.x. https://github.com/html-next/vertical-collection/pull/379
31
- * No change in Node support.
32
- * Drop the positional param for `items` on the vertical collection component.
33
- * Drop ember-compatibility-helpers https://github.com/html-next/vertical-collection/pull/375
34
- * Refactor a bunch of debug code to DEBUG https://github.com/html-next/vertical-collection/pull/388
35
- * Adopt angle bracket invocation
36
- * Adopt native getters
37
-
38
-
39
- ## v4.0.0-beta.2 (2022-09-08)
40
-
41
-
42
- ## v4.0.0-beta.1 (2022-09-07)
43
-
44
-
45
- ## v4.0.0-beta.0 (2022-08-28)
46
-
47
- * Drop support for Ember versions prior to 3.12
48
- * Drop support for Ember CLI 2.x
49
- * Adopt native getters
50
- * Adopt angle bracket invocation
51
- * Drop positional param argument for `item`
52
-
53
-
54
- ## v3.1.0 (2022-08-04)
55
-
56
- #### :rocket: Enhancement
57
- * [#380](https://github.com/html-next/vertical-collection/pull/380) fix: enable parallel builds ([@runspired](https://github.com/runspired))
58
-
59
- #### :bug: Bug Fix
60
- * [#380](https://github.com/html-next/vertical-collection/pull/380) fix: enable parallel builds ([@runspired](https://github.com/runspired))
61
- * [#358](https://github.com/html-next/vertical-collection/pull/358) Delete virtual element ([@Atrue](https://github.com/Atrue))
62
-
63
- #### Committers: 3
64
- - Chris Thoburn ([@runspired](https://github.com/runspired))
65
- - Matthew Beale ([@mixonic](https://github.com/mixonic))
66
- - [@Atrue](https://github.com/Atrue)
67
-
68
- ## v3.0.0 (2022-05-03)
69
-
70
-
71
- ## v3.0.0-1 (2022-03-01)
72
-
73
-
74
- ## v3.0.0-0 (2021-12-09)
75
-
76
- #### What's new
77
-
78
- * Drop support for Ember < 2.18, add support for Ember 4.0+ (#343) (3343ecc)
79
- * 4 retries on CI, 1s sleep (#352) (4a75d99)
80
- * Extend timeout for base tests, tweak retry (#351) (8fff4c7)
81
- * Remove implicit this in tests (#349) (5f58de6)
82
-
83
-
84
- ## v2.1.0 (2021-12-09)
85
-
86
- Changelog:
87
-
88
- * Upgrade ember-cli and dev deps (#348) (e8924e9)
89
- * Drop Ember global use in favor of native API (#347) (d101d8a)
90
- * Proper runloop imports (#346) (a765241)
91
- * Remove property fallback lookup (no implicit this) (#345) (506d798)
92
- * Modernize `htmlSafe` module imports / More cleanup (#344) (32e9460)
93
- * Update CI for vertical-collection v2 (#342) (5613faa)
94
-
95
-
96
- ## v2.0.1 (2021-12-07)
97
-
98
- #### :bug: Bug Fix
99
- * [#322](https://github.com/html-next/vertical-collection/pull/322) Remove comma in selector list in css ([@CubeSquared](https://github.com/CubeSquared))
100
-
101
- #### :house: Internal
102
- * [#336](https://github.com/html-next/vertical-collection/pull/336) Add rwjblue release-it setup ([@rwwagner90](https://github.com/rwwagner90))
103
-
104
- #### Committers: 2
105
- - Matthew Jacobs ([@CubeSquared](https://github.com/CubeSquared))
106
- - Robert Wagner ([@rwwagner90](https://github.com/rwwagner90))
107
-
108
-
109
- ## 0.5.5
110
-
111
- ### Pull Requests
112
-
113
- - [#128](https://github.com/runspired/smoke-and-mirrors/pull/128) **fix**: only update scroll handler length when elements array changes *by [adamjmcgrath](https://github.com/adamjmcgrath)*
114
- - [#126](https://github.com/runspired/smoke-and-mirrors/pull/126) **fix**: update height after render when the item is shown *by [adamjmcgrath](https://github.com/adamjmcgrath)*
115
- - [#136](https://github.com/runspired/smoke-and-mirrors/pull/136) New Release *by [Chris Thoburn](https://github.com/runspired)*
116
- - [#137](https://github.com/runspired/smoke-and-mirrors/pull/137) 0.5.5 *by [Chris Thoburn](https://github.com/runspired)*
117
-
118
- #### Commits
119
-
120
- - [dc04f499](https://github.com/runspired/smoke-and-mirrors/commit/dc04f49924e5b3379df4d97692e5405ad8c393a6) **feat(code-stripping)**: remove classCallChecks for perf, strip unused code from builds *by [Chris Thoburn](https://github.com/runspired)*
121
- - [bf1c02b4](https://github.com/runspired/smoke-and-mirrors/commit/bf1c02b4fa4c5d32c3bad0df9ab3a9e2086184a5) **fix(scroll-handler)**: only update scroll handler length when elements array changes *by [adamjmcgrath](https://github.com/adamjmcgrath)*
122
- - [c6399038](https://github.com/runspired/smoke-and-mirrors/commit/c6399038759d46b234f585f48b8e52a1434a1b46) **fix(vertical-item)**: update height after render when the item is shown *by [adamjmcgrath](https://github.com/adamjmcgrath)*
123
- - [441f7635](https://github.com/runspired/smoke-and-mirrors/commit/441f76359695439ce91bae21cc34309409b6e0bc) **fix(readme)**: cleanup style *by [Chris Thoburn](https://github.com/runspired)*
124
-
125
- ## 0.5.4
126
-
127
- ### Pull Requests
128
-
129
- - [#106](https://github.com/runspired/smoke-and-mirrors/pull/106) Patch Release *by [Chris Thoburn](https://github.com/runspired)*
130
- - [#107](https://github.com/runspired/smoke-and-mirrors/pull/107) fix addon dependency issue *by [Chris Thoburn](https://github.com/runspired)*
131
-
132
- ## 0.5.3
133
-
134
- ## 0.5.2
135
-
136
- ### Pull Requests
137
-
138
- - [#105](https://github.com/runspired/smoke-and-mirrors/pull/105) Fixing links to runspired blog *by [pete_the_pete](https://github.com/pete-the-pete)*
139
- - [#107](https://github.com/runspired/smoke-and-mirrors/pull/107) fix addon dependency issue *by [Chris Thoburn](https://github.com/runspired)*
140
-
141
- ## 0.5.1
142
-
143
- ### Pull Requests
144
-
145
- - [#102](https://github.com/runspired/smoke-and-mirrors/pull/102) patch log output *by [Chris Thoburn](https://github.com/runspired)*
146
- - [#104](https://github.com/runspired/smoke-and-mirrors/pull/104) Include ember-getowner-polyfill in dependencies. *by [Chris Thoburn](https://github.com/runspired)*
147
-
148
- ## 0.5.0
149
-
150
- ### Pull Requests
151
-
152
- - [#100](https://github.com/runspired/smoke-and-mirrors/pull/100) Released 0.4.7 *by [Chris Thoburn](https://github.com/runspired)*
153
-
154
- #### Commits
155
-
156
- - [fc36460c](https://github.com/runspired/smoke-and-mirrors/commit/fc36460c463da33e53c72c6374373e25b3fde996) **fix(changelog)**: updates changelog from last release *by [Chris Thoburn](https://github.com/runspired)*
157
- - [132216e5](https://github.com/runspired/smoke-and-mirrors/commit/132216e5acc0fdd0754a23323ffe97ee6018f2c9) **fix(container)**: use getOwner to resolve deprecation *by [Chris Thoburn](https://github.com/runspired)*
158
- - [e68fcb43](https://github.com/runspired/smoke-and-mirrors/commit/e68fcb43f19517c976ec0cd31b0e3dfe4ee0babe) **fix(visualizer)**: improves teardown *by [Chris Thoburn](https://github.com/runspired)*
159
- - [90138118](https://github.com/runspired/smoke-and-mirrors/commit/90138118c154144c7c29f5d8abab2a60f0d7571d) **fix(geography)**: ensures that destroy sequence completes before update sequence *by [Chris Thoburn](https://github.com/runspired)*
160
- - [a6afb468](https://github.com/runspired/smoke-and-mirrors/commit/a6afb46808a3caa7424c09687d80ed658015c995) **fix(geography)**: don't cycle if we don't have any components *by [Chris Thoburn](https://github.com/runspired)*
161
-
162
- ## 0.4.7
163
-
164
- - [c4aabc20](https://github.com/runspired/smoke-and-mirrors/commit/c4aabc209f2d42668c12b5c121a363384c7b42c4) **fix(changelog-config)**: generate changelog from the develop branch *by [Chris Thoburn](https://github.com/runspired)*
165
- - [917e2e8c](https://github.com/runspired/smoke-and-mirrors/commit/917e2e8c2886116092f38fefb8bf5da2dd70adca) **fix(vertical-collection)**: removes template logic that crept in from smart-collection *by [Chris Thoburn](https://github.com/runspired)*
166
- - [#97](https://github.com/runspired/smoke-and-mirrors/pull/97) Chore/dependencies *by [Chris Thoburn](https://github.com/runspired/chore)*
167
- - [#99](https://github.com/runspired/smoke-and-mirrors/pull/99) Fix (Firefox) *by [Chris Thoburn](https://github.com/runspired)*
168
-
169
- ## 0.4.6
170
-
171
- ## 0.0.0
172
-
173
- - Hold Your Horses,
174
- - Pack Your Parachutes,
175
- - We're Coming,
176
- - But we haven't released anything yet.