vue-screen
Advanced tools
Comparing version 1.5.3 to 2.0.0-alpha.0
'use strict'; | ||
function _typeof(obj) { | ||
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { | ||
_typeof = function (obj) { | ||
return typeof obj; | ||
}; | ||
} else { | ||
_typeof = function (obj) { | ||
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; | ||
}; | ||
} | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
return _typeof(obj); | ||
} | ||
var vue = require('vue'); | ||
function _classCallCheck(instance, Constructor) { | ||
if (!(instance instanceof Constructor)) { | ||
throw new TypeError("Cannot call a class as a function"); | ||
} | ||
} | ||
var inBrowser = typeof window !== 'undefined'; | ||
var debounce = function (callback, wait) { | ||
var timeout; | ||
// eslint-disable-next-line func-names | ||
return function () { | ||
// eslint-disable-next-line @typescript-eslint/no-this-alias | ||
var context = this; | ||
// eslint-disable-next-line prefer-rest-params | ||
var args = arguments; | ||
// eslint-disable-next-line func-names | ||
var later = function () { | ||
timeout = null; | ||
callback.apply(context, args); | ||
}; | ||
clearTimeout(timeout); | ||
timeout = setTimeout(later, wait); | ||
}; | ||
}; | ||
function _defineProperties(target, props) { | ||
for (var i = 0; i < props.length; i++) { | ||
var descriptor = props[i]; | ||
descriptor.enumerable = descriptor.enumerable || false; | ||
descriptor.configurable = true; | ||
if ("value" in descriptor) descriptor.writable = true; | ||
Object.defineProperty(target, descriptor.key, descriptor); | ||
} | ||
} | ||
function _createClass(Constructor, protoProps, staticProps) { | ||
if (protoProps) _defineProperties(Constructor.prototype, protoProps); | ||
if (staticProps) _defineProperties(Constructor, staticProps); | ||
return Constructor; | ||
} | ||
function _defineProperty(obj, key, value) { | ||
if (key in obj) { | ||
Object.defineProperty(obj, key, { | ||
value: value, | ||
enumerable: true, | ||
configurable: true, | ||
writable: true | ||
// GoogleBot default screen properties | ||
var DEFAULT_WIDTH = 410; | ||
var DEFAULT_HEIGHT = 730; | ||
var DEFAULT_ORIENTATION = 'portrait'; | ||
var DEFAULT_TOUCH_SUPPORT = true; | ||
var DEFAULT_DEBOUNCE_DELAY = 100; | ||
var useScreen = function (config, debounceDelay) { | ||
if (config === void 0) { config = {}; } | ||
if (debounceDelay === void 0) { debounceDelay = DEFAULT_DEBOUNCE_DELAY; } | ||
var width = config.width || DEFAULT_WIDTH; | ||
var height = config.height || DEFAULT_HEIGHT; | ||
var orientation = config.orientation || DEFAULT_ORIENTATION; | ||
var touch = config.touch === undefined ? DEFAULT_TOUCH_SUPPORT : config.touch; | ||
var screen = vue.reactive({ | ||
resolution: width + "x" + height, | ||
width: width, | ||
height: height, | ||
orientation: orientation, | ||
portrait: orientation === 'portrait', | ||
landscape: orientation !== 'portrait', | ||
touch: touch, | ||
}); | ||
} else { | ||
obj[key] = value; | ||
} | ||
return obj; | ||
} | ||
function ownKeys(object, enumerableOnly) { | ||
var keys = Object.keys(object); | ||
if (Object.getOwnPropertySymbols) { | ||
var symbols = Object.getOwnPropertySymbols(object); | ||
if (enumerableOnly) symbols = symbols.filter(function (sym) { | ||
return Object.getOwnPropertyDescriptor(object, sym).enumerable; | ||
}); | ||
keys.push.apply(keys, symbols); | ||
} | ||
return keys; | ||
} | ||
function _objectSpread2(target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i] != null ? arguments[i] : {}; | ||
if (i % 2) { | ||
ownKeys(source, true).forEach(function (key) { | ||
_defineProperty(target, key, source[key]); | ||
}); | ||
} else if (Object.getOwnPropertyDescriptors) { | ||
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); | ||
} else { | ||
ownKeys(source).forEach(function (key) { | ||
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); | ||
}); | ||
var updateWindowProperties = function () { | ||
screen.width = window.innerWidth; | ||
screen.height = window.innerHeight; | ||
screen.resolution = screen.width + "x" + screen.height; | ||
}; | ||
var updateOrientationPropperties = function (e) { | ||
screen.portrait = e.matches; | ||
screen.landscape = !e.matches; | ||
screen.orientation = e.matches ? 'portrait' : 'landscape'; | ||
}; | ||
if (inBrowser) { | ||
window.addEventListener('resize', debounce(updateWindowProperties, debounceDelay)); | ||
updateWindowProperties(); | ||
var query = window.matchMedia('(orientation: portrait)'); | ||
if ('addEventListener' in query) { | ||
query.addEventListener('change', updateOrientationPropperties); | ||
} | ||
else { | ||
// query.addListener is not deprecated for iOS 12 | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
query.addListener(updateOrientationPropperties); | ||
} | ||
updateOrientationPropperties(query); | ||
// This does not react to resize events. | ||
// You always need to reload the browser to add/remove touch support, | ||
// even when using DevTools device simulation | ||
screen.touch = 'ontouchstart' in window; | ||
} | ||
} | ||
return screen; | ||
}; | ||
return target; | ||
} | ||
var inBrowser = typeof window !== 'undefined'; | ||
var debounce = function debounce(callback, wait) { | ||
var timeout; // eslint-disable-next-line func-names | ||
return function () { | ||
var context = this; // eslint-disable-next-line prefer-rest-params | ||
var args = arguments; // eslint-disable-next-line func-names | ||
var later = function later() { | ||
timeout = null; | ||
callback.apply(context, args); | ||
}; | ||
clearTimeout(timeout); | ||
timeout = setTimeout(later, wait); | ||
}; | ||
var tailwind = { | ||
sm: '640px', | ||
md: '768px', | ||
lg: '1024px', | ||
xl: '1280px', | ||
'2xl': 1536, | ||
}; | ||
var parseSemver = function parseSemver(version) { | ||
var fragments = version.split('.'); | ||
var major = parseInt(fragments[0], 10); | ||
return { | ||
major: typeof major === 'number' ? major : 1, | ||
minor: parseInt(fragments[1], 10) || 0, | ||
patch: parseInt(fragments[2], 10) || 0 | ||
}; | ||
}; | ||
var checkVersion = function checkVersion(current, required) { | ||
var currentVersion = parseSemver(current); | ||
var requiredVersion = parseSemver(required); | ||
return currentVersion.major > requiredVersion.major || currentVersion.major === requiredVersion.major && currentVersion.minor > requiredVersion.minor || currentVersion.major === requiredVersion.major && currentVersion.minor === requiredVersion.minor && currentVersion.patch >= requiredVersion.patch; | ||
}; | ||
var bootstrap = { | ||
xs: 0, | ||
sm: 576, | ||
md: 768, | ||
lg: 992, | ||
xl: 1200 | ||
xs: '0px', | ||
sm: '480px', | ||
md: '768px', | ||
lg: '992px', | ||
xl: '1200px', | ||
xxl: '1400px', | ||
}; | ||
var bulma = { | ||
mobile: 0, | ||
tablet: 769, | ||
desktop: 1024, | ||
widescreen: 1216, | ||
fullhd: 1408 | ||
mobile: 0, | ||
tablet: 769, | ||
desktop: 1024, | ||
widescreen: 1216, | ||
fullhd: 1408, | ||
}; | ||
var foundation = { | ||
small: 0, | ||
medium: 640, | ||
large: 1024 | ||
}; | ||
var materialize = { | ||
s: 0, | ||
m: 601, | ||
l: 993, | ||
xl: 1201 | ||
s: 0, | ||
m: 601, | ||
l: 993, | ||
xl: 1201, | ||
}; | ||
var semantic = { | ||
mobile: 0, | ||
tablet: 768, | ||
computer: 992, | ||
large: 1201 | ||
var foundation = { | ||
small: 0, | ||
medium: 640, | ||
large: 1024, | ||
}; | ||
var tailwind = { | ||
xs: 0, | ||
sm: 640, | ||
md: 768, | ||
lg: 1024, | ||
xl: 1280, | ||
'2xl': 1536 | ||
var semanticUi = { | ||
mobile: 0, | ||
tablet: 768, | ||
computer: 992, | ||
large: 1201, | ||
}; | ||
var grids = { | ||
bootstrap: bootstrap, | ||
bulma: bulma, | ||
foundation: foundation, | ||
materialize: materialize, | ||
'semantic-ui': semantic, | ||
tailwind: tailwind | ||
tailwind: tailwind, | ||
bootstrap: bootstrap, | ||
bulma: bulma, | ||
materialize: materialize, | ||
foundation: foundation, | ||
semanticUi: semanticUi, | ||
}; | ||
var Vue; | ||
var MIN_VUE_VERSION = '2.6.0'; // GoogleBot default screen size | ||
var DEFAULT_WIDTH = 410; | ||
var DEFAULT_HEIGHT = 730; | ||
var DEFAULT_FRAMEWORK = 'tailwind'; | ||
var DEBOUNCE_MS = 100; | ||
var RESERVED_KEYS = ['width', 'height', 'touch', 'portrait', 'landscape', 'config']; | ||
var CUSTOM_FRAMEWORK_NAME = '__CUSTOM__'; | ||
var DEFAULT_ORDERS = { | ||
bootstrap: ['xs', 'sm', 'md', 'lg', 'xl'], | ||
bulma: ['mobile', 'tablet', 'desktop', 'widescreen', 'fullhd'], | ||
foundation: ['small', 'medium', 'large'], | ||
materialize: ['s', 'm', 'l', 'xl'], | ||
'semantic-ui': ['mobile', 'tablet', 'computer', 'large'], | ||
tailwind: ['xs', 'sm', 'md', 'lg', 'xl'] | ||
var DEFAULT_GRID_FRAMEWORK = 'tailwind'; | ||
var createGridObject = function (config) { | ||
return Object.keys(config).reduce(function (accumulator, key) { | ||
accumulator[key] = false; | ||
return accumulator; | ||
}, { | ||
breakpoint: '', | ||
}); | ||
}; | ||
var Plugin = | ||
/*#__PURE__*/ | ||
function () { | ||
/** | ||
* Class constructor | ||
* | ||
* @param {object | string} breakpoints | ||
*/ | ||
function Plugin() { | ||
var breakpoints = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; | ||
_classCallCheck(this, Plugin); | ||
this.callbacks = {}; | ||
this.framework = ''; | ||
this.config = Plugin.parseBreakpoints(breakpoints); | ||
this.createScreen(); | ||
this.init(); | ||
} | ||
/** | ||
* Parse the breakpoints parameter and return a Breakpoint object | ||
* | ||
* @param {object | string} breakpoints | ||
* @returns {object} | ||
*/ | ||
_createClass(Plugin, [{ | ||
key: "init", | ||
/** | ||
* Init the reactive object | ||
*/ | ||
value: function init() { | ||
this.attachResize(); | ||
this.setScreenSize(); | ||
this.checkTouch(); | ||
var createConfigFromLiteral = function (literal) { | ||
if (!grids[literal]) { | ||
throw new Error("Invalid grid type \"" + literal + "\""); | ||
} | ||
/** | ||
* Attach a listener to the window resize event | ||
*/ | ||
}, { | ||
key: "attachResize", | ||
value: function attachResize() { | ||
if (inBrowser) { | ||
window.addEventListener('resize', debounce(this.setScreenSize.bind(this), DEBOUNCE_MS)); | ||
} | ||
} | ||
/** | ||
* Set the screen size | ||
*/ | ||
}, { | ||
key: "setScreenSize", | ||
value: function setScreenSize() { | ||
if (inBrowser) { | ||
this.screen.width = window.innerWidth; | ||
this.screen.height = window.innerHeight; | ||
this.runCallbacks(); | ||
this.findCurrentBreakpoint(); | ||
} | ||
} | ||
/** | ||
* Run callbacks | ||
*/ | ||
}, { | ||
key: "runCallbacks", | ||
value: function runCallbacks() { | ||
var _this = this; | ||
Object.keys(this.callbacks).forEach(function (key) { | ||
_this.screen[key] = _this.callbacks[key].call(null, _this.screen); | ||
}); | ||
} | ||
/** | ||
* Calculate the current breakpoint name based on "order" property | ||
*/ | ||
}, { | ||
key: "findCurrentBreakpoint", | ||
value: function findCurrentBreakpoint() { | ||
var _this2 = this; | ||
this.screen.breakpoint = this.config.breakpointsOrder.reduce(function (activeBreakpoint, currentBreakpoint) { | ||
if (_this2.screen[currentBreakpoint]) { | ||
return currentBreakpoint; | ||
return grids[literal]; | ||
}; | ||
var getCurrentBreakpoint = function (object) { | ||
var current = Object.keys(object).filter(function (key) { return !['breakpoint'].includes(key); }).reverse().find(function (key) { return object[key]; }); | ||
return current || ''; | ||
}; | ||
var createMediaQueries = function (config, object) { | ||
Object.keys(config).forEach(function (breakpoint) { | ||
var width = config[breakpoint]; | ||
if (typeof width === 'number') { | ||
width = width + "px"; | ||
} | ||
return activeBreakpoint; | ||
}, this.config.breakpointsOrder[0]); | ||
} | ||
/** | ||
* Check touch screen capability | ||
*/ | ||
}, { | ||
key: "checkTouch", | ||
value: function checkTouch() { | ||
if (inBrowser) { | ||
this.screen.touch = 'ontouchstart' in window; | ||
} | ||
} | ||
/** | ||
* Create the reactive object | ||
*/ | ||
}, { | ||
key: "createScreen", | ||
value: function createScreen() { | ||
var _this3 = this; | ||
var breakpointKeys = Object.keys(this.config).filter(function (key) { | ||
return key !== 'breakpointsOrder'; | ||
}); | ||
this.screen = Vue.observable({ | ||
width: DEFAULT_WIDTH, | ||
height: DEFAULT_HEIGHT, | ||
touch: true, | ||
portrait: true, | ||
landscape: false, | ||
breakpoint: this.config.breakpointsOrder[0], | ||
breakpointsOrder: this.config.breakpointsOrder, | ||
config: this.config | ||
}); | ||
this.findCurrentBreakpoint(); | ||
breakpointKeys.forEach(function (name) { | ||
if (RESERVED_KEYS.indexOf(name) >= 0) { | ||
throw new Error("Invalid breakpoint name: \"".concat(name, "\". This key is reserved.")); | ||
else { | ||
width = width.toString(); | ||
} | ||
Vue.set(_this3.screen, name, false); | ||
}); | ||
if (inBrowser) { | ||
this.initMediaQueries(); | ||
} | ||
} | ||
/** | ||
* Initialize the media queries to test | ||
*/ | ||
}, { | ||
key: "initMediaQueries", | ||
value: function initMediaQueries() { | ||
var _this4 = this; | ||
Object.keys(this.config).filter(function (key) { | ||
return key !== 'breakpointsOrder'; | ||
}).forEach(function (name) { | ||
var w = null; | ||
if (name !== 'breakpointsOrder') { | ||
var width = _this4.config[name]; | ||
if (typeof width === 'function') { | ||
_this4.callbacks[name] = width; | ||
} else if (typeof width === 'number') { | ||
w = "".concat(width, "px"); | ||
} else if (typeof width === 'string') { | ||
w = width; | ||
} else { | ||
_this4.screen[name] = width; | ||
} | ||
var onChange = function (event) { | ||
object[breakpoint] = event.matches; | ||
object.breakpoint = getCurrentBreakpoint(object); | ||
}; | ||
var query = window.matchMedia("(min-width: " + width + ")"); | ||
if ('addEventListener' in query) { | ||
query.addEventListener('change', onChange); | ||
} | ||
if (w) { | ||
var _query = window.matchMedia("(min-width: ".concat(w, ")")); | ||
if ('addEventListener' in _query) { | ||
_query.addEventListener('change', function (e) { | ||
return _this4.mediaStateChanged(name, e.matches); | ||
}); | ||
} else { | ||
_query.addListener(function (e) { | ||
return _this4.mediaStateChanged(name, e.matches); | ||
}); | ||
} | ||
_this4.mediaStateChanged(name, _query.matches); | ||
else { | ||
// query.addListener is not deprecated for iOS 12 | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
query.addListener(onChange); | ||
} | ||
}); | ||
var query = window.matchMedia('(orientation: portrait)'); | ||
if ('addEventListener' in query) { | ||
query.addEventListener('change', function (e) { | ||
_this4.mediaStateChanged('portrait', e.matches); | ||
_this4.mediaStateChanged('landscape', !e.matches); | ||
}); | ||
} else { | ||
query.addListener(function (e) { | ||
_this4.mediaStateChanged('portrait', e.matches); | ||
_this4.mediaStateChanged('landscape', !e.matches); | ||
}); | ||
} | ||
this.mediaStateChanged('portrait', query.matches); | ||
this.mediaStateChanged('landscape', !query.matches); | ||
object[breakpoint] = query.matches; | ||
object.breakpoint = getCurrentBreakpoint(object); | ||
}); | ||
}; | ||
function useGrid(gridConfig) { | ||
if (gridConfig === void 0) { gridConfig = DEFAULT_GRID_FRAMEWORK; } | ||
var config; | ||
if (typeof gridConfig === 'string') { | ||
config = createConfigFromLiteral(gridConfig); | ||
} | ||
/** | ||
* Set the media query state on the reactive object | ||
* | ||
* @param {string} name | ||
* @param {boolean} matches | ||
*/ | ||
}, { | ||
key: "mediaStateChanged", | ||
value: function mediaStateChanged(name, matches) { | ||
Vue.set(this.screen, name, matches); | ||
else { | ||
config = Object.assign(gridConfig); | ||
} | ||
/** | ||
* Install the plugin | ||
* | ||
* @param {Vue} vue | ||
* @param {object} options | ||
*/ | ||
}], [{ | ||
key: "parseBreakpoints", | ||
value: function parseBreakpoints(breakpoints) { | ||
if (_typeof(breakpoints) === 'object') { | ||
if (breakpoints.extend) { | ||
this.framework = breakpoints.extend.toString(); // eslint-disable-next-line no-param-reassign | ||
delete breakpoints.extend; | ||
return Object.assign({}, breakpoints, Plugin.getBreakpoints()); | ||
} | ||
this.framework = CUSTOM_FRAMEWORK_NAME; | ||
return _objectSpread2({ | ||
breakpointsOrder: Object.keys(breakpoints).filter(function (key) { | ||
return key !== 'breakpointsOrder'; | ||
}) | ||
}, breakpoints); | ||
} | ||
this.framework = breakpoints.toString(); | ||
return Plugin.getBreakpoints(); | ||
var gridObject = vue.reactive(createGridObject(config)); | ||
if (inBrowser) { | ||
createMediaQueries(config, gridObject); | ||
} | ||
/** | ||
* Get the breakpoints of one of the supported frameworks | ||
* | ||
* @param {string} framework | ||
* @returns {object} | ||
*/ | ||
return gridObject; | ||
} | ||
}, { | ||
key: "getBreakpoints", | ||
value: function getBreakpoints() { | ||
if (!this.framework) { | ||
// eslint-disable-next-line no-param-reassign | ||
this.framework = DEFAULT_FRAMEWORK; | ||
} | ||
if (!grids[this.framework]) { | ||
throw new Error("Cannot find grid breakpoints for framework \"".concat(this.framework, "\"")); | ||
} | ||
return _objectSpread2({}, grids[this.framework], { | ||
breakpointsOrder: DEFAULT_ORDERS[this.framework] | ||
}); | ||
var install = function (app, options) { | ||
var screen; | ||
var grid; | ||
if (typeof options === 'string') { | ||
screen = useScreen(); | ||
grid = useGrid(options); | ||
} | ||
}, { | ||
key: "install", | ||
value: function install(vue, options) { | ||
Vue = vue; | ||
if (!checkVersion(Vue.version, MIN_VUE_VERSION)) { | ||
throw Error("VueScreen requires at least Vue ".concat(MIN_VUE_VERSION)); | ||
} // eslint-disable-next-line no-param-reassign | ||
Vue.prototype.$screen = new Plugin(options).screen; | ||
else { | ||
options = options || { grid: undefined, ssr: undefined, debounceDelay: undefined }; | ||
screen = useScreen(options.ssr, options.debounceDelay); | ||
// ts cant figure out the type of arguments when union types are | ||
// passed to an overloaded function, so we need to use "any" or do a typeof check | ||
// on the arguments, which would ship 5 lines of js instead of one. | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
grid = useGrid(options.grid); | ||
} | ||
}]); | ||
app.config.globalProperties.$screen = screen; | ||
app.config.globalProperties.$grid = grid; | ||
}; | ||
return Plugin; | ||
}(); | ||
var index = { | ||
install: install | ||
}; | ||
if (inBrowser && window.Vue) { | ||
window.Vue.use(Plugin); | ||
} | ||
module.exports = Plugin; | ||
exports.default = index; | ||
exports.grids = grids; | ||
exports.useGrid = useGrid; | ||
exports.useScreen = useScreen; |
@@ -1,477 +0,215 @@ | ||
function _typeof(obj) { | ||
if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { | ||
_typeof = function (obj) { | ||
return typeof obj; | ||
import { reactive } from 'vue'; | ||
var inBrowser = typeof window !== 'undefined'; | ||
var debounce = function (callback, wait) { | ||
var timeout; | ||
// eslint-disable-next-line func-names | ||
return function () { | ||
// eslint-disable-next-line @typescript-eslint/no-this-alias | ||
var context = this; | ||
// eslint-disable-next-line prefer-rest-params | ||
var args = arguments; | ||
// eslint-disable-next-line func-names | ||
var later = function () { | ||
timeout = null; | ||
callback.apply(context, args); | ||
}; | ||
clearTimeout(timeout); | ||
timeout = setTimeout(later, wait); | ||
}; | ||
} else { | ||
_typeof = function (obj) { | ||
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; | ||
}; | ||
} | ||
}; | ||
return _typeof(obj); | ||
} | ||
function _classCallCheck(instance, Constructor) { | ||
if (!(instance instanceof Constructor)) { | ||
throw new TypeError("Cannot call a class as a function"); | ||
} | ||
} | ||
function _defineProperties(target, props) { | ||
for (var i = 0; i < props.length; i++) { | ||
var descriptor = props[i]; | ||
descriptor.enumerable = descriptor.enumerable || false; | ||
descriptor.configurable = true; | ||
if ("value" in descriptor) descriptor.writable = true; | ||
Object.defineProperty(target, descriptor.key, descriptor); | ||
} | ||
} | ||
function _createClass(Constructor, protoProps, staticProps) { | ||
if (protoProps) _defineProperties(Constructor.prototype, protoProps); | ||
if (staticProps) _defineProperties(Constructor, staticProps); | ||
return Constructor; | ||
} | ||
function _defineProperty(obj, key, value) { | ||
if (key in obj) { | ||
Object.defineProperty(obj, key, { | ||
value: value, | ||
enumerable: true, | ||
configurable: true, | ||
writable: true | ||
// GoogleBot default screen properties | ||
var DEFAULT_WIDTH = 410; | ||
var DEFAULT_HEIGHT = 730; | ||
var DEFAULT_ORIENTATION = 'portrait'; | ||
var DEFAULT_TOUCH_SUPPORT = true; | ||
var DEFAULT_DEBOUNCE_DELAY = 100; | ||
var useScreen = function (config, debounceDelay) { | ||
if (config === void 0) { config = {}; } | ||
if (debounceDelay === void 0) { debounceDelay = DEFAULT_DEBOUNCE_DELAY; } | ||
var width = config.width || DEFAULT_WIDTH; | ||
var height = config.height || DEFAULT_HEIGHT; | ||
var orientation = config.orientation || DEFAULT_ORIENTATION; | ||
var touch = config.touch === undefined ? DEFAULT_TOUCH_SUPPORT : config.touch; | ||
var screen = reactive({ | ||
resolution: width + "x" + height, | ||
width: width, | ||
height: height, | ||
orientation: orientation, | ||
portrait: orientation === 'portrait', | ||
landscape: orientation !== 'portrait', | ||
touch: touch, | ||
}); | ||
} else { | ||
obj[key] = value; | ||
} | ||
return obj; | ||
} | ||
function ownKeys(object, enumerableOnly) { | ||
var keys = Object.keys(object); | ||
if (Object.getOwnPropertySymbols) { | ||
var symbols = Object.getOwnPropertySymbols(object); | ||
if (enumerableOnly) symbols = symbols.filter(function (sym) { | ||
return Object.getOwnPropertyDescriptor(object, sym).enumerable; | ||
}); | ||
keys.push.apply(keys, symbols); | ||
} | ||
return keys; | ||
} | ||
function _objectSpread2(target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i] != null ? arguments[i] : {}; | ||
if (i % 2) { | ||
ownKeys(source, true).forEach(function (key) { | ||
_defineProperty(target, key, source[key]); | ||
}); | ||
} else if (Object.getOwnPropertyDescriptors) { | ||
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); | ||
} else { | ||
ownKeys(source).forEach(function (key) { | ||
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); | ||
}); | ||
var updateWindowProperties = function () { | ||
screen.width = window.innerWidth; | ||
screen.height = window.innerHeight; | ||
screen.resolution = screen.width + "x" + screen.height; | ||
}; | ||
var updateOrientationPropperties = function (e) { | ||
screen.portrait = e.matches; | ||
screen.landscape = !e.matches; | ||
screen.orientation = e.matches ? 'portrait' : 'landscape'; | ||
}; | ||
if (inBrowser) { | ||
window.addEventListener('resize', debounce(updateWindowProperties, debounceDelay)); | ||
updateWindowProperties(); | ||
var query = window.matchMedia('(orientation: portrait)'); | ||
if ('addEventListener' in query) { | ||
query.addEventListener('change', updateOrientationPropperties); | ||
} | ||
else { | ||
// query.addListener is not deprecated for iOS 12 | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
query.addListener(updateOrientationPropperties); | ||
} | ||
updateOrientationPropperties(query); | ||
// This does not react to resize events. | ||
// You always need to reload the browser to add/remove touch support, | ||
// even when using DevTools device simulation | ||
screen.touch = 'ontouchstart' in window; | ||
} | ||
} | ||
return screen; | ||
}; | ||
return target; | ||
} | ||
var inBrowser = typeof window !== 'undefined'; | ||
var debounce = function debounce(callback, wait) { | ||
var timeout; // eslint-disable-next-line func-names | ||
return function () { | ||
var context = this; // eslint-disable-next-line prefer-rest-params | ||
var args = arguments; // eslint-disable-next-line func-names | ||
var later = function later() { | ||
timeout = null; | ||
callback.apply(context, args); | ||
}; | ||
clearTimeout(timeout); | ||
timeout = setTimeout(later, wait); | ||
}; | ||
var tailwind = { | ||
sm: '640px', | ||
md: '768px', | ||
lg: '1024px', | ||
xl: '1280px', | ||
'2xl': 1536, | ||
}; | ||
var parseSemver = function parseSemver(version) { | ||
var fragments = version.split('.'); | ||
var major = parseInt(fragments[0], 10); | ||
return { | ||
major: typeof major === 'number' ? major : 1, | ||
minor: parseInt(fragments[1], 10) || 0, | ||
patch: parseInt(fragments[2], 10) || 0 | ||
}; | ||
}; | ||
var checkVersion = function checkVersion(current, required) { | ||
var currentVersion = parseSemver(current); | ||
var requiredVersion = parseSemver(required); | ||
return currentVersion.major > requiredVersion.major || currentVersion.major === requiredVersion.major && currentVersion.minor > requiredVersion.minor || currentVersion.major === requiredVersion.major && currentVersion.minor === requiredVersion.minor && currentVersion.patch >= requiredVersion.patch; | ||
}; | ||
var bootstrap = { | ||
xs: 0, | ||
sm: 576, | ||
md: 768, | ||
lg: 992, | ||
xl: 1200 | ||
xs: '0px', | ||
sm: '480px', | ||
md: '768px', | ||
lg: '992px', | ||
xl: '1200px', | ||
xxl: '1400px', | ||
}; | ||
var bulma = { | ||
mobile: 0, | ||
tablet: 769, | ||
desktop: 1024, | ||
widescreen: 1216, | ||
fullhd: 1408 | ||
mobile: 0, | ||
tablet: 769, | ||
desktop: 1024, | ||
widescreen: 1216, | ||
fullhd: 1408, | ||
}; | ||
var foundation = { | ||
small: 0, | ||
medium: 640, | ||
large: 1024 | ||
}; | ||
var materialize = { | ||
s: 0, | ||
m: 601, | ||
l: 993, | ||
xl: 1201 | ||
s: 0, | ||
m: 601, | ||
l: 993, | ||
xl: 1201, | ||
}; | ||
var semantic = { | ||
mobile: 0, | ||
tablet: 768, | ||
computer: 992, | ||
large: 1201 | ||
var foundation = { | ||
small: 0, | ||
medium: 640, | ||
large: 1024, | ||
}; | ||
var tailwind = { | ||
xs: 0, | ||
sm: 640, | ||
md: 768, | ||
lg: 1024, | ||
xl: 1280, | ||
'2xl': 1536 | ||
var semanticUi = { | ||
mobile: 0, | ||
tablet: 768, | ||
computer: 992, | ||
large: 1201, | ||
}; | ||
var grids = { | ||
bootstrap: bootstrap, | ||
bulma: bulma, | ||
foundation: foundation, | ||
materialize: materialize, | ||
'semantic-ui': semantic, | ||
tailwind: tailwind | ||
tailwind: tailwind, | ||
bootstrap: bootstrap, | ||
bulma: bulma, | ||
materialize: materialize, | ||
foundation: foundation, | ||
semanticUi: semanticUi, | ||
}; | ||
var Vue; | ||
var MIN_VUE_VERSION = '2.6.0'; // GoogleBot default screen size | ||
var DEFAULT_WIDTH = 410; | ||
var DEFAULT_HEIGHT = 730; | ||
var DEFAULT_FRAMEWORK = 'tailwind'; | ||
var DEBOUNCE_MS = 100; | ||
var RESERVED_KEYS = ['width', 'height', 'touch', 'portrait', 'landscape', 'config']; | ||
var CUSTOM_FRAMEWORK_NAME = '__CUSTOM__'; | ||
var DEFAULT_ORDERS = { | ||
bootstrap: ['xs', 'sm', 'md', 'lg', 'xl'], | ||
bulma: ['mobile', 'tablet', 'desktop', 'widescreen', 'fullhd'], | ||
foundation: ['small', 'medium', 'large'], | ||
materialize: ['s', 'm', 'l', 'xl'], | ||
'semantic-ui': ['mobile', 'tablet', 'computer', 'large'], | ||
tailwind: ['xs', 'sm', 'md', 'lg', 'xl'] | ||
var DEFAULT_GRID_FRAMEWORK = 'tailwind'; | ||
var createGridObject = function (config) { | ||
return Object.keys(config).reduce(function (accumulator, key) { | ||
accumulator[key] = false; | ||
return accumulator; | ||
}, { | ||
breakpoint: '', | ||
}); | ||
}; | ||
var Plugin = | ||
/*#__PURE__*/ | ||
function () { | ||
/** | ||
* Class constructor | ||
* | ||
* @param {object | string} breakpoints | ||
*/ | ||
function Plugin() { | ||
var breakpoints = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; | ||
_classCallCheck(this, Plugin); | ||
this.callbacks = {}; | ||
this.framework = ''; | ||
this.config = Plugin.parseBreakpoints(breakpoints); | ||
this.createScreen(); | ||
this.init(); | ||
} | ||
/** | ||
* Parse the breakpoints parameter and return a Breakpoint object | ||
* | ||
* @param {object | string} breakpoints | ||
* @returns {object} | ||
*/ | ||
_createClass(Plugin, [{ | ||
key: "init", | ||
/** | ||
* Init the reactive object | ||
*/ | ||
value: function init() { | ||
this.attachResize(); | ||
this.setScreenSize(); | ||
this.checkTouch(); | ||
var createConfigFromLiteral = function (literal) { | ||
if (!grids[literal]) { | ||
throw new Error("Invalid grid type \"" + literal + "\""); | ||
} | ||
/** | ||
* Attach a listener to the window resize event | ||
*/ | ||
}, { | ||
key: "attachResize", | ||
value: function attachResize() { | ||
if (inBrowser) { | ||
window.addEventListener('resize', debounce(this.setScreenSize.bind(this), DEBOUNCE_MS)); | ||
} | ||
} | ||
/** | ||
* Set the screen size | ||
*/ | ||
}, { | ||
key: "setScreenSize", | ||
value: function setScreenSize() { | ||
if (inBrowser) { | ||
this.screen.width = window.innerWidth; | ||
this.screen.height = window.innerHeight; | ||
this.runCallbacks(); | ||
this.findCurrentBreakpoint(); | ||
} | ||
} | ||
/** | ||
* Run callbacks | ||
*/ | ||
}, { | ||
key: "runCallbacks", | ||
value: function runCallbacks() { | ||
var _this = this; | ||
Object.keys(this.callbacks).forEach(function (key) { | ||
_this.screen[key] = _this.callbacks[key].call(null, _this.screen); | ||
}); | ||
} | ||
/** | ||
* Calculate the current breakpoint name based on "order" property | ||
*/ | ||
}, { | ||
key: "findCurrentBreakpoint", | ||
value: function findCurrentBreakpoint() { | ||
var _this2 = this; | ||
this.screen.breakpoint = this.config.breakpointsOrder.reduce(function (activeBreakpoint, currentBreakpoint) { | ||
if (_this2.screen[currentBreakpoint]) { | ||
return currentBreakpoint; | ||
return grids[literal]; | ||
}; | ||
var getCurrentBreakpoint = function (object) { | ||
var current = Object.keys(object).filter(function (key) { return !['breakpoint'].includes(key); }).reverse().find(function (key) { return object[key]; }); | ||
return current || ''; | ||
}; | ||
var createMediaQueries = function (config, object) { | ||
Object.keys(config).forEach(function (breakpoint) { | ||
var width = config[breakpoint]; | ||
if (typeof width === 'number') { | ||
width = width + "px"; | ||
} | ||
return activeBreakpoint; | ||
}, this.config.breakpointsOrder[0]); | ||
} | ||
/** | ||
* Check touch screen capability | ||
*/ | ||
}, { | ||
key: "checkTouch", | ||
value: function checkTouch() { | ||
if (inBrowser) { | ||
this.screen.touch = 'ontouchstart' in window; | ||
} | ||
} | ||
/** | ||
* Create the reactive object | ||
*/ | ||
}, { | ||
key: "createScreen", | ||
value: function createScreen() { | ||
var _this3 = this; | ||
var breakpointKeys = Object.keys(this.config).filter(function (key) { | ||
return key !== 'breakpointsOrder'; | ||
}); | ||
this.screen = Vue.observable({ | ||
width: DEFAULT_WIDTH, | ||
height: DEFAULT_HEIGHT, | ||
touch: true, | ||
portrait: true, | ||
landscape: false, | ||
breakpoint: this.config.breakpointsOrder[0], | ||
breakpointsOrder: this.config.breakpointsOrder, | ||
config: this.config | ||
}); | ||
this.findCurrentBreakpoint(); | ||
breakpointKeys.forEach(function (name) { | ||
if (RESERVED_KEYS.indexOf(name) >= 0) { | ||
throw new Error("Invalid breakpoint name: \"".concat(name, "\". This key is reserved.")); | ||
else { | ||
width = width.toString(); | ||
} | ||
Vue.set(_this3.screen, name, false); | ||
}); | ||
if (inBrowser) { | ||
this.initMediaQueries(); | ||
} | ||
} | ||
/** | ||
* Initialize the media queries to test | ||
*/ | ||
}, { | ||
key: "initMediaQueries", | ||
value: function initMediaQueries() { | ||
var _this4 = this; | ||
Object.keys(this.config).filter(function (key) { | ||
return key !== 'breakpointsOrder'; | ||
}).forEach(function (name) { | ||
var w = null; | ||
if (name !== 'breakpointsOrder') { | ||
var width = _this4.config[name]; | ||
if (typeof width === 'function') { | ||
_this4.callbacks[name] = width; | ||
} else if (typeof width === 'number') { | ||
w = "".concat(width, "px"); | ||
} else if (typeof width === 'string') { | ||
w = width; | ||
} else { | ||
_this4.screen[name] = width; | ||
} | ||
var onChange = function (event) { | ||
object[breakpoint] = event.matches; | ||
object.breakpoint = getCurrentBreakpoint(object); | ||
}; | ||
var query = window.matchMedia("(min-width: " + width + ")"); | ||
if ('addEventListener' in query) { | ||
query.addEventListener('change', onChange); | ||
} | ||
if (w) { | ||
var _query = window.matchMedia("(min-width: ".concat(w, ")")); | ||
if ('addEventListener' in _query) { | ||
_query.addEventListener('change', function (e) { | ||
return _this4.mediaStateChanged(name, e.matches); | ||
}); | ||
} else { | ||
_query.addListener(function (e) { | ||
return _this4.mediaStateChanged(name, e.matches); | ||
}); | ||
} | ||
_this4.mediaStateChanged(name, _query.matches); | ||
else { | ||
// query.addListener is not deprecated for iOS 12 | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
query.addListener(onChange); | ||
} | ||
}); | ||
var query = window.matchMedia('(orientation: portrait)'); | ||
if ('addEventListener' in query) { | ||
query.addEventListener('change', function (e) { | ||
_this4.mediaStateChanged('portrait', e.matches); | ||
_this4.mediaStateChanged('landscape', !e.matches); | ||
}); | ||
} else { | ||
query.addListener(function (e) { | ||
_this4.mediaStateChanged('portrait', e.matches); | ||
_this4.mediaStateChanged('landscape', !e.matches); | ||
}); | ||
} | ||
this.mediaStateChanged('portrait', query.matches); | ||
this.mediaStateChanged('landscape', !query.matches); | ||
object[breakpoint] = query.matches; | ||
object.breakpoint = getCurrentBreakpoint(object); | ||
}); | ||
}; | ||
function useGrid(gridConfig) { | ||
if (gridConfig === void 0) { gridConfig = DEFAULT_GRID_FRAMEWORK; } | ||
var config; | ||
if (typeof gridConfig === 'string') { | ||
config = createConfigFromLiteral(gridConfig); | ||
} | ||
/** | ||
* Set the media query state on the reactive object | ||
* | ||
* @param {string} name | ||
* @param {boolean} matches | ||
*/ | ||
}, { | ||
key: "mediaStateChanged", | ||
value: function mediaStateChanged(name, matches) { | ||
Vue.set(this.screen, name, matches); | ||
else { | ||
config = Object.assign(gridConfig); | ||
} | ||
/** | ||
* Install the plugin | ||
* | ||
* @param {Vue} vue | ||
* @param {object} options | ||
*/ | ||
}], [{ | ||
key: "parseBreakpoints", | ||
value: function parseBreakpoints(breakpoints) { | ||
if (_typeof(breakpoints) === 'object') { | ||
if (breakpoints.extend) { | ||
this.framework = breakpoints.extend.toString(); // eslint-disable-next-line no-param-reassign | ||
delete breakpoints.extend; | ||
return Object.assign({}, breakpoints, Plugin.getBreakpoints()); | ||
} | ||
this.framework = CUSTOM_FRAMEWORK_NAME; | ||
return _objectSpread2({ | ||
breakpointsOrder: Object.keys(breakpoints).filter(function (key) { | ||
return key !== 'breakpointsOrder'; | ||
}) | ||
}, breakpoints); | ||
} | ||
this.framework = breakpoints.toString(); | ||
return Plugin.getBreakpoints(); | ||
var gridObject = reactive(createGridObject(config)); | ||
if (inBrowser) { | ||
createMediaQueries(config, gridObject); | ||
} | ||
/** | ||
* Get the breakpoints of one of the supported frameworks | ||
* | ||
* @param {string} framework | ||
* @returns {object} | ||
*/ | ||
return gridObject; | ||
} | ||
}, { | ||
key: "getBreakpoints", | ||
value: function getBreakpoints() { | ||
if (!this.framework) { | ||
// eslint-disable-next-line no-param-reassign | ||
this.framework = DEFAULT_FRAMEWORK; | ||
} | ||
if (!grids[this.framework]) { | ||
throw new Error("Cannot find grid breakpoints for framework \"".concat(this.framework, "\"")); | ||
} | ||
return _objectSpread2({}, grids[this.framework], { | ||
breakpointsOrder: DEFAULT_ORDERS[this.framework] | ||
}); | ||
var install = function (app, options) { | ||
var screen; | ||
var grid; | ||
if (typeof options === 'string') { | ||
screen = useScreen(); | ||
grid = useGrid(options); | ||
} | ||
}, { | ||
key: "install", | ||
value: function install(vue, options) { | ||
Vue = vue; | ||
if (!checkVersion(Vue.version, MIN_VUE_VERSION)) { | ||
throw Error("VueScreen requires at least Vue ".concat(MIN_VUE_VERSION)); | ||
} // eslint-disable-next-line no-param-reassign | ||
Vue.prototype.$screen = new Plugin(options).screen; | ||
else { | ||
options = options || { grid: undefined, ssr: undefined, debounceDelay: undefined }; | ||
screen = useScreen(options.ssr, options.debounceDelay); | ||
// ts cant figure out the type of arguments when union types are | ||
// passed to an overloaded function, so we need to use "any" or do a typeof check | ||
// on the arguments, which would ship 5 lines of js instead of one. | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
grid = useGrid(options.grid); | ||
} | ||
}]); | ||
app.config.globalProperties.$screen = screen; | ||
app.config.globalProperties.$grid = grid; | ||
}; | ||
return Plugin; | ||
}(); | ||
var index = { | ||
install: install | ||
}; | ||
if (inBrowser && window.Vue) { | ||
window.Vue.use(Plugin); | ||
} | ||
export default Plugin; | ||
export default index; | ||
export { grids, useGrid, useScreen }; |
105
package.json
{ | ||
"name": "vue-screen", | ||
"version": "1.5.3", | ||
"description": "Reactive window size and media query states for Vue components. Integrates with most UI frameworks.", | ||
"version": "2.0.0-alpha.0", | ||
"description": "Reactive window size and media query states for Vue components. Integrates with most UI frameworks out of the box.", | ||
"main": "dist/vue-screen.cjs.js", | ||
"module": "dist/vue-screen.esm.js", | ||
"types": "dist/vue-screen.d.ts", | ||
"files": [ | ||
"dist/**.js", | ||
"dist/*/**.ts" | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/reegodev/vue-screen.git" | ||
}, | ||
"author": "Matteo Rigon", | ||
"license": "MIT", | ||
"private": false, | ||
"homepage": "https://github.com/reegodev/vue-screen#readme", | ||
"keywords": [ | ||
"vuejs", | ||
"vue", | ||
"screen", | ||
"window", | ||
@@ -16,74 +33,22 @@ "reactive window", | ||
], | ||
"main": "dist/vue-screen.cjs.js", | ||
"module": "dist/vue-screen.esm.js", | ||
"types": "types/index.d.ts", | ||
"scripts": { | ||
"test": "npm run lint && npm run test:unit && npm run test:e2e && npm run test:types", | ||
"test:unit": "mocha --require @babel/register --timeout 20000 --exit 'tests/units/*.spec.js'", | ||
"test:e2e": "node tests/e2e/runner.js", | ||
"test:types": "tsc -p types/test", | ||
"build:browser": "rollup -c rollup.config.browser.js", | ||
"build:cjs": "rollup -c rollup.config.cjs.js", | ||
"build:esm": "rollup -c rollup.config.esm.js", | ||
"build": "npm run build:esm && npm run build:cjs && npm run build:browser", | ||
"lint": "eslint src/**.js", | ||
"update-demo": "git subtree push --prefix demo/dist origin gh-pages" | ||
"test": "jest", | ||
"build": "rollup -c", | ||
"watch": "rollup -cw" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/reegodev/vue-screen.git" | ||
}, | ||
"files": [ | ||
"src", | ||
"dist/*.js", | ||
"types/*.d.ts", | ||
"nuxt.js" | ||
], | ||
"author": "Matteo Rigon", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/reegodev/vue-screen/issues" | ||
}, | ||
"homepage": "https://github.com/reegodev/vue-screen#readme", | ||
"devDependencies": { | ||
"@babel/core": "^7.4.3", | ||
"@babel/plugin-proposal-class-properties": "^7.4.0", | ||
"@babel/polyfill": "^7.4.3", | ||
"@babel/preset-env": "^7.4.3", | ||
"@babel/register": "^7.4.0", | ||
"@types/babel__core": "^7.1.5", | ||
"@types/babel__template": "^7.0.2", | ||
"@types/terser-webpack-plugin": "^2.2.0", | ||
"babel-loader": "^8.0.5", | ||
"chai": "^4.2.0", | ||
"cross-spawn": "^6.0.5", | ||
"eslint": "^5.3.0", | ||
"eslint-config-airbnb": "^17.1.0", | ||
"eslint-plugin-import": "^2.17.2", | ||
"eslint-plugin-jsx-a11y": "^6.2.1", | ||
"eslint-plugin-react": "^7.12.4", | ||
"express": "^4.16.4", | ||
"express-urlrewrite": "^1.2.0", | ||
"husky": "^2.2.0", | ||
"install-peers": "^1.0.3", | ||
"mocha": "^6.1.4", | ||
"nuxt": "^2.10.0", | ||
"puppeteer": "^1.15.0", | ||
"rollup": "^1.11.3", | ||
"rollup-plugin-babel": "^4.3.2", | ||
"rollup-plugin-uglify": "^6.0.2", | ||
"typescript": "^3.8.2", | ||
"vue": "^2.6.10", | ||
"webpack": "^4.30.0", | ||
"webpack-cli": "^3.3.1", | ||
"webpack-dev-middleware": "^3.6.2" | ||
"@types/jest": "^26.0.16", | ||
"@typescript-eslint/eslint-plugin": "^4.0.1", | ||
"@typescript-eslint/parser": "^4.0.1", | ||
"eslint": "^7.8.1", | ||
"jest": "^26.6.3", | ||
"rollup": "^2.34.2", | ||
"rollup-plugin-typescript2": "^0.29.0", | ||
"ts-jest": "^26.4.4", | ||
"typescript": "^4.1.2", | ||
"vue": "^3.0.4" | ||
}, | ||
"husky": { | ||
"hooks": { | ||
"pre-commit": "npm run lint" | ||
} | ||
}, | ||
"browserslist": [ | ||
"ie >= 10" | ||
] | ||
"peerDependencies": { | ||
"vue": "^3.0.0" | ||
} | ||
} |
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
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
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
10
20814
1
18
540
1
1
1
0
1