UNPKG

@mskcc/carbon-react

Version:

Carbon react components for the MSKCC DSM

149 lines (135 loc) 4.39 kB
/** * MSKCC 2021, 2024 */ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var FeatureFlags$1 = require('@carbon/feature-flags'); var PropTypes = require('prop-types'); var React = require('react'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes); var React__default = /*#__PURE__*/_interopDefaultLegacy(React); /** * Our FeatureFlagContext is used alongside the FeatureFlags component to enable * or disable feature flags in a given React tree */ const FeatureFlagContext = /*#__PURE__*/React.createContext(FeatureFlags$1.FeatureFlags); /** * Supports an object of feature flag values with the `flags` prop, merging them * along with the current `FeatureFlagContext` to provide consumers to check if * a feature flag is enabled or disabled in a given React tree */ function FeatureFlags(_ref) { let { children, flags = {} } = _ref; const parentScope = React.useContext(FeatureFlagContext); const [prevParentScope, setPrevParentScope] = React.useState(parentScope); const [scope, updateScope] = React.useState(() => { const scope = FeatureFlags$1.createScope(flags); scope.mergeWithScope(parentScope); return scope; }); if (parentScope !== prevParentScope) { const scope = FeatureFlags$1.createScope(flags); scope.mergeWithScope(parentScope); updateScope(scope); setPrevParentScope(parentScope); } // We use a custom hook to detect if any of the keys or their values change // for flags that are passed in. If they have changed, then we re-create the // FeatureFlagScope using the new flags useChangedValue(flags, isEqual, changedFlags => { const scope = FeatureFlags$1.createScope(changedFlags); scope.mergeWithScope(parentScope); updateScope(scope); }); return /*#__PURE__*/React__default["default"].createElement(FeatureFlagContext.Provider, { value: scope }, children); } FeatureFlags.propTypes = { children: PropTypes__default["default"].node, /** * Provide the feature flags to enabled or disabled in the current React tree */ flags: PropTypes__default["default"].objectOf(PropTypes__default["default"].bool) }; /** * This hook will store previous versions of the given `value` and compare the * current value to the previous one using the `compare` function. If the * compare function returns true, then the given `callback` is invoked in an * effect. * * @param {any} value * @param {Function} compare * @param {Function} callback */ function useChangedValue(value, compare, callback) { const initialRender = React.useRef(false); const savedCallback = React.useRef(callback); const [prevValue, setPrevValue] = React.useState(value); if (!compare(prevValue, value)) { setPrevValue(value); } React.useEffect(() => { savedCallback.current = callback; }); React.useEffect(() => { // We only want the callback triggered after the first render if (initialRender.current) { savedCallback.current(prevValue); } }, [prevValue]); React.useEffect(() => { initialRender.current = true; }, []); } /** * Access whether a given flag is enabled or disabled in a given * FeatureFlagContext * * @returns {boolean} */ function useFeatureFlag(flag) { const scope = React.useContext(FeatureFlagContext); return scope.enabled(flag); } /** * Access all feature flag information for the given FeatureFlagContext * * @returns {FeatureFlagScope} */ function useFeatureFlags() { return React.useContext(FeatureFlagContext); } /** * Compare two objects and determine if they are equal. This is a shallow * comparison since the objects we are comparing are objects with boolean flags * from the flags prop in the `FeatureFlags` component * * @param {object} a * @param {object} b * @returns {boolean} */ function isEqual(a, b) { if (a === b) { return true; } for (const key of Object.keys(a)) { if (a[key] !== b[key]) { return false; } } for (const key of Object.keys(b)) { if (b[key] !== a[key]) { return false; } } return true; } exports.FeatureFlagContext = FeatureFlagContext; exports.FeatureFlags = FeatureFlags; exports.useFeatureFlag = useFeatureFlag; exports.useFeatureFlags = useFeatureFlags;