UNPKG

@fiddle-digital/string-responsive

Version:

StringResponsive is a comprehensive JavaScript library for responsive design management in web applications. It enables dynamic handling of device-specific media queries and events, allowing developers to programmatically adjust UI and functionality based

264 lines (255 loc) 11.2 kB
let d: any = null let w: any = null interface DeviceQueryConfig { min?: number; max?: number; enable?: boolean; } interface QueryConfig { mobile?: DeviceQueryConfig; tablet?: DeviceQueryConfig; laptop?: DeviceQueryConfig; desktop?: DeviceQueryConfig; } class StringResponsiveQueryDevice { public min?: number = undefined; public max?: number = undefined; public enable: boolean = true; constructor(min?: number, max?: number) { this.min = min ?? undefined; this.max = max ?? undefined; } setEnable(enable: boolean = true) { this.enable = enable; } setRange(min?: number, max?: number) { this.min = min ?? undefined; this.max = max ?? undefined; } } class StringResponsiveDeviceEvent { private eventsIn: Array<Function> = new Array<Function>(); private eventsOut: Array<Function> = new Array<Function>(); private stringResponsive: StringResponsive private state: StringResponsiveState constructor(stringResponsive: StringResponsive, state: StringResponsiveState){ this.stringResponsive = stringResponsive this.state = state } addIn(event: Function) { if (!this.eventsIn.includes(event)) { this.eventsIn.push(event); } if (this.stringResponsive.state == this.state) { event() } } removeIn(event: Function) { const index = this.eventsIn.indexOf(event); if (index !== -1) { this.eventsIn.splice(index, 1); } } callIn() { this.eventsIn.forEach(event => { event() }) } addOut(event: Function) { if (!this.eventsOut.includes(event)) { this.eventsOut.push(event); } if (this.stringResponsive.state != this.state) { event() } } removeOut(event: Function) { const index = this.eventsOut.indexOf(event); if (index !== -1) { this.eventsOut.splice(index, 1); } } callOut() { this.eventsOut.forEach(event => { event() }) } } enum StringResponsiveState { Mobile, Tablet, Laptop, Desktop } class StringResponsive { private static instance: StringResponsive; private mobileQuery: StringResponsiveQueryDevice private tabletQuery: StringResponsiveQueryDevice private laptopQuery: StringResponsiveQueryDevice private desktopQuery: StringResponsiveQueryDevice private mobileMatchMedia: MediaQueryList private tabletMatchMedia: MediaQueryList private laptopMatchMedia: MediaQueryList private desktopMatchMedia: MediaQueryList public mobile: StringResponsiveDeviceEvent public tablet: StringResponsiveDeviceEvent public laptop: StringResponsiveDeviceEvent public desktop: StringResponsiveDeviceEvent private onMobileEvent private onTabletEvent private onLaptopEvent private onDesktopEvent private _state: StringResponsiveState = StringResponsiveState.Mobile public get state() { return this._state; } private constructor() { d = document w = window this.mobileQuery = new StringResponsiveQueryDevice(undefined, 359); this.tabletQuery = new StringResponsiveQueryDevice(360, 1079); this.laptopQuery = new StringResponsiveQueryDevice(1080, 1365); this.desktopQuery = new StringResponsiveQueryDevice(1366, undefined); this.mobileMatchMedia = window.matchMedia("screen and (max-width: 359px)") this.tabletMatchMedia = window.matchMedia("screen and (min-width: 360px) and (min-width: 1079px)") this.laptopMatchMedia = window.matchMedia("screen and (min-width: 1080px) and (min-width: 1365px)") this.desktopMatchMedia = window.matchMedia("screen and (min-width: 1366px)") this.onMobileEvent = this.onMobileQuery.bind(this) this.onTabletEvent = this.onTabletQuery.bind(this) this.onLaptopEvent = this.onLaptopQuery.bind(this) this.onDesktopEvent = this.onDesktopQuery.bind(this) this.setupQueries() this.matchMedia() this.mobile = new StringResponsiveDeviceEvent(this, StringResponsiveState.Mobile) this.tablet = new StringResponsiveDeviceEvent(this, StringResponsiveState.Tablet) this.laptop = new StringResponsiveDeviceEvent(this, StringResponsiveState.Laptop) this.desktop = new StringResponsiveDeviceEvent(this, StringResponsiveState.Desktop) } public static getInstance(): StringResponsive { if (!StringResponsive.instance) { StringResponsive.instance = new StringResponsive(); } return StringResponsive.instance; } public setQuery(config: QueryConfig) { if (config.mobile) { this.mobileQuery.setEnable(config.mobile.enable ?? this.mobileQuery.enable); this.mobileQuery.setRange(config.mobile.min == undefined ? this.mobileQuery.min : config.mobile.min, config.mobile.max ?? this.mobileQuery.max); } if (config.tablet) { this.tabletQuery.setEnable(config.tablet.enable ?? this.tabletQuery.enable); this.tabletQuery.setRange(config.tablet.min == undefined ? this.tabletQuery.min : config.tablet.min, config.tablet.max ?? this.tabletQuery.max); } if (config.laptop) { this.laptopQuery.setEnable(config.laptop.enable ?? this.laptopQuery.enable); this.laptopQuery.setRange(config.laptop.min == undefined ? this.laptopQuery.min : config.laptop.min, config.laptop.max ?? this.laptopQuery.max); } if (config.desktop) { this.desktopQuery.setEnable(config.desktop.enable ?? this.desktopQuery.enable); this.desktopQuery.setRange(config.desktop.min == undefined ? this.desktopQuery.min : config.desktop.min, config.desktop.max ?? this.desktopQuery.max); } this.setupQueries() this.matchMedia() console.log(this.state) } private setupQueries() { this.mobileMatchMedia.onchange = null if (this.mobileQuery.enable) { if (this.mobileQuery.min != undefined && this.mobileQuery.max != undefined) { this.mobileMatchMedia = window.matchMedia(`screen and (min-width: ${this.mobileQuery.min}px) and (max-width: ${this.mobileQuery.max}px)`) } else { if (this.mobileQuery.min != undefined) { this.mobileMatchMedia = window.matchMedia(`screen and (min-width: ${this.mobileQuery.min}px)`) } if (this.mobileQuery.max != undefined) { this.mobileMatchMedia = window.matchMedia(`screen and (max-width: ${this.mobileQuery.max}px)`) } } this.mobileMatchMedia.onchange = this.onMobileEvent } this.tabletMatchMedia.onchange = null if (this.tabletQuery.enable) { if (this.tabletQuery.min != undefined && this.tabletQuery.max != undefined) { this.tabletMatchMedia = window.matchMedia(`screen and (min-width: ${this.tabletQuery.min}px) and (max-width: ${this.tabletQuery.max}px)`) } else { if (this.tabletQuery.min != undefined) { this.tabletMatchMedia = window.matchMedia(`screen and (min-width: ${this.tabletQuery.min}px)`) } if (this.tabletQuery.max != undefined) { this.tabletMatchMedia = window.matchMedia(`screen and (max-width: ${this.tabletQuery.max}px)`) } } this.tabletMatchMedia.onchange = this.onTabletEvent } this.laptopMatchMedia.onchange = null if (this.laptopQuery.enable) { if (this.laptopQuery.min != undefined && this.laptopQuery.max != undefined) { this.laptopMatchMedia = window.matchMedia(`screen and (min-width: ${this.laptopQuery.min}px) and (max-width: ${this.laptopQuery.max}px)`) } else { if (this.laptopQuery.min != undefined) { this.laptopMatchMedia = window.matchMedia(`screen and (min-width: ${this.laptopQuery.min}px)`) } if (this.laptopQuery.max != undefined) { this.laptopMatchMedia = window.matchMedia(`screen and (max-width: ${this.laptopQuery.max}px)`) } } this.laptopMatchMedia.onchange = this.onLaptopEvent } this.desktopMatchMedia.onchange = null if (this.desktopQuery.enable) { if (this.desktopQuery.min != undefined && this.desktopQuery.max != undefined) { this.desktopMatchMedia = window.matchMedia(`screen and (min-width: ${this.desktopQuery.min}px) and (max-width: ${this.desktopQuery.max}px)`) } else { if (this.desktopQuery.min != undefined) { this.desktopMatchMedia = window.matchMedia(`screen and (min-width: ${this.desktopQuery.min}px)`) } if (this.desktopQuery.max != undefined) { this.desktopMatchMedia = window.matchMedia(`screen and (max-width: ${this.desktopQuery.max}px)`) } } this.desktopMatchMedia.onchange = this.onDesktopEvent } } private matchMedia() { if (this.mobileMatchMedia.matches && this.mobileQuery.enable) { this._state = StringResponsiveState.Mobile } if (this.tabletMatchMedia.matches && this.tabletQuery.enable) { this._state = StringResponsiveState.Tablet } if (this.laptopMatchMedia.matches && this.laptopQuery.enable) { this._state = StringResponsiveState.Laptop } if (this.desktopMatchMedia.matches && this.desktopQuery.enable) { this._state = StringResponsiveState.Desktop } } private onMobileQuery(event: MediaQueryListEvent) { if (event.matches) { this._state = StringResponsiveState.Mobile this.mobile.callIn() } else { this.mobile.callOut() } } private onTabletQuery(event: MediaQueryListEvent) { if (event.matches) { this._state = StringResponsiveState.Tablet this.tablet.callIn() } else { this.tablet.callOut() } } private onLaptopQuery(event: MediaQueryListEvent) { if (event.matches) { this._state = StringResponsiveState.Laptop this.laptop.callIn() } else { this.laptop.callOut() } } private onDesktopQuery(event: MediaQueryListEvent) { if (event.matches) { this._state = StringResponsiveState.Desktop this.desktop.callIn() } else { this.desktop.callOut() } } } export default StringResponsive