next-yak
Version:
next-yak is a CSS-in-JS solution tailored for Next.js that seamlessly combines the expressive power of styled-components syntax with efficient build-time extraction of CSS using Next.js's built-in CSS configuration
55 lines (48 loc) • 1.55 kB
text/typescript
import { ClassNames } from "../cssLiteral.js";
import { RuntimeStyleProcessor } from "../publicStyledApi.js";
/**
* This is an internal helper function to merge relevant props of a native element with a css prop.
* It's automatically added when using the `css` prop in a JSX element.
* e.g.:
* ```tsx
* <p
* className="foo"
* css={css`
* color: green;
* `}
* {...{ style: { padding: "30px" }}}
* />
*/
export const mergeCssProp = (
relevantProps: {
className?: string;
style?: Record<string, string>;
} & Record<string, unknown>,
cssProp: RuntimeStyleProcessor<unknown> | false | null | undefined,
) => {
const classNames = new ClassNames(relevantProps.className);
const existingStyle = relevantProps.style;
const style = existingStyle ? { ...existingStyle } : {};
// a falsy css prop applies no styles, e.g. `css={on && css`...`}` with `on` false
if (cssProp) {
cssProp({}, classNames, style);
}
// Forward all other props (onClick, aria-*, id, …) untouched and only
// override className/style with the merged result — the transform already
// built `relevantProps` in JSX attribute order, so this preserves overrides.
const result: Record<string, unknown> & {
className?: string;
style?: Record<string, string>;
} = { ...relevantProps };
if (Object.keys(style).length > 0) {
result.style = style;
} else {
delete result.style;
}
if (classNames.value) {
result.className = classNames.value;
} else {
delete result.className;
}
return result;
};