UNPKG

@dnb/eufemia

Version:

DNB Eufemia Design System UI Library

212 lines 6.56 kB
import _pushInstanceProperty from "core-js-pure/stable/instance/push.js"; import _Object$hasOwn from "core-js-pure/stable/object/has-own.js"; import { isTrue, toKebabCase } from "./component-helper.js"; import { warn } from "./helpers.js"; export const defaultBreakpoints = { small: '40em', medium: '60em', large: '72em', 'x-large': '80em', 'xx-large': '90em' }; export function onMediaQueryChange(property, callback, { runOnInit = false } = {}) { let query = property; let when = null; let not = null; if (property && typeof property === 'object') { query = null; when = property.when || property; not = property.not; } const mediaQueryList = makeMediaQueryList({ query, when, not }); if (runOnInit) { if (typeof callback === 'function') { callback(mediaQueryList === null || mediaQueryList === void 0 ? void 0 : mediaQueryList.matches, mediaQueryList); } } return createMediaQueryListener(mediaQueryList, callback); } export const isMatchMediaSupported = () => typeof window !== 'undefined' && typeof window.matchMedia !== 'undefined'; export function makeMediaQueryList({ query, when, not = null } = {}, breakpoints = null, options) { const isSupported = isMatchMediaSupported(); if (options !== null && options !== void 0 && options.disabled || !isSupported) { return null; } if (when) { query = buildQuery({ query, when, not }, breakpoints, options); } const mediaQueryString = convertToMediaQuery(query, breakpoints, options); const mediaQueryList = window.matchMedia(mediaQueryString); if (options !== null && options !== void 0 && options.log) { warn('MediaQuery:', mediaQueryString); } return mediaQueryList; } export function createMediaQueryListener(mediaQueryList, callback) { if (!mediaQueryList) { return () => null; } const listener = event => { if (typeof callback === 'function') { callback(event === null || event === void 0 ? void 0 : event.matches, event); } }; if (mediaQueryList !== null && mediaQueryList !== void 0 && mediaQueryList.addEventListener) { mediaQueryList.addEventListener('change', listener); } return () => { if (mediaQueryList !== null && mediaQueryList !== void 0 && mediaQueryList.removeEventListener) { mediaQueryList.removeEventListener('change', listener); } }; } export function buildQuery({ query = null, when = null, not = null } = {}, breakpoints, options) { if (when) { if (typeof when === 'string') { when = when.split(/[ ,]/g); } let listOfQueries = []; if (Array.isArray(when)) { listOfQueries = listOfQueries.concat(combineQueries(when, breakpoints, options)); } else if (typeof when === 'object') { const queryItem = convertToMediaQuery(when, breakpoints, options); if (queryItem) { _pushInstanceProperty(listOfQueries).call(listOfQueries, queryItem); } } if (listOfQueries.length > 0) { query = [listOfQueries.join(' '), query || ''].filter(Boolean).join(' and ').replace(/ +/g, ' ').replace(/ ,/g, ','); } } if (isTrue(not)) { query = reverseQuery(String(query)); } return query || 'not'; } function reverseQuery(query) { if (query.startsWith('not')) { return query.replace(/^not +/, ''); } if (!/^(screen|all|print|speech)/.test(query)) { query = `all and ${query}`; } return `not ${query}`; } function combineQueries(queries, breakpoints = null, options) { return queries.reduce((listOfQueries, when, i, arr) => { if (breakpoints) { breakpoints = mergeBreakpoints(breakpoints); } const query = convertToMediaQuery(when, breakpoints, options); if (query) { if (query !== 'and' && arr[i - 1] !== 'and') { _pushInstanceProperty(listOfQueries).call(listOfQueries, ', '); } _pushInstanceProperty(listOfQueries).call(listOfQueries, query); } return listOfQueries; }, []).filter((query, i) => { return !(i === 0 && query.startsWith(', ')); }); } function mergeBreakpoints(breakpoints) { return Object.entries({ ...defaultBreakpoints, ...breakpoints }).sort((a, b) => a[1] > b[1] ? 1 : -1).reduce((acc, [key, value]) => { acc[key] = value; return acc; }, {}); } export function convertToMediaQuery(query, breakpoints = null, options) { if (typeof query === 'string') { return query; } if (Array.isArray(query)) { return query.reduce((acc, q, index) => { acc += objToMediaQuery(q, breakpoints, options); if (index < query.length - 1) { if (q !== 'and' && query[index + 1] !== 'and') { acc += ','; } acc += ' '; } return acc; }, ''); } return objToMediaQuery(query, breakpoints, options); } function objToMediaQuery(obj, breakpoints = null, options) { if (typeof obj === 'string') { return obj; } let hasNot = false; let query = Object.keys(obj).reduce((acc, feature) => { let value = obj[feature]; feature = toKebabCase(feature); if (feature === 'not') { hasNot = true; return acc; } if (feature === 'monochrome') { feature = `(${feature})`; } if (feature === 'min' || feature === 'max') { feature = `${feature}-width`; } if (typeof value === 'number' && /[height|width]$/.test(feature)) { value = value + 'em'; } if (value === true) { _pushInstanceProperty(acc).call(acc, feature); } else if (value === false) { _pushInstanceProperty(acc).call(acc, 'not ' + feature); } else { value = getValueByFeature(value, breakpoints); if (typeof value !== 'undefined') { _pushInstanceProperty(acc).call(acc, `(${feature}: ${value})`); } } return acc; }, []); if (Array.isArray(query)) { query = query.length > 0 ? query.join(' and ') : query.join(''); } if (hasNot) { query = reverseQuery(query); } if (options !== null && options !== void 0 && options.correctRange && /\(min-width: [0-9]+em\)/.test(query)) { const size = parseFloat(query.match(/\(min-width: ([0-9]+)em\)/)[1]) || 0; if (size > 0) { const correctedSize = (size * 16 + 0.1) / 16; query = query.replace(/(min-width: [0-9]+em)/, `min-width: ${correctedSize}em`); } } return query; } function getValueByFeature(value, types = null) { types = types || defaultBreakpoints; if (_Object$hasOwn(types, value)) { value = types[value]; } return value; } //# sourceMappingURL=MediaQueryUtils.js.map