import { isObject } from './is.mjs'; function getLastItem(array) { const length = array == null ? 0 : array.length; return length ? array[length - 1] : void 0; } function analyzeCSSValue(value) { const num = parseFloat(value.toString()); const unit = value.toString().replace(String(num), ""); return { unitless: !unit, value: num, unit }; } function px(value) { if (value == null) return value; const { unitless } = analyzeCSSValue(value); return unitless || typeof value === "number" ? `${value}px` : value; } const sortByBreakpointValue = (a, b) => parseInt(a[1], 10) > parseInt(b[1], 10) ? 1 : -1; const sortBps = (breakpoints) => Object.fromEntries(Object.entries(breakpoints).sort(sortByBreakpointValue)); function normalize(breakpoints) { const sorted = sortBps(breakpoints); return Object.assign(Object.values(sorted), sorted); } function keys(breakpoints) { const value = Object.keys(sortBps(breakpoints)); return new Set(value); } function subtract(value) { if (!value) return value; value = px(value) ?? value; const OFFSET = -0.02; return typeof value === "number" ? `${value + OFFSET}` : value.replace(/(\d+\.?\d*)/u, (m) => `${parseFloat(m) + OFFSET}`); } function toMediaQueryString(min, max) { const query = ["@media screen"]; if (min) query.push("and", `(min-width: ${px(min)})`); if (max) query.push("and", `(max-width: ${px(max)})`); return query.join(" "); } function analyzeBreakpoints(breakpoints) { if (!breakpoints) return null; breakpoints.base = breakpoints.base ?? "0px"; const normalized = normalize(breakpoints); const queries = Object.entries(breakpoints).sort(sortByBreakpointValue).map(([breakpoint, minW], index, entry) => { let [, maxW] = entry[index + 1] ?? []; maxW = parseFloat(maxW) > 0 ? subtract(maxW) : void 0; return { _minW: subtract(minW), breakpoint, minW, maxW, maxWQuery: toMediaQueryString(null, maxW), minWQuery: toMediaQueryString(minW), minMaxQuery: toMediaQueryString(minW, maxW) }; }); const _keys = keys(breakpoints); const _keysArr = Array.from(_keys.values()); return { keys: _keys, normalized, isResponsive(test) { const keys2 = Object.keys(test); return keys2.length > 0 && keys2.every((key) => _keys.has(key)); }, asObject: sortBps(breakpoints), asArray: normalize(breakpoints), details: queries, get(key) { return queries.find((q) => q.breakpoint === key); }, media: [ null, ...normalized.map((minW) => toMediaQueryString(minW)).slice(1) ], /** * Converts the object responsive syntax to array syntax * * @example * toArrayValue({ base: 1, sm: 2, md: 3 }) // => [1, 2, 3] */ toArrayValue(test) { if (!isObject(test)) { throw new Error("toArrayValue: value must be an object"); } const result = _keysArr.map((bp) => test[bp] ?? null); while (getLastItem(result) === null) { result.pop(); } return result; }, /** * Converts the array responsive syntax to object syntax * * @example * toObjectValue([1, 2, 3]) // => { base: 1, sm: 2, md: 3 } */ toObjectValue(test) { if (!Array.isArray(test)) { throw new Error("toObjectValue: value must be an array"); } return test.reduce( (acc, value, index) => { const key = _keysArr[index]; if (key != null && value != null) acc[key] = value; return acc; }, {} ); } }; } export { analyzeBreakpoints, px, toMediaQueryString };