Skip to content

Instantly share code, notes, and snippets.

@aaroniker
Last active July 19, 2024 14:22
Show Gist options
  • Save aaroniker/da82d10c581cbe4b240745b4f34890c3 to your computer and use it in GitHub Desktop.
Save aaroniker/da82d10c581cbe4b240745b4f34890c3 to your computer and use it in GitHub Desktop.
panda-css fluid typography
import { defineUtility } from '@pandacss/dev';
type Unit = 'px' | 'rem' | 'em';
type VwUnit = 'vw' | 'vh' | '%';
interface FluidFontConfig {
defaultUnit: Unit;
defaultVwUnit: VwUnit;
defaultMinVw: number;
defaultMaxVw: number;
}
interface FluidFontProps {
min: number;
max: number;
minVw?: number;
maxVw?: number;
unit?: Unit;
vwUnit?: VwUnit;
}
const fluidTypographyValue = (
min: number,
max: number,
minVw: number,
maxVw: number,
unit: Unit,
vwUnit: VwUnit
): string => {
const slope = (max - min) / (maxVw - minVw);
const yAxisIntersection = -minVw * slope + min;
return `clamp(${min}${unit}, ${yAxisIntersection.toFixed(4)}${unit} + ${(slope * 100).toFixed(4)}${vwUnit}, ${max}${unit})`;
};
export const fluidTypography = (config: FluidFontConfig) =>
defineUtility({
transform(props: { fluidFont?: string | FluidFontProps }, { theme }) {
if (!props.fluidFont) return props;
const {
defaultUnit,
defaultVwUnit,
defaultMinVw,
defaultMaxVw,
} = config;
let fluidFontProps: FluidFontProps;
if (typeof props.fluidFont === 'string') {
fluidFontProps = theme.fluidFont[props.fluidFont] as FluidFontProps;
if (!fluidFontProps) {
console.warn(`Fluid type preset "${props.fluidFont}" not found in theme.`);
return props;
}
} else {
fluidFontProps = props.fluidFont;
}
const {
min,
max,
minVw = defaultMinVw,
maxVw = defaultMaxVw,
unit = defaultUnit,
vwUnit = defaultVwUnit,
} = fluidFontProps;
const fluidValue = fluidTypographyValue(min, max, minVw, maxVw, unit, vwUnit);
return {
...props,
fontSize: fluidValue,
};
},
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment