컴포넌트
Number Field
숫자를 입력하거나 증감 버튼으로 조절합니다.
설치
pnpm dlx ply-ui add number-field icon공통 설치 설정을 먼저 적용합니다.
사용법
min/max로 허용 범위, step으로 변화량을 지정할 수 있습니다.
value/onValueChange로 값에 반응하고, 증감 버튼에는 의미 있는 aria-label을 넣습니다.
구성
| 구성 요소 | 역할 |
|---|---|
Root | 숫자 값, 범위, 증감 단위를 관리합니다. |
Group | 입력과 증감 버튼을 묶습니다. |
Input | 숫자 입력 영역입니다. |
Increment / Decrement | 값을 늘리거나 줄입니다. |
ScrubArea | 드래그로 숫자를 바꿀 수 있는 영역입니다. |
범위와 증감 단위
min, max, step을 함께 지정합니다. 이 예제는 0에서 100까지 5씩 조절합니다.
구현 코드
components/ui/number-field.tsx
"use client";
import type { ComponentProps } from "react";
import { NumberField as Primitive } from "@base-ui/react/number-field";
import { withClassName } from "../../lib/cx";
import "./number-field.css";
// 동작과 접근성은 Base UI가 담당합니다. 이 파일은 스타일 연결만 담당합니다.
function NumberFieldRoot({
className,
...props
}: ComponentProps<typeof Primitive.Root>) {
return (
<Primitive.Root
{...props}
className={withClassName("rbx-field", className)}
/>
);
}
function NumberFieldGroup({
className,
...props
}: ComponentProps<typeof Primitive.Group>) {
return (
<Primitive.Group
{...props}
className={withClassName("rbx-number-group", className)}
/>
);
}
function NumberFieldInput({
className,
...props
}: ComponentProps<typeof Primitive.Input>) {
return (
<Primitive.Input
{...props}
className={withClassName("rbx-input", className)}
/>
);
}
function NumberFieldIncrement({
className,
...props
}: ComponentProps<typeof Primitive.Increment>) {
return (
<Primitive.Increment
{...props}
className={withClassName("rbx-icon-button", className)}
/>
);
}
function NumberFieldDecrement({
className,
...props
}: ComponentProps<typeof Primitive.Decrement>) {
return (
<Primitive.Decrement
{...props}
className={withClassName("rbx-icon-button", className)}
/>
);
}
function NumberFieldScrubArea({
className,
...props
}: ComponentProps<typeof Primitive.ScrubArea>) {
return (
<Primitive.ScrubArea
{...props}
className={withClassName("rbx-label", className)}
/>
);
}
// Root/Portal 등 스타일 없는 파트와 제네릭 API는 원본을 그대로 보존합니다.
export const NumberField = {
...Primitive,
Root: NumberFieldRoot,
Group: NumberFieldGroup,
Input: NumberFieldInput,
Increment: NumberFieldIncrement,
Decrement: NumberFieldDecrement,
ScrubArea: NumberFieldScrubArea,
};
components/ui/number-field.css
/* NumberField: 공통 구조는 theme.css, 컴포넌트 전용 조정은 아래에 작성합니다. */
.rbx-number-group {
display: flex;
gap: 4px;
}
.rbx-number-group .rbx-input {
text-align: center;
min-width: 0;
}