Comparing version 2.1.0 to 2.2.0
@@ -19,2 +19,6 @@ import json2mq from 'json2mq'; | ||
function _slicedToArray(arr, i) { | ||
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); | ||
} | ||
function _toConsumableArray(arr) { | ||
@@ -28,2 +32,6 @@ return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); | ||
function _arrayWithHoles(arr) { | ||
if (Array.isArray(arr)) return arr; | ||
} | ||
function _iterableToArray(iter) { | ||
@@ -33,2 +41,29 @@ if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); | ||
function _iterableToArrayLimit(arr, i) { | ||
if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; | ||
var _arr = []; | ||
var _n = true; | ||
var _d = false; | ||
var _e = undefined; | ||
try { | ||
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { | ||
_arr.push(_s.value); | ||
if (i && _arr.length === i) break; | ||
} | ||
} catch (err) { | ||
_d = true; | ||
_e = err; | ||
} finally { | ||
try { | ||
if (!_n && _i["return"] != null) _i["return"](); | ||
} finally { | ||
if (_d) throw _e; | ||
} | ||
} | ||
return _arr; | ||
} | ||
function _unsupportedIterableToArray(o, minLen) { | ||
@@ -55,43 +90,6 @@ if (!o) return; | ||
var listeners = []; | ||
function convertBreakpointsToMediaQueries(breakpoints) { | ||
var keys = Object.keys(breakpoints); | ||
var values = keys.map(function (key) { | ||
return breakpoints[key]; | ||
}); | ||
var breakpointValues = [0].concat(_toConsumableArray(values.slice(0, -1))); | ||
var mediaQueries = breakpointValues.reduce(function (sum, value, index) { | ||
var options = Object.assign({ | ||
minWidth: value | ||
}, index < keys.length - 1 ? { | ||
maxWidth: breakpointValues[index + 1] - 1 | ||
} : {}); | ||
var mediaQuery = json2mq(options); | ||
return Object.assign(sum, _defineProperty({}, keys[index], mediaQuery)); | ||
}, {}); | ||
return mediaQueries; | ||
function _nonIterableRest() { | ||
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); | ||
} | ||
function selectBreakpoints(breakpoints, currentBreakpoint) { | ||
var index = breakpoints.findIndex(function (b) { | ||
return b === currentBreakpoint; | ||
}); | ||
return breakpoints.slice(index); | ||
} | ||
function subscribeToMediaQuery(mediaQuery, enter) { | ||
var mql = window.matchMedia(mediaQuery); | ||
var cb = function cb(_ref) { | ||
var matches = _ref.matches; | ||
if (matches) enter(); | ||
}; | ||
listeners.push({ | ||
mql: mql, | ||
cb: cb | ||
}); | ||
mql.addEventListener('change', cb); //subscribing | ||
cb(mql); //initial trigger | ||
} | ||
var state = { | ||
@@ -109,6 +107,4 @@ mqAvailableBreakpoints: ref({}), | ||
var currentBreakpoint = readonly(state.currentBreakpoint); | ||
function isArray(arg) { | ||
return Object.prototype.toString.call(arg) === '[object Array]'; | ||
} | ||
function updateBreakpoints(breakpoints) { | ||
// Remove any existing MQ listeners | ||
for (var i = listeners.length - 1; i >= 0; i--) { | ||
@@ -120,7 +116,9 @@ var _listeners$i = listeners[i], | ||
listeners.splice(i, 1); | ||
} | ||
} // Save new breakpoints to reactive variable | ||
setAvailableBreakpoints(breakpoints); | ||
var mediaQueries = convertBreakpointsToMediaQueries(breakpoints); // setup listeners | ||
setAvailableBreakpoints(breakpoints); // Create css media queries from breakpoints | ||
var mediaQueries = convertBreakpointsToMediaQueries(breakpoints); // Add new MQ listeners | ||
var _loop = function _loop(key) { | ||
@@ -141,3 +139,121 @@ var mediaQuery = mediaQueries[key]; | ||
// USAGE | ||
var listeners = []; | ||
function convertBreakpointsToMediaQueries(breakpoints) { | ||
var keys = Object.keys(breakpoints); | ||
var values = keys.map(function (key) { | ||
return breakpoints[key]; | ||
}); | ||
var breakpointValues = [0].concat(_toConsumableArray(values.slice(0, -1))); | ||
var mediaQueries = breakpointValues.reduce(function (accumulator, current, index) { | ||
var options = Object.assign({ | ||
minWidth: current | ||
}, index < keys.length - 1 ? { | ||
maxWidth: breakpointValues[index + 1] - 1 | ||
} : {}); | ||
var mediaQuery = json2mq(options); | ||
return Object.assign(accumulator, _defineProperty({}, keys[index], mediaQuery)); | ||
}, {}); | ||
return mediaQueries; | ||
} | ||
function selectBreakpoints(_ref) { | ||
var mqProp = _ref.mqProp, | ||
_ref$isMqPlus = _ref.isMqPlus, | ||
isMqPlus = _ref$isMqPlus === void 0 ? { | ||
value: false | ||
} : _ref$isMqPlus, | ||
_ref$isMqMinus = _ref.isMqMinus, | ||
isMqMinus = _ref$isMqMinus === void 0 ? { | ||
value: false | ||
} : _ref$isMqMinus, | ||
_ref$isMqRange = _ref.isMqRange, | ||
isMqRange = _ref$isMqRange === void 0 ? { | ||
value: false | ||
} : _ref$isMqRange; | ||
var ents = Object.entries(mqAvailableBreakpoints.value); | ||
if (ents.length === 0) return []; | ||
if (isMqPlus.value) mqProp = mqProp.replace(/\+$/, "");else if (isMqMinus.value) mqProp = mqProp.replace(/-$/, "");else if (isMqRange.value) { | ||
mqProp = mqProp.split("-"); | ||
if (!mqProp || mqProp.length !== 2) throw new Error("Invalid MQ range provided"); | ||
} | ||
var eligible; | ||
if (isMqRange.value) { | ||
var from = ents.find(function (_ref2) { | ||
var _ref3 = _slicedToArray(_ref2, 2), | ||
key = _ref3[0], | ||
value = _ref3[1]; | ||
return key == mqProp[0].trim(); | ||
}); | ||
if (!from || from.length === 0) throw new Error('Range from breakpoint (' + mqProp[0].trim() + ') not found'); | ||
var to = ents.find(function (_ref4) { | ||
var _ref5 = _slicedToArray(_ref4, 2), | ||
key = _ref5[0], | ||
value = _ref5[1]; | ||
return key == mqProp[1].trim(); | ||
}); | ||
if (!to || to.length === 0) throw new Error('Range to breakpoint (' + mqProp[1].trim() + ') not found'); | ||
if (from[1] > to[1]) { | ||
var _ref6 = [to, from]; | ||
from = _ref6[0]; | ||
to = _ref6[1]; | ||
} | ||
eligible = ents.filter(function (_ref7) { | ||
var _ref8 = _slicedToArray(_ref7, 2), | ||
key = _ref8[0], | ||
value = _ref8[1]; | ||
return value >= from[1] && value <= to[1]; | ||
}); | ||
} else { | ||
var base = ents.find(function (_ref9) { | ||
var _ref10 = _slicedToArray(_ref9, 2), | ||
key = _ref10[0], | ||
value = _ref10[1]; | ||
return key == mqProp; | ||
}); | ||
if (isMqPlus.value) eligible = ents.filter(function (_ref11) { | ||
var _ref12 = _slicedToArray(_ref11, 2), | ||
key = _ref12[0], | ||
value = _ref12[1]; | ||
return value >= base[1]; | ||
});else if (isMqMinus.value) eligible = ents.filter(function (_ref13) { | ||
var _ref14 = _slicedToArray(_ref13, 2), | ||
key = _ref14[0], | ||
value = _ref14[1]; | ||
return value <= base[1]; | ||
}); | ||
} | ||
eligible.sort(function (a, b) { | ||
return a[1] - b[1]; | ||
}); | ||
return eligible.map(function (el) { | ||
return el[0]; | ||
}); | ||
} | ||
function subscribeToMediaQuery(mediaQuery, enter) { | ||
var mql = window.matchMedia(mediaQuery); | ||
var cb = function cb(_ref15) { | ||
var matches = _ref15.matches; | ||
if (matches) enter(); | ||
}; | ||
listeners.push({ | ||
mql: mql, | ||
cb: cb | ||
}); | ||
mql.addEventListener('change', cb); //subscribing | ||
cb(mql); //initial trigger | ||
} | ||
// USAGE // mq-layout(mq="lg") // p I’m lg | ||
var MqLayout = { | ||
@@ -148,17 +264,46 @@ name: "MqLayout", | ||
required: true, | ||
type: [String, Array] | ||
type: [Object] | ||
}, | ||
tag: { | ||
type: String, | ||
"default": 'div' | ||
"default": "div" | ||
} | ||
}, | ||
setup: function setup(props, context) { | ||
var plusModifier = computed(function () { | ||
return !isArray(props.mq) && props.mq.slice(-1) === "+"; | ||
/* | ||
props.mq | ||
['sm','md','lg'] ( respond to sm, md and lg ) | ||
md+ ( respond to md and above ) | ||
-lg ( respond to lg and below ) | ||
sm-lg ( respond to sm, md and lg ) | ||
*/ | ||
var isMqArray = computed(function () { | ||
return Array.isArray(props.mq); | ||
}); | ||
var isMqPlus = computed(function () { | ||
return !isMqArray.value && /\+$/.test(props.mq) === true; | ||
}); | ||
var isMqMinus = computed(function () { | ||
return !isMqArray.value && /-$/.test(props.mq) === true; | ||
}); | ||
var isMqRange = computed(function () { | ||
return !isMqArray.value && /^\w*-\w*/.test(props.mq) === true; | ||
}); | ||
/* | ||
const plusModifier = computed( | ||
() => !Array.isArray(props.mq) && props.mq.slice(-1) === "+" | ||
); | ||
*/ | ||
// Add a minus modifier here | ||
var activeBreakpoints = computed(function () { | ||
var breakpoints = Object.keys(mqAvailableBreakpoints.value); | ||
var mq = plusModifier.value ? props.mq.slice(0, -1) : isArray(props.mq) ? props.mq : [props.mq]; | ||
return plusModifier.value ? selectBreakpoints(breakpoints, mq) : mq; | ||
if (isMqArray.value) return props.mq;else if (!isMqPlus.value && !isMqMinus.value && !isMqRange.value) return [props.mq];else { | ||
console.log(mqAvailableBreakpoints.value); | ||
return selectBreakpoints({ | ||
mqProp: props.mq, | ||
isMqPlus: isMqPlus, | ||
isMqMinus: isMqMinus, | ||
isMqRange: isMqRange | ||
}); | ||
} | ||
}); | ||
@@ -205,3 +350,3 @@ var shouldRenderChildren = computed(function () { | ||
app.config.globalProperties.$mqAvailableBreakpoints = breakpoints; | ||
app.component('mq-layout', MqLayout); | ||
app.component('MqLayout', MqLayout); | ||
}; | ||
@@ -208,0 +353,0 @@ |
@@ -25,2 +25,6 @@ 'use strict'; | ||
function _slicedToArray(arr, i) { | ||
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); | ||
} | ||
function _toConsumableArray(arr) { | ||
@@ -34,2 +38,6 @@ return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); | ||
function _arrayWithHoles(arr) { | ||
if (Array.isArray(arr)) return arr; | ||
} | ||
function _iterableToArray(iter) { | ||
@@ -39,2 +47,29 @@ if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); | ||
function _iterableToArrayLimit(arr, i) { | ||
if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; | ||
var _arr = []; | ||
var _n = true; | ||
var _d = false; | ||
var _e = undefined; | ||
try { | ||
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { | ||
_arr.push(_s.value); | ||
if (i && _arr.length === i) break; | ||
} | ||
} catch (err) { | ||
_d = true; | ||
_e = err; | ||
} finally { | ||
try { | ||
if (!_n && _i["return"] != null) _i["return"](); | ||
} finally { | ||
if (_d) throw _e; | ||
} | ||
} | ||
return _arr; | ||
} | ||
function _unsupportedIterableToArray(o, minLen) { | ||
@@ -61,43 +96,6 @@ if (!o) return; | ||
var listeners = []; | ||
function convertBreakpointsToMediaQueries(breakpoints) { | ||
var keys = Object.keys(breakpoints); | ||
var values = keys.map(function (key) { | ||
return breakpoints[key]; | ||
}); | ||
var breakpointValues = [0].concat(_toConsumableArray(values.slice(0, -1))); | ||
var mediaQueries = breakpointValues.reduce(function (sum, value, index) { | ||
var options = Object.assign({ | ||
minWidth: value | ||
}, index < keys.length - 1 ? { | ||
maxWidth: breakpointValues[index + 1] - 1 | ||
} : {}); | ||
var mediaQuery = json2mq__default['default'](options); | ||
return Object.assign(sum, _defineProperty({}, keys[index], mediaQuery)); | ||
}, {}); | ||
return mediaQueries; | ||
function _nonIterableRest() { | ||
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); | ||
} | ||
function selectBreakpoints(breakpoints, currentBreakpoint) { | ||
var index = breakpoints.findIndex(function (b) { | ||
return b === currentBreakpoint; | ||
}); | ||
return breakpoints.slice(index); | ||
} | ||
function subscribeToMediaQuery(mediaQuery, enter) { | ||
var mql = window.matchMedia(mediaQuery); | ||
var cb = function cb(_ref) { | ||
var matches = _ref.matches; | ||
if (matches) enter(); | ||
}; | ||
listeners.push({ | ||
mql: mql, | ||
cb: cb | ||
}); | ||
mql.addEventListener('change', cb); //subscribing | ||
cb(mql); //initial trigger | ||
} | ||
var state = { | ||
@@ -115,6 +113,4 @@ mqAvailableBreakpoints: vue.ref({}), | ||
var currentBreakpoint = vue.readonly(state.currentBreakpoint); | ||
function isArray(arg) { | ||
return Object.prototype.toString.call(arg) === '[object Array]'; | ||
} | ||
function updateBreakpoints(breakpoints) { | ||
// Remove any existing MQ listeners | ||
for (var i = listeners.length - 1; i >= 0; i--) { | ||
@@ -126,7 +122,9 @@ var _listeners$i = listeners[i], | ||
listeners.splice(i, 1); | ||
} | ||
} // Save new breakpoints to reactive variable | ||
setAvailableBreakpoints(breakpoints); | ||
var mediaQueries = convertBreakpointsToMediaQueries(breakpoints); // setup listeners | ||
setAvailableBreakpoints(breakpoints); // Create css media queries from breakpoints | ||
var mediaQueries = convertBreakpointsToMediaQueries(breakpoints); // Add new MQ listeners | ||
var _loop = function _loop(key) { | ||
@@ -147,3 +145,121 @@ var mediaQuery = mediaQueries[key]; | ||
// USAGE | ||
var listeners = []; | ||
function convertBreakpointsToMediaQueries(breakpoints) { | ||
var keys = Object.keys(breakpoints); | ||
var values = keys.map(function (key) { | ||
return breakpoints[key]; | ||
}); | ||
var breakpointValues = [0].concat(_toConsumableArray(values.slice(0, -1))); | ||
var mediaQueries = breakpointValues.reduce(function (accumulator, current, index) { | ||
var options = Object.assign({ | ||
minWidth: current | ||
}, index < keys.length - 1 ? { | ||
maxWidth: breakpointValues[index + 1] - 1 | ||
} : {}); | ||
var mediaQuery = json2mq__default['default'](options); | ||
return Object.assign(accumulator, _defineProperty({}, keys[index], mediaQuery)); | ||
}, {}); | ||
return mediaQueries; | ||
} | ||
function selectBreakpoints(_ref) { | ||
var mqProp = _ref.mqProp, | ||
_ref$isMqPlus = _ref.isMqPlus, | ||
isMqPlus = _ref$isMqPlus === void 0 ? { | ||
value: false | ||
} : _ref$isMqPlus, | ||
_ref$isMqMinus = _ref.isMqMinus, | ||
isMqMinus = _ref$isMqMinus === void 0 ? { | ||
value: false | ||
} : _ref$isMqMinus, | ||
_ref$isMqRange = _ref.isMqRange, | ||
isMqRange = _ref$isMqRange === void 0 ? { | ||
value: false | ||
} : _ref$isMqRange; | ||
var ents = Object.entries(mqAvailableBreakpoints.value); | ||
if (ents.length === 0) return []; | ||
if (isMqPlus.value) mqProp = mqProp.replace(/\+$/, "");else if (isMqMinus.value) mqProp = mqProp.replace(/-$/, "");else if (isMqRange.value) { | ||
mqProp = mqProp.split("-"); | ||
if (!mqProp || mqProp.length !== 2) throw new Error("Invalid MQ range provided"); | ||
} | ||
var eligible; | ||
if (isMqRange.value) { | ||
var from = ents.find(function (_ref2) { | ||
var _ref3 = _slicedToArray(_ref2, 2), | ||
key = _ref3[0], | ||
value = _ref3[1]; | ||
return key == mqProp[0].trim(); | ||
}); | ||
if (!from || from.length === 0) throw new Error('Range from breakpoint (' + mqProp[0].trim() + ') not found'); | ||
var to = ents.find(function (_ref4) { | ||
var _ref5 = _slicedToArray(_ref4, 2), | ||
key = _ref5[0], | ||
value = _ref5[1]; | ||
return key == mqProp[1].trim(); | ||
}); | ||
if (!to || to.length === 0) throw new Error('Range to breakpoint (' + mqProp[1].trim() + ') not found'); | ||
if (from[1] > to[1]) { | ||
var _ref6 = [to, from]; | ||
from = _ref6[0]; | ||
to = _ref6[1]; | ||
} | ||
eligible = ents.filter(function (_ref7) { | ||
var _ref8 = _slicedToArray(_ref7, 2), | ||
key = _ref8[0], | ||
value = _ref8[1]; | ||
return value >= from[1] && value <= to[1]; | ||
}); | ||
} else { | ||
var base = ents.find(function (_ref9) { | ||
var _ref10 = _slicedToArray(_ref9, 2), | ||
key = _ref10[0], | ||
value = _ref10[1]; | ||
return key == mqProp; | ||
}); | ||
if (isMqPlus.value) eligible = ents.filter(function (_ref11) { | ||
var _ref12 = _slicedToArray(_ref11, 2), | ||
key = _ref12[0], | ||
value = _ref12[1]; | ||
return value >= base[1]; | ||
});else if (isMqMinus.value) eligible = ents.filter(function (_ref13) { | ||
var _ref14 = _slicedToArray(_ref13, 2), | ||
key = _ref14[0], | ||
value = _ref14[1]; | ||
return value <= base[1]; | ||
}); | ||
} | ||
eligible.sort(function (a, b) { | ||
return a[1] - b[1]; | ||
}); | ||
return eligible.map(function (el) { | ||
return el[0]; | ||
}); | ||
} | ||
function subscribeToMediaQuery(mediaQuery, enter) { | ||
var mql = window.matchMedia(mediaQuery); | ||
var cb = function cb(_ref15) { | ||
var matches = _ref15.matches; | ||
if (matches) enter(); | ||
}; | ||
listeners.push({ | ||
mql: mql, | ||
cb: cb | ||
}); | ||
mql.addEventListener('change', cb); //subscribing | ||
cb(mql); //initial trigger | ||
} | ||
// USAGE // mq-layout(mq="lg") // p I’m lg | ||
var MqLayout = { | ||
@@ -154,17 +270,46 @@ name: "MqLayout", | ||
required: true, | ||
type: [String, Array] | ||
type: [Object] | ||
}, | ||
tag: { | ||
type: String, | ||
"default": 'div' | ||
"default": "div" | ||
} | ||
}, | ||
setup: function setup(props, context) { | ||
var plusModifier = vue.computed(function () { | ||
return !isArray(props.mq) && props.mq.slice(-1) === "+"; | ||
/* | ||
props.mq | ||
['sm','md','lg'] ( respond to sm, md and lg ) | ||
md+ ( respond to md and above ) | ||
-lg ( respond to lg and below ) | ||
sm-lg ( respond to sm, md and lg ) | ||
*/ | ||
var isMqArray = vue.computed(function () { | ||
return Array.isArray(props.mq); | ||
}); | ||
var isMqPlus = vue.computed(function () { | ||
return !isMqArray.value && /\+$/.test(props.mq) === true; | ||
}); | ||
var isMqMinus = vue.computed(function () { | ||
return !isMqArray.value && /-$/.test(props.mq) === true; | ||
}); | ||
var isMqRange = vue.computed(function () { | ||
return !isMqArray.value && /^\w*-\w*/.test(props.mq) === true; | ||
}); | ||
/* | ||
const plusModifier = computed( | ||
() => !Array.isArray(props.mq) && props.mq.slice(-1) === "+" | ||
); | ||
*/ | ||
// Add a minus modifier here | ||
var activeBreakpoints = vue.computed(function () { | ||
var breakpoints = Object.keys(mqAvailableBreakpoints.value); | ||
var mq = plusModifier.value ? props.mq.slice(0, -1) : isArray(props.mq) ? props.mq : [props.mq]; | ||
return plusModifier.value ? selectBreakpoints(breakpoints, mq) : mq; | ||
if (isMqArray.value) return props.mq;else if (!isMqPlus.value && !isMqMinus.value && !isMqRange.value) return [props.mq];else { | ||
console.log(mqAvailableBreakpoints.value); | ||
return selectBreakpoints({ | ||
mqProp: props.mq, | ||
isMqPlus: isMqPlus, | ||
isMqMinus: isMqMinus, | ||
isMqRange: isMqRange | ||
}); | ||
} | ||
}); | ||
@@ -211,3 +356,3 @@ var shouldRenderChildren = vue.computed(function () { | ||
app.config.globalProperties.$mqAvailableBreakpoints = breakpoints; | ||
app.component('mq-layout', MqLayout); | ||
app.component('MqLayout', MqLayout); | ||
}; | ||
@@ -214,0 +359,0 @@ |
@@ -22,2 +22,6 @@ (function (global, factory) { | ||
function _slicedToArray(arr, i) { | ||
return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); | ||
} | ||
function _toConsumableArray(arr) { | ||
@@ -31,2 +35,6 @@ return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); | ||
function _arrayWithHoles(arr) { | ||
if (Array.isArray(arr)) return arr; | ||
} | ||
function _iterableToArray(iter) { | ||
@@ -36,2 +44,29 @@ if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); | ||
function _iterableToArrayLimit(arr, i) { | ||
if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; | ||
var _arr = []; | ||
var _n = true; | ||
var _d = false; | ||
var _e = undefined; | ||
try { | ||
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { | ||
_arr.push(_s.value); | ||
if (i && _arr.length === i) break; | ||
} | ||
} catch (err) { | ||
_d = true; | ||
_e = err; | ||
} finally { | ||
try { | ||
if (!_n && _i["return"] != null) _i["return"](); | ||
} finally { | ||
if (_d) throw _e; | ||
} | ||
} | ||
return _arr; | ||
} | ||
function _unsupportedIterableToArray(o, minLen) { | ||
@@ -58,2 +93,6 @@ if (!o) return; | ||
function _nonIterableRest() { | ||
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); | ||
} | ||
var camel2hyphen = function (str) { | ||
@@ -119,43 +158,2 @@ return str | ||
var listeners = []; | ||
function convertBreakpointsToMediaQueries(breakpoints) { | ||
var keys = Object.keys(breakpoints); | ||
var values = keys.map(function (key) { | ||
return breakpoints[key]; | ||
}); | ||
var breakpointValues = [0].concat(_toConsumableArray(values.slice(0, -1))); | ||
var mediaQueries = breakpointValues.reduce(function (sum, value, index) { | ||
var options = Object.assign({ | ||
minWidth: value | ||
}, index < keys.length - 1 ? { | ||
maxWidth: breakpointValues[index + 1] - 1 | ||
} : {}); | ||
var mediaQuery = json2mq_1(options); | ||
return Object.assign(sum, _defineProperty({}, keys[index], mediaQuery)); | ||
}, {}); | ||
return mediaQueries; | ||
} | ||
function selectBreakpoints(breakpoints, currentBreakpoint) { | ||
var index = breakpoints.findIndex(function (b) { | ||
return b === currentBreakpoint; | ||
}); | ||
return breakpoints.slice(index); | ||
} | ||
function subscribeToMediaQuery(mediaQuery, enter) { | ||
var mql = window.matchMedia(mediaQuery); | ||
var cb = function cb(_ref) { | ||
var matches = _ref.matches; | ||
if (matches) enter(); | ||
}; | ||
listeners.push({ | ||
mql: mql, | ||
cb: cb | ||
}); | ||
mql.addEventListener('change', cb); //subscribing | ||
cb(mql); //initial trigger | ||
} | ||
var state = { | ||
@@ -173,6 +171,4 @@ mqAvailableBreakpoints: vue.ref({}), | ||
var currentBreakpoint = vue.readonly(state.currentBreakpoint); | ||
function isArray(arg) { | ||
return Object.prototype.toString.call(arg) === '[object Array]'; | ||
} | ||
function updateBreakpoints(breakpoints) { | ||
// Remove any existing MQ listeners | ||
for (var i = listeners.length - 1; i >= 0; i--) { | ||
@@ -184,7 +180,9 @@ var _listeners$i = listeners[i], | ||
listeners.splice(i, 1); | ||
} | ||
} // Save new breakpoints to reactive variable | ||
setAvailableBreakpoints(breakpoints); | ||
var mediaQueries = convertBreakpointsToMediaQueries(breakpoints); // setup listeners | ||
setAvailableBreakpoints(breakpoints); // Create css media queries from breakpoints | ||
var mediaQueries = convertBreakpointsToMediaQueries(breakpoints); // Add new MQ listeners | ||
var _loop = function _loop(key) { | ||
@@ -205,3 +203,121 @@ var mediaQuery = mediaQueries[key]; | ||
// USAGE | ||
var listeners = []; | ||
function convertBreakpointsToMediaQueries(breakpoints) { | ||
var keys = Object.keys(breakpoints); | ||
var values = keys.map(function (key) { | ||
return breakpoints[key]; | ||
}); | ||
var breakpointValues = [0].concat(_toConsumableArray(values.slice(0, -1))); | ||
var mediaQueries = breakpointValues.reduce(function (accumulator, current, index) { | ||
var options = Object.assign({ | ||
minWidth: current | ||
}, index < keys.length - 1 ? { | ||
maxWidth: breakpointValues[index + 1] - 1 | ||
} : {}); | ||
var mediaQuery = json2mq_1(options); | ||
return Object.assign(accumulator, _defineProperty({}, keys[index], mediaQuery)); | ||
}, {}); | ||
return mediaQueries; | ||
} | ||
function selectBreakpoints(_ref) { | ||
var mqProp = _ref.mqProp, | ||
_ref$isMqPlus = _ref.isMqPlus, | ||
isMqPlus = _ref$isMqPlus === void 0 ? { | ||
value: false | ||
} : _ref$isMqPlus, | ||
_ref$isMqMinus = _ref.isMqMinus, | ||
isMqMinus = _ref$isMqMinus === void 0 ? { | ||
value: false | ||
} : _ref$isMqMinus, | ||
_ref$isMqRange = _ref.isMqRange, | ||
isMqRange = _ref$isMqRange === void 0 ? { | ||
value: false | ||
} : _ref$isMqRange; | ||
var ents = Object.entries(mqAvailableBreakpoints.value); | ||
if (ents.length === 0) return []; | ||
if (isMqPlus.value) mqProp = mqProp.replace(/\+$/, "");else if (isMqMinus.value) mqProp = mqProp.replace(/-$/, "");else if (isMqRange.value) { | ||
mqProp = mqProp.split("-"); | ||
if (!mqProp || mqProp.length !== 2) throw new Error("Invalid MQ range provided"); | ||
} | ||
var eligible; | ||
if (isMqRange.value) { | ||
var from = ents.find(function (_ref2) { | ||
var _ref3 = _slicedToArray(_ref2, 2), | ||
key = _ref3[0], | ||
value = _ref3[1]; | ||
return key == mqProp[0].trim(); | ||
}); | ||
if (!from || from.length === 0) throw new Error('Range from breakpoint (' + mqProp[0].trim() + ') not found'); | ||
var to = ents.find(function (_ref4) { | ||
var _ref5 = _slicedToArray(_ref4, 2), | ||
key = _ref5[0], | ||
value = _ref5[1]; | ||
return key == mqProp[1].trim(); | ||
}); | ||
if (!to || to.length === 0) throw new Error('Range to breakpoint (' + mqProp[1].trim() + ') not found'); | ||
if (from[1] > to[1]) { | ||
var _ref6 = [to, from]; | ||
from = _ref6[0]; | ||
to = _ref6[1]; | ||
} | ||
eligible = ents.filter(function (_ref7) { | ||
var _ref8 = _slicedToArray(_ref7, 2), | ||
key = _ref8[0], | ||
value = _ref8[1]; | ||
return value >= from[1] && value <= to[1]; | ||
}); | ||
} else { | ||
var base = ents.find(function (_ref9) { | ||
var _ref10 = _slicedToArray(_ref9, 2), | ||
key = _ref10[0], | ||
value = _ref10[1]; | ||
return key == mqProp; | ||
}); | ||
if (isMqPlus.value) eligible = ents.filter(function (_ref11) { | ||
var _ref12 = _slicedToArray(_ref11, 2), | ||
key = _ref12[0], | ||
value = _ref12[1]; | ||
return value >= base[1]; | ||
});else if (isMqMinus.value) eligible = ents.filter(function (_ref13) { | ||
var _ref14 = _slicedToArray(_ref13, 2), | ||
key = _ref14[0], | ||
value = _ref14[1]; | ||
return value <= base[1]; | ||
}); | ||
} | ||
eligible.sort(function (a, b) { | ||
return a[1] - b[1]; | ||
}); | ||
return eligible.map(function (el) { | ||
return el[0]; | ||
}); | ||
} | ||
function subscribeToMediaQuery(mediaQuery, enter) { | ||
var mql = window.matchMedia(mediaQuery); | ||
var cb = function cb(_ref15) { | ||
var matches = _ref15.matches; | ||
if (matches) enter(); | ||
}; | ||
listeners.push({ | ||
mql: mql, | ||
cb: cb | ||
}); | ||
mql.addEventListener('change', cb); //subscribing | ||
cb(mql); //initial trigger | ||
} | ||
// USAGE // mq-layout(mq="lg") // p I’m lg | ||
var MqLayout = { | ||
@@ -212,17 +328,46 @@ name: "MqLayout", | ||
required: true, | ||
type: [String, Array] | ||
type: [Object] | ||
}, | ||
tag: { | ||
type: String, | ||
"default": 'div' | ||
"default": "div" | ||
} | ||
}, | ||
setup: function setup(props, context) { | ||
var plusModifier = vue.computed(function () { | ||
return !isArray(props.mq) && props.mq.slice(-1) === "+"; | ||
/* | ||
props.mq | ||
['sm','md','lg'] ( respond to sm, md and lg ) | ||
md+ ( respond to md and above ) | ||
-lg ( respond to lg and below ) | ||
sm-lg ( respond to sm, md and lg ) | ||
*/ | ||
var isMqArray = vue.computed(function () { | ||
return Array.isArray(props.mq); | ||
}); | ||
var isMqPlus = vue.computed(function () { | ||
return !isMqArray.value && /\+$/.test(props.mq) === true; | ||
}); | ||
var isMqMinus = vue.computed(function () { | ||
return !isMqArray.value && /-$/.test(props.mq) === true; | ||
}); | ||
var isMqRange = vue.computed(function () { | ||
return !isMqArray.value && /^\w*-\w*/.test(props.mq) === true; | ||
}); | ||
/* | ||
const plusModifier = computed( | ||
() => !Array.isArray(props.mq) && props.mq.slice(-1) === "+" | ||
); | ||
*/ | ||
// Add a minus modifier here | ||
var activeBreakpoints = vue.computed(function () { | ||
var breakpoints = Object.keys(mqAvailableBreakpoints.value); | ||
var mq = plusModifier.value ? props.mq.slice(0, -1) : isArray(props.mq) ? props.mq : [props.mq]; | ||
return plusModifier.value ? selectBreakpoints(breakpoints, mq) : mq; | ||
if (isMqArray.value) return props.mq;else if (!isMqPlus.value && !isMqMinus.value && !isMqRange.value) return [props.mq];else { | ||
console.log(mqAvailableBreakpoints.value); | ||
return selectBreakpoints({ | ||
mqProp: props.mq, | ||
isMqPlus: isMqPlus, | ||
isMqMinus: isMqMinus, | ||
isMqRange: isMqRange | ||
}); | ||
} | ||
}); | ||
@@ -269,3 +414,3 @@ var shouldRenderChildren = vue.computed(function () { | ||
app.config.globalProperties.$mqAvailableBreakpoints = breakpoints; | ||
app.component('mq-layout', MqLayout); | ||
app.component('MqLayout', MqLayout); | ||
}; | ||
@@ -272,0 +417,0 @@ |
@@ -1,2 +0,2 @@ | ||
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n(require("vue")):"function"==typeof define&&define.amd?define(["vue"],n):(e="undefined"!=typeof globalThis?globalThis:e||self)["vue3-mq"]=n(e.vue)}(this,(function(e){"use strict";function n(e){return function(e){if(Array.isArray(e))return t(e)}(e)||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||function(e,n){if(!e)return;if("string"==typeof e)return t(e,n);var r=Object.prototype.toString.call(e).slice(8,-1);"Object"===r&&e.constructor&&(r=e.constructor.name);if("Map"===r||"Set"===r)return Array.from(e);if("Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r))return t(e,n)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function t(e,n){(null==n||n>e.length)&&(n=e.length);for(var t=0,r=new Array(n);t<n;t++)r[t]=e[t];return r}var r=function(e){return e.replace(/[A-Z]/g,(function(e){return"-"+e.toLowerCase()})).toLowerCase()},o=function(e){var n="",t=Object.keys(e);return t.forEach((function(o,i){var u=e[o];(function(e){return/[height|width]$/.test(e)})(o=r(o))&&"number"==typeof u&&(u+="px"),n+=!0===u?o:!1===u?"not "+o:"("+o+": "+u+")",i<t.length-1&&(n+=" and ")})),n},i=function(e){var n="";return"string"==typeof e?e:e instanceof Array?(e.forEach((function(t,r){n+=o(t),r<e.length-1&&(n+=", ")})),n):o(e)},u=[];function a(e){var t=Object.keys(e),r=t.map((function(n){return e[n]})),o=[0].concat(n(r.slice(0,-1)));return o.reduce((function(e,n,r){var u=Object.assign({minWidth:n},r<t.length-1?{maxWidth:o[r+1]-1}:{}),a=i(u);return Object.assign(e,function(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}({},t[r],a))}),{})}var c={mqAvailableBreakpoints:e.ref({}),currentBreakpoint:e.ref("")},f=e.readonly(c.mqAvailableBreakpoints),l=function(e){return c.currentBreakpoint.value=e},s=e.readonly(c.currentBreakpoint);function m(e){return"[object Array]"===Object.prototype.toString.call(e)}function d(e){for(var n=u.length-1;n>=0;n--){var t=u[n],r=t.mql,o=t.cb;r.removeEventListener("change",o),u.splice(n,1)}var i;i=e,c.mqAvailableBreakpoints.value=i;var f=a(e),s=function(e){!function(e,n){var t=window.matchMedia(e),r=function(e){e.matches&&n()};u.push({mql:t,cb:r}),t.addEventListener("change",r),r(t)}(f[e],(function(){l(e)}))};for(var m in f)s(m)}var p={name:"MqLayout",props:{mq:{required:!0,type:[String,Array]},tag:{type:String,default:"div"}},setup:function(n,t){var r=e.computed((function(){return!m(n.mq)&&"+"===n.mq.slice(-1)})),o=e.computed((function(){var e=Object.keys(f.value),t=r.value?n.mq.slice(0,-1):m(n.mq)?n.mq:[n.mq];return r.value?function(e,n){var t=e.findIndex((function(e){return e===n}));return e.slice(t)}(e,t):t})),i=e.computed((function(){return o.value.includes(s.value)}));return function(){return i.value?e.h(n.tag,{},t.slots.default()):e.h()}}},v={sm:450,md:1250,lg:1/0};return{install:function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},t=n.breakpoints,r=void 0===t?v:t,o=n.defaultBreakpoint,i=void 0===o?"sm":o,u=!1;l(i),e.provide("updateBreakpoints",d),e.mixin({computed:{$mq:function(){return s.value}},mounted:function(){u||(d(r),u=!0)}}),e.config.globalProperties.$mqAvailableBreakpoints=r,e.component("mq-layout",p)}}})); | ||
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?module.exports=n(require("vue")):"function"==typeof define&&define.amd?define(["vue"],n):(e="undefined"!=typeof globalThis?globalThis:e||self)["vue3-mq"]=n(e.vue)}(this,(function(e){"use strict";function n(e,n){return function(e){if(Array.isArray(e))return e}(e)||function(e,n){if("undefined"==typeof Symbol||!(Symbol.iterator in Object(e)))return;var t=[],r=!0,o=!1,i=void 0;try{for(var u,a=e[Symbol.iterator]();!(r=(u=a.next()).done)&&(t.push(u.value),!n||t.length!==n);r=!0);}catch(e){o=!0,i=e}finally{try{r||null==a.return||a.return()}finally{if(o)throw i}}return t}(e,n)||r(e,n)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function t(e){return function(e){if(Array.isArray(e))return o(e)}(e)||function(e){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(e))return Array.from(e)}(e)||r(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function r(e,n){if(e){if("string"==typeof e)return o(e,n);var t=Object.prototype.toString.call(e).slice(8,-1);return"Object"===t&&e.constructor&&(t=e.constructor.name),"Map"===t||"Set"===t?Array.from(e):"Arguments"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?o(e,n):void 0}}function o(e,n){(null==n||n>e.length)&&(n=e.length);for(var t=0,r=new Array(n);t<n;t++)r[t]=e[t];return r}var i=function(e){return e.replace(/[A-Z]/g,(function(e){return"-"+e.toLowerCase()})).toLowerCase()},u=function(e){var n="",t=Object.keys(e);return t.forEach((function(r,o){var u=e[r];(function(e){return/[height|width]$/.test(e)})(r=i(r))&&"number"==typeof u&&(u+="px"),n+=!0===u?r:!1===u?"not "+r:"("+r+": "+u+")",o<t.length-1&&(n+=" and ")})),n},a=function(e){var n="";return"string"==typeof e?e:e instanceof Array?(e.forEach((function(t,r){n+=u(t),r<e.length-1&&(n+=", ")})),n):u(e)},l={mqAvailableBreakpoints:e.ref({}),currentBreakpoint:e.ref("")},f=e.readonly(l.mqAvailableBreakpoints),c=function(e){return l.currentBreakpoint.value=e},v=e.readonly(l.currentBreakpoint);function s(e){for(var n=d.length-1;n>=0;n--){var r=d[n],o=r.mql,i=r.cb;o.removeEventListener("change",i),d.splice(n,1)}var u;u=e,l.mqAvailableBreakpoints.value=u;var f=function(e){var n=Object.keys(e),r=n.map((function(n){return e[n]})),o=[0].concat(t(r.slice(0,-1)));return o.reduce((function(e,t,r){var i,u,l,f=Object.assign({minWidth:t},r<n.length-1?{maxWidth:o[r+1]-1}:{}),c=a(f);return Object.assign(e,(i={},u=n[r],l=c,u in i?Object.defineProperty(i,u,{value:l,enumerable:!0,configurable:!0,writable:!0}):i[u]=l,i))}),{})}(e),v=function(e){!function(e,n){var t=window.matchMedia(e),r=function(e){e.matches&&n()};d.push({mql:t,cb:r}),t.addEventListener("change",r),r(t)}(f[e],(function(){c(e)}))};for(var s in f)v(s)}var d=[];var m={name:"MqLayout",props:{mq:{required:!0,type:[Object]},tag:{type:String,default:"div"}},setup:function(t,r){var o=e.computed((function(){return Array.isArray(t.mq)})),i=e.computed((function(){return!o.value&&!0===/\+$/.test(t.mq)})),u=e.computed((function(){return!o.value&&!0===/-$/.test(t.mq)})),a=e.computed((function(){return!o.value&&!0===/^\w*-\w*/.test(t.mq)})),l=e.computed((function(){return o.value?t.mq:i.value||u.value||a.value?(console.log(f.value),function(e){var t,r=e.mqProp,o=e.isMqPlus,i=void 0===o?{value:!1}:o,u=e.isMqMinus,a=void 0===u?{value:!1}:u,l=e.isMqRange,c=void 0===l?{value:!1}:l,v=Object.entries(f.value);if(0===v.length)return[];if(i.value)r=r.replace(/\+$/,"");else if(a.value)r=r.replace(/-$/,"");else if(c.value&&(!(r=r.split("-"))||2!==r.length))throw new Error("Invalid MQ range provided");if(c.value){var s=v.find((function(e){var t=n(e,2),o=t[0];t[1];return o==r[0].trim()}));if(!s||0===s.length)throw new Error("Range from breakpoint ("+r[0].trim()+") not found");var d=v.find((function(e){var t=n(e,2),o=t[0];t[1];return o==r[1].trim()}));if(!d||0===d.length)throw new Error("Range to breakpoint ("+r[1].trim()+") not found");if(s[1]>d[1]){var m=[d,s];s=m[0],d=m[1]}t=v.filter((function(e){var t=n(e,2),r=(t[0],t[1]);return r>=s[1]&&r<=d[1]}))}else{var p=v.find((function(e){var t=n(e,2),o=t[0];t[1];return o==r}));i.value?t=v.filter((function(e){var t=n(e,2);t[0];return t[1]>=p[1]})):a.value&&(t=v.filter((function(e){var t=n(e,2);t[0];return t[1]<=p[1]})))}return t.sort((function(e,n){return e[1]-n[1]})),t.map((function(e){return e[0]}))}({mqProp:t.mq,isMqPlus:i,isMqMinus:u,isMqRange:a})):[t.mq]})),c=e.computed((function(){return l.value.includes(v.value)}));return function(){return c.value?e.h(t.tag,{},r.slots.default()):e.h()}}},p={sm:450,md:1250,lg:1/0};return{install:function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},t=n.breakpoints,r=void 0===t?p:t,o=n.defaultBreakpoint,i=void 0===o?"sm":o,u=!1;c(i),e.provide("updateBreakpoints",s),e.mixin({computed:{$mq:function(){return v.value}},mounted:function(){u||(s(r),u=!0)}}),e.config.globalProperties.$mqAvailableBreakpoints=r,e.component("MqLayout",m)}}})); | ||
//# sourceMappingURL=index.umd.min.js.map |
{ | ||
"name": "vue3-mq", | ||
"version": "2.1.0", | ||
"description": "Handle media queries easily & build responsive design with Vue", | ||
"version": "2.2.0", | ||
"description": "Handle media queries easily & build responsive design with Vue 3", | ||
"main": "dist/index.js", | ||
@@ -19,11 +19,2 @@ "module": "dist/index.es.js", | ||
}, | ||
"poi": { | ||
"entry": "demo/index.js", | ||
"output": { | ||
"dir": "demo/dist", | ||
"html": { | ||
"template": "demo/index.html" | ||
} | ||
} | ||
}, | ||
"license": "MIT", | ||
@@ -38,8 +29,17 @@ "devDependencies": { | ||
"browser-env": "^3.2.1", | ||
"eslint": "^7.12.1", | ||
"eslint-config-prettier": "^6.15.0", | ||
"eslint-plugin-vue": "^7.0.0-beta.4", | ||
"gh-pages": "^3.1.0", | ||
"json2mq": "^0.2.0", | ||
"match-media-mock": "^0.1.1", | ||
"prettier": "^2.1.2", | ||
"primeflex": "^2.0.0", | ||
"primeicons": "^4.0.0", | ||
"primevue": "^3.0.1", | ||
"sass": "^1.27.0", | ||
"vite": "^1.0.0-rc.8", | ||
"vue": "^3.0.2", | ||
"vite": "^1.0.0-rc.6" | ||
"vue-jest": "^5.0.0-alpha.5" | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
# Vue MQ (MediaQuery) | ||
# Vue 3 MQ (Media Query) | ||
Define your breakpoints and build responsive design semantically and declaratively in a mobile-first way with Vue 3. | ||
@@ -29,3 +29,3 @@ | ||
```sh | ||
npm install @craigrileyuk/vue3-mq | ||
npm install vue3-mq | ||
``` | ||
@@ -35,3 +35,3 @@ | ||
#### 1.) Add plugin to Vue | ||
### 1.) Add plugin to Vue | ||
Define your custom breakpoints by passing `breakpoints` option. This let you name the breakpoints as you want | ||
@@ -49,3 +49,3 @@ | ||
import { createApp } from "vue"; | ||
import VueMq from "@craigrileyuk/vue3-mq"; | ||
import VueMq from "vue3-mq"; | ||
@@ -65,8 +65,11 @@ const app = createApp({}); | ||
#### 2.) Use `$mq` property | ||
### 2.) Use `$mq` global property | ||
After installing the plugin every instance of Vue component is given access to a reactive $mq property. Its value will be a `String` which is the current breakpoint. | ||
**Eg:** _(with default breakpoints)_ | ||
`'sm'` => **0 > screenWidth < 450** | ||
`'md'` => **450 >= screenWidth < 1250** | ||
`'lg'` => **screenWidth >= 1250** | ||
@@ -80,8 +83,8 @@ | ||
#### 3.) Use `$mq` with a computed property | ||
### 3.) Use `$mq` with a computed property | ||
The `$mq` property is fully reactive (like a data property) so feel free to use it in a computed. | ||
The `$mq` property is fully reactive, so feel free to use it in a computed. | ||
```js | ||
new Vue({ | ||
createApp({ | ||
computed: { | ||
@@ -98,3 +101,3 @@ displayText() { | ||
#### 4.) Update breakpoints | ||
### 4.) Update breakpoints | ||
@@ -122,3 +125,3 @@ A function is available via Vue's `provide` method which allows you to dynamically change the breakpoints which are responded to. Simply `inject` it into any component where it's needed. | ||
#### 5.) MqLayout component | ||
### 5.) MqLayout component | ||
In addition to `$mq` property this plugin provide a wrapper component to facilitate conditional rendering with media queries. | ||
@@ -141,10 +144,26 @@ | ||
`mq` => required : [String,Array] | ||
`mq` => required : [String,Array] - see below | ||
`tag` => optional : String - sets the HTML tag to use for the rendered component (default 'div') | ||
*Important*: note that you can append a `+` modifier at the end of the string to specify that the conditional rendering happens for all greater breakpoints. | ||
#### MQ prop: plus modifier | ||
Appending a `+` to your mq property will make the component render on that breakpoint and any *above* | ||
```html | ||
<mq-layout mq="lg+" tag="span">I will render on large and above screen sizes</mq-layout> | ||
``` | ||
#### MQ prop: minus modifier | ||
Appending a `-` to your mq property will make the component render on that breakpoint and any *below* | ||
```html | ||
<mq-layout mq="md-" tag="span">I will render on medium and below screen sizes</mq-layout> | ||
``` | ||
#### MQ prop: range modifier | ||
Placing a `-` between two breakpoints in your mq property will make the component render on any breakpoints in that range | ||
```html | ||
<mq-layout mq="sm-lg">I will render on small, medium and large screen sizes</mq-layout> | ||
``` | ||
## Browser Support | ||
This plugin relies on matchMedia API to detect screensize change. So for older browsers and IE, you should polyfill this out: | ||
This plugin relies on matchMedia API to detect screen size change. So for older browsers and IE, you should polyfill this out: | ||
Paul Irish: [matchMedia polyfill](https://github.com/paulirish/matchMedia.js) | ||
@@ -151,0 +170,0 @@ |
@@ -1,8 +0,13 @@ | ||
// USAGE | ||
// mq-layout(mq="lg") | ||
// p I’m lg | ||
import { selectBreakpoints } from "./helpers"; | ||
import { isArray } from "./utils"; | ||
import { mqAvailableBreakpoints, currentBreakpoint } from "./utils"; | ||
import { computed, h } from "vue"; | ||
// USAGE // mq-layout(mq="lg") // p I’m lg | ||
import { | ||
selectBreakpoints | ||
} from "./helpers"; | ||
import { | ||
mqAvailableBreakpoints, | ||
currentBreakpoint | ||
} from "./store"; | ||
import { | ||
computed, | ||
h | ||
} from "vue"; | ||
@@ -14,24 +19,40 @@ export default { | ||
required: true, | ||
type: [String, Array], | ||
type: [Object] | ||
}, | ||
tag: { | ||
type: String, | ||
default: 'div' | ||
type: String, | ||
default: "div" | ||
} | ||
}, | ||
setup(props, context) { | ||
/* | ||
props.mq | ||
['sm','md','lg'] ( respond to sm, md and lg ) | ||
md+ ( respond to md and above ) | ||
-lg ( respond to lg and below ) | ||
sm-lg ( respond to sm, md and lg ) | ||
*/ | ||
const isMqArray = computed(() => Array.isArray(props.mq)); | ||
const isMqPlus = computed( | ||
() => !isMqArray.value && /\+$/.test(props.mq) === true | ||
); | ||
const isMqMinus = computed( | ||
() => !isMqArray.value && /-$/.test(props.mq) === true | ||
); | ||
const isMqRange = computed( | ||
() => !isMqArray.value && /^\w*-\w*/.test(props.mq) === true | ||
); | ||
/* | ||
const plusModifier = computed( | ||
() => !isArray(props.mq) && props.mq.slice(-1) === "+" | ||
() => !Array.isArray(props.mq) && props.mq.slice(-1) === "+" | ||
); | ||
*/ | ||
// Add a minus modifier here | ||
const activeBreakpoints = computed(() => { | ||
const breakpoints = Object.keys(mqAvailableBreakpoints.value); | ||
// Add minus to the mix here too, in a bracket with pM.val | ||
const mq = plusModifier.value | ||
? props.mq.slice(0, -1) | ||
: isArray(props.mq) | ||
? props.mq | ||
: [props.mq]; | ||
// Add minus to the mix here too | ||
return plusModifier.value ? selectBreakpoints(breakpoints, mq) : mq; | ||
if (isMqArray.value) return props.mq; | ||
else if (!isMqPlus.value && !isMqMinus.value && !isMqRange.value) return [props.mq]; | ||
else { | ||
console.log(mqAvailableBreakpoints.value) | ||
return selectBreakpoints({mqProp: props.mq, isMqPlus, isMqMinus, isMqRange }); | ||
} | ||
}); | ||
@@ -43,6 +64,6 @@ | ||
return () => | ||
shouldRenderChildren.value | ||
? h(props.tag, {}, context.slots.default()) | ||
: h(); | ||
}, | ||
shouldRenderChildren.value ? | ||
h(props.tag, {}, context.slots.default()) : | ||
h(); | ||
} | ||
}; |
import json2mq from 'json2mq'; | ||
import { mqAvailableBreakpoints } from "./store"; | ||
export const listeners = []; | ||
@@ -8,6 +9,6 @@ | ||
const breakpointValues = [0, ...values.slice(0, -1)] | ||
const mediaQueries = breakpointValues.reduce((sum, value, index) => { | ||
const mediaQueries = breakpointValues.reduce((accumulator, current, index) => { | ||
const options = Object.assign( | ||
{ | ||
minWidth: value, | ||
minWidth: current, | ||
}, | ||
@@ -18,3 +19,3 @@ index < keys.length - 1 ? { maxWidth: breakpointValues[index+1] - 1 } : {} | ||
return Object.assign( | ||
sum, | ||
accumulator, | ||
{ | ||
@@ -24,10 +25,31 @@ [keys[index]]: mediaQuery, | ||
) | ||
}, {}) | ||
}, {}); | ||
return mediaQueries | ||
} | ||
export function selectBreakpoints(breakpoints, currentBreakpoint) { | ||
const index = breakpoints.findIndex(b => b === currentBreakpoint) | ||
// Need to have a slice for index < for minus | ||
return breakpoints.slice(index) | ||
export function selectBreakpoints({mqProp, isMqPlus = {value: false}, isMqMinus = {value: false}, isMqRange = {value: false}}) { | ||
const ents = Object.entries(mqAvailableBreakpoints.value); | ||
if (ents.length === 0) return []; | ||
if (isMqPlus.value) mqProp = mqProp.replace(/\+$/,""); | ||
else if (isMqMinus.value) mqProp = mqProp.replace(/-$/,""); | ||
else if (isMqRange.value) { | ||
mqProp = mqProp.split("-"); | ||
if (!mqProp || mqProp.length !== 2) throw new Error("Invalid MQ range provided"); | ||
} | ||
let eligible; | ||
if (isMqRange.value) { | ||
let from = ents.find(([key,value]) => key == mqProp[0].trim()); | ||
if (!from || from.length === 0) throw new Error('Range from breakpoint (' + mqProp[0].trim() + ') not found'); | ||
let to = ents.find(([key,value]) => key == mqProp[1].trim()); | ||
if (!to || to.length === 0) throw new Error('Range to breakpoint (' + mqProp[1].trim() + ') not found'); | ||
if (from[1] > to[1]) [from,to] = [to,from]; | ||
eligible = ents.filter(([key,value]) => value >= from[1] && value <= to[1]); | ||
} | ||
else { | ||
const base = ents.find(([key,value]) => key == mqProp); | ||
if (isMqPlus.value) eligible = ents.filter(([key,value]) => value >= base[1]); | ||
else if (isMqMinus.value) eligible = ents.filter(([key,value]) => value <= base[1]); | ||
} | ||
eligible.sort((a,b) => a[1] - b[1]); | ||
return eligible.map(el => el[0]); | ||
} | ||
@@ -34,0 +56,0 @@ |
@@ -1,3 +0,3 @@ | ||
import MqLayout from './component.js' | ||
import { setAvailableBreakpoints, setCurrentBreakpoint, currentBreakpoint, updateBreakpoints } from "./utils"; | ||
import MqLayout from './component'; | ||
import { setCurrentBreakpoint, currentBreakpoint, updateBreakpoints } from "./store"; | ||
@@ -14,3 +14,3 @@ const DEFAULT_BREAKPOINTS = { | ||
app.provide('updateBreakpoints', updateBreakpoints) | ||
app.provide('updateBreakpoints', updateBreakpoints); | ||
@@ -33,5 +33,7 @@ // Init reactive component | ||
app.config.globalProperties.$mqAvailableBreakpoints = breakpoints; | ||
app.component('mq-layout', MqLayout) | ||
app.component('MqLayout', MqLayout) | ||
} | ||
export default { install }; | ||
export default { | ||
install | ||
} |
@@ -1,64 +0,98 @@ | ||
import { | ||
convertBreakpointsToMediaQueries, | ||
transformValuesFromBreakpoints, | ||
selectBreakpoints | ||
} from '../../src/helpers.js' | ||
convertBreakpointsToMediaQueries, | ||
transformValuesFromBreakpoints, | ||
selectBreakpoints, | ||
} from "../../src/helpers.js"; | ||
import * as store from "../../src/store.js"; | ||
describe('helpers.js', () => { | ||
it('#convertBreakpointsToMediaQueries', () => { | ||
const breakpoints = { | ||
sm: 350, | ||
md: 900, | ||
lg: Infinity, | ||
} | ||
const expected = { | ||
sm: '(min-width: 0px) and (max-width: 349px)', | ||
md: '(min-width: 350px) and (max-width: 899px)', | ||
lg: '(min-width: 900px)', | ||
} | ||
const result = convertBreakpointsToMediaQueries(breakpoints) | ||
expect(result).toEqual(expected) | ||
}) | ||
it('#selectBreakpoints', () => { | ||
const breakpoints = ['sm', 'md', 'lg'] | ||
const result = selectBreakpoints(breakpoints, 'md') | ||
expect(result).toEqual(['md', 'lg']) | ||
}) | ||
describe('#transformValuesFromBreakpoints', () => { | ||
it('should work with falsy values', () => { | ||
const breakpoints = ['sm', 'md', 'lg'] | ||
const values = { | ||
sm: false, | ||
lg: true, | ||
} | ||
const result1 = transformValuesFromBreakpoints(breakpoints, values, 'sm') | ||
expect(result1).toBe(false) | ||
}) | ||
it('should return values correctly', () => { | ||
const breakpoints = ['sm', 'md', 'lg'] | ||
const values = { | ||
sm: 1, | ||
md: 2, | ||
lg: 3, | ||
} | ||
const result1 = transformValuesFromBreakpoints(breakpoints, values, 'sm') | ||
const result2 = transformValuesFromBreakpoints(breakpoints, values, 'md') | ||
const result3 = transformValuesFromBreakpoints(breakpoints, values, 'lg') | ||
expect(result1).toBe(1) | ||
expect(result2).toBe(2) | ||
expect(result3).toBe(3) | ||
}) | ||
it('should return values with mobile-first override', () => { | ||
const breakpoints = ['sm', 'md', 'lg'] | ||
const values = { | ||
sm: 1, | ||
lg: 3, | ||
} | ||
const result1 = transformValuesFromBreakpoints(breakpoints, values, 'sm') | ||
const result2 = transformValuesFromBreakpoints(breakpoints, values, 'md') | ||
expect(result1).toBe(1) | ||
expect(result2).toBe(1) | ||
}) | ||
}) | ||
}) | ||
describe("convertBreakpointsToMediaQueries", () => { | ||
it("expected output with 3 breakpoints", () => { | ||
const breakpoints = { | ||
sm: 350, | ||
md: 900, | ||
lg: Infinity, | ||
}; | ||
const expected = { | ||
sm: "(min-width: 0px) and (max-width: 349px)", | ||
md: "(min-width: 350px) and (max-width: 899px)", | ||
lg: "(min-width: 900px)", | ||
}; | ||
const result = convertBreakpointsToMediaQueries(breakpoints); | ||
expect(result).toEqual(expected); | ||
}); | ||
}); | ||
describe("selectBreakpoints", () => { | ||
beforeAll(() => { | ||
store.mqAvailableBreakpoints = { | ||
value: { | ||
xs: 576, | ||
sm: 768, | ||
md: 992, | ||
lg: 1200, | ||
xl: 1400, | ||
xxl: Infinity, | ||
}, | ||
}; | ||
}); | ||
it("returns the correct breakpoints in mq+ mode", () => { | ||
const result = selectBreakpoints({ | ||
mqProp: "md+", | ||
isMqPlus: { value: true }, | ||
}); | ||
expect(result).toEqual(["md", "lg", "xl", "xxl"]); | ||
}); | ||
it("returns the correct breakpoints in mq- mode", () => { | ||
const result = selectBreakpoints({ | ||
mqProp: "lg-", | ||
isMqMinus: { value: true }, | ||
}); | ||
expect(result).toEqual(["xs", "sm", "md", "lg"]); | ||
}); | ||
it("returns the correct breakpoints in mq range mode", () => { | ||
const result = selectBreakpoints({ | ||
mqProp: "xs-md", | ||
isMqRange: { value: true }, | ||
}); | ||
expect(result).toEqual(["xs", "sm", "md"]); | ||
}); | ||
it("throws an error if an invalid range is provided", () => { | ||
expect(() => | ||
selectBreakpoints({ | ||
mqProp: "md-lg-xl", | ||
isMqRange: { value: true }, | ||
}) | ||
).toThrow("Invalid MQ range provided"); | ||
}); | ||
it('throws an error if the "from" breakpoint is not found in range', () => { | ||
expect(() => | ||
selectBreakpoints({ | ||
mqProp: "error-xl", | ||
isMqRange: { value: true }, | ||
}) | ||
).toThrow("Range from breakpoint (error) not found"); | ||
}); | ||
it('throws an error if the "from" breakpoint is empty', () => { | ||
expect(() => | ||
selectBreakpoints({ | ||
mqProp: "-xl", | ||
isMqRange: { value: true }, | ||
}) | ||
).toThrow("Range from breakpoint () not found"); | ||
}); | ||
it('throws an error if the "to" breakpoint is not found in range', () => { | ||
expect(() => | ||
selectBreakpoints({ | ||
mqProp: "md-error", | ||
isMqRange: { value: true }, | ||
}) | ||
).toThrow("Range to breakpoint (error) not found"); | ||
}); | ||
}); |
import plugin from "../../src/index.js"; | ||
import { shallowMount, createLocalVue } from "@vue/test-utils"; | ||
import { mount } from "@vue/test-utils"; | ||
import { h } from "vue"; | ||
import MatchMediaMock from "match-media-mock"; | ||
import MatchMediaMock from "../mock/MatchMediaMock"; | ||
describe("index.js", () => { | ||
let results; | ||
let matchMediaMock; | ||
beforeEach(() => { | ||
results = new Set(); | ||
matchMediaMock = MatchMediaMock.create(); | ||
matchMediaMock.setConfig({ type: "screen", width: 1200 }); | ||
window.matchMedia = jest.fn(query => { | ||
const result = matchMediaMock(query); | ||
results.add(result); | ||
return result; | ||
}); | ||
}); | ||
let results; | ||
let matchMediaMock; | ||
beforeEach(() => { | ||
results = new Set(); | ||
matchMediaMock = MatchMediaMock.create(); | ||
matchMediaMock.setConfig({ type: "screen", width: 1200 }); | ||
window.matchMedia = jest.fn((...args) => { | ||
const result = matchMediaMock(...args); | ||
results.add(result); | ||
return result; | ||
}); | ||
}); | ||
test("should register $mq property", () => { | ||
const wrapper = shallowMount( | ||
{ | ||
render() { | ||
return h("div"); | ||
} | ||
}, | ||
{ global: { plugins: [plugin] } } | ||
it("should register $mq property", () => { | ||
const wrapper = mount( | ||
{ | ||
render() { | ||
return h("div"); | ||
} | ||
}, | ||
{ global: { plugins: [plugin] }, shallow: true } | ||
); | ||
expect("$mq" in wrapper.vm).toBe(true); | ||
}); | ||
expect("$mq" in wrapper.vm).toBe(true); | ||
}); | ||
test("should default to defaultBreakpoint in options", () => { | ||
const plugins = [ | ||
[ | ||
plugin, | ||
{ | ||
defaultBreakpoint: "md" | ||
} | ||
] | ||
]; | ||
for (let plugin of plugins) { | ||
if (Array.isArray(plugin)) { | ||
continue; | ||
} | ||
} | ||
const wrapper = shallowMount( | ||
{ | ||
render() { | ||
return h("div"); | ||
} | ||
}, | ||
{ | ||
global: { | ||
plugins | ||
} | ||
} | ||
); | ||
expect(wrapper.vm.$mq).toBe("md"); | ||
}); | ||
test("should default to defaultBreakpoint in options", () => { | ||
const plugins = [ | ||
[ | ||
plugin, | ||
{ | ||
defaultBreakpoint: "md" | ||
} | ||
] | ||
]; | ||
for (let plugin of plugins) { | ||
if (Array.isArray(plugin)) { | ||
continue; | ||
} | ||
} | ||
const wrapper = mount( | ||
{ | ||
render() { | ||
return h("div"); | ||
} | ||
}, | ||
{ | ||
global: { | ||
plugins | ||
}, | ||
shallow: true | ||
} | ||
); | ||
expect(wrapper.vm.$mq).toBe("md"); | ||
}); | ||
test("should subscribe to media queries", () => { | ||
const wrapper = shallowMount( | ||
{ | ||
render() { | ||
return h("div"); | ||
} | ||
}, | ||
{ global: { plugins: [plugin] } } | ||
); | ||
expect(window.matchMedia).toBeCalledWith("(min-width: 1250px)"); | ||
expect(window.matchMedia).toBeCalledWith( | ||
"(min-width: 450px) and (max-width: 1249px)" | ||
); | ||
expect(window.matchMedia).toBeCalledWith( | ||
"(min-width: 0px) and (max-width: 449px)" | ||
); | ||
}); | ||
test("should subscribe to media queries", () => { | ||
const wrapper = mount( | ||
{ | ||
render() { | ||
return h("div"); | ||
} | ||
}, | ||
{ global: { plugins: [plugin] }, shallow: true } | ||
); | ||
expect(window.matchMedia).toBeCalledWith("(min-width: 1250px)"); | ||
expect(window.matchMedia).toBeCalledWith( | ||
"(min-width: 450px) and (max-width: 1249px)" | ||
); | ||
expect(window.matchMedia).toBeCalledWith( | ||
"(min-width: 0px) and (max-width: 449px)" | ||
); | ||
}); | ||
test("should set $mq accordingly when media query change", () => { | ||
const wrapper = shallowMount( | ||
{ | ||
render() { | ||
return h("div"); | ||
} | ||
}, | ||
{ global: { plugins: [plugin] } } | ||
); | ||
matchMediaMock.setConfig({ type: "screen", width: 700 }); | ||
Array.from(results)[1].callListeners(); | ||
expect(wrapper.vm.$mq).toBe("md"); | ||
test("should set $mq accordingly when media query change", () => { | ||
const wrapper = mount( | ||
{ | ||
render() { | ||
return h("div"); | ||
} | ||
}, | ||
{ global: { plugins: [plugin] }, shallow: true } | ||
); | ||
matchMediaMock.setConfig({ type: "screen", width: 700 }); | ||
Array.from(results)[1].callListeners(); | ||
expect(wrapper.vm.$mq).toBe("md"); | ||
}); | ||
}); |
@@ -5,5 +5,5 @@ module.exports = { | ||
optimizeDeps: { | ||
include: ['json2mq'] | ||
include: ['json2mq','primevue/toolbar'] | ||
}, | ||
assetsDir: '' | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1445
166
71129
21
21
1