@toolpad/utils
Version:
Shared utilities used by Toolpad packages.
127 lines (121 loc) • 4.35 kB
JavaScript
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
};
}
;