UNPKG

@soyleninjs/postcss-flow

Version:

PostCSS plugin for creating fluid and responsive CSS values with granular breakpoint control using the flow() function

87 lines (73 loc) 3.1 kB
// postcss-easy-functions function flow (decl, definition) { // Example: flow(10-360, 20-834, 30-1440-0); const breakpoints = definition .split(',') .map(point => { const [value, vw, isFluid] = point.trim().split('-').map(Number) return { value, vw, isFluid: isFluid === undefined } }) .sort((a, b) => b.vw - a.vw) const property = decl.prop const selector = decl.parent.selector let cssProperty = '' let cssMediaQueries = '' const setProperty = (value) => { cssProperty += `${property}: ${value}\n` } const setMediaQuery = (value, vw) => { cssMediaQueries += `@media (width <= ${vw}px) { ${selector} {\n` cssMediaQueries += `${property}: ${value}\n` cssMediaQueries += '}}\n' } if (breakpoints.length > 1) { breakpoints.forEach((point, index) => { // Si el punto actual es el ultimo y el punto anterior es fluido, no hacer nada if (index === breakpoints.length - 1 && breakpoints[index - 1].isFluid) return // Si el punto anterior es fluido y el punto actual no es fluido, no hacer nada if (index > 0 && breakpoints[index - 1].isFluid && !point.isFluid) return const nextBreakpoint = breakpoints[index + 1] if (nextBreakpoint) { const minValue = nextBreakpoint.value const maxValue = point.value const minViewportWidth = nextBreakpoint.vw const maxViewportWidth = point.vw if (!point.isFluid) { const value = `${point.value}px;` index > 0 ? setMediaQuery(value, point.vw) : setProperty(value) } else { if (minValue > maxValue) { const value = `clamp(${maxValue}px, calc(${maxValue}px + (${minValue} - ${maxValue}) * ((100vw - ${maxViewportWidth}px) / ${minViewportWidth - maxViewportWidth})), ${minValue}px);` index > 0 ? setMediaQuery(value, point.vw) : setProperty(value) } else { const value = `clamp(${minValue}px, calc(${minValue}px + (${maxValue} - ${minValue}) * ((100vw - ${minViewportWidth}px) / ${maxViewportWidth - minViewportWidth})), ${maxValue}px);` index > 0 ? setMediaQuery(value, point.vw) : setProperty(value) } } } else { const value = `${point.value}px;` index > 0 ? setMediaQuery(value, point.vw) : setProperty(value) } }) } else { setProperty(`${breakpoints[0].value}px;`) } // return css return { cssProperty, cssMediaQueries } } module.exports = (opts = {}) => { return { postcssPlugin: 'postcss-flow', Declaration (decl) { const match = decl.value.match(/^flow\((.+)\)$/) if (match) { const { cssProperty, cssMediaQueries } = flow(decl, match[1]) // Primero hacer lo que se tenga que hacer con el parent, por que aqui aun existe mi propiedad decl.parent.after(cssMediaQueries) // Luego reemplazar la propiedad por la nueva, en este punto se remplace la propiedad anterior, por ende "decl" ya no es el mismo de antes! decl.replaceWith(cssProperty) } } } } module.exports.postcss = true