UNPKG

@fluentui/react-northstar

Version:
223 lines (217 loc) 9.95 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.providerClassName = exports.Provider = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _noop2 = _interopRequireDefault(require("lodash/noop")); var _isBoolean2 = _interopRequireDefault(require("lodash/isBoolean")); var _isFunction2 = _interopRequireDefault(require("lodash/isFunction")); var _forEach2 = _interopRequireDefault(require("lodash/forEach")); var _isPlainObject2 = _interopRequireDefault(require("lodash/isPlainObject")); var _reactBindings = require("@fluentui/react-bindings"); var _styles = require("@fluentui/styles"); var PropTypes = _interopRequireWildcard(require("prop-types")); var React = _interopRequireWildcard(require("react")); var _utils = require("../../utils"); var _mergeProviderContexts = require("../../utils/mergeProviderContexts"); var _ProviderConsumer = require("./ProviderConsumer"); var _portalContext = require("./portalContext"); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(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; } var renderFontFaces = function renderFontFaces(renderer, theme) { if (!theme.fontFaces) { return; } var renderFontObject = function renderFontObject(font) { if (!(0, _isPlainObject2.default)(font)) { throw new Error("fontFaces must be objects, got: " + typeof font); } renderer.renderFont(font); }; theme.fontFaces.forEach(function (font) { renderFontObject(font); }); }; var renderStaticStyles = function renderStaticStyles(renderer, theme, siteVariables) { if (!theme.staticStyles) { return; } var renderObject = function renderObject(object) { (0, _forEach2.default)(object, function (style, selector) { renderer.renderGlobal(style, selector); }); }; theme.staticStyles.forEach(function (staticStyle) { if (typeof staticStyle === 'string') { renderer.renderGlobal(staticStyle); } else if ((0, _isPlainObject2.default)(staticStyle)) { renderObject(staticStyle); } else if ((0, _isFunction2.default)(staticStyle)) { var preparedSiteVariables = (0, _styles.mergeSiteVariables)(undefined, siteVariables); renderObject(staticStyle(preparedSiteVariables)); } else { throw new Error("staticStyles array must contain CSS strings, style objects, or style functions, got: " + typeof staticStyle); } }); }; var providerClassName = 'ui-provider'; /** * The Provider passes the CSS-in-JS renderer, theme styles and other settings to Fluent UI components. */ exports.providerClassName = providerClassName; var Provider = function Provider(props) { var children = props.children, className = props.className, design = props.design, overwrite = props.overwrite, styles = props.styles, variables = props.variables, telemetryRef = props.telemetryRef; var ElementType = (0, _reactBindings.getElementType)(props); var unhandledProps = (0, _reactBindings.useUnhandledProps)(Provider.handledProps, props); var rendersReactFragment = ElementType === React.Fragment; var telemetry = React.useMemo(function () { if (!telemetryRef) { return undefined; } if (!telemetryRef.current) { telemetryRef.current = new _reactBindings.Telemetry(); } return telemetryRef.current; }, [telemetryRef]); var consumedContext = (0, _reactBindings.useFluentContext)(); var incomingContext = overwrite ? _reactBindings.defaultContextValue : consumedContext; var createRenderer = React.useContext(_reactBindings.RendererContext); // Memoization of `inputContext` & `outgoingContext` is required to avoid useless notifications of components that // consume `useFluentContext()` on each render // @see https://reactjs.org/docs/context.html#caveats var inputContext = React.useMemo(function () { return { disableAnimations: props.disableAnimations, performance: props.performance, rtl: props.rtl, target: props.target, telemetry: telemetry, theme: props.theme }; }, [props.disableAnimations, props.performance, props.rtl, props.target, telemetry, props.theme]); var outgoingContext = React.useMemo(function () { return (0, _mergeProviderContexts.mergeProviderContexts)(createRenderer, incomingContext, inputContext); }, [createRenderer, incomingContext, inputContext]); var rtlProps = {}; // only add dir attribute for top level provider or when direction changes from parent to child if (consumedContext.rtl !== outgoingContext.rtl && (0, _isBoolean2.default)(outgoingContext.rtl)) { rtlProps.dir = outgoingContext.rtl ? 'rtl' : 'ltr'; } // Perf optimisation // Do not invoke styling layer is there is no need var _ref = rendersReactFragment ? { classes: { root: '' } } : (0, _reactBindings.unstable_getStyles)({ allDisplayNames: [Provider.displayName], className: providerClassName, primaryDisplayName: Provider.displayName, componentProps: {}, inlineStylesProps: { className: className, design: design, styles: styles, variables: variables }, disableAnimations: outgoingContext.disableAnimations, performance: outgoingContext.performance, renderer: outgoingContext.renderer, rtl: outgoingContext.rtl, theme: outgoingContext.theme, saveDebug: _noop2.default, telemetry: undefined }), classes = _ref.classes; var portalContextValue = React.useMemo(function () { return { className: classes.root }; }, [classes.root]); var RenderProvider = outgoingContext.renderer.Provider; (0, _reactBindings.useIsomorphicLayoutEffect)(function () { renderFontFaces(outgoingContext.renderer, props.theme); renderStaticStyles(outgoingContext.renderer, props.theme, outgoingContext.theme.siteVariables); if (props.target) { (0, _utils.setUpWhatInput)(props.target); } outgoingContext.renderer.registerUsage(); return function () { if (props.target) { (0, _utils.tryCleanupWhatInput)(props.target); } outgoingContext.renderer.unregisterUsage(); }; }, []); // If a Fragment is rendered: // - do not spread anything to an element - React.Fragment can only have `key` and `children` props // - as we don't apply styles "PortalContext.Provider" should not be rendered if (rendersReactFragment) { return /*#__PURE__*/React.createElement(RenderProvider, { target: outgoingContext.target }, /*#__PURE__*/React.createElement(_reactBindings.Unstable_FluentContextProvider, { value: outgoingContext }, /*#__PURE__*/React.createElement(React.Fragment, null, children))); } return /*#__PURE__*/React.createElement(RenderProvider, { target: outgoingContext.target }, /*#__PURE__*/React.createElement(_reactBindings.Unstable_FluentContextProvider, { value: outgoingContext }, /*#__PURE__*/React.createElement(_portalContext.PortalContext.Provider, { value: portalContextValue }, /*#__PURE__*/React.createElement(ElementType, (0, _extends2.default)({ className: classes.root }, rtlProps, unhandledProps), children)))); }; exports.Provider = Provider; Provider.displayName = 'Provider'; Provider.defaultProps = { theme: {} }; Provider.propTypes = { as: PropTypes.elementType, design: PropTypes.object, variables: PropTypes.oneOfType([PropTypes.object, PropTypes.func]), styles: PropTypes.oneOfType([PropTypes.object, PropTypes.func]), theme: PropTypes.shape({ siteVariables: PropTypes.object, componentVariables: PropTypes.object, componentStyles: PropTypes.objectOf(PropTypes.any), fontFaces: PropTypes.arrayOf(PropTypes.exact({ name: PropTypes.string.isRequired, paths: PropTypes.arrayOf(PropTypes.string), props: PropTypes.shape({ fontStretch: PropTypes.string, fontStyle: PropTypes.string, fontVariant: PropTypes.string, fontWeight: PropTypes.number, localAlias: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]), unicodeRange: PropTypes.string }) })), staticStyles: PropTypes.array, animations: PropTypes.objectOf(PropTypes.any) }), rtl: PropTypes.bool, disableAnimations: PropTypes.bool, // Heads Up! // Keep in sync with packages/react-bindings/src/styles/types.ts performance: PropTypes.shape({ enableSanitizeCssPlugin: PropTypes.bool, enableStylesCaching: PropTypes.bool, enableVariablesCaching: PropTypes.bool }), children: PropTypes.node.isRequired, overwrite: PropTypes.bool, target: PropTypes.object, telemetryRef: PropTypes.object }; Provider.handledProps = Object.keys(Provider.propTypes); Provider.Consumer = _ProviderConsumer.ProviderConsumer; //# sourceMappingURL=Provider.js.map