UNPKG

@textea/json-viewer

Version:

Interactive Json Viewer, but not only a json viewer

424 lines (407 loc) 14.9 kB
import * as react from 'react'; import { CSSProperties, Dispatch, SetStateAction, ComponentType, FC } from 'react'; import { SxProps, Theme } from '@mui/material/styles'; type NamedColorspace = { scheme: string; author: string; } & Colorspace; type Colorspace = { base00: string; base01: string; base02: string; base03: string; base04: string; base05: string; base06: string; base07: string; base08: string; base09: string; base0A: string; base0B: string; base0C: string; base0D: string; base0E: string; base0F: string; }; declare const lightColorspace: NamedColorspace; declare const darkColorspace: NamedColorspace; type base16_Colorspace = Colorspace; type base16_NamedColorspace = NamedColorspace; declare const base16_darkColorspace: typeof darkColorspace; declare const base16_lightColorspace: typeof lightColorspace; declare namespace base16 { export { type base16_Colorspace as Colorspace, type base16_NamedColorspace as NamedColorspace, base16_darkColorspace as darkColorspace, base16_lightColorspace as lightColorspace }; } type Path = (string | number)[]; /** * @param path path to the target value * @param oldValue * @param newValue */ type JsonViewerOnChange = <U = unknown>(path: Path, oldValue: U, newValue: U) => void; /** * @param path path to the target value * @param value the value to be copied * @param copy the function to copy the value to clipboard */ type JsonViewerOnCopy = <U = unknown>(path: Path, value: U, copy: (value: string) => Promise<void>) => unknown | Promise<unknown>; /** * @param path path to the target value * @param value the value to be selected */ type JsonViewerOnSelect = <U = unknown>(path: Path, value: U) => void; /** * @param path path to the parent target where the value will be added */ type JsonViewerOnAdd = (path: Path) => void; /** * @param path path to the target value * @param value the value to be deleted */ type JsonViewerOnDelete = <U = unknown>(path: Path, value: U) => void; interface DataItemProps<ValueType = unknown> { inspect: boolean; setInspect: Dispatch<SetStateAction<boolean>>; value: ValueType; prevValue: ValueType | undefined; path: Path; nestedIndex?: number; } type EditorProps<ValueType = unknown> = { path: Path; value: ValueType; setValue: Dispatch<ValueType>; abortEditing: () => void; commitEditing: (newValue: string) => void; }; /** * A data type definition, including methods for checking, serializing, and deserializing values, as well as components for rendering and editing values. * * @template ValueType The type of the value represented by this data type */ type DataType<ValueType = unknown> = { /** * Determines whether a given value belongs to this data type. * * @param value The value to check * @param path The path to the value within the input data structure * @returns `true` if the value belongs to this data type, `false` otherwise */ is: (value: unknown, path: Path) => boolean; /** * Convert the value of this data type to a string for editing */ serialize?: (value: ValueType) => string; /** * Converts a string representation of a value back to a value of this data type. * * Throws an error if the input is invalid, in which case the editor will ignore the change. */ deserialize?: (value: string) => ValueType; /** * The main component used to render a value of this data type. */ Component: ComponentType<DataItemProps<ValueType>>; /** * An optional custom editor component for editing values of this data type. * * You must also provide a `serialize` and `deserialize` function to enable this feature. */ Editor?: ComponentType<EditorProps<string>>; /** * An optional component to render before the value. * * In collapsed mode, it will still be rendered as a prefix. */ PreComponent?: ComponentType<DataItemProps<ValueType>>; /** * An optional component to render after the value. * * In collapsed mode, it will still be rendered as a suffix. */ PostComponent?: ComponentType<DataItemProps<ValueType>>; }; interface JsonViewerKeyRenderer extends FC<DataItemProps> { when(props: DataItemProps): boolean; } type JsonViewerTheme = 'light' | 'dark' | 'auto' | Colorspace; type JsonViewerProps<T = unknown> = { /** * Any value, `object`, `Array`, primitive type, even `Map` or `Set`. */ value: T; /** * Name of the root value * * @default "root" */ rootName?: false | string; /** * Color theme. * * @default 'light' */ theme?: JsonViewerTheme; className?: string; style?: CSSProperties; /** * [The `sx` prop](https://mui.com/system/getting-started/the-sx-prop/) lets you style elements inline, using values from the theme. * * @see https://mui.com/system/getting-started/the-sx-prop/ */ sx?: SxProps<Theme>; /** * Indent width for nested objects * * @default 3 */ indentWidth?: number; /** * Customize a key, if `keyRenderer.when` returns `true`. */ keyRenderer?: JsonViewerKeyRenderer; /** * Customize the definition of data types. * * @see https://viewer.textea.io/how-to/data-types */ valueTypes?: DataType<any>[]; /** * Whether enable add feature. * * @default false * */ enableAdd?: boolean | (<U = unknown>(path: Path, currentValue: U) => boolean); /** * Whether enable delete feature. * * @default false * */ enableDelete?: boolean | (<U = unknown>(path: Path, currentValue: U) => boolean); /** * Whether enable clipboard feature. * * @default true */ enableClipboard?: boolean; /** * Whether this value can be edited. * * Provide a function to customize this behavior by returning a boolean based on the value and path. * * @default false */ editable?: boolean | (<U = unknown>(path: Path, currentValue: U) => boolean); /** Callback when value changed. */ onChange?: JsonViewerOnChange; /** Callback when value copied, you can use it to customize the copy behavior.<br />\*Note: you will have to write the data to the clipboard by yourself. */ onCopy?: JsonViewerOnCopy; /** Callback when value selected. */ onSelect?: JsonViewerOnSelect; /** Callback when the add button is clicked. This is the function which implements the add feature. Please see the official demo for more details. */ onAdd?: JsonViewerOnAdd; /** Callback when the delete button is clicked. This is the function which implements the delete feature. Please see the official demo for more details. */ onDelete?: JsonViewerOnDelete; /** * Default inspect depth for nested objects. * _If the number is set too large, it could result in performance issues._ * * @default 5 */ defaultInspectDepth?: number; /** * Default inspect control for nested objects. * * Provide a function to customize which fields should be expanded by default. */ defaultInspectControl?: (path: Path, value: unknown) => boolean; /** * Hide items after reaching the count. * `Array` and `Object` will be affected. * * _If the number is set too large, it could result in performance issues._ * * @default 30 */ maxDisplayLength?: number; /** * When an integer value is assigned, arrays will be displayed in groups by count of the value. * Groups are displayed with bracket notation and can be expanded and collapsed by clicking on the brackets. * * @default 100 */ groupArraysAfterLength?: number; /** * Cut off the string after reaching the count. * Collapsed strings are followed by an ellipsis. * * String content can be expanded and collapsed by clicking on the string value. * * @default 50 */ collapseStringsAfterLength?: number | false; /** * Whether sort keys through `String.prototype.localeCompare()` * * @default false */ objectSortKeys?: boolean | ((a: string, b: string) => number); /** * Whether add quotes on keys. * * @default true */ quotesOnKeys?: boolean; /** * Whether display data type labels * * @default true */ displayDataTypes?: boolean; /** * Whether display the size of `Object`, `Array`, `Map` and `Set`. * * Provide a function to customize this behavior by returning a boolean based on the value and path. * * @default true */ displaySize?: boolean | ((path: Path, value: unknown) => boolean); /** * Whether display comma at the end of items. Just like valid JSON. * * @default false */ displayComma?: boolean; /** * Whether to highlight updates. * * @default false */ highlightUpdates?: boolean; }; /** * Apply a value to a given path of an object. */ declare function applyValue(input: any, path: (string | number)[], value: any): any; /** * Delete a value from a given path of an object. */ declare function deleteValue(input: any, path: (string | number)[], value: any): any; /** * Define custom data types for any data structure */ declare function defineDataType<ValueType = unknown>({ is, serialize, deserialize, Component, Editor, PreComponent, PostComponent }: { /** * Determines whether a given value belongs to this data type. * * @param value The value to check * @param path The path to the value within the input data structure * @returns `true` if the value belongs to this data type, `false` otherwise */ is: (value: unknown, path: Path) => boolean; /** * Convert the value of this data type to a string for editing */ serialize?: (value: ValueType) => string; /** * Converts a string representation of a value back to a value of this data type. * * Throws an error if the input is invalid, in which case the editor will ignore the change. */ deserialize?: (value: string) => ValueType; /** * The main component used to render a value of this data type. */ Component: ComponentType<DataItemProps<ValueType>>; /** * An optional custom editor component for editing values of this data type. * * You must also provide a `serialize` and `deserialize` function to enable this feature. */ Editor?: ComponentType<EditorProps<string>>; /** * An optional component to render before the value. * * In collapsed mode, it will still be rendered as a prefix. */ PreComponent?: ComponentType<DataItemProps<ValueType>>; /** * An optional component to render after the value. * * In collapsed mode, it will still be rendered as a suffix. */ PostComponent?: ComponentType<DataItemProps<ValueType>>; }): DataType<ValueType>; /** * A safe version of `JSON.stringify` that handles circular references and BigInts. * * *This function might be changed in the future to support more types. Use it with caution.* * * @param obj A JavaScript value, usually an object or array, to be converted. * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. * @returns */ declare function safeStringify(obj: any, space?: string | number): string; declare const booleanType: DataType<boolean>; declare const dateType: DataType<Date>; type EasyTypeConfig<Value> = Pick<DataType<Value>, 'is' | 'serialize' | 'deserialize'> & { type: string; colorKey: keyof Colorspace; displayTypeLabel?: boolean; Renderer: ComponentType<DataItemProps<Value>>; }; /** * Enhanced version of `defineDataType` that creates a `DataType` with editor and a optional type label. * It will take care of the color and all the necessary props. * * *All of the built-in data types are defined with this function.* * * @param config.type The type name. * @param config.colorKey The color key in the colorspace. ('base00' - 'base0F') * @param config.displayTypeLabel Whether to display the type label. * @param config.Renderer The component to render the value. */ declare function defineEasyType<Value>({ is, serialize, deserialize, type, colorKey, displayTypeLabel, Renderer }: EasyTypeConfig<Value>): DataType<Value>; declare const functionType: DataType<Function>; declare const nullType: DataType<null>; declare const nanType: DataType<number>; declare const floatType: DataType<number>; declare const intType: DataType<number>; declare const bigIntType: DataType<bigint>; declare const objectType: DataType<object>; declare const stringType: DataType<string>; declare const undefinedType: DataType<undefined>; type dataTypes_EasyTypeConfig<Value> = EasyTypeConfig<Value>; declare const dataTypes_bigIntType: typeof bigIntType; declare const dataTypes_booleanType: typeof booleanType; declare const dataTypes_dateType: typeof dateType; declare const dataTypes_defineEasyType: typeof defineEasyType; declare const dataTypes_floatType: typeof floatType; declare const dataTypes_functionType: typeof functionType; declare const dataTypes_intType: typeof intType; declare const dataTypes_nanType: typeof nanType; declare const dataTypes_nullType: typeof nullType; declare const dataTypes_objectType: typeof objectType; declare const dataTypes_stringType: typeof stringType; declare const dataTypes_undefinedType: typeof undefinedType; declare namespace dataTypes { export { type dataTypes_EasyTypeConfig as EasyTypeConfig, dataTypes_bigIntType as bigIntType, dataTypes_booleanType as booleanType, dataTypes_dateType as dateType, dataTypes_defineEasyType as defineEasyType, dataTypes_floatType as floatType, dataTypes_functionType as functionType, dataTypes_intType as intType, dataTypes_nanType as nanType, dataTypes_nullType as nullType, dataTypes_objectType as objectType, dataTypes_stringType as stringType, dataTypes_undefinedType as undefinedType }; } declare class JsonViewer { private props; private root?; static Component: <Value>(props: JsonViewerProps<Value>) => react.ReactElement; static DataTypes: typeof dataTypes; static Themes: typeof base16; static Utils: { applyValue: typeof applyValue; defineDataType: typeof defineDataType; deleteValue: typeof deleteValue; isCycleReference: (root: any, path: (string | number)[], value: unknown) => false | string; safeStringify: typeof safeStringify; }; constructor(props: JsonViewerProps); render(el?: string | Element): void; destroy(): void; } export { JsonViewer as default };