Last active
October 31, 2023 14:36
-
-
Save conradfuhrman/7c2cc87fef35804d594c87b005f1d92a to your computer and use it in GitHub Desktop.
A simple clamp plugin for Tailwind
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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), | |
}), | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment