Skip to content

Commit

Permalink
feat(cxl-ui): [cxl-vaadin-accordion] update mobile behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
anoblet committed Feb 9, 2023
1 parent 058e421 commit b9bf94a
Showing 1 changed file with 72 additions and 26 deletions.
98 changes: 72 additions & 26 deletions packages/cxl-ui/src/components/cxl-vaadin-accordion.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand All @@ -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.
Expand All @@ -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);
}
}
}
Expand Down

0 comments on commit b9bf94a

Please sign in to comment.