JsonInput

JsonInput (JSON 입력)

JsonInput 컴포넌트는 사용자로부터 JSON 데이터를 입력받는 컴포넌트예요. Textarea 컴포넌트를 기반으로 하며 JSON 검증 로직과 blur 시 입력 값 포맷팅 옵션을 포함해요.

출처: 문서

본문

JsonInput은 Textarea 컴포넌트를 기반으로 해요. JSON 검증 로직과 blur 시 입력 값을 포맷팅하는 옵션을 포함해요.

import { JsonInput } from '@mantine/core';

function Demo() {
  return (
    <JsonInput
      label="Your package.json"
      placeholder="Textarea will autosize to fit the content"
      validationError="Invalid JSON"
      formatOnBlur
      autosize
      minRows={4}
    />
  );
}

로딩 상태 (Loading state)

loading prop을 설정하면 로딩 인디케이터를 표시해요. 기본적으로 로더는 input 오른쪽에 표시돼요. loadingPosition prop을 'left'나 'right'로 바꿔 위치를 조절할 수 있어요.

import { JsonInput } from '@mantine/core';

function Demo() {
  return <JsonInput placeholder="Enter JSON" formatOnBlur autosize minRows={4} loading />;
}

제어 사용 (Controlled)

import { useState } from 'react';
import { JsonInput } from '@mantine/core';

function Demo() {
  const [value, setValue] = useState('');
  return <JsonInput value={value} onChange={setValue} />;
}

비제어 사용 (Uncontrolled)

JsonInput은 네이티브 textarea 요소처럼 비제어 폼에서도 사용할 수 있어요. 폼 제출 시 FormData 객체에 JSON 입력 값을 포함하려면 name 속성을 설정해요. 비제어 폼에서 초기 값을 제어하려면 defaultValue prop을 사용해요.

FormData와 함께 비제어 JsonInput을 사용하는 예시:

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>
  );
}

커스텀 직렬화

표준 JSON을 넘어서는 데이터 포맷을 지원하려면 커스텀 serialize와 deserialize 함수를 제공할 수 있어요. Date, Map, Set, undefined 또는 다른 JSON 직렬화 불가능한 값을 다뤄야 할 때 유용해요.

아래 예시는 확장 데이터 타입을 처리하기 위해 superjson 라이브러리를 사용하는 방법을 보여 줘요.

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}
    />
  );
}

deserialize 함수는 입력이 유효하지 않을 때 에러를 던져야 해요. serialize와 deserialize 함수는 formatOnBlur가 활성화되었을 때 포맷팅에 모두 사용돼요.

Input props

JsonInput 컴포넌트는 Input과 Input.Wrapper 컴포넌트의 기능과 모든 textarea 요소 props를 지원해요. JsonInput 문서는 컴포넌트가 지원하는 모든 기능을 담고 있지 않아요. 사용 가능한 모든 기능은 Input 문서를 참고해요.

import { JsonInput } from '@mantine/core';

function Demo() {
  return (
    <JsonInput
      label="Input label"
      description="Input description"
      placeholder="Input placeholder"
    />
  );
}

성공 상태 (Success state)

success prop으로 성공 메시지를 표시할 수 있어요.

import { JsonInput } from '@mantine/core';

function Demo() {
  return <JsonInput label="JSON config" placeholder="JSON config" success="Valid JSON" />;
}

비활성 상태 (Disabled state)

import { JsonInput } from '@mantine/core';

function Demo() {
  return (
    <JsonInput disabled defaultValue='{ "a": 1, "B": 2 }' label="Disabled" placeholder="Disabled" />
  );
}

Styles API

JsonInput은 Styles API를 지원해요. classNames prop으로 내부 요소에 스타일을 추가할 수 있어요.

주요 선택자는 다음과 같아요.

  • wrapper – Input의 루트 요소
  • input – input 요소
  • section – 왼쪽·오른쪽 섹션
  • bottomSection – input border 아래쪽에 렌더링되는 하단 섹션 요소
  • root – 루트 요소
  • label – 라벨 요소
  • required – 라벨 안에 렌더링되는 필수 별표 요소
  • description – 설명 요소
  • error – 오류 요소
  • success – 성공 요소

요소 ref 가져오기

import { useRef } from 'react';
import { JsonInput } from '@mantine/core';

function Demo() {
  const ref = useRef<HTMLTextAreaElement>(null);
  return <JsonInput ref={ref} />;
}

접근성 (Accessibility)

JsonInput을 label prop 없이 사용하면 스크린 리더가 제대로 인지하지 못해요.

import { JsonInput } from '@mantine/core';

// Inaccessible input – screen reader will not announce it properly
function Demo() {
  return <JsonInput />;
}

aria-label을 설정하면 input을 접근 가능하게 만들 수 있어요. 이 경우 라벨은 보이지 않지만 스크린 리더가 읽어줘요.

import { JsonInput } from '@mantine/core';

// Accessible input – it has aria-label
function Demo() {
  return <JsonInput aria-label="My input" />;
}

label prop이 설정되면 input은 접근 가능하며 aria-label을 설정할 필요가 없어요.

import { JsonInput } from '@mantine/core';

// Accessible input – it has associated label element
function Demo() {
  return <JsonInput label="My input" />;
}

더 알아보기 (Learn more)

  • Input — 입력 컴포넌트 기반 문서
  • Textarea — 텍스트 영역 컴포넌트