TimeFieldBase

Data Input

시간 입력과 시·분·오전/오후 선택 패널을 결합한 시간 필드.

Usage

시간을 직접 입력하거나 선택 패널에서 고르게 할 때 사용한다.

import

import

import { TimeFieldBase } from '@mildang/design-system/TimeField';

예제를 복사해 쓸 때 필요한 준비

@mildang/icons 를 따로 설치한다. DS 패키지에 아이콘 컴포넌트가 포함되지 않는다.

@mildang/styled-system 은 이 저장소에서 Panda 가 생성하는 산출물이다. 저장소 안에서는 turbo run ship 이후 쓸 수 있고, 패키지 소비자는 자기 Panda 산출물이나 다른 레이아웃 수단으로 바꿔야 한다.

API Reference

TimeFieldBase Props

Prop

Type

Default

autoComplete

string

지정 안 함

autoFocus

boolean

지정 안 함

className

string

지정 안 함

description

ReactNode

지정 안 함

editable

boolean

false

error

boolean

지정 안 함

formatDisplay

(value: string) => string

지정 안 함

fullWidth

boolean

지정 안 함

ghost

boolean

false

helperText

ReactNode

지정 안 함

hideHelperText

boolean

지정 안 함

inputContainerClassName

string

지정 안 함

inputElementClassName

string

지정 안 함

label

ReactNode

지정 안 함

minuteStep

1 | 5 | 10 | 15 | 30

지정 안 함

multiple

boolean

지정 안 함

name

string

지정 안 함

onBlur

FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>

지정 안 함

onChange

(value: string) => void

지정 안 함

onFocus

FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>

지정 안 함

onInvalid

FormEventHandler<HTMLInputElement | HTMLTextAreaElement>

지정 안 함

onKeyDown

KeyboardEventHandler<HTMLInputElement | HTMLTextAreaElement>

지정 안 함

onKeyUp

KeyboardEventHandler<HTMLInputElement | HTMLTextAreaElement>

지정 안 함

outEndAdornment

ReactNode

지정 안 함

renderPicker

(props: { value?: string; onChange: (value: string) => void; onClose: () => void; }) => ReactNode

지정 안 함

required

boolean

지정 안 함

showFooter

boolean

지정 안 함

sideContent

ReactNode

지정 안 함

size

"xs" | "sm" | "md" | "lg" | "xl"

md

startAdornment

ReactNode

지정 안 함

success

boolean

지정 안 함

timeMode

"HH AA" | "HH:MM AA" | "HH:MM:SS AA" | "HH:MM:SS.MSS AA" | "HH:MM:SS.MSS" | "HH:MM:SS" | "HH:MM" | "HH" | "MM:SS.MSS" | "MM:SS" | "SS.MSS"

HH:MM

triggerIcon

ReactNode

지정 안 함

value

string

지정 안 함

warning

boolean

지정 안 함

TimeInput

Prop

Type

Default

autoComplete

string

지정 안 함

autoFocus

boolean

지정 안 함

className

string

지정 안 함

description

ReactNode

지정 안 함

endAdornment

ReactNode

지정 안 함

error

boolean

지정 안 함

fullWidth

boolean

지정 안 함

ghost

boolean

false

helperText

ReactNode

지정 안 함

hideHelperText

boolean

지정 안 함

inputContainerClassName

string

지정 안 함

inputElementClassName

string

지정 안 함

label

ReactNode

지정 안 함

multiple

boolean

지정 안 함

name

string

지정 안 함

onBlur

FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>

지정 안 함

onClockClick

() => void

지정 안 함

onFocus

FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>

지정 안 함

onInvalid

FormEventHandler<HTMLInputElement | HTMLTextAreaElement>

지정 안 함

onKeyDown

KeyboardEventHandler<HTMLInputElement | HTMLTextAreaElement>

지정 안 함

onKeyUp

KeyboardEventHandler<HTMLInputElement | HTMLTextAreaElement>

지정 안 함

outEndAdornment

ReactNode

지정 안 함

required

boolean

지정 안 함

sideContent

ReactNode

지정 안 함

size

"xs" | "sm" | "md" | "lg" | "xl"

md

startAdornment

ReactNode

지정 안 함

success

boolean

지정 안 함

value

string

지정 안 함

warning

boolean

지정 안 함

TimeMaskedInput

Prop

Type

Default

autoComplete

string

지정 안 함

autoFocus

boolean

지정 안 함

className

string

지정 안 함

description

ReactNode

지정 안 함

endAdornment

ReactNode

지정 안 함

error

boolean

지정 안 함

fullWidth

boolean

지정 안 함

ghost

boolean

false

helperText

ReactNode

지정 안 함

hideHelperText

boolean

지정 안 함

inputContainerClassName

string

지정 안 함

inputElementClassName

string

지정 안 함

label

ReactNode

지정 안 함

multiple

boolean

지정 안 함

name

string

지정 안 함

onBlur

FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>

지정 안 함

onChange

(value: string) => void

지정 안 함

onClockClick

() => void

지정 안 함

onFocus

FocusEventHandler<HTMLInputElement | HTMLTextAreaElement>

지정 안 함

onInvalid

FormEventHandler<HTMLInputElement | HTMLTextAreaElement>

지정 안 함

onKeyDown

KeyboardEventHandler<HTMLInputElement | HTMLTextAreaElement>

지정 안 함

onKeyUp

KeyboardEventHandler<HTMLInputElement | HTMLTextAreaElement>

지정 안 함

outEndAdornment

ReactNode

지정 안 함

required

boolean

지정 안 함

sideContent

ReactNode

지정 안 함

size

"xs" | "sm" | "md" | "lg" | "xl"

md

success

boolean

지정 안 함

timeMode

"HH AA" | "HH:MM AA" | "HH:MM:SS AA" | "HH:MM:SS.MSS AA" | "HH:MM:SS.MSS" | "HH:MM:SS" | "HH:MM" | "HH" | "MM:SS.MSS" | "MM:SS" | "SS.MSS"

HH:MM

value

string

지정 안 함

warning

boolean

지정 안 함

같은 패밀리

@mildang/design-system/TimeField 에서 같이 내보내는 컴포넌트다.

표시 형식

formatDisplay 를 넘기지 않으면 닫힌 입력에는 12시간제 + 오전/오후 표기가 자동으로 뜬다 (useFormatDateTime({ type: 'time' }) 내부가 hourCycle: 'h12' 를 쓴다). 시간 표시는 직접 포맷 함수를 만들지 않고 항상 DS 의 FormatDateTime / useFormatDateTime 를 거친다.

구성요소

컴포넌트역할
TimeFieldTanStack Form 필드로 쓰는 form-integrated wrapper (field.TimeField)
TimeFieldBaselabel / helperText / error / picker 를 통합한 standalone 필드
TimePicker오전·오후 / 시 / 분 3-column wheel + 선택적 footer(취소·확인). 다른 popover 안에도 조립 가능
TimeInputreadonly 트리거 인풋 (시계 아이콘 endAdornment). editable=false 경로에서 사용
TimeMaskedInputmaskito 마스크 트리거 인풋. editable=true 경로에서 사용

예제

입력과 선택 패널

평상시(닫힌) 상태의 완성형 시간 필드입니다. 열린 패널은 TimePicker 카드에서 따로 봅니다.

import { TimeFieldBase } from '@mildang/design-system/TimeField';

/**
 * 평상시(닫힌) 상태의 완성형 시간 필드.
 *
 * 예전에는 옆에 `TimePicker` 패널을 강제로 함께 세웠다. 트리거를 눌러야 열리는 UI 를
 * 억지로 열어 두면 실제 동작과 다른 그림이 되고, 카드 안에서 입력 위로 패널이 겹쳐
 * 깨진 것처럼 보였다(사용자 지적). 패널 자체는 `TimePicker` 카드가 따로 보여준다.
 */
export default function TimeFieldOverviewExample() {
  return <TimeFieldBase value="15:30" placeholder="시간 선택" />;
}

크기와 비활성 상태

xs부터 xl까지의 높이와 오류·비활성을 한 줄에서 비교합니다.

import { TimeFieldBase } from '@mildang/design-system/TimeField';
import { HStack } from '@mildang/styled-system/jsx';

export default function TimeFieldSizesExample() {
  return (
    <HStack alignItems="flex-end" gap="12" flexWrap="wrap">
      <TimeFieldBase size="xs" value="09:00" />
      <TimeFieldBase size="sm" value="09:00" />
      <TimeFieldBase size="md" value="09:00" />
      <TimeFieldBase size="lg" value="09:00" />
      <TimeFieldBase size="xl" value="09:00" />
      <TimeFieldBase size="md" value="09:00" error />
      <TimeFieldBase size="md" value="09:00" disabled />
    </HStack>
  );
}

editable 모드 비교

import { Stack } from '@mildang/styled-system/jsx';
import { css } from '@mildang/styled-system/css';
import { Text } from '@mildang/design-system/Text';
import { TimeFieldBase } from '@mildang/design-system/TimeField';
import { useState } from 'react';

/* ─── Helper ─── */

function TimeFieldDemo(props: React.ComponentProps<typeof TimeFieldBase>) {
  const [value, setValue] = useState(props.value);
  return (
    <div className={css({ width: '240px' })}>
      <TimeFieldBase {...props} value={value} onChange={setValue} />
      <Text variant="caption-lg-medium" color="neutral.text.lowest" className={css({ mt: '8px' })}>
        value: {value ?? '(없음)'}
      </Text>
    </div>
  );
}

const TimeFieldBaseCombinationsExample = () => (
    <Stack gap="20" className={css({ width: '280px' })}>
      <Stack gap="4">
        <Text variant="caption-lg-medium" color="neutral.text.lowest">
          readOnly (기본) — 클릭 시 피커 열림
        </Text>
        <TimeFieldDemo placeholder="시간 선택" fullWidth />
      </Stack>

      <Stack gap="4">
        <Text variant="caption-lg-medium" color="neutral.text.lowest">
          editable — 타이핑 + 피커 아이콘
        </Text>
        <TimeFieldDemo editable placeholder="00:00" fullWidth />
      </Stack>
    </Stack>
  );

export default TimeFieldBaseCombinationsExample;

minuteStep 비교

import { HStack, Stack } from '@mildang/styled-system/jsx';
import { useState } from 'react';
import { Text } from '@mildang/design-system/Text';
import { css } from '@mildang/styled-system/css';
import { TimeFieldBase } from '@mildang/design-system/TimeField';

function MinuteStepItem({ step }: { step: 1 | 5 | 10 | 15 | 30 }) {
  const [value, setValue] = useState('14:00');
  return (
    <Stack gap="4">
      <Text variant="caption-lg-medium" color="neutral.text.lowest">
        minuteStep={step}
      </Text>
      <div className={css({ width: '180px' })}>
        <TimeFieldBase
          value={value}
          onChange={setValue}
          minuteStep={step}
          placeholder="시간 선택"
          fullWidth
        />
      </div>
    </Stack>
  );
}

const TimeFieldBaseMinuteStepsExample = () => (
    <HStack gap="16" flexWrap="wrap">
      {([1, 5, 10, 15, 30] as const).map((step) => (
        <MinuteStepItem key={step} step={step} />
      ))}
    </HStack>
  );

export default TimeFieldBaseMinuteStepsExample;

formatDisplay (24시간 표시)

import { TimeFieldBase } from '@mildang/design-system/TimeField';
import { useState } from 'react';
import { css } from '@mildang/styled-system/css';
import { Text } from '@mildang/design-system/Text';

/* ─── Helper ─── */

function TimeFieldDemo(props: React.ComponentProps<typeof TimeFieldBase>) {
  const [value, setValue] = useState(props.value);
  return (
    <div className={css({ width: '240px' })}>
      <TimeFieldBase {...props} value={value} onChange={setValue} />
      <Text variant="caption-lg-medium" color="neutral.text.lowest" className={css({ mt: '8px' })}>
        value: {value ?? '(없음)'}
      </Text>
    </div>
  );
}

const TimeFieldBaseCustomFormatExample = () => <TimeFieldDemo value="15:30" formatDisplay={(v) => v} placeholder="HH:mm" fullWidth />;

export default TimeFieldBaseCustomFormatExample;

사이즈 비교

import { HStack, Stack } from '@mildang/styled-system/jsx';
import { Text } from '@mildang/design-system/Text';
import { css } from '@mildang/styled-system/css';
import { TimeFieldBase } from '@mildang/design-system/TimeField';

const TimeFieldBaseSizesExample = () => (
    <Stack gap="12">
      {(['xs', 'sm', 'md', 'lg', 'xl'] as const).map((size) => (
        <HStack key={size} gap="8" alignItems="center">
          <Text variant="caption-lg-medium" color="neutral.text.lowest" className={css({ width: '60px' })}>
            {size}
          </Text>
          <div className={css({ width: '200px' })}>
            <TimeFieldBase value="15:30" size={size} placeholder="시간 선택" fullWidth />
          </div>
        </HStack>
      ))}
    </Stack>
  );

export default TimeFieldBaseSizesExample;

InputFieldBase 상속 Props

import { Stack } from '@mildang/styled-system/jsx';
import { css } from '@mildang/styled-system/css';
import { TimeFieldBase } from '@mildang/design-system/TimeField';
import { Text } from '@mildang/design-system/Text';
import CalendarIcon from '@mildang/icons/react/calendar';

const TimeFieldBaseInheritedPropsExample = () => (
    <Stack gap="20" className={css({ width: '280px' })}>
      <TimeFieldBase value="15:30" label="label + required" required fullWidth />
      <TimeFieldBase
        value="15:30"
        label="sideContent"
        sideContent={
          <Text variant="caption-lg-medium" color="neutral.text.lowest">
            선택사항
          </Text>
        }
        fullWidth
      />
      <TimeFieldBase value="15:30" label="helperText" helperText="안내 텍스트" fullWidth />
      <TimeFieldBase label="error" error helperText="필수 항목입니다." placeholder="시간 선택" fullWidth />
      <TimeFieldBase value="23:30" label="warning" warning helperText="warning" fullWidth />
      <TimeFieldBase value="09:00" label="success" success helperText="success" fullWidth />
      <TimeFieldBase value="10:30" label="disabled" disabled fullWidth />
      <TimeFieldBase value="15:30" label="triggerIcon" triggerIcon={<CalendarIcon />} fullWidth />
    </Stack>
  );

export default TimeFieldBaseInheritedPropsExample;

Demo

import type { ComponentProps } from 'react';
import { TimeFieldBase } from '@mildang/design-system/TimeField';
import { useState } from 'react';
import { css } from '@mildang/styled-system/css';
import { Text } from '@mildang/design-system/Text';

/* ─── Helper ─── */

function TimeFieldDemo(props: React.ComponentProps<typeof TimeFieldBase>) {
  const [value, setValue] = useState(props.value);
  return (
    <div className={css({ width: '240px' })}>
      <TimeFieldBase {...props} value={value} onChange={setValue} />
      <Text variant="caption-lg-medium" color="neutral.text.lowest" className={css({ mt: '8px' })}>
        value: {value ?? '(없음)'}
      </Text>
    </div>
  );
}

const STORY_DEFAULT_ARGS = { ...({}), ...({}) } as ComponentProps<typeof TimeFieldDemo>;

const TimeFieldBaseDemoExampleRender = (args: ComponentProps<typeof TimeFieldDemo>) => <TimeFieldDemo {...args} />;

export default function TimeFieldBaseDemoExample(props: Partial<ComponentProps<typeof TimeFieldDemo>>) {
  const mergedProps = { ...STORY_DEFAULT_ARGS, ...props } as ComponentProps<typeof TimeFieldDemo>;
  return TimeFieldBaseDemoExampleRender(mergedProps);
}

WithValue

import type { ComponentProps } from 'react';
import { TimeFieldBase } from '@mildang/design-system/TimeField';
import { useState } from 'react';
import { css } from '@mildang/styled-system/css';
import { Text } from '@mildang/design-system/Text';

/* ─── Helper ─── */

function TimeFieldDemo(props: React.ComponentProps<typeof TimeFieldBase>) {
  const [value, setValue] = useState(props.value);
  return (
    <div className={css({ width: '240px' })}>
      <TimeFieldBase {...props} value={value} onChange={setValue} />
      <Text variant="caption-lg-medium" color="neutral.text.lowest" className={css({ mt: '8px' })}>
        value: {value ?? '(없음)'}
      </Text>
    </div>
  );
}

const STORY_DEFAULT_ARGS = { ...({}), ...({}) } as ComponentProps<typeof TimeFieldDemo>;

const TimeFieldBaseWithValueExampleRender = (args: ComponentProps<typeof TimeFieldDemo>) => <TimeFieldDemo {...args} value="15:30" />;

export default function TimeFieldBaseWithValueExample(props: Partial<ComponentProps<typeof TimeFieldDemo>>) {
  const mergedProps = { ...STORY_DEFAULT_ARGS, ...props } as ComponentProps<typeof TimeFieldDemo>;
  return TimeFieldBaseWithValueExampleRender(mergedProps);
}