import { LightningElement } from "lwc"; import { BREAKPOINT_MOBILE, BREAKPOINT_TABLET, DEVICE_DESKTOP, DEVICE_TABLET, DEVICE_MOBILE } from "dxUtils/constants"; const boilerplate = "screen and "; const BREAKPOINT_QUERY_MOBILE = `${boilerplate}(max-width: ${BREAKPOINT_MOBILE})`; const BREAKPOINT_QUERY_TABLET = `${boilerplate}(min-width: ${BREAKPOINT_MOBILE}) and (max-width: ${BREAKPOINT_TABLET})`; const BREAKPOINT_QUERY_DESKTOP = `${boilerplate}(min-width: ${BREAKPOINT_TABLET})`; type DeviceType = | typeof DEVICE_MOBILE | typeof DEVICE_TABLET | typeof DEVICE_DESKTOP; const breakpointConfigs = [ { name: DEVICE_MOBILE, query: BREAKPOINT_QUERY_MOBILE }, { name: DEVICE_TABLET, query: BREAKPOINT_QUERY_TABLET }, { name: DEVICE_DESKTOP, query: BREAKPOINT_QUERY_DESKTOP } ] as { name: DeviceType; query: string }[]; export abstract class MatchMediaElement extends LightningElement { private deviceType: DeviceType = DEVICE_DESKTOP; private matches: { match: MediaQueryList; callback: (e: MediaQueryListEvent | MediaQueryList) => void; }[] = []; private get isMobile(): boolean { return this.deviceType === DEVICE_MOBILE; } private get isTablet(): boolean { return this.deviceType === DEVICE_TABLET; } private get isDesktop(): boolean { return this.deviceType === DEVICE_DESKTOP; } connectedCallback() { this.matches = breakpointConfigs.map( ({ name, query }: { name: DeviceType; query: string }) => { const match = window.matchMedia(query); const callback = (e: MediaQueryListEvent | MediaQueryList) => { if (e.matches) { this.deviceType = name; } }; match.addEventListener("change", callback); return { match, callback }; } ); } disconnectedCallback() { this.matches.forEach(({ match, callback }) => match.removeEventListener("change", callback) ); } }