UNPKG

@dash-ui/react

Version:

React components and hooks for dash-ui

185 lines (159 loc) 6.22 kB
"use strict"; exports.__esModule = true; exports.Inline = Inline; exports.useCSS = useCSS; exports.useGlobal = useGlobal; exports.useThemes = useThemes; exports.useTokens = useTokens; var _styles = /*#__PURE__*/require("@dash-ui/styles"); var _passiveLayoutEffect = /*#__PURE__*/_interopRequireDefault( /*#__PURE__*/require("@react-hook/passive-layout-effect")); var React = /*#__PURE__*/_interopRequireWildcard( /*#__PURE__*/require("react")); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const __reactCreateElement__ = React.createElement; const IS_BROWSER = typeof document !== "undefined"; const useInsertionEffect = typeof React.useInsertionEffect === "function" ? React.useInsertionEffect : _passiveLayoutEffect.default; /** * A component for creating an inline `<style>` tag that is unmounted when * the component unmounts. * * @param root0 * @param root0.css * @param root0.styles */ function Inline({ styles, css: input }) { const css = styles.one(input).css(); return !css ? null : /*#__PURE__*/ // We don't want data-cache, data-dash props here because // we don't want this to be moved into the head of the document // during SSR hydration __reactCreateElement__("style", { dangerouslySetInnerHTML: { __html: css }, nonce: styles.dash.sheet.nonce ? styles.dash.sheet.nonce : void 0 }); } /** * A hook for inserting transient global styles into the DOM. These styles * will be injected when the hook mounts and flushed when the hook unmounts. * * @param styles - A Dash `styles` instance * @param value - Global CSS to inject into the DOM and flush when the hook unmounts * @param deps - A dependency array that will force the hook to re-insert global styles * @example * const Component = () => { * const [userFontSize, setUserFontSize] = React.useState('100%') * * useGlobal( * ` * html { * font-size: ${userFontSize}; * } * `, * [userFontSize] * ) * } */ function useGlobal(styles, value, deps) { // inserts global styles into the dom and cleans up its // styles when the component is unmounted useInsertionEffect(() => value ? styles.insertGlobal(value) : noop, deps = deps && deps.concat(styles)); if (!IS_BROWSER && value) { styles.insertGlobal(value); } } /** * A hook for inserting transient CSS tokens into the DOM. These tokens * will be injected when the hook mounts and flushed when the hook unmounts. * * @param styles - A Dash `styles` instance * @param value - CSS tokens to inject into the DOM and flush when the hook unmounts * @param deps - A dependency array that will force the hook to re-insert tokens * @example * const Component = () => { * const [userFontSize, setUserFontSize] = React.useState('100%') * * useTokens( * styles, * {fontSize: userFontSize}, * [userFontSize] * ) * } */ function useTokens(styles, value, deps) { useInsertionEffect(() => value ? styles.insertTokens(value) : noop, deps = deps && deps.concat(styles)); if (!IS_BROWSER && value) { styles.insertTokens(value); } } /** * A hook for inserting transient CSS theme tokens into the DOM. These tokens * will be injected when the hook mounts and flushed when the hook unmounts. * * @param styles - A Dash `styles` instance * @param value - Themes to inject into the DOM and flush when the hook unmounts * @param deps - A dependency array that will force the hook to re-insert themes * @example * const Component = () => { * const [color, setColor] = React.useState('aliceblue') * * useThemes( * styles, * { * dark: {color} * }, * [color] * ) * } */ function useThemes(styles, value, deps) { useInsertionEffect(() => value ? styles.insertThemes(value) : noop, deps = deps && deps.concat(styles)); if (!IS_BROWSER && value) { styles.insertThemes(value); } } /** * A hook for performantly and reliably inserting CSS into the DOM in React 18 using the * `useInsertionEffect` hook. * * @param styles - A Dash `styles` instance * @param classNames - A map of class names to CSS generators * @see https://github.com/reactwg/react-18/discussions/110 * @example * ```tsx * const classes = useCSS(styles, { * root: styles.one({ display: 'flex' }) * }) * * return <div className={classes.root}/> * ``` */ function useCSS(styles, classNames) { function insertClasses() { for (const className in classNames) { const style = classNames[className]; if (typeof style === "function" && "css" in style) { style(); } else { styles.cls(style); } } } useInsertionEffect(insertClasses); if (!IS_BROWSER) { insertClasses(); } const classes = {}; for (const className in classNames) { const style = classNames[className]; classes[className] = styles.dash.key + "-" + styles.hash(typeof style === "function" && "css" in style ? style.css() : (0, _styles.compileStyles)(style, styles.tokens)); } return classes; } function noop() {}