@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
text/typescript
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