JsonInput
Install: npm install @mantine/core@9.7.1 @mantine/hooks@9.7.1
Version and compatibility
Pinned Mantine Core 9.7.1 requires React and React DOM ^19.2.0 and matching @mantine/hooks@9.7.1, from the installed npm package's peerDependencies. Do not force it into React 18 or another incompatible version. Explain upgrade impact and agree on a plan with the project owner; do not hide conflicts with --force/--legacy-peer-deps. The native Provider enables theme.respectReducedMotion and uses forceColorScheme for light/dark.
Use case
Edit and format JSON text.
Native props used by this example
These props are extracted from the local typechecked JSX and grouped by their owning native component. This is not an exhaustive prop list; see pinned source signatures and inheritance below.
| Component prop | Explanation |
|---|---|
JsonInput.disabled | Disable user input/action; not equivalent to readOnly. |
JsonInput.error | Local error display; it does not run validation by itself. |
JsonInput.readOnly | Prevent editing while preserving the read-only interaction. |
JsonInput.label | Visible label or component-specific label content. |
JsonInput.defaultValue | Initial uncontrolled value, not a live controlled update. |
JsonInput.formatOnBlur | Format valid JSON when the input loses focus. |
JsonInput.autosize | Size the input based on its content. |
Interaction and state checks
Current scenarios: Default, Disabled, Invalid, Read only. Check actual behavior after selecting supported disabled/error/read-only scenarios; components without those native states do not receive invented universal props. Verify keyboard focus and exits, then connect changed values through the native callback signature.
Business integration boundary
Formatting and local JSON validity are not a server schema validator. Preserve invalid text until the user corrects it.
Host setup
Install pinned @mantine/core and @mantine/hooks, import @mantine/core/styles.css at the entry and use MantineProvider. The example's theme/variant are JGuang-authored host props, not universal native component APIs; forceColorScheme synchronizes the app theme. Native implementation source is a reading reference: use npm exports rather than copying internal engines. This batch covers Core, not dates/charts/forms extension packages. Detailed upstream prose remains English.
Runnable usage
import { useState } from 'react';
import * as M from '@mantine/core';
import '@mantine/core/styles.css';
function ComponentPreview({ variant = 'Default' }: { variant?: string }) {
const disabled = variant === "Disabled";
const invalid = variant === "Invalid";
const readOnly = variant === "Read only";
return <M.JsonInput disabled={disabled} error={invalid ? "Invalid JSON / JSON 格式错误" : undefined} readOnly={readOnly} label="JSON" defaultValue={'{"name":"JGuang"}'} formatOnBlur autosize />;
}
export default function Example({ variant = 'Default', theme = 'light' }: { variant?: string; theme?: 'light' | 'dark' }) {
return <M.MantineProvider forceColorScheme={theme} theme={{ respectReducedMotion: true }}><ComponentPreview variant={variant} /></M.MantineProvider>;
}
Preview states
Default, Disabled, Invalid, Read only
The example uses the native Mantine API. For supported input demos, change the local variant to Disabled, Invalid or Read only; these are example labels, not new component props. Keep the documented data, controlled values, stores and compound children when adapting the example.
Usage
JsonInput is based on the Textarea component.
It includes JSON validation logic and an option to format the input value on blur:
Loading state
Set loading prop to display a loading indicator. By default, the loader is displayed on the right side of the input.
You can change the position with the loadingPosition prop to 'left' or 'right'. This is useful for async operations like API calls, searches, or validations:
Controlled
import { useState } from 'react';
import { JsonInput } from '@mantine/core';
function Demo() {
const [value, setValue] = useState('');
return <JsonInput value={value} onChange={setValue} />;
}
Uncontrolled
JsonInput can be used with uncontrolled forms the same way as a native textarea element.
Set the name attribute to include json input value in FormData object on form submission.
To control the initial value in uncontrolled forms, use the defaultValue prop.
Example usage of uncontrolled JsonInput with FormData:
import { JsonInput } from '@mantine/core';
function Demo() {
return (
<form
onSubmit={(event) => {
event.preventDefault();
const formData = new FormData(event.currentTarget);
console.log('JSON input value:', formData.get('data'));
}}
>
<JsonInput
label="Enter JSON"
name="data"
defaultValue="{}"
formatOnBlur
/>
<button type="submit">Submit</button>
</form>
);
}
Custom serialization
You can provide custom serialize and deserialize functions to support data formats beyond standard JSON.
This is useful when you need to handle types like Date, Map, Set, undefined, or other non-JSON-serializable values.
The example below shows how to use superjson library to handle extended data types:
import { useState } from 'react';
import { JsonInput } from '@mantine/core';
import superjson from 'superjson';
function Demo() {
const [value, setValue] = useState(
superjson.stringify(
{
name: 'John Doe',
createdAt: new Date(),
tags: new Set(['admin', 'user']),
metadata: new Map([['role', 'developer']]),
},
null,
2
)
);
return (
<JsonInput
label="Extended JSON with superjson"
description="Supports Date, Map, Set, BigInt, RegExp, and more"
placeholder="Enter extended JSON"
value={value}
onChange={setValue}
serialize={(val) => superjson.stringify(val, null, 2)}
deserialize={superjson.parse}
validationError="Invalid extended JSON format"
formatOnBlur
autosize
minRows={6}
/>
);
}
The deserialize function must throw an error when the input is invalid. Both serialize and deserialize
functions are used for formatting when formatOnBlur is enabled.
Input props
Success state
Disabled state
Source-backed parameter reference
Implementation signatures and types are generated from the pinned local source. Optional props, native inherited types, union branches and never exclusions are preserved. A forwardRef implementation's ref is a React reference, not an additional business prop.
JsonInput(props)
export interface JsonInputProps extends Omit<TextareaProps, 'onChange'> {
/** Controlled component value */
value?: string;
/** Uncontrolled component default value */
defaultValue?: string;
/** Called when value changes */
onChange?: (value: string) => void;
/** Determines whether the value should be formatted on blur @default false */
formatOnBlur?: boolean;
/** Error message shown when the input value is invalid JSON (checked on blur). If not provided, a generic error state is shown. Takes precedence over the `error` prop when validation fails. */
validationError?: React.ReactNode;
/** Function to serialize value into a string for formatting. Called with (value, null, 2) where 2 is the indentation level. @default JSON.stringify */
serialize?: typeof JSON.stringify;
/** Function to deserialize string value for formatting and validation. Must throw an error if the string is invalid JSON. @default JSON.parse */
deserialize?: typeof JSON.parse;
/** Number of spaces to use as white space for formatting. Passed as the third argument to `serialize` function. @default 2 */
indentSpaces?: number;
}
export type JsonInputFactory = Factory<{
props: JsonInputProps;
ref: HTMLTextAreaElement;
stylesNames: __InputStylesNames;
}>;
export type __InputStylesNames = InputStylesNames | InputWrapperStylesNames;
export type InputStylesNames = 'input' | 'wrapper' | 'section' | 'bottomSection';
export type InputWrapperStylesNames =
| 'root'
| InputLabelStylesNames
| InputDescriptionStylesNames
| InputErrorStylesNames
| InputSuccessStylesNames;
Native and external types
External types remain defined by React or native dependencies, not manually expanded into guessed props. The installed version's TypeScript definitions are authoritative.
Factory<{
props: JsonInputProps;
ref: HTMLTextAreaElement;
stylesNames: __InputStylesNames;
}>
Omit<TextareaProps, 'onChange'>
TextareaProps
React.ReactNode
HTMLTextAreaElement
InputLabelStylesNames
InputDescriptionStylesNames
InputErrorStylesNames
InputSuccessStylesNames