CSS
import { matrix, transform } from '@studiometa/js-toolkit/utils';Transforms
transform
transform(props: TransformProps): stringimport { transform } from '@studiometa/js-toolkit/utils';
transform({ x: 10, y: 20, scale: 1.5, rotate: 45 });Builds a transform value from named parts, so a component composes a transform instead of assembling a string. TransformProps takes x, y, z, rotate, rotateX, rotateY, rotateZ, scale, scaleX, scaleY, scaleZ, skew and the rest of the family.
The order is fixed by TRANSFORM_PROPS, not by the object. Transform functions do not commute, so two components building "the same" transform from differently-ordered literals must still get the same matrix.
matrix
matrix(props?: MatrixProps): stringimport { matrix } from '@studiometa/js-toolkit/utils';
matrix({ scaleX: 2, translateX: 10 });A matrix() string. Reach for it when a value has to be interpolated as a matrix rather than as separate functions.
TRANSFORM_PROPS
const TRANSFORM_PROPS: readonly (keyof TransformProps)[];The ordered list of keys transform() reads.
Measuring
getOffsetSizes
getOffsetSizes(element: HTMLElement): { x, y, width, height, top, right, bottom, left }import { getOffsetSizes } from '@studiometa/js-toolkit/utils';
const box = getOffsetSizes(document.body);The element's box from its offset properties rather than from getBoundingClientRect() — so a transform the component itself applied does not move the measurement.
That is exactly what a drag or a tilt needs: the layout box is the frame of reference, and the transform is the output.
It is a layout read
Call it from the read phase — $read() — so it batches with every other measurement of the frame.
Applying
setClassesOrStyles
setClassesOrStyles(
el: HTMLElement,
value: string | string[] | Partial<CSSStyleDeclaration> | undefined,
method?: 'add' | 'remove',
): voidimport { setClassesOrStyles } from '@studiometa/js-toolkit/utils';
const el = document.body;
setClassesOrStyles(el, 'is-active'); // a class
setClassesOrStyles(el, ['is-active', 'is-open']); // several
setClassesOrStyles(el, { opacity: '0' }); // inline styles
setClassesOrStyles(el, 'is-active', 'remove'); // undo itApplies a value that may be either classes or inline styles, which is what lets transition() take one option in both forms.
An undefined value does nothing, so a caller with an optional state does not have to branch.
What is not here
addClass, removeClass, toggleClass, addStyle, removeStyle and animate are not shipped. el.classList and el.style say the first five, and time-based playback belongs to the separate ui-animation package.