diff --git a/packages/cxl-ui/src/components/cxl-vaadin-accordion.js b/packages/cxl-ui/src/components/cxl-vaadin-accordion.js index a374c6422..0cc002de2 100644 --- a/packages/cxl-ui/src/components/cxl-vaadin-accordion.js +++ b/packages/cxl-ui/src/components/cxl-vaadin-accordion.js @@ -11,6 +11,12 @@ import cxlVaadinAccordionGlobalStyles from '../styles/global/cxl-vaadin-accordio */ @customElement('cxl-vaadin-accordion') export class CXLVaadinAccordionElement extends Accordion { + // Keep track of device width. + _wide = true; + + // Device width media query + _wideMediaQuery = '(min-width: 750px)'; + /** * Global styles. */ @@ -20,6 +26,46 @@ export class CXLVaadinAccordionElement extends Accordion { registerGlobalStyles(cxlVaadinAccordionGlobalStyles, { moduleId: 'cxl-vaadin-accordion-global', }); + + this._registerMediaListener(); + } + + /** + * Registers a media query listener to keep track of device width. + * If the user is on mobile, open all panels, and disable panel toggling. + */ + _registerMediaListener() { + const observer = window.matchMedia(this._wideMediaQuery); + const matches = (mediaQueryList) => { + if (mediaQueryList.matches) { + this._wide = true; + + if (this.items) { + for (let i = 0; i < this.items.length; i++) { + this.items[i].disabled = false; + } + + this._updateItems(this.items, 0); + } + } else { + this._wide = false; + + if (this.items) { + for (let i = 0; i < this.items.length; i++) { + this.items[i].opened = true; + this.items[i].disabled = true; + } + } + } + }; + + // Items aren't available on first load, so we need to listen for changes. + this.addEventListener('items-changed', () => { + matches(observer); + }); + + // Listen for changes to the device width. + observer.addEventListener('change', matches); } // Keep track of accordion panels state. @@ -37,39 +83,39 @@ export class CXLVaadinAccordionElement extends Accordion { this.opened = null; } - this._saveAccordionState(this.items, e.detail.value, idx); + // If the user is on mobile, don't save panel state. + if (this._wide) { + this._saveAccordionState(this.items, e.detail.value, idx); + } } // Restore accordion panel state. _updateItems(items, opened) { - if (!items) { + // If there are no items, or the user is on mobile, don't restore panel state. + if (!items || !this._wide) { return; } - if (!this.hasAppliedState) { - const storageId = this.getAttribute('id'); - - // Avoid null key. - if (storageId) { - const stateItems = JSON.parse(localStorage.getItem(storageId)); - - if (stateItems) { - items.forEach((item, key) => { - // eslint-disable-next-line no-param-reassign - item.opened = stateItems[key]; - }); - - this.hasAppliedState = true; - - /** - * If no state, allow initial first panel open. - * - * @see https://github.com/vaadin/vaadin-accordion/blob/v1.0.1/src/vaadin-accordion.html#L89 - * @todo maybe unhook from storageId dependency? Some stories may not need `id` attrs. - */ - } else if (opened === 0) { - super._updateItems(items, opened); - } + const storageId = this.getAttribute('id'); + + // Avoid null key. + if (storageId) { + const stateItems = JSON.parse(localStorage.getItem(storageId)); + + if (stateItems) { + items.forEach((item, key) => { + // eslint-disable-next-line no-param-reassign + item.opened = stateItems[key]; + }); + + /** + * If no state, allow initial first panel open. + * + * @see https://github.com/vaadin/vaadin-accordion/blob/v1.0.1/src/vaadin-accordion.html#L89 + * @todo maybe unhook from storageId dependency? Some stories may not need `id` attrs. + */ + } else if (opened === 0) { + super._updateItems(items, opened); } } }