UNPKG

@toolpad/utils

Version:

Shared utilities used by Toolpad packages.

127 lines (121 loc) 4.35 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createGlobalState = createGlobalState; exports.createProvidedContext = createProvidedContext; exports.default = getComponentDisplayName; exports.interleave = interleave; exports.useAssertedContext = useAssertedContext; exports.useNonNullableContext = useNonNullableContext; exports.useTraceUpdates = useTraceUpdates; var React = _interopRequireWildcard(require("react")); var ReactIs = _interopRequireWildcard(require("react-is")); var _jsxRuntime = require("react/jsx-runtime"); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } /** * Like `Array.prototype.join`, but for React nodes. */ function interleave(items, separator) { const result = []; for (let i = 0; i < items.length; i += 1) { if (i > 0) { if (ReactIs.isElement(separator)) { result.push(/*#__PURE__*/React.cloneElement(separator, { key: `separator-${i}` })); } else { result.push(separator); } } const item = items[i]; result.push(item); } return /*#__PURE__*/(0, _jsxRuntime.jsx)(React.Fragment, { children: result }); } /** * Consume a context but throw when used outside of a provider. */ function useNonNullableContext(context, name) { const maybeContext = React.useContext(context); if (maybeContext === null || maybeContext === undefined) { throw new Error(`context "${name}" was used without a Provider`); } return maybeContext; } /** * Context that throws when used outside of a provider. */ function createProvidedContext(name) { const context = /*#__PURE__*/React.createContext(undefined); const useContext = () => useNonNullableContext(context, name); return [useContext, context.Provider]; } function useAssertedContext(context) { const value = React.useContext(context); if (value === undefined) { throw new Error('context was used without a Provider'); } return value; } /** * Debugging tool that logs updates to props. */ function useTraceUpdates(prefix, props) { const prev = React.useRef(props); React.useEffect(() => { const changedProps = {}; for (const key of Object.keys(props)) { if (!Object.is(prev.current[key], props[key])) { changedProps[key] = props[key]; } } if (Object.keys(changedProps).length > 0) { // eslint-disable-next-line no-console console.log(`${prefix} changed props:`, changedProps); } prev.current = props; }); } // eslint-disable-next-line @typescript-eslint/no-explicit-any function getComponentDisplayName(Component) { if (typeof Component === 'string') { return Component || 'Unknown'; } return Component.displayName || Component.name; } /** * Create a shared state to be used across the application. Returns a useState hook that * is synchronized on the same state between all instances where it is called. */ function createGlobalState(initialState) { let state = initialState; const listeners = []; const subscribe = cb => { listeners.push(cb); return () => { const index = listeners.indexOf(cb); listeners.splice(index, 1); }; }; const getState = () => state; const setState = newState => { state = typeof newState === 'function' ? newState(state) : newState; listeners.forEach(cb => cb(state)); }; const useValue = () => React.useSyncExternalStore(subscribe, getState, getState); const useState = () => { const value = useValue(); return [value, setState]; }; return { getState, setState, useValue, useState, subscribe }; }