UNPKG

xstate-helpers

Version:

A collection of helpers for XState (with React).

193 lines (166 loc) • 5.81 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var React = require('react'); var ReactDOM = require('react-dom'); function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; } function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n["default"] = e; return Object.freeze(n); } var React__default = /*#__PURE__*/_interopDefault(React); var ReactDOM__default = /*#__PURE__*/_interopDefault(ReactDOM); const LOCAL_STORAGE_KEY_IS_ENABLED = 'xstate-helpers::isEnabled'; const LOCAL_STORAGE_KEY_OVERRIDE_OPTIONS = 'xstate-helpers::overrideOptions'; // declare global { const XStateInspectLoader = ({ children, initialIsEnabled = false, options, wrapperElement, forceEnabled, styles, stylesIframe }) => { const [loading, setLoading] = React__default["default"].useState(true); const [overrideOptions, _setOverrideOptions] = React__default["default"].useState(() => getItem(LOCAL_STORAGE_KEY_OVERRIDE_OPTIONS, {})); const setOverrideOptions = value => { _setOverrideOptions(value); setItem(LOCAL_STORAGE_KEY_OVERRIDE_OPTIONS, value); }; const [isEnabled, _setIsEnabled] = React__default["default"].useState(() => forceEnabled != null ? forceEnabled : getItem(LOCAL_STORAGE_KEY_IS_ENABLED, initialIsEnabled)); const setIsEnabled = value => { _setIsEnabled(value); setItem(LOCAL_STORAGE_KEY_IS_ENABLED, value); }; React__default["default"].useEffect(() => { if (forceEnabled !== undefined) { setIsEnabled(forceEnabled); } }, [forceEnabled]); const optionsRef = React__default["default"].useRef(options); React__default["default"].useEffect(() => { // expose an interface for setting open/closed directly on console const XStateInspector = { enable: () => { setIsEnabled(true); }, disable: () => { setIsEnabled(false); }, overrideOptions: (overrideOptions = {}) => { setOverrideOptions(overrideOptions); return { ...optionsRef.current, ...overrideOptions }; } }; window.XStateInspector = XStateInspector; }, []); const finalOptions = { ...options, ...overrideOptions }; React__default["default"].useEffect(() => { let active = true; // keep track if this effect was cleaned up Promise.resolve().then(function () { return /*#__PURE__*/_interopNamespace(require('@xstate/inspect')); }).then(({ inspect }) => { if (!active || !isEnabled) { return; } if (wrapperElement) { if (typeof wrapperElement === 'string') { // eslint-disable-next-line wrapperElement = document.querySelector(wrapperElement); if (!wrapperElement) { console.error('Cannot initialize XStateInspectorLoader, invalid wrapperElement selector given'); return; } } } else { // no wrapper given, we make our own wrapperElement = document.createElement('div'); document.body.insertBefore(wrapperElement, document.body.firstChild); } ReactDOM__default["default"].render( /*#__PURE__*/React__default["default"].createElement(XStateInspector, { styles, stylesIframe, inspect, options: finalOptions }, null), wrapperElement); setLoading(false); }); return () => { active = false; if (wrapperElement && typeof wrapperElement !== 'string') { ReactDOM__default["default"].unmountComponentAtNode(wrapperElement); } }; }, [isEnabled, JSON.stringify(finalOptions)]); return isEnabled && loading ? null : /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, children); }; const defaultStyles = { height: '600px', overflow: 'hidden', overflowY: 'scroll' }; const defaultStylesIframe = { width: '100%', height: '5000px' }; const XStateInspector = ({ inspect, options, styles = defaultStyles, stylesIframe = defaultStylesIframe }) => { const ref = /*#__PURE__*/React__default["default"].createRef(); React__default["default"].useLayoutEffect(() => { const inspector = inspect({ iframe: options !== null && options !== void 0 && options.iframe ? options.iframe : () => ref.current, ...options }); return () => inspector === null || inspector === void 0 ? void 0 : inspector.disconnect(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [JSON.stringify(options)]); if ((options === null || options === void 0 ? void 0 : options.iframe) === false) { return null; } return /*#__PURE__*/React__default["default"].createElement('div', { style: styles }, /*#__PURE__*/React__default["default"].createElement('iframe', { ref, title: 'xstate-inspector', style: stylesIframe, 'data-xstate': true }, null)); }; function getItem(key, defaultValue) { let initialValue = undefined; try { initialValue = JSON.parse(localStorage.getItem(key)); } catch {} if (typeof initialValue === 'undefined' || initialValue === null) { return defaultValue; } else { return initialValue; } } function setItem(key, value) { try { localStorage.setItem(key, JSON.stringify(value)); } catch {} } exports.LOCAL_STORAGE_KEY_IS_ENABLED = LOCAL_STORAGE_KEY_IS_ENABLED; exports.LOCAL_STORAGE_KEY_OVERRIDE_OPTIONS = LOCAL_STORAGE_KEY_OVERRIDE_OPTIONS; exports.XStateInspectLoader = XStateInspectLoader;