vue3-mq
Version:
Build responsive design into your Vue 3 app
1 lines • 8.88 kB
JavaScript
(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`vue`)):typeof define==`function`&&define.amd?define([`exports`,`vue`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.Vue3Mq={},e.Vue))})(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var n=Object.defineProperty,r=(e,t)=>{let r={};for(var i in e)n(r,i,{get:e[i],enumerable:!0});return t&&n(r,Symbol.toStringTag,{value:`Module`}),r},i=(0,t.ref)([]),a=(0,t.ref)(null),o=(0,t.ref)(null),s=(0,t.ref)(null),c=(0,t.ref)(null),l=(0,t.reactive)({current:``});let u=[],d=(0,t.ref)(!1),f=(0,t.readonly)(i),p=(0,t.readonly)(a),m=(0,t.readonly)(o),h=(0,t.readonly)(s),g=(0,t.readonly)(c),_=(0,t.readonly)(l),v=e=>{i.value=e},y=e=>{a.value=e},b=e=>{o.value=e},x=e=>{s.value=e},S=e=>{c.value=e},C=(e=p.value)=>{l.current=e;let t=f.value.findIndex(t=>t.name===e),n=f.value.map(e=>e.name);for(let r=0;r<n.length;r++){if(r>0&&r<n.length-1){let e=n[r]+`Minus`,i=n[r]+`Plus`;l[e]=t<=r,l[i]=t>=r}l[n[r]]=n[r]===e}},w=()=>{let e=Object.keys(l);for(let t of e)delete l[t];C(),T(),E(),D()},T=(e=m.value)=>{l.orientation=e,l.isLandscape=e===`landscape`,l.isPortrait=e===`portrait`},E=(e=h.value||`light`)=>{l.theme=e,l.isDark=e===`dark`,l.isLight=e===`light`},D=(e=g.value||`no-preference`)=>{l.motionPreference=e,l.isMotion=e===`no-preference`,l.isInert=e===`reduce`};function ee(){for(;u.length>0;){let e=u.shift();if(e&&typeof e==`object`){let{mql:t,cb:n}=e;t.addEventListener&&typeof t.addEventListener==`function`?t.removeEventListener(`change`,n):t.removeListener(n)}}}function te(){return f.value.reduce((e,t,n,r)=>{let i=`(min-width: ${t.min}px)`,a=n<r.length-1?`(max-width: ${r[n+1].min-1}px)`:null,o=i+(a?` and `+a:``);return Object.assign(e,{[t.name]:o})},{})}function O(e,t){if(typeof window>`u`||!window.matchMedia)return!1;if(typeof window<`u`&&!window.matchMedia)return console.error(`Vue3 Mq: No MatchMedia support detected in this browser. Responsive breakpoints not available.`),!1;{d.value=!0;let n=window.matchMedia(e),r=({matches:e})=>{e&&t()};u.push({mql:n,cb:r}),n.addEventListener&&typeof n.addEventListener==`function`?n.addEventListener(`change`,r):n.addListener(r),r(n)}}var k=e=>f.value.some(t=>t.name===e);let A=(e,t)=>{let n=t.value.map(e=>e.name);if(e){if(Array.isArray(e))return e.filter(e=>k(e));if(typeof e==`string`&&/\w+\+$/.test(e)){if(e=e.replace(/\+$/,``),k(e)===!1)return console.error(`Vue3 Mq: ${e} is not a valid breakpoint key. Invalid range.`),n;let r=t.value.findIndex(t=>t.name===e);return t.value.slice(r).map(e=>e.name)}else if(typeof e==`string`&&/\w+-$/.test(e)){if(e=e.replace(/-$/,``),k(e)===!1)return console.error(`Vue3 Mq: ${e} is not a valid breakpoint key. Invalid range.`),n;let r=t.value.findIndex(t=>t.name===e);return t.value.slice(0,r+1).map(e=>e.name)}else if(typeof e==`string`&&/^\w+-\w+$/.test(e)){let[r,i]=e.split(`-`);if(k(r)===!1)return console.error(`Vue3 Mq: ${r} is not a valid breakpoint key. Invalid range.`),n;if(k(i)===!1)return console.error(`Vue3 Mq: ${i} is not a valid breakpoint key. Invalid range.`),n;let a=t.value.findIndex(e=>e.name===r),o=t.value.findIndex(e=>e.name===i);return t.value.slice(a,o+1).map(e=>e.name)}else if(typeof e==`string`&&k(e)===!0)return[e];else return n}else return n},j=(e,t)=>{let n=[];return!e&&!t?[`landscape`,`portrait`]:(e&&n.push(`landscape`),t&&n.push(`portrait`),n)},M=(e,t)=>{let n=[];return!t&&!e?[`light`,`dark`]:(t&&n.push(`light`),e&&n.push(`dark`),n)},N=(e,t)=>{let n=[];return!e&&!t?[`reduce`,`no-preference`]:(e&&n.push(`reduce`),t&&n.push(`no-preference`),n)};var P=r({bootstrap3:()=>L,bootstrap4:()=>I,bootstrap5:()=>F,bulma:()=>G,devices:()=>H,mui:()=>W,tailwind:()=>V,vuetify:()=>B,vuetify3:()=>z,vuetify4:()=>R,wordpress:()=>U},1);let F={xs:0,sm:576,md:768,lg:992,xl:1200,xxl:1400},I={xs:0,sm:576,md:768,lg:992,xl:1200},L={xs:0,sm:768,md:992,lg:1200},R={xs:0,sm:600,md:840,lg:1145,xl:1545,xxl:2138},z={xs:0,sm:600,md:960,lg:1280,xl:1920,xxl:2560},B={xs:0,sm:600,md:960,lg:1264,xl:1904},V={xs:0,sm:640,md:768,lg:1024,xl:1280,xxl:1536},H={phone:0,tablet:768,laptop:1370,desktop:1906},U={mobile:0,small:600,medium:782,large:960,xlarge:1080,wide:1280,huge:1440},W={xs:0,sm:600,md:900,lg:1200,xl:1536},G={mobile:0,tablet:768,desktop:1024,widescreen:1216,fullhd:1408},K=e=>{if(typeof e==`string`&&P[e])return P[e];{let t=Object.keys(P);return console.error(`Vue3 Mq: "${e}" is not a valid preset. Available options are: ${t.join(`, `)}`),!1}},q=e=>[`landscape`,`portrait`].includes(e)===!1?(console.error(`Vue3 Mq: "${e}" is not a valid default orientation. Reverting to unset value.`),null):e,J=(e=null)=>[`dark`,`light`].includes(e)===!1&&e!==null?(console.error(`Vue3 Mq: "${e}" is not a valid default theme. Reverting to unset value.`),null):e,Y=(e=null)=>[`no-preference`,`reduce`].includes(e)===!1&&e!==null?(console.error(`Vue3 Mq: "${e}" is not a valid default motion preference. Reverting to unset value.`),null):e,X=e=>{if(!e||typeof e!=`object`)return!1;let t=[];for(let n in e){let r=parseFloat(e[n]);if(!n||typeof n!=`string`){console.warn(`Vue3 Mq: Invalid or missing breakpoint key (${JSON.stringify(n)}). Skipping.`);continue}else if(/^[^a-z]/i.test(n)||/[^a-zA-Z0-9_]/.test(n)){console.warn(`Vue3 Mq: "${n}" is an invalid breakpoint key. Breakpoint keys must start with a letter and contain only alphanumeric characters and underscores. Skipping.`);continue}else if(!r&&r!==0||isNaN(r)||r<0){console.warn(`Vue3 Mq: "${n}: ${e[n]}" is not a valid breakpoint. Breakpoints should be a number of zero or above. Skipping.`);continue}t.push({name:n,min:r})}return t.some(e=>e.min===0)||console.warn(`Vue3 Mq: You have not declared a breakpoint with a minimum value of 0. There may be screen sizes to which Vue3Mq does not respond.`),new Set(t.map(e=>e.min)).size<t.length&&console.warn(`Vue3 Mq: Your breakpoint configuration contains duplicate values. Behaviour may be unpredictable.`),t.length===0?!1:t.sort((e,t)=>e.min-t.min)},Z=e=>{let t=e.split(`:`),n={};for(let e of t)if(/\D/.test(e)===!1)continue;else [`landscape`,`portrait`].includes(e)?n.slotOrientation=e:[`light`,`dark`].includes(e)?n.slotTheme=e:[`inert`,`motion`].includes(e)?n.slotMotion=e:n.slotBp=e;return n};var ne={name:`fade`,mode:`out-in`},Q={name:`MqResponsive`,props:{target:[String,Array],landscape:{type:Boolean,default:!1},portrait:{type:Boolean,default:!1},dark:{type:Boolean,default:!1},light:{type:Boolean,default:!1},inert:{type:Boolean,default:!1},motion:{type:Boolean,default:!1},tag:{type:String,default:`div`},listTag:{type:String,default:`div`},group:{type:Boolean,default:!1}},setup(e,{attrs:n,emit:r,slots:i}){let a=(0,t.computed)(()=>A(e.target,f)),o=(0,t.computed)(()=>j(e.landscape,e.portrait)),s=(0,t.computed)(()=>M(e.dark,e.light)),c=(0,t.computed)(()=>N(e.inert,e.motion)),l=(0,t.computed)(()=>a.value.includes(_.current)&&o.value.includes(_.orientation)&&s.value.includes(_.theme)&&c.value.includes(_.motionPreference)),u=n=>{if(!e.group&&i.length>0)return i;let r=[];for(let e in i){let{slotBp:a,slotOrientation:o,slotTheme:s,slotMotion:c}=Z(e),l=(0,t.computed)(()=>A(a,f)),u=(0,t.computed)(()=>j(o===`landscape`,o===`portrait`)),d=(0,t.computed)(()=>M(s===`dark`,s===`light`)),p=(0,t.computed)(()=>N(c===`inert`,c===`motion`));(0,t.computed)(()=>l.value.includes(_.current)&&u.value.includes(_.orientation)&&d.value.includes(_.theme)&&p.value.includes(_.motionPreference)).value===!0&&r.push((0,t.h)(n||i[e],{key:e},n?i[e]():void 0))}return r.length>0?r:void 0};return i.default?()=>l.value?(0,t.h)(e.tag,{...n},i.default()):void 0:()=>{let r=Object.assign({},ne,n,{tag:e.tag});return(0,t.h)(e.group?t.TransitionGroup:t.Transition,r,()=>u(e.listTag))}}};function $({breakpoints:e,mergeBreakpoints:t={},preset:n}){let r=n?K(n):!1,i=e?X(e):!1;if(r===!1&&!i)throw TypeError(`Vue3 Mq: You must provide a valid preset, or valid breakpoint settings.`);v(i||X({...r,...t})),ee(),w();let a=te();for(let e in a){let t=a[e];O(t,()=>{C(e)})}[`portrait`,`landscape`].forEach(e=>{O(`(orientation: ${e})`,()=>{T(e)})}),[`light`,`dark`].forEach(e=>{O(`(prefers-color-scheme: ${e})`,()=>{E(e)})}),[`reduce`,`no-preference`].forEach(e=>{O(`(prefers-reduced-motion: ${e})`,()=>{D(e)})})}function re(){let e=(0,t.inject)(`mq`);if(e)return e;throw Error(`Vue3Mq is not installed in this app. Please follow the installation instructions and try again.`)}e.MqResponsive=Q,e.Vue3Mq={install:(e,{preset:t=`bootstrap5`,breakpoints:n,mergeBreakpoints:r,defaultBreakpoint:i,defaultOrientation:a=`landscape`,defaultMotion:o=`no-preference`,defaultTheme:s,global:c=!1}={})=>{try{let l=q(a),u=J(s),d=Y(o);y(i),b(l),x(u),S(d),e.provide(`mq`,_),e.provide(`updateBreakpoints`,$),c===!0&&(e.component(`MqResponsive`,Q),e.config.globalProperties.$mq=_),$({breakpoints:n,mergeBreakpoints:r,preset:t})}catch(e){console.error(e)}}},e.availableBreakpoints=f,e.updateBreakpoints=$,e.useMq=re});