src/index.ts1.4 KB · typescript
export * from "./scale";
export * from "./generator";
interface FluidConfig {
minSize: number;
maxSize: number;
minView?: number; // default 320
maxView?: number; // default 1200
unit?: "px" | "rem"; // default rem
rootSize?: number; // default 16
}
/**
* Generates a CSS clamp() value for fluid scaling.
*
* @param config Configuration object
* @returns CSS clamp() string
*/
export function fluid(config: FluidConfig): string {
const {
minSize,
maxSize,
minView = 320,
maxView = 1200,
unit = "rem",
rootSize = 16
} = config;
const slope = (maxSize - minSize) / (maxView - minView);
const yAxisIntersection = -minView * slope + minSize;
// Slope in vw units (slope * 100)
const slopeVw = (slope * 100).toFixed(4);
// Determine bounds for clamp() so it is always clamp(MIN, VAL, MAX)
// even if the scaling is inverted (minSize > maxSize)
const clampMin = Math.min(minSize, maxSize);
const clampMax = Math.max(minSize, maxSize);
if (unit === "px") {
const yPx = yAxisIntersection.toFixed(4);
return `clamp(${clampMin}px, ${yPx}px + ${slopeVw}vw, ${clampMax}px)`;
}
// Convert to rem (Accessibilty FTW)
const minRem = (clampMin / rootSize).toFixed(4);
const maxRem = (clampMax / rootSize).toFixed(4);
const yRem = (yAxisIntersection / rootSize).toFixed(4);
return `clamp(${minRem}rem, ${yRem}rem + ${slopeVw}vw, ${maxRem}rem)`;
}