2018-05-09 01:08:30 +00:00
|
|
|
import Component from '@ember/component';
|
|
|
|
import { computed, get } from '@ember/object';
|
2019-10-15 18:32:58 +00:00
|
|
|
import { computed as overridable } from 'ember-overridable-computed';
|
2020-06-10 13:49:16 +00:00
|
|
|
import { classNames } from '@ember-decorators/component';
|
|
|
|
import classic from 'ember-classic-decorator';
|
2018-05-09 01:08:30 +00:00
|
|
|
|
2020-06-10 13:49:16 +00:00
|
|
|
@classic
|
|
|
|
@classNames('accordion')
|
|
|
|
export default class ListAccordion extends Component {
|
|
|
|
key = 'id';
|
|
|
|
@overridable(() => []) source;
|
2018-05-09 01:08:30 +00:00
|
|
|
|
2020-06-10 13:49:16 +00:00
|
|
|
onToggle /* item, isOpen */() {}
|
|
|
|
startExpanded = false;
|
2018-05-09 01:08:30 +00:00
|
|
|
|
2020-06-10 13:49:16 +00:00
|
|
|
@computed('source.[]')
|
|
|
|
get decoratedSource() {
|
2019-03-26 07:46:44 +00:00
|
|
|
const stateCache = this.stateCache;
|
|
|
|
const key = this.key;
|
2018-05-09 01:08:30 +00:00
|
|
|
const deepKey = `item.${key}`;
|
2019-03-26 07:46:44 +00:00
|
|
|
const startExpanded = this.startExpanded;
|
2018-05-09 01:08:30 +00:00
|
|
|
|
2019-03-26 07:46:44 +00:00
|
|
|
const decoratedSource = this.source.map(item => {
|
2018-05-09 01:08:30 +00:00
|
|
|
const cacheItem = stateCache.findBy(deepKey, get(item, key));
|
|
|
|
return {
|
|
|
|
item,
|
2018-07-12 19:05:51 +00:00
|
|
|
isOpen: cacheItem ? !!cacheItem.isOpen : startExpanded,
|
2018-05-09 01:08:30 +00:00
|
|
|
};
|
|
|
|
});
|
|
|
|
|
2020-06-09 21:03:28 +00:00
|
|
|
// eslint-disable-next-line ember/no-side-effects
|
2018-05-09 01:08:30 +00:00
|
|
|
this.set('stateCache', decoratedSource);
|
|
|
|
return decoratedSource;
|
2020-06-10 13:49:16 +00:00
|
|
|
}
|
2018-05-09 01:08:30 +00:00
|
|
|
|
|
|
|
// When source updates come in, the state cache is used to preserve
|
|
|
|
// open/close state.
|
2020-06-10 13:49:16 +00:00
|
|
|
@overridable(() => []) stateCache;
|
|
|
|
}
|