@scriptloom/ngx-media-query
Version:
A convenient media query service for building responsive Angular components.
507 lines (494 loc) • 21.1 kB
JavaScript
import { ɵɵdefineInjectable, ɵɵinject, Injectable, Component, Directive, NgModule } from '@angular/core';
import { createAction, props, createReducer, on, createFeatureSelector, createSelector, select, Store, StoreModule } from '@ngrx/store';
import { createEntityAdapter } from '@ngrx/entity';
import { createEffect, ofType, Actions, EffectsModule } from '@ngrx/effects';
import { map, catchError } from 'rxjs/operators';
import { of } from 'rxjs';
var MediaQueriesActionsEnum;
(function (MediaQueriesActionsEnum) {
MediaQueriesActionsEnum["LoadMediaQueries"] = "[NgxMediaQuery/API] Load Media Queries";
MediaQueriesActionsEnum["LoadMediaQueriesSuccess"] = "[NgxMediaQuery/API] Load MediaQueries Success";
MediaQueriesActionsEnum["LoadMediaQueriesFailure"] = "[NgxMediaQuery/API] Load MediaQueries Failure";
MediaQueriesActionsEnum["AddMediaQuery"] = "[NgxMediaQuery/API] Add Media Query";
MediaQueriesActionsEnum["SetMediaQuery"] = "[NgxMediaQuery/API] Set Media Query";
MediaQueriesActionsEnum["UpsertMediaQuery"] = "[NgxMediaQuery/API] Upsert Media Query";
MediaQueriesActionsEnum["AddMediaQueries"] = "[NgxMediaQuery/API] Add Media Queries";
MediaQueriesActionsEnum["UpsertMediaQueries"] = "[NgxMediaQuery/API] Upsert Media Queries";
MediaQueriesActionsEnum["UpdateMediaQuery"] = "[NgxMediaQuery/API] Update Media Query";
MediaQueriesActionsEnum["UpdateMediaQueries"] = "[NgxMediaQuery/API] Update Media Queries";
MediaQueriesActionsEnum["MapMediaQueries"] = "[NgxMediaQuery/API] Map Media Queries";
MediaQueriesActionsEnum["DeleteMediaQuery"] = "[NgxMediaQuery/API] Delete Media Query";
MediaQueriesActionsEnum["DeleteMediaQueries"] = "[NgxMediaQuery/API] Delete Media Queries";
MediaQueriesActionsEnum["DeleteMediaQueriesByPredicate"] = "[NgxMediaQuery/API] Delete Media Queries By Predicate";
MediaQueriesActionsEnum["ClearMediaQueries"] = "[NgxMediaQuery/API] Clear Media Queries";
MediaQueriesActionsEnum["SelectMediaQuery"] = "[NgxMediaQuery/API] Select Media Query by ID";
})(MediaQueriesActionsEnum || (MediaQueriesActionsEnum = {}));
const loadMediaQueries = createAction(MediaQueriesActionsEnum.LoadMediaQueries);
const loadMediaQueriesSuccess = createAction(MediaQueriesActionsEnum.LoadMediaQueriesSuccess, props());
const selectMediaQuery = createAction(MediaQueriesActionsEnum.SelectMediaQuery, props());
const loadMediaQueriesFailure = createAction(MediaQueriesActionsEnum.LoadMediaQueriesFailure, props());
const addMediaQuery = createAction(MediaQueriesActionsEnum.AddMediaQuery, props());
const setMediaQuery = createAction(MediaQueriesActionsEnum.SetMediaQuery, props());
const upsertMediaQuery = createAction(MediaQueriesActionsEnum.UpsertMediaQuery, props());
const addMediaQueries = createAction(MediaQueriesActionsEnum.AddMediaQueries, props());
const upsertMediaQueries = createAction(MediaQueriesActionsEnum.UpsertMediaQueries, props());
const updateMediaQuery = createAction(MediaQueriesActionsEnum.UpdateMediaQuery, props());
const updateMediaQueries = createAction(MediaQueriesActionsEnum.UpdateMediaQueries, props());
const mapMediaQueries = createAction(MediaQueriesActionsEnum.MapMediaQueries, props());
const deleteMediaQuery = createAction(MediaQueriesActionsEnum.DeleteMediaQuery, props());
const deleteMediaQueries = createAction(MediaQueriesActionsEnum.DeleteMediaQueries, props());
const deleteMediaQueriesByPredicate = createAction(MediaQueriesActionsEnum.DeleteMediaQueriesByPredicate, props());
const clearMediaQueries = createAction(MediaQueriesActionsEnum.ClearMediaQueries);
const NGX_MEDIA_QUERY_FEATURE_KEY = 'mediaQueries';
const mediaQueriesAdapter = createEntityAdapter();
const initialMediaQueriesState = mediaQueriesAdapter.getInitialState({
// set initial required properties
loaded: false,
});
const ɵ0 = (state) => (Object.assign(Object.assign({}, state), { loaded: false, error: null })), ɵ1 = (state, { mediaQueries }) => {
return mediaQueriesAdapter.setAll(mediaQueries, Object.assign(Object.assign({}, state), { loaded: true }));
}, ɵ2 = (state, { error }) => (Object.assign(Object.assign({}, state), { error })), ɵ3 = (state, { id }) => (Object.assign(Object.assign({}, state), { selectedId: state.entities[id] !== undefined ? id : undefined })), ɵ4 = (state, { mediaQuery }) => {
return mediaQueriesAdapter.addOne(mediaQuery, state);
}, ɵ5 = (state, { mediaQuery }) => {
return mediaQueriesAdapter.setOne(mediaQuery, state);
}, ɵ6 = (state, { mediaQuery }) => {
return mediaQueriesAdapter.upsertOne(mediaQuery, state);
}, ɵ7 = (state, { mediaQueries }) => {
return mediaQueriesAdapter.addMany(mediaQueries, state);
}, ɵ8 = (state, { mediaQueries }) => {
return mediaQueriesAdapter.upsertMany(mediaQueries, state);
}, ɵ9 = (state, { update }) => {
return mediaQueriesAdapter.updateOne(update, state);
}, ɵ10 = (state, { updates }) => {
return mediaQueriesAdapter.updateMany(updates, state);
}, ɵ11 = (state, { entityMap }) => {
return mediaQueriesAdapter.map(entityMap, state);
}, ɵ12 = (state, { id }) => {
return mediaQueriesAdapter.removeOne(id, state);
}, ɵ13 = (state, { ids }) => {
return mediaQueriesAdapter.removeMany(ids, state);
}, ɵ14 = (state, { predicate }) => {
return mediaQueriesAdapter.removeMany(predicate, state);
}, ɵ15 = state => {
return mediaQueriesAdapter.removeAll(Object.assign(Object.assign({}, state), { selectedId: null }));
};
const mediaQueriesReducer = createReducer(initialMediaQueriesState, on(loadMediaQueries, ɵ0), on(loadMediaQueriesSuccess, ɵ1), on(loadMediaQueriesFailure, ɵ2), on(selectMediaQuery, ɵ3), on(addMediaQuery, ɵ4), on(setMediaQuery, ɵ5), on(upsertMediaQuery, ɵ6), on(addMediaQueries, ɵ7), on(upsertMediaQueries, ɵ8), on(updateMediaQuery, ɵ9), on(updateMediaQueries, ɵ10), on(mapMediaQueries, ɵ11), on(deleteMediaQuery, ɵ12), on(deleteMediaQueries, ɵ13), on(deleteMediaQueriesByPredicate, ɵ14), on(clearMediaQueries, ɵ15));
function NGX_MEDIA_QUERY_REDUCER(state, action) {
return mediaQueriesReducer(state, action);
}
// Lookup the 'MediaQueries' feature state managed by NgRx
const getMediaQueriesState = createFeatureSelector(NGX_MEDIA_QUERY_FEATURE_KEY);
const { selectAll, selectEntities } = mediaQueriesAdapter.getSelectors();
const ɵ0$1 = (state) => state.loaded;
const getMediaQueriesLoaded = createSelector(getMediaQueriesState, ɵ0$1);
const ɵ1$1 = (state) => state.error;
const getMediaQueriesError = createSelector(getMediaQueriesState, ɵ1$1);
const ɵ2$1 = (state) => selectAll(state);
const getAllMediaQueries = createSelector(getMediaQueriesState, ɵ2$1);
const ɵ3$1 = (state) => selectEntities(state);
const getMediaQueriesEntities = createSelector(getMediaQueriesState, ɵ3$1);
const ɵ4$1 = (state) => state.selectedId;
const getSelectedMediaQueryId = createSelector(getMediaQueriesState, ɵ4$1);
const ɵ5$1 = (state) => state.ids;
const getMediaQueryIds = createSelector(getMediaQueriesState, ɵ5$1);
const ɵ6$1 = (entities, selectedId) => entities[selectedId];
const getSelectedMediaQuery = createSelector(getMediaQueriesEntities, getSelectedMediaQueryId, ɵ6$1);
class NgxMediaQueryService {
constructor(store) {
this.store = store;
}
getSelectedMediaQuery$() {
return this.store.pipe(select(getSelectedMediaQuery));
}
clearMediaQueries() {
this.store.dispatch(clearMediaQueries());
}
}
NgxMediaQueryService.ɵprov = ɵɵdefineInjectable({ factory: function NgxMediaQueryService_Factory() { return new NgxMediaQueryService(ɵɵinject(Store)); }, token: NgxMediaQueryService, providedIn: "root" });
NgxMediaQueryService.decorators = [
{ type: Injectable, args: [{
providedIn: 'root'
},] }
];
NgxMediaQueryService.ctorParameters = () => [
{ type: Store }
];
class NgxMediaQueryComponent {
constructor(store) {
this.store = store;
}
ngOnInit() {
this.store.dispatch(loadMediaQueries());
}
ngOnDestroy() {
this.store.dispatch(clearMediaQueries());
}
}
NgxMediaQueryComponent.decorators = [
{ type: Component, args: [{
selector: 'lib-ngx-media-query',
template: `
<div libNgxMediaQuery></div>
`
},] }
];
NgxMediaQueryComponent.ctorParameters = () => [
{ type: Store }
];
const nullMediaQuery = {
xs: null,
sm: null,
md: null,
lg: null,
xl: null,
lt_sm: null,
lt_md: null,
lt_lg: null,
lt_xl: null,
gt_xs: null,
gt_sm: null,
gt_md: null,
gt_lg: null,
};
const screenWidthXl = {
xs: false,
sm: false,
md: false,
lg: false,
xl: true,
lt_sm: false,
lt_md: false,
lt_lg: false,
lt_xl: false,
gt_xs: true,
gt_sm: true,
gt_md: true,
gt_lg: true
};
const screenWidthLg = {
xs: false,
sm: false,
md: false,
lg: true,
xl: false,
lt_sm: false,
lt_md: false,
lt_lg: false,
lt_xl: true,
gt_xs: true,
gt_sm: true,
gt_md: true,
gt_lg: false
};
const screenWidthMd = {
xs: false,
sm: false,
md: true,
lg: false,
xl: false,
lt_sm: false,
lt_md: false,
lt_lg: true,
lt_xl: true,
gt_xs: true,
gt_sm: true,
gt_md: false,
gt_lg: false
};
const screenWidthSm = {
xs: false,
sm: true,
md: false,
lg: false,
xl: false,
lt_sm: false,
lt_md: true,
lt_lg: true,
lt_xl: true,
gt_xs: true,
gt_sm: false,
gt_md: false,
gt_lg: false
};
const screenWidthXs = {
xs: true,
sm: false,
md: false,
lg: false,
xl: false,
lt_sm: true,
lt_md: true,
lt_lg: true,
lt_xl: true,
gt_xs: false,
gt_sm: false,
gt_md: false,
gt_lg: false
};
class MediaQueriesDirective {
constructor(store) {
this.store = store;
// screen
this.screenQuery = window.matchMedia('screen');
this.screenQueryListener = () => { };
// xs
this.upperXsQuery = window.matchMedia('(max-width: 599px)');
this.xsQueryListener = this.screenXsConditional();
// sm
this.lowerSmQuery = window.matchMedia('(min-width: 600px)');
this.upperSmQuery = window.matchMedia('(max-width: 959px)');
this.smQueryListener = this.screenSmConditional();
// md
this.lowerMdQuery = window.matchMedia('(min-width: 960px)');
this.upperMdQuery = window.matchMedia('(max-width: 1279px)');
this.mdQueryListener = this.screenMdConditional();
// lg
this.lowerLgQuery = window.matchMedia('(min-width: 1280px)');
this.upperLgQuery = window.matchMedia('(max-width: 1919px)');
this.lgQueryListener = this.screenLgConditional();
// xl
this.lowerXlQuery = window.matchMedia('(min-width: 1920px)');
this.upperXlQuery = window.matchMedia('(max-width: 5000px)');
this.xlQueryListener = this.screenXlConditional();
}
ngOnInit() {
if (typeof window.matchMedia('(min-width: 0px)').addEventListener !== 'undefined') {
// screen
this.screenQuery.addEventListener('change', this.screenQueryListener);
// xs
this.upperXsQuery.addEventListener('change', this.xsQueryListener);
// sm
this.lowerSmQuery.addEventListener('change', this.smQueryListener);
this.upperSmQuery.addEventListener('change', this.smQueryListener);
// md
this.lowerMdQuery.addEventListener('change', this.mdQueryListener);
this.upperMdQuery.addEventListener('change', this.mdQueryListener);
// lg
this.lowerLgQuery.addEventListener('change', this.lgQueryListener);
this.upperLgQuery.addEventListener('change', this.lgQueryListener);
// xl
this.lowerXlQuery.addEventListener('change', this.xlQueryListener);
this.upperXlQuery.addEventListener('change', this.xlQueryListener);
}
else {
// As of July 4, 2020 it is expect Safari does not implement
// MediaQueryList.addEventListener and so MediaQueryList.addListener
// is used if the MediaQueryList.addEventListener is not found. See:
// https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList.
// screen
this.screenQuery.addListener(this.screenQueryListener);
// xs
this.upperXsQuery.addListener(this.xsQueryListener);
// sm
this.lowerSmQuery.addListener(this.smQueryListener);
this.upperSmQuery.addListener(this.smQueryListener);
// md
this.lowerMdQuery.addListener(this.mdQueryListener);
this.upperMdQuery.addListener(this.mdQueryListener);
// lg
this.lowerLgQuery.addListener(this.lgQueryListener);
this.upperLgQuery.addListener(this.lgQueryListener);
// xl
this.lowerXlQuery.addListener(this.xlQueryListener);
this.upperXlQuery.addListener(this.xlQueryListener);
}
// initialize states
this.initializeState();
}
ngOnDestroy() {
if (typeof window.matchMedia('(min-width: 0px)').removeEventListener !== 'undefined') {
// screen
this.screenQuery.removeEventListener('change', this.screenQueryListener);
// xs
this.upperXsQuery.removeEventListener('change', this.xsQueryListener);
// sm
this.lowerSmQuery.removeEventListener('change', this.smQueryListener);
this.upperSmQuery.removeEventListener('change', this.smQueryListener);
// md
this.lowerMdQuery.removeEventListener('change', this.mdQueryListener);
this.upperMdQuery.removeEventListener('change', this.mdQueryListener);
// lg
this.lowerLgQuery.removeEventListener('change', this.lgQueryListener);
this.upperLgQuery.removeEventListener('change', this.lgQueryListener);
// xl
this.lowerXlQuery.removeEventListener('change', this.xlQueryListener);
this.upperXlQuery.removeEventListener('change', this.xlQueryListener);
}
else {
// As of July 4, 2020 it is expect Safari does not implement
// MediaQueryList.removeEventListener and so MediaQueryList.removeListener
// is used if the MediaQueryList.removeEventListener is not found. See:
// https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList
// screen
this.screenQuery.removeListener(this.screenQueryListener);
// xs
this.upperXsQuery.removeListener(this.xsQueryListener);
// sm
this.lowerSmQuery.removeListener(this.smQueryListener);
this.upperSmQuery.removeListener(this.smQueryListener);
// md
this.lowerMdQuery.removeListener(this.mdQueryListener);
this.upperMdQuery.removeListener(this.mdQueryListener);
// lg
this.lowerLgQuery.removeListener(this.lgQueryListener);
this.upperLgQuery.removeListener(this.lgQueryListener);
// xl
this.lowerXlQuery.removeListener(this.xlQueryListener);
this.upperXlQuery.removeListener(this.xlQueryListener);
}
}
dispatchMediaQuery() {
const id = new Date().getTime().toString();
this.store.dispatch(addMediaQuery({
mediaQuery: {
id,
query: this.currentMediaQuery,
}
}));
this.store.dispatch(selectMediaQuery({ id }));
}
// Class methods.
// xs
screenXsConditional() {
return () => {
if (this.screenQuery.matches
&& this.upperXsQuery.matches) {
this.notifyStoreScreenWidthXs();
}
};
}
notifyStoreScreenWidthXs() {
this.currentMediaQuery = screenWidthXs;
this.dispatchMediaQuery();
}
// sm
screenSmConditional() {
return () => {
if (this.screenQuery.matches
&& this.lowerSmQuery.matches
&& this.upperSmQuery.matches) {
this.notifyStoreScreenWidthSm();
}
};
}
notifyStoreScreenWidthSm() {
this.currentMediaQuery = screenWidthSm;
this.dispatchMediaQuery();
}
// md
screenMdConditional() {
return () => {
if (this.screenQuery.matches
&& this.lowerMdQuery.matches
&& this.upperMdQuery.matches) {
this.notifyStoreScreenWidthMd();
}
};
}
notifyStoreScreenWidthMd() {
this.currentMediaQuery = screenWidthMd;
this.dispatchMediaQuery();
}
// lg
screenLgConditional() {
return () => {
if (this.screenQuery.matches
&& this.lowerLgQuery.matches
&& this.upperLgQuery.matches) {
this.notifyStoreScreenWidthLg();
}
};
}
notifyStoreScreenWidthLg() {
this.currentMediaQuery = screenWidthLg;
this.dispatchMediaQuery();
}
// xl
screenXlConditional() {
return () => {
if (this.screenQuery.matches
&& this.lowerXlQuery.matches
&& this.upperXlQuery.matches) {
this.notifyStoreScreenWidthXl();
}
};
}
notifyStoreScreenWidthXl() {
this.currentMediaQuery = screenWidthXl;
this.dispatchMediaQuery();
}
initializeState() {
// Initialize the store with a MediaQueryStateInterface
// reflecting the size of current user's screen.
// Since the media events will not have fired on initialization,
// we set the starting state using the window object.
if (window.screen && window.innerWidth < 600) {
this.notifyStoreScreenWidthXs();
}
else if (window.screen && window.innerWidth < 960 && window.innerWidth >= 600) {
this.notifyStoreScreenWidthSm();
}
else if (window.screen && window.innerWidth < 1280 && window.innerWidth >= 960) {
this.notifyStoreScreenWidthMd();
}
else if (window.screen && window.innerWidth < 1920 && window.innerWidth >= 960) {
this.notifyStoreScreenWidthLg();
}
else if (window.screen) {
this.notifyStoreScreenWidthXl();
}
}
}
MediaQueriesDirective.decorators = [
{ type: Directive, args: [{
selector: '[libNgxMediaQuery]'
},] }
];
MediaQueriesDirective.ctorParameters = () => [
{ type: Store }
];
class MediaQueriesEffects {
constructor(actions$) {
this.actions$ = actions$;
this.loadMediaQueries$ = createEffect(() => this.actions$.pipe(ofType(loadMediaQueries), map(() => {
// Your custom service 'load' logic goes here.
const mediaQueries = this.loadMediaQueries();
return loadMediaQueriesSuccess({ mediaQueries });
}), catchError((error) => {
console.error('Error', error);
return of(loadMediaQueriesFailure({ error }));
})), { dispatch: true, resubscribeOnError: false });
}
loadMediaQueries() {
return [];
}
}
MediaQueriesEffects.decorators = [
{ type: Injectable }
];
MediaQueriesEffects.ctorParameters = () => [
{ type: Actions }
];
class NgxMediaQueryModule {
}
NgxMediaQueryModule.decorators = [
{ type: NgModule, args: [{
declarations: [
NgxMediaQueryComponent,
MediaQueriesDirective
],
imports: [
StoreModule.forFeature(NGX_MEDIA_QUERY_FEATURE_KEY, NGX_MEDIA_QUERY_REDUCER),
EffectsModule.forFeature([MediaQueriesEffects])
],
exports: [NgxMediaQueryComponent]
},] }
];
/*
* Public API Surface of ngx-media-query
*/
/**
* Generated bundle index. Do not edit.
*/
export { NgxMediaQueryComponent, NgxMediaQueryModule, NgxMediaQueryService, nullMediaQuery, screenWidthLg, screenWidthMd, screenWidthSm, screenWidthXl, screenWidthXs, MediaQueriesDirective as ɵa, NGX_MEDIA_QUERY_FEATURE_KEY as ɵb, mediaQueriesAdapter as ɵc, initialMediaQueriesState as ɵd, NGX_MEDIA_QUERY_REDUCER as ɵe, MediaQueriesActionsEnum as ɵf, loadMediaQueries as ɵg, loadMediaQueriesSuccess as ɵh, selectMediaQuery as ɵi, loadMediaQueriesFailure as ɵj, addMediaQuery as ɵk, setMediaQuery as ɵl, upsertMediaQuery as ɵm, addMediaQueries as ɵn, upsertMediaQueries as ɵo, updateMediaQuery as ɵp, updateMediaQueries as ɵq, mapMediaQueries as ɵr, deleteMediaQuery as ɵs, deleteMediaQueries as ɵt, deleteMediaQueriesByPredicate as ɵu, clearMediaQueries as ɵv, MediaQueriesEffects as ɵw };
//# sourceMappingURL=scriptloom-ngx-media-query.js.map