const plugin = require('tailwindcss/plugin') // Usage For padding - default in px // p-c-[20,40] // p-c-[20px,40px] // p-c-[20rem,40rem] // p-c-[40px,200] // Usage For Text // text-c-[24px,96px] // text-c-[24,96] // text-c-[2rem,5rem] // text-c-[24,36,1.5,1.2] // text-c-[24px,36px,1.5,1.2] // text-c-[2rem,4rem,2,1.5] module.exports = plugin(function ({ matchUtilities }) { const minViewport = 375; const maxViewport = 3840; const baseFontSize = 16; function createClampValue(values) { let v = values.split(',') let pixelSizeAtMinViewport = toPixels(v[0]) let pixelSizeAtMaxViewport = toPixels(v[1]) // Calculate a and b const a = (pixelSizeAtMaxViewport - pixelSizeAtMinViewport) / (maxViewport - minViewport); const b = pixelSizeAtMinViewport - a * minViewport; // Adjust a for the vw unit const aVw = (100 * a).toFixed(4); // Convert pixel values to rem (assuming 1rem = 16px) const minRem = (pixelSizeAtMinViewport / baseFontSize).toFixed(4); const maxRem = (pixelSizeAtMaxViewport / baseFontSize).toFixed(4); const bRem = (b / baseFontSize).toFixed(4); // Form the clamp value const clampValue = `clamp(${minRem}rem, ${bRem}rem + ${aVw}vw, ${maxRem}rem)`; return clampValue; } function createLineHeightClamp(values) { let v = values.split(',') v[2] = v[2] || 1.5; v[3] = v[3] || 1.3; let pixelSizeAtMinViewport = toPixels(v[0]) * v[2] let pixelSizeAtMaxViewport = toPixels(v[1]) * v[3] let lineHeight = pixelSizeAtMinViewport + ',' + pixelSizeAtMaxViewport return createClampValue(lineHeight) } function toPixels(value) { // If value is in rem, convert to px if (value.endsWith('rem')) { return parseFloat(value) * baseFontSize; } // If value is in px, just return the numeric value if (value.endsWith('px')) { return parseFloat(value); } // If value is a plain number, return it as a number if (!isNaN(value)) { return parseFloat(value); } // If the value doesn't match any known formats, return it as-is return value; } matchUtilities({ "p-c": (value) => ({ padding: createClampValue(value), }), "pt-c": (value) => ({ paddingTop: createClampValue(value), }), "pr-c": (value) => ({ paddingRight: createClampValue(value), }), "pb-c": (value) => ({ paddingBottom: createClampValue(value), }), "pl-c": (value) => ({ paddingLeft: createClampValue(value), }), "px-c": (value) => ({ paddingLeft: createClampValue(value), paddingRight: createClampValue(value), }), "py-c": (value) => ({ paddingTop: createClampValue(value), paddingBottom: createClampValue(value), }), "m-c": (value) => ({ margin: createClampValue(value), }), "mt-c": (value) => ({ marginTop: createClampValue(value), }), "mr-c": (value) => ({ marginRight: createClampValue(value), }), "mb-c": (value) => ({ marginBottom: createClampValue(value), }), "ml-c": (value) => ({ marginLeft: createClampValue(value), }), "mx-c": (value) => ({ marginLeft: createClampValue(value), marginRight: createClampValue(value), }), "my-c": (value) => ({ marginTop: createClampValue(value), marginBottom: createClampValue(value), }), "text-c": (value) => ({ fontSize: createClampValue(value), lineHeight: createLineHeightClamp(value), }), "tracking-c": (value) => ({ letterSpacing: createClampValue(value), }), "w-c": (value) => ({ width: createClampValue(value), }), "h-c": (value) => ({ height: createClampValue(value), }), }); });