@quillforms/utils
Version:
Utils package for defining some helpful functions
68 lines (61 loc) • 1.72 kB
text/typescript
/**
* External dependencies
*/
// @ts-expect-error
import { __unsafe_useEmotionCache as useEmotionCache } from '@emotion/react';
import type { SerializedStyles } from '@emotion/serialize';
import { insertStyles } from '@emotion/utils';
// eslint-disable-next-line no-restricted-imports
import { cx as innerCx } from '@emotion/css';
/**
* WordPress dependencies
*/
import { useCallback } from 'react';
const isSerializedStyles = (o: any): o is SerializedStyles =>
typeof o !== 'undefined' &&
o !== null &&
['name', 'styles'].every((p) => typeof o[p] !== 'undefined');
/**
* Retrieve a `cx` function that knows how to handle `SerializedStyles`
* returned by the `@emotion/react` `css` function in addition to what
* `cx` normally knows how to handle. It also hooks into the Emotion
* Cache, allowing `css` calls to work inside iframes.
*
* @example
* import { css } from '@emotion/react';
*
* const styles = css`
* color: red
* `;
*
* function RedText( { className, ...props } ) {
* const cx = useCx();
*
* const classes = cx(styles, className);
*
* return <span className={classes} {...props} />;
* }
*/
export const useCx = () => {
const cache = useEmotionCache();
const cx = useCallback(
(...classNames: (SerializedStyles)[]) => {
if (cache === null) {
throw new Error(
'The `useCx` hook should be only used within a valid Emotion Cache Context'
);
}
return innerCx(
...classNames.map((arg) => {
if (isSerializedStyles(arg)) {
insertStyles(cache, arg, false);
return `${cache.key}-${arg.name}`;
}
return arg;
})
);
},
[cache]
);
return cx;
};