import type { JsonTypes } from "atom.io/foundations/json" import { isJson } from "atom.io/foundations/json" import { actUponStore, arbitrary } from "atom.io/internal" import { jsonRefinery } from "atom.io/introspection" import { type CSSProperties, type FC, type ReactElement, useContext, } from "react" import { button } from "../Button.tsx" import { ElasticInput } from "../elastic-input/index.ts" import { DevtoolsContext } from "../store.ts" import type { SetterOrUpdater } from "." import { SubEditors } from "." import type { JsonEditorComponents } from "./default-components.tsx" import { NonJsonEditor } from "./editors-by-type/non-json.tsx" export type JsonEditorProps_INTERNAL = { data: T set: SetterOrUpdater name?: string | undefined rename?: ((newKey: string) => void) | undefined remove?: (() => void) | undefined recast?: (newType: keyof JsonTypes) => void path?: ReadonlyArray isReadonly?: (path: ReadonlyArray) => boolean isHidden?: (path: ReadonlyArray) => boolean className?: string | undefined style?: CSSProperties | undefined Header?: FC<{ data: T }> | undefined Components: JsonEditorComponents isOpen?: boolean setIsOpen?: (newValue: boolean) => void testid?: string | undefined } export const JsonEditor_INTERNAL = ({ data, set, name, rename, remove, recast, path = [], isReadonly = () => false, isHidden = () => false, className, style, Components, isOpen, setIsOpen, testid, }: JsonEditorProps_INTERNAL): ReactElement | null => { const { openCloseAllTX, store } = useContext(DevtoolsContext) const dataIsJson = isJson(data) const refined = jsonRefinery.refine(data) ?? { type: `non-json`, data, } const SubEditor = dataIsJson ? SubEditors[refined.type as keyof JsonTypes] : NonJsonEditor const disabled = isReadonly(path) const dataIsTree = refined.type === `array` || refined.type === `object` const dataIsExpandable = dataIsTree && isOpen !== undefined && setIsOpen let stringified: string try { stringified = JSON.stringify(data) } catch (_) { stringified = `?` } return isHidden(path) ? null : (
{remove || dataIsExpandable ? ( { actUponStore(store, openCloseAllTX, arbitrary())(path, isOpen) return false }} setIsOpen={setIsOpen} disabled={!dataIsExpandable} /> ) : null} {rename && ( { rename(e.target.value) }} disabled={disabled} data-testid={`${testid}-rename`} /> )} {dataIsTree ? ( <> {isOpen !== undefined && setIsOpen ? ( {stringified} ) : null} {recast ? ( ) : null} ) : ( <> {recast && dataIsJson ? ( ) : null} )}
{remove ? ( { remove() }} testid={`${testid}-delete`} > ) : null}
{dataIsTree && isOpen !== false ? ( ) : null}
) }