Low-level, framework-agnostic styling helpers: color mixing, CSS unit conversion, responsive media-query strings, CSS-in-JS property builders, an sr-only style object, and shared CSS unit types.
Reach for @uxf/styles when you need small, pure helpers that produce CSS values or media-query strings in TypeScript/CSS-in-JS code (used internally by @uxf/ui and by app styling). Every helper is a plain function or object that returns a string/number/object.
It is not a component library and ships no stylesheet, global CSS, or Tailwind preset — only compiled JS and type declarations. It peer-depends on @uxf/core for a few utilities.
yarn add @uxf/styles
@uxf/core is a required peer dependency; color2k is bundled as a regular dependency. There is no CSS to import and no provider to set up.
Import from the exact subpath (there is no package-root entry — see Gotchas):
import { rem } from "@uxf/styles/units/rem";
import { mqMin } from "@uxf/styles/responsive/mq-min";
const styles = {
padding: rem(16), // "1rem"
[`@media ${mqMin(768)}`]: {
// "(min-width: 48em)"
padding: rem(24), // "1.5rem"
},
};
shade and tintcolor2k libraryshade) or white (tint)import { shade } from "@uxf/styles/color/shade";
const darker = shade("#f00", 0.1);
import { tint } from "@uxf/styles/color/tint";
const lighter = tint("#f00", 0.1);
srOnlyCSSProperties) with CSS to hide an element from all devices except screen readersimport { srOnly } from "@uxf/styles/mixins/sr-only";
const example = <div style={srOnly} />;
columnsToPercentcalc() value with relative width of provided number of columns in provided total columns (default is 12) compensated by an optionally provided gutter (default 0, in pixels)import { columnsToPercent } from "@uxf/styles/properties/columns-to-percent";
const example = columnsToPercent(4, 12, 24);
/* returns "calc((100% + 1.5rem) / 12 * 4)" */
encodedSvgUrlurl() value of an encoded version of provided svgimport { encodedSvgUrl } from "@uxf/styles/properties/encoded-svg-url";
const example = encodedSvgUrl(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path fill="currentColor" d="0 20 20 0" /></svg>`);
repeatGridColumnsrepeat() value of provided number of columns and size (default "1fr")null when count is falsyimport { repeatGridColumns } from "@uxf/styles/properties/repeat-grid-columns";
const example = repeatGridColumns(6, "1fr"); /* returns "repeat(6, 1fr)" */
transitiontransition property for specified property or an array of propertieskeyof CSSProperties value (or array); defaults: duration = 400 (ms), easing = "ease-in-out"import { transition } from "@uxf/styles/properties/transition";
const example = transition(["color", "transform"], 400, "ease-in-out");
/* returns "color 400ms ease-in-out, transform 400ms ease-in-out" */
mqBetween, mqHiDpi, mqMax, mqMinimport { mqBetween } from "@uxf/styles/responsive/mq-between";
const example = mqBetween(320, 480);
/* returns "(min-width: 20em) and (max-width: 29.9375em)" */
import { mqHiDpi } from "@uxf/styles/responsive/mq-hidpi";
const example = mqHiDpi(3);
/* returns hidpi media query string for DPR 3.0 (default ratio is 2) */
window.matchMedia().matches media queries: matchBetween, matchHidpi, matchMax, matchMinwindow) they return falseimport { matchBetween } from "@uxf/styles/responsive/match-between";
const example = matchBetween(320, 480); /* returns boolean */
import { matchHidpi } from "@uxf/styles/responsive/match-hidpi";
const example = matchHidpi(3); /* returns boolean */
em and rem16); 0 returns the string "0"import { em } from "@uxf/styles/units/em";
const example1 = em(320); /* returns "20em" */
const example2 = em(320, 10); /* returns "32em" */
import { rem } from "@uxf/styles/units/rem";
const example1 = rem(320); /* returns "20rem" */
const example2 = rem(320, 10); /* returns "32rem" */
emToPx and remToPxnumber) by specified base (default 16)"0" is also accepted and returns 0import { emToPx } from "@uxf/styles/units/em-to-px";
const example1 = emToPx("20em"); /* 320 */
const example2 = emToPx("20em", 10); /* 200 */
const example3 = emToPx("0"); /* 0 */
// emToPx("20rem") — throws error: Invalid value
import { remToPx } from "@uxf/styles/units/rem-to-px";
const example1 = remToPx("20rem"); /* 320 */
const example2 = remToPx("20rem", 10); /* 200 */
const example3 = remToPx("0"); /* 0 */
// remToPx("20%") — throws error: Invalid value
formatCssValuerem (or a plain string when 0 or forceString), non-empty strings pass through, anything else returns nullimport { formatCssValue } from "@uxf/styles/units/format-css-value";
const example1 = formatCssValue(0); /* returns "0" */
const example2 = formatCssValue(24); /* returns "1.5rem" */
const example3 = formatCssValue("100%"); /* returns "100%" */
const example4 = formatCssValue(1, true); /* returns "1" */
percent100) with provided precision (default 2)import { percent } from "@uxf/styles/units/percent";
const example = percent(54.874, 80, 2); /* returns 68.59 */
spacingDeprecated — this function will be deleted in future versions.
8)import { spacing } from "@uxf/styles/units/spacing";
const example = spacing(4); /* returns 32 */
withUnitimport { withUnit } from "@uxf/styles/units/with-unit";
const example = withUnit(80, "vh"); /* returns "80vh" */
Shared, typed CSS units and helper types, all exported from @uxf/styles/types:
import type { CssUnits, TransitionProperties } from "@uxf/styles/types";
| Type | Description |
|---|---|
CssTimeUnits |
"ms" | "s" |
CssAbsoluteLengthsUnits |
absolute length/angle units (cm, mm, in, px, pt, pc, deg, rad) |
CssRelativeLengthsUnits |
relative units (em, ex, ch, rem, vw, vh, vmin, vmax, %) |
CssUnits |
union of all of the above (accepted by withUnit) |
TransitionProperty |
keyof CSSProperties |
TransitionProperties |
TransitionProperty | TransitionProperty[] (accepted by transition) |
index), so a bare import … from "@uxf/styles" does not resolve. Always import from the exact subpath, e.g. @uxf/styles/units/rem.exports map. Subpaths resolve by filesystem, so a path must match the on-disk file exactly — note it is color (singular) and match-hidpi.mqHiDpi (capital D), but the boolean matcher is matchHidpi (lowercase d)..d.ts files are published (see .npmignore); there is no stylesheet, global CSS, or Tailwind preset to import.srOnly is a JS object, not a class — apply it via style={srOnly} or by spreading, not className.match* helpers are client-only in effect. They read window.matchMedia and return false on the server (guarded by @uxf/core's isBrowser), so they are SSR-safe but never true during server render.emToPx / remToPx throw on any input that is not a matching em / rem string or the string "0".@uxf/core is a required peer dependency.