JGuang

JsonInput

JsonInput · Mantine Core

Preview
npm install @mantine/core@9.7.1 @mantine/hooks@9.7.1

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 propExplanation
JsonInput.disabledDisable user input/action; not equivalent to readOnly.
JsonInput.errorLocal error display; it does not run validation by itself.
JsonInput.readOnlyPrevent editing while preserving the read-only interaction.
JsonInput.labelVisible label or component-specific label content.
JsonInput.defaultValueInitial uncontrolled value, not a live controlled update.
JsonInput.formatOnBlurFormat valid JSON when the input loses focus.
JsonInput.autosizeSize 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