UNPKG

@tanstack/table-devtools

Version:

Devtools for TanStack Table.

247 lines (245 loc) 8.44 kB
import { useTableDevtoolsContext } from "../TableContextProvider.js"; import { useStyles } from "../styles/use-styles.js"; import { useTableStore } from "../useTableStore.js"; import { NoTableConnected } from "./NoTableConnected.js"; import { ThreeWayResizableSplit } from "./ThreeWayResizableSplit.js"; import { For, Show, createMemo, createSignal } from "solid-js"; import { className, createComponent, delegateEvents, effect, insert, memo, template } from "solid-js/web"; import { JsonTree } from "@tanstack/devtools-ui"; import { batch as batch$1 } from "@tanstack/solid-store"; //#region src/components/StatePanel.tsx var _tmpl$ = /*#__PURE__*/ template(`<div>`); var _tmpl$2 = /*#__PURE__*/ template(`<div>initialState`); var _tmpl$3 = /*#__PURE__*/ template(`<div><button type=button>`); var _tmpl$4 = /*#__PURE__*/ template(`<div>Atoms`); var _tmpl$5 = /*#__PURE__*/ template(`<div><button type=button>Reset to initialState`); var _tmpl$6 = /*#__PURE__*/ template(`<div>Store`); var _tmpl$7 = /*#__PURE__*/ template(`<div><button type=button></button><button type=button>Paste`); var _tmpl$8 = /*#__PURE__*/ template(`<div><div><span></span><span></span></div><div>`); function StatePanel() { const styles = useStyles(); const { table } = useTableDevtoolsContext(); const [initialStateCopied, setInitialStateCopied] = createSignal(false); const [storeCopied, setStoreCopied] = createSignal(false); const [pasteError, setPasteError] = createSignal(null); const tableState = useTableStore(() => table()?.store, (state) => state); const optionsStoreValue = useTableStore(() => table()?.optionsStore, (options) => options); const initialState = createMemo(() => { const tableInstance = table(); if (!tableInstance) return void 0; return tableInstance.initialState; }); const storeState = createMemo(() => { const tableInstance = table(); if (!tableInstance) return void 0; return tableState() ?? tableInstance.store.get(); }); const tableOptions = createMemo(() => { const tableInstance = table(); if (!tableInstance) return void 0; return optionsStoreValue() ?? tableInstance.options; }); const atomKeys = createMemo(() => Object.keys(storeState() ?? {})); const getAtomSource = (key) => { const options = tableOptions() ?? {}; const externalAtoms = options.atoms ?? {}; const externalState = options.state ?? {}; const hasExternalAtom = externalAtoms[key] != null; const hasExternalState = !hasExternalAtom && key in externalState && externalState[key] !== void 0; return hasExternalAtom ? "external-atom" : hasExternalState ? "external-state" : "internal"; }; const copyToClipboard = async (value, setCopied) => { try { await navigator.clipboard.writeText(JSON.stringify(value, null, 2)); setCopied(true); setTimeout(() => setCopied(false), 1500); } catch {} }; const handlePaste = async () => { const tableInstance = table(); if (!tableInstance) return; setPasteError(null); try { const text = await navigator.clipboard.readText(); const parsed = JSON.parse(text); if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) { setPasteError("Invalid state: must be a JSON object"); return; } const baseAtoms = tableInstance.baseAtoms; batch$1(() => { for (const [key, value] of Object.entries(parsed)) if (key in baseAtoms) baseAtoms[key].set(value); }); } catch (e) { setPasteError(e instanceof Error ? e.message : "Failed to parse clipboard"); } }; const handleReset = () => { table()?.reset(); }; return createComponent(Show, { get fallback() { return createComponent(NoTableConnected, { title: "State" }); }, get when() { return table(); }, get children() { var _el$ = _tmpl$(); insert(_el$, createComponent(ThreeWayResizableSplit, { get left() { return [ (() => { var _el$2 = _tmpl$2(); effect(() => className(_el$2, styles().sectionTitle)); return _el$2; })(), (() => { var _el$3 = _tmpl$3(), _el$4 = _el$3.firstChild; _el$4.$$click = () => copyToClipboard(initialState(), setInitialStateCopied); insert(_el$4, () => initialStateCopied() ? "Copied!" : "Copy"); effect((_p$) => { var _v$ = styles().buttonRow, _v$2 = styles().copyButton; _v$ !== _p$.e && className(_el$3, _p$.e = _v$); _v$2 !== _p$.t && className(_el$4, _p$.t = _v$2); return _p$; }, { e: void 0, t: void 0 }); return _el$3; })(), createComponent(JsonTree, { copyable: true, get value() { return initialState(); } }) ]; }, get middle() { return [ (() => { var _el$5 = _tmpl$4(); effect(() => className(_el$5, styles().sectionTitle)); return _el$5; })(), (() => { var _el$6 = _tmpl$5(), _el$7 = _el$6.firstChild; _el$7.$$click = handleReset; effect((_p$) => { var _v$3 = styles().buttonRow, _v$4 = styles().resetButton; _v$3 !== _p$.e && className(_el$6, _p$.e = _v$3); _v$4 !== _p$.t && className(_el$7, _p$.t = _v$4); return _p$; }, { e: void 0, t: void 0 }); return _el$6; })(), createComponent(For, { get each() { return atomKeys(); }, children: (key) => createComponent(AtomRow, { atomKey: key, source: () => getAtomSource(key), styles, value: () => storeState()?.[key] }) }) ]; }, get right() { return [ (() => { var _el$8 = _tmpl$6(); effect(() => className(_el$8, styles().sectionTitle)); return _el$8; })(), (() => { var _el$9 = _tmpl$7(), _el$0 = _el$9.firstChild, _el$1 = _el$0.nextSibling; _el$0.$$click = () => copyToClipboard(storeState(), setStoreCopied); insert(_el$0, () => storeCopied() ? "Copied!" : "Copy"); _el$1.$$click = handlePaste; effect((_p$) => { var _v$5 = styles().buttonRow, _v$6 = styles().copyButton, _v$7 = styles().pasteButton; _v$5 !== _p$.e && className(_el$9, _p$.e = _v$5); _v$6 !== _p$.t && className(_el$0, _p$.t = _v$6); _v$7 !== _p$.a && className(_el$1, _p$.a = _v$7); return _p$; }, { e: void 0, t: void 0, a: void 0 }); return _el$9; })(), memo(() => memo(() => !!pasteError())() && (() => { var _el$10 = _tmpl$(); insert(_el$10, pasteError); effect(() => className(_el$10, styles().pasteError)); return _el$10; })()), createComponent(JsonTree, { copyable: true, get value() { return storeState(); } }) ]; } })); effect(() => className(_el$, styles().panelScroll)); return _el$; } }); } function AtomRow(props) { const badgeLabel = () => { switch (props.source()) { case "external-atom": return "External Atom"; case "external-state": return "External State"; case "internal": return "Internal"; } }; const badgeClass = () => { const base = props.styles().atomBadge; switch (props.source()) { case "external-atom": return `${base} ${props.styles().atomBadgeExternalAtom}`; case "external-state": return `${base} ${props.styles().atomBadgeExternalState}`; case "internal": return `${base} ${props.styles().atomBadgeInternal}`; } }; return (() => { var _el$11 = _tmpl$8(), _el$12 = _el$11.firstChild, _el$13 = _el$12.firstChild, _el$14 = _el$13.nextSibling, _el$15 = _el$12.nextSibling; insert(_el$13, () => props.atomKey); insert(_el$14, badgeLabel); insert(_el$15, createComponent(JsonTree, { copyable: true, get value() { return props.value(); } })); effect((_p$) => { var _v$8 = props.styles().atomRow, _v$9 = props.styles().atomRowHeader, _v$0 = props.styles().atomKey, _v$1 = badgeClass(), _v$10 = props.styles().atomValue; _v$8 !== _p$.e && className(_el$11, _p$.e = _v$8); _v$9 !== _p$.t && className(_el$12, _p$.t = _v$9); _v$0 !== _p$.a && className(_el$13, _p$.a = _v$0); _v$1 !== _p$.o && className(_el$14, _p$.o = _v$1); _v$10 !== _p$.i && className(_el$15, _p$.i = _v$10); return _p$; }, { e: void 0, t: void 0, a: void 0, o: void 0, i: void 0 }); return _el$11; })(); } delegateEvents(["click"]); //#endregion export { StatePanel };