AIFT Design
Components

FieldButton

폼과 연동되는 필드형 버튼(headless) 패턴

기본 export FieldButton은 레이블·설명·오류 메시지와 메인 버튼을 한 덩어리로 제공합니다. buttonProps로 클릭·aria-label 등 버튼 속성을 넘깁니다. 값 배열·hidden input이 필요하면 values, onValuesChange, name을 함께 쓰면 됩니다.

커스텀 레이아웃이 필요할 때는 FieldButtonRoot, FieldButtonButton 등 headless 부품을 직접 조합할 수 있습니다.

기본 사용법

'use client';import FieldButton, {  FieldButtonPlaceholder,  FieldButtonValue,} from '@aift/ui/FieldButton';import { useState } from 'react';export default function FieldButtonPreviewExample() {  const [selected, setSelected] = useState('');  return (    <div className="max-w-md">      <FieldButton        values={selected ? [selected] : []}        onValuesChange={(next) => setSelected(next[0] ?? '')}        buttonProps={{          onClick: () => setSelected('서울'),          'aria-label': '알림 표시',        }}        showClearButton      >        {selected ? (          <FieldButtonValue>{selected}</FieldButtonValue>        ) : (          <FieldButtonPlaceholder>            값을 입력하려면 클릭하세요          </FieldButtonPlaceholder>        )}      </FieldButton>    </div>  );}

Label

레이블을 추가할 수 있습니다.

'use client';import FieldButton, { FieldButtonPlaceholder } from '@aift/ui/FieldButton';export default function FieldButtonLabelExample() {  return (    <div className="max-w-md space-y-6">      <FieldButton        label="레이블"        buttonProps={{ type: 'button', onClick: () => alert('클릭') }}      >        <FieldButtonPlaceholder>          값을 입력하려면 클릭하세요.        </FieldButtonPlaceholder>      </FieldButton>    </div>  );}

Message

invaliderrorMessage는 오류 상태를 표시합니다.

이 필드는 유효하지 않습니다.
'use client';import FieldButton, { FieldButtonPlaceholder } from '@aift/ui/FieldButton';export default function FieldButtonMessageExample() {  return (    <div className="max-w-md space-y-6">      <FieldButton        invalid        errorMessage="이 필드는 유효하지 않습니다."        buttonProps={{ type: 'button', onClick: () => alert('클릭') }}      >        <FieldButtonPlaceholder>          값을 입력하려면 클릭하세요.        </FieldButtonPlaceholder>      </FieldButton>    </div>  );}

Required (Dot)

required가 true이면 레이블 옆에 필수 표시 도트가 나타납니다.

'use client';import FieldButton, { FieldButtonPlaceholder } from '@aift/ui/FieldButton';export default function FieldButtonRequiredExample() {  return (    <div className="max-w-md space-y-6">      <FieldButton        required        label="필수 입력"        buttonProps={{ type: 'button', onClick: () => alert('클릭') }}      >        <FieldButtonPlaceholder>          값을 입력하려면 클릭하세요.        </FieldButtonPlaceholder>      </FieldButton>    </div>  );}

Disabled

disabled는 버튼을 막고 클리어 버튼을 숨기며, hidden input도 제출되지 않습니다. readOnly는 조작만 막고 hidden 값은 유지할 수 있습니다.

'use client';import { useState } from 'react';import FieldButton, { FieldButtonPlaceholder } from '@aift/ui/FieldButton';export default function FieldButtonDisabledExample() {  return (    <div className="max-w-md space-y-6">      <FieldButton        disabled        buttonProps={{ type: 'button', onClick: () => alert('클릭') }}      >        <FieldButtonPlaceholder>          입력 불가능한 상태입니다.        </FieldButtonPlaceholder>      </FieldButton>      <FieldButton        readOnly        buttonProps={{ type: 'button', onClick: () => alert('클릭') }}      >        <FieldButtonPlaceholder>          입력 불가능한 상태입니다.        </FieldButtonPlaceholder>      </FieldButton>    </div>  );}

Color

TextField와 동일하게 color( white | gray )로 메인 버튼 배경을 바꿀 수 있습니다. 세부 스타일은 buttonProps.className으로 덮어쓸 수 있습니다.

'use client';import FieldButton, { FieldButtonPlaceholder } from '@aift/ui/FieldButton';export default function FieldButtonColorExample() {  return (    <div className="max-w-md space-y-6">      <FieldButton        color="white"        buttonProps={{ type: 'button', onClick: () => alert('클릭') }}      >        <FieldButtonPlaceholder>흰색 배경</FieldButtonPlaceholder>      </FieldButton>      <FieldButton        color="gray"        buttonProps={{ type: 'button', onClick: () => alert('클릭') }}      >        <FieldButtonPlaceholder>회색 배경</FieldButtonPlaceholder>      </FieldButton>    </div>  );}

React Hook Form

useControllerfieldvalues / onValuesChange / name을 맞추면 제출·검증과 연동할 수 있습니다.

'use client';import { useController, useForm } from 'react-hook-form';import FieldButton, {  FieldButtonPlaceholder,  FieldButtonValue,} from '@aift/ui/FieldButton';import { Button } from '@aift/ui/Button';import { useState } from 'react';interface FormData {  region: string;}export default function FieldButtonReactHookFormExample() {  const {    reset,    handleSubmit,    formState: { errors, isSubmitting },    control,  } = useForm<FormData>({    mode: 'onSubmit',    reValidateMode: 'onChange',    defaultValues: { region: '' },  });  const { field } = useController({    name: 'region',    control,    rules: { required: '지역을 선택해 주세요.' },  });  const [submitted, setSubmitted] = useState<FormData | null>(null);  const selected = field.value;  return (    <form      onSubmit={handleSubmit((data) => setSubmitted(data))}      className="max-w-md space-y-4"    >      <FieldButton        required        label="지역"        name={field.name}        values={selected ? [selected] : []}        onValuesChange={(next) => field.onChange(next[0] ?? '')}        invalid={!!errors.region}        errorMessage={errors.region?.message as string | undefined}        showClearButton={!!selected}        buttonProps={{          type: 'button',          onBlur: field.onBlur,          onClick: () => field.onChange('서울'),          'aria-label': '지역 선택',        }}      >        {selected ? (          <FieldButtonValue>{selected}</FieldButtonValue>        ) : (          <FieldButtonPlaceholder>클릭하여 지역 선택</FieldButtonPlaceholder>        )}      </FieldButton>      <div className="flex gap-2">        <Button type="button" variant="outlined" onClick={() => reset()}>          초기화        </Button>        <Button          type="submit"          disabled={isSubmitting}          variant="surface"          color="primary"        >          제출        </Button>      </div>      {submitted && (        <p className="text-sm font-semibold text-neutral-80">          선택한 지역: {submitted.region}        </p>      )}    </form>  );}

Props

컴포넌트역할
FieldButtonRootvalues, onValuesChange, name, disabled, readOnly, invalid 및 루트 포인터 상태
FieldButtonButton메인 트리거 버튼(포커스·active 등)
FieldButtonClearButtononValuesChange([]) 호출
FieldButtonHiddenInputvalueIndex에 해당하는 hidden input
FieldButtonDescription보조 설명
FieldButtonErrorMessage오류 영역(aria-live)

useFieldButtonContext로 동일 컨텍스트의 props를 커스텀 레이아웃에 붙일 수 있습니다.

On this page