UNPKG

@cwist/vue-match-media

Version:

React to media query changes in your Vue 3 application (useful for adaptive design).

100 lines (99 loc) 4.2 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createVueMatchMediaPlugin = void 0; var vue_1 = require("vue"); var useApi_1 = require("./useApi"); function isNumberWithUnit(v) { return typeof v === 'string' && !!v.match(/^\d+(?:r?em|px)$/); } function valueWithUnit(v) { if ((typeof v === 'number' && !isNaN(v)) || (typeof v === 'string' && v.match(/^\d+(?:\.\d+)?$/))) { return v + "px"; } else if (typeof v === 'string') { return v; } throw new TypeError('Unknown unit value.'); } function pascalToKebab(str) { return str.replace(/[\w]([A-Z])/g, function (m) { return m[0] + '-' + m[1]; }).toLowerCase(); } function populateRules(breakpoint) { var rules = {}; if (typeof breakpoint === 'number' || isNumberWithUnit(breakpoint)) { rules.minWidth = breakpoint; } else if (breakpoint instanceof Array && breakpoint.length === 2) { var _a = breakpoint, minWidth = _a[0], maxWidth = _a[1]; if (typeof minWidth === 'number' || isNumberWithUnit(minWidth)) { rules.minWidth = minWidth; } if (typeof maxWidth === 'number' || isNumberWithUnit(maxWidth)) { rules.maxWidth = maxWidth; } } else if (typeof breakpoint === 'object') { rules = __assign(__assign({}, rules), breakpoint); } return rules; } function createVueMatchMediaPlugin(options) { return { options: options, install: function (app) { if (options && options.breakpoints) { var breakpoints_1 = options.breakpoints; var keys = Object.keys(breakpoints_1); var computedBreakpoints_1 = keys.reduce(function (acc, k) { var rules = populateRules((typeof breakpoints_1[k] === 'object' && breakpoints_1[k].breakpoint) || breakpoints_1[k]); acc[k] = Object.keys(rules) .map(function (r) { return "(" + pascalToKebab(r) + ": " + valueWithUnit(rules[r]) + ")"; }) .join(' and '); return acc; }, {}); var matchMediaObservable_1 = vue_1.reactive(keys.reduce(function (acc, k) { // SSR if (typeof window === 'undefined') { if (typeof breakpoints_1[k] .defaultValue === 'undefined') { throw new Error("In order to use this plugin with SSR, you must provide a default value for every breakpoint (defaultValue is missing for breakpoint '" + k + "')"); } acc[k] = breakpoints_1[k].defaultValue || false; } // Client else { var mq = window.matchMedia(computedBreakpoints_1[k]); // Using the deprecated addListener instead of addEventListener // due to the lack of support in Safari mq.addListener(function (e) { matchMediaObservable_1[k] = e.matches; }); acc[k] = mq.matches; } return acc; }, {})); app.config.globalProperties.$matchMedia = matchMediaObservable_1; app.provide(useApi_1.matchMediaKey, matchMediaObservable_1); } }, }; } exports.createVueMatchMediaPlugin = createVueMatchMediaPlugin; var useApi_2 = require("./useApi"); Object.defineProperty(exports, "useMatchMedia", { enumerable: true, get: function () { return useApi_2.useMatchMedia; } });