UNPKG

postcss-calc

Version:
93 lines (84 loc) • 2.37 kB
import { num, dim } from '../node.js'; import { baseOf, convert } from '../convertUnits.js'; /** @typedef {import('../node.js').Node} Node */ /** @typedef {import('../node.js').Num} Num */ /** @typedef {import('../node.js').Dim} Dim */ /** @typedef {import('../convertUnits.js').BaseType} BaseType */ /** * Construct a Num or Dim node from a folded result. * @param {{ unit: string }} fold * @param {number} value * @return {Num | Dim} */ function foldResult(fold, value) { return fold.unit === '' ? num(value) : dim(value, fold.unit); } /** * Return the argument that produced a folded min/max/clamp value, so the * result keeps its own unit, spelling and zero sign. Falls back to a fresh * node when no argument matches (NaN). * @param {Node[]} args * @param {{ values: number[], unit: string }} fold * @param {number} value * @return {Node} */ function chosenArg(args, fold, value) { const index = fold.values.findIndex((v) => Object.is(v, value)); return index === -1 ? foldResult(fold, value) : args[index]; } /** * @param {Node[]} args * @return {{ values: number[], unit: string } | null} */ function foldConstArgs(args) { if (args.length === 0) { return null; } const first = args[0]; if (first.type === 'Num') { return foldNumberArgs(args); } if (first.type === 'Dim') { const b = first.unit === '%' ? null : baseOf(first.unit); if (!b) { return null; } return foldDimArgs(args, first.unit, b); } return null; } /** * @param {Node[]} args * @return {{ values: number[], unit: '' } | null} */ function foldNumberArgs(args) { /** @type {number[]} */ const values = []; for (const a of args) { if (a.type !== 'Num') { return null; } values.push(a.value); } return { values, unit: '' }; } /** * @param {Node[]} args * @param {string} unit * @param {BaseType} base * @return {{ values: number[], unit: string } | null} */ function foldDimArgs(args, unit, base) { /** @type {number[]} */ const values = []; for (const a of args) { if (a.type !== 'Dim' || a.unit === '%' || baseOf(a.unit) !== base) { return null; } const converted = convert(a.value, a.unit, unit); if (converted === null) { return null; } values.push(converted); } return { values, unit }; } export { foldConstArgs, foldResult, chosenArg };