UNPKG

@maizzle/framework

Version:

Maizzle is a framework that helps you quickly build HTML emails with Tailwind CSS.

151 lines (150 loc) 4.19 kB
//#region src/utils/cssBox.ts const NO_BORDER_STYLES = new Set(["none", "hidden"]); /** * Parse a length token into px. Handles `Npx`, `Nrem`, `Nem`, `Npt`, and * unitless N (treated as px). Returns null for percentages, calc(), * keywords, or anything that doesn't reduce to a concrete length. */ function lengthToPx(value) { const m = value.trim().match(/^([\d.]+)(px|rem|em|pt)?$/i); if (!m) return null; const n = parseFloat(m[1]); const unit = (m[2] || "px").toLowerCase(); return n * (unit === "rem" || unit === "em" ? 16 : unit === "pt" ? 1.333 : 1); } /** * Expand a 1-4 token CSS shorthand (T R B L) into a left/right pair: * 1: all sides * 2: TB RL * 3: T RL B * 4: T R B L */ function shorthandSides(value) { const parts = value.trim().split(/\s+/); switch (parts.length) { case 1: return { left: parts[0], right: parts[0] }; case 2: case 3: return { left: parts[1], right: parts[1] }; case 4: return { left: parts[3], right: parts[1] }; default: return {}; } } /** * Read horizontal padding (left + right) px from a parsed style root. * Percentages are skipped since they'd need a known container width. */ function horizontalPaddingPx(root) { let left = null; let right = null; root.walkDecls((d) => { switch (d.prop) { case "padding": { const { left: l, right: r } = shorthandSides(d.value); if (l) left = lengthToPx(l); if (r) right = lengthToPx(r); break; } case "padding-left": left = lengthToPx(d.value); break; case "padding-right": right = lengthToPx(d.value); break; } }); return (left ?? 0) + (right ?? 0); } /** * Extract a px length from a CSS border shorthand (e.g. `1px solid red` → 1). * Returns null when the value indicates no border (`none` or `hidden`). * Defaults to 3px (CSS `medium`) when a visible style is set but no * explicit width token is present in the shorthand value. */ function shorthandBorderWidthPx(value) { const tokens = value.trim().split(/\s+/); if (tokens.some((t) => NO_BORDER_STYLES.has(t.toLowerCase()))) return null; for (const t of tokens) { const px = lengthToPx(t); if (px != null) return px; } return 3; } /** * Read horizontal border widths (left + right) px from a parsed style root. * Per-side `border-style: none|hidden` overrides count as zero * contribution. Returns total px or 0 when nothing resolves. */ function horizontalBorderPx(root) { let left = null; let right = null; let leftNone = false; let rightNone = false; root.walkDecls((d) => { switch (d.prop) { case "border": { const w = shorthandBorderWidthPx(d.value); if (w == null) leftNone = rightNone = true; else { left = right = w; leftNone = rightNone = false; } break; } case "border-width": { const { left: l, right: r } = shorthandSides(d.value); if (l) left = lengthToPx(l) ?? left; if (r) right = lengthToPx(r) ?? right; break; } case "border-style": { const { left: l, right: r } = shorthandSides(d.value); if (l && NO_BORDER_STYLES.has(l.toLowerCase())) leftNone = true; if (r && NO_BORDER_STYLES.has(r.toLowerCase())) rightNone = true; break; } case "border-left": { const w = shorthandBorderWidthPx(d.value); if (w == null) leftNone = true; else { left = w; leftNone = false; } break; } case "border-right": { const w = shorthandBorderWidthPx(d.value); if (w == null) rightNone = true; else { right = w; rightNone = false; } break; } case "border-left-width": left = lengthToPx(d.value) ?? left; break; case "border-right-width": right = lengthToPx(d.value) ?? right; break; case "border-left-style": if (NO_BORDER_STYLES.has(d.value.trim().toLowerCase())) leftNone = true; break; case "border-right-style": if (NO_BORDER_STYLES.has(d.value.trim().toLowerCase())) rightNone = true; break; } }); return (leftNone ? 0 : left ?? 0) + (rightNone ? 0 : right ?? 0); } //#endregion export { NO_BORDER_STYLES, horizontalBorderPx, horizontalPaddingPx, lengthToPx, shorthandBorderWidthPx, shorthandSides }; //# sourceMappingURL=cssBox.js.map