Skip to content

Commit

Permalink
Added updateBreakpoints provide/inject functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
Craig Riley committed Oct 25, 2020
1 parent d1b1b3a commit c2ad336
Show file tree
Hide file tree
Showing 10 changed files with 205 additions and 103 deletions.
63 changes: 47 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ _
#### Filter
Since Vue 3 has dropped support for filters, the previous functionality has been removed
#### SSR
Presently, support for SSR is not supported
Presently, support for SSR has been removed


## Installation
Expand All @@ -31,12 +31,17 @@ npm install @craigrileyuk/vue3-mq

## Usage

#### 1. Install plugin
#### 1.) Add plugin to Vue
Define your custom breakpoints by passing `breakpoints` option. This let you name the breakpoints as you want

**Eg**:

`{ phone: 500, tablet: 1200, other: Infinity }`

`{ small: 500, large: 1200, whatever: Infinity }`

`{ xs: 300, s: 500, m: 800, l: 1200, xl: Infinity }`

```js
import { createApp } from "vue";
import VueMq from "@craigrileyuk/vue3-mq";
Expand All @@ -48,13 +53,13 @@ app.use(VueMq, {
sm: 450,
md: 1250,
lg: Infinity,
},
defaultBreakpoint: 'sm'
}
})

app.mount('#app');
```
#### Use `$mq` property

#### 2.) Use `$mq` 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)_
Expand All @@ -63,14 +68,14 @@ After installing the plugin every instance of Vue component is given access to a
`'lg'` => **screenWidth >= 1250**

```html
//Use it in a component
<template>
<div>{{ $mq }}</div>
</template>
```

#### Use `$mq` with a computed property
`$mq` property is fully reactive (like a data property) so feel free to use it in a computed.
#### 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.

```js
new Vue({
Expand All @@ -85,24 +90,50 @@ new Vue({
})
```

#### MqLayout component
In addition to `$mq` property this plugin provide a wrapper component to facilitate conditional rendering with media queries.
#### 4.) Update breakpoints

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.

**Usage**:
```js
import { inject, onMounted } from "vue";

setup() {
const updateBreakpoints = inject("updateBreakpoints");

onMounted() {
updateBreakpoints({
xs: 576,
sm: 768,
md: 992,
lg: 1200,
xl: 1400,
xxl: Infinity
})
}
}
```

#### 5.) MqLayout component
In addition to `$mq` property this plugin provide a wrapper component to facilitate conditional rendering with media queries.

> **Usage**:
```html
<mq-layout mq="lg">
<span> Display on lg </span>
</mq-layout>
<mq-layout mq="md+">
<span> Display on md and larger </span>
</mq-layout>
<mq-layout :mq="['sm', 'lg']">
<span> Display on sm and lg </span>
<mq-layout :mq="['sm', 'lg']" tag="span">
Display on sm and lg
</mq-layout>
```
**Props**
mq => required : String | Array
tag => optional : String - sets the HTML tag to use for the rendered component (default 'div')

> **Props**
`mq` => required : [String,Array]

`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.

Expand Down
64 changes: 42 additions & 22 deletions dist/index.es.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}

var listeners = [];
function convertBreakpointsToMediaQueries(breakpoints) {
var keys = Object.keys(breakpoints);
var values = keys.map(function (key) {
Expand Down Expand Up @@ -80,7 +81,11 @@ function subscribeToMediaQuery(mediaQuery, enter) {
if (matches) enter();
};

mql.addListener(cb); //subscribing
listeners.push({
mql: mql,
cb: cb
});
mql.addEventListener('change', cb); //subscribing

cb(mql); //initial trigger
}
Expand All @@ -100,6 +105,32 @@ var currentBreakpoint = readonly(state.currentBreakpoint);
function isArray(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
}
function updateBreakpoints(breakpoints) {
for (var i = listeners.length - 1; i >= 0; i--) {
var _listeners$i = listeners[i],
mql = _listeners$i.mql,
cb = _listeners$i.cb;
mql.removeEventListener('change', cb);
listeners.splice(i, 1);
}

setAvailableBreakpoints(breakpoints);
var mediaQueries = convertBreakpointsToMediaQueries(breakpoints); // setup listeners

var _loop = function _loop(key) {
var mediaQuery = mediaQueries[key];

var enter = function enter() {
setCurrentBreakpoint(key);
};

subscribeToMediaQuery(mediaQuery, enter);
};

for (var key in mediaQueries) {
_loop(key);
}
}

// USAGE
var MqLayout = {
Expand All @@ -108,6 +139,10 @@ var MqLayout = {
mq: {
required: true,
type: [String, Array]
},
tag: {
type: String,
"default": 'div'
}
},
setup: function setup(props, context) {
Expand All @@ -123,12 +158,12 @@ var MqLayout = {
return activeBreakpoints.value.includes(currentBreakpoint.value);
});
return function () {
return shouldRenderChildren.value ? h("div", {}, context.slots["default"]()) : h();
return shouldRenderChildren.value ? h(props.tag, {}, context.slots["default"]()) : h();
};
}
};

var DEFAULT_BREAKPOINT = {
var DEFAULT_BREAKPOINTS = {
sm: 450,
md: 1250,
lg: Infinity
Expand All @@ -137,12 +172,13 @@ var DEFAULT_BREAKPOINT = {
var install = function install(app) {
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref$breakpoints = _ref.breakpoints,
breakpoints = _ref$breakpoints === void 0 ? DEFAULT_BREAKPOINT : _ref$breakpoints,
breakpoints = _ref$breakpoints === void 0 ? DEFAULT_BREAKPOINTS : _ref$breakpoints,
_ref$defaultBreakpoin = _ref.defaultBreakpoint,
defaultBreakpoint = _ref$defaultBreakpoin === void 0 ? 'sm' : _ref$defaultBreakpoin;

var hasSetupListeners = false;
setCurrentBreakpoint(defaultBreakpoint); // Init reactive component
setCurrentBreakpoint(defaultBreakpoint);
app.provide('updateBreakpoints', updateBreakpoints); // Init reactive component

app.mixin({
computed: {
Expand All @@ -152,28 +188,12 @@ var install = function install(app) {
},
mounted: function mounted() {
if (!hasSetupListeners) {
var mediaQueries = convertBreakpointsToMediaQueries(breakpoints); // setup listeners

var _loop = function _loop(key) {
var mediaQuery = mediaQueries[key];

var enter = function enter() {
setCurrentBreakpoint(key);
};

subscribeToMediaQuery(mediaQuery, enter);
};

for (var key in mediaQueries) {
_loop(key);
}

updateBreakpoints(breakpoints);
hasSetupListeners = true;
}
}
});
app.config.globalProperties.$mqAvailableBreakpoints = breakpoints;
setAvailableBreakpoints(breakpoints);
app.component('mq-layout', MqLayout);
};

Expand Down
64 changes: 42 additions & 22 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ function _nonIterableSpread() {
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}

var listeners = [];
function convertBreakpointsToMediaQueries(breakpoints) {
var keys = Object.keys(breakpoints);
var values = keys.map(function (key) {
Expand Down Expand Up @@ -86,7 +87,11 @@ function subscribeToMediaQuery(mediaQuery, enter) {
if (matches) enter();
};

mql.addListener(cb); //subscribing
listeners.push({
mql: mql,
cb: cb
});
mql.addEventListener('change', cb); //subscribing

cb(mql); //initial trigger
}
Expand All @@ -106,6 +111,32 @@ var currentBreakpoint = vue.readonly(state.currentBreakpoint);
function isArray(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
}
function updateBreakpoints(breakpoints) {
for (var i = listeners.length - 1; i >= 0; i--) {
var _listeners$i = listeners[i],
mql = _listeners$i.mql,
cb = _listeners$i.cb;
mql.removeEventListener('change', cb);
listeners.splice(i, 1);
}

setAvailableBreakpoints(breakpoints);
var mediaQueries = convertBreakpointsToMediaQueries(breakpoints); // setup listeners

var _loop = function _loop(key) {
var mediaQuery = mediaQueries[key];

var enter = function enter() {
setCurrentBreakpoint(key);
};

subscribeToMediaQuery(mediaQuery, enter);
};

for (var key in mediaQueries) {
_loop(key);
}
}

// USAGE
var MqLayout = {
Expand All @@ -114,6 +145,10 @@ var MqLayout = {
mq: {
required: true,
type: [String, Array]
},
tag: {
type: String,
"default": 'div'
}
},
setup: function setup(props, context) {
Expand All @@ -129,12 +164,12 @@ var MqLayout = {
return activeBreakpoints.value.includes(currentBreakpoint.value);
});
return function () {
return shouldRenderChildren.value ? vue.h("div", {}, context.slots["default"]()) : vue.h();
return shouldRenderChildren.value ? vue.h(props.tag, {}, context.slots["default"]()) : vue.h();
};
}
};

var DEFAULT_BREAKPOINT = {
var DEFAULT_BREAKPOINTS = {
sm: 450,
md: 1250,
lg: Infinity
Expand All @@ -143,12 +178,13 @@ var DEFAULT_BREAKPOINT = {
var install = function install(app) {
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref$breakpoints = _ref.breakpoints,
breakpoints = _ref$breakpoints === void 0 ? DEFAULT_BREAKPOINT : _ref$breakpoints,
breakpoints = _ref$breakpoints === void 0 ? DEFAULT_BREAKPOINTS : _ref$breakpoints,
_ref$defaultBreakpoin = _ref.defaultBreakpoint,
defaultBreakpoint = _ref$defaultBreakpoin === void 0 ? 'sm' : _ref$defaultBreakpoin;

var hasSetupListeners = false;
setCurrentBreakpoint(defaultBreakpoint); // Init reactive component
setCurrentBreakpoint(defaultBreakpoint);
app.provide('updateBreakpoints', updateBreakpoints); // Init reactive component

app.mixin({
computed: {
Expand All @@ -158,28 +194,12 @@ var install = function install(app) {
},
mounted: function mounted() {
if (!hasSetupListeners) {
var mediaQueries = convertBreakpointsToMediaQueries(breakpoints); // setup listeners

var _loop = function _loop(key) {
var mediaQuery = mediaQueries[key];

var enter = function enter() {
setCurrentBreakpoint(key);
};

subscribeToMediaQuery(mediaQuery, enter);
};

for (var key in mediaQueries) {
_loop(key);
}

updateBreakpoints(breakpoints);
hasSetupListeners = true;
}
}
});
app.config.globalProperties.$mqAvailableBreakpoints = breakpoints;
setAvailableBreakpoints(breakpoints);
app.component('mq-layout', MqLayout);
};

Expand Down
Loading

0 comments on commit c2ad336

Please sign in to comment.