Number field
שדה קלט מספרי עם כפתורי הגדלה והקטנה.
- דפדפנים
- Chrome 123+Firefox 121+Safari 17.5+
- שכבה
- 1
- גודל חבילה דחוסה
- 2.58 kB
- מגבלת פריסה כפויה
- 0 ms
- מגבלת Axe
- 0
- תואם SSR
- כן
- חוזה מפורסם
- סביבת בדיקות
מגרש ניסויים
import { NumberField } from "@gunkin/uiify";
export default function Example() {
return (
<NumberField.Root className="" defaultValue={1} min={0} max={10}>
<NumberField.Decrement className="" aria-label="Decrease" />
<NumberField.Input className="" aria-label="Quantity" />
<NumberField.Increment className="" aria-label="Increase" />
</NumberField.Root>
);
}/* Number field — spinbutton with increment/decrement controls. */
@layer components {
[data-uiify-number-field] {
display: inline-flex;
align-items: stretch;
border: var(--border-width) solid var(--input);
border-radius: var(--radius-md);
background-color: var(--card);
overflow: hidden;
}
[data-uiify-number-field] > [role="spinbutton"],
[data-uiify-number-field] > [data-part="group"] > [role="spinbutton"] {
inline-size: 4rem;
min-block-size: 36px;
line-height: 1.25rem;
padding-block: 0;
padding-inline: var(--space-md);
border: none;
background: none;
color: var(--foreground);
font-size: var(--uiify-control-text);
text-align: center;
outline: none;
}
[data-uiify-number-field]:focus-within {
outline: 2px solid var(--ring);
outline-offset: 2px;
}
[data-uiify-number-field] :focus-visible {
outline: none;
}
[data-uiify-number-field] > button,
[data-uiify-number-field] > [data-part="group"] > button,
[data-uiify-number-field] > [data-part="group"] > [data-part="increment"],
[data-uiify-number-field] > [data-part="group"] > [data-part="decrement"] {
display: inline-flex;
align-items: center;
justify-content: center;
flex: none;
inline-size: 36px;
block-size: 36px;
padding: 0;
border: none;
border-inline-start: var(--border-width) solid var(--border);
background-color: transparent;
color: var(--foreground);
font-size: var(--text-lg);
line-height: 1;
cursor: pointer;
transition: var(--transition-colors);
}
[data-uiify-number-field] > button:empty::before,
[data-uiify-number-field] > [data-part="group"] > button:empty::before,
[data-uiify-number-field] > [data-part="group"] > [data-part="increment"]:empty::before,
[data-uiify-number-field] > [data-part="group"] > [data-part="decrement"]:empty::before {
display: block;
}
[data-uiify-number-field] > button:first-child:empty::before,
[data-uiify-number-field] > [data-part="group"] > button:first-child:empty::before,
[data-uiify-number-field]
> [data-part="group"]
> [data-part="decrement"]:first-child:empty::before {
content: "←" / "";
}
[data-uiify-number-field] > button:last-child:empty::before,
[data-uiify-number-field] > [data-part="group"] > button:last-child:empty::before,
[data-uiify-number-field]
> [data-part="group"]
> [data-part="increment"]:last-child:empty::before {
content: "→" / "";
}
[data-uiify-number-field]:dir(rtl) > button:empty::before,
[data-uiify-number-field]:dir(rtl) > [data-part="group"] > button:empty::before,
[data-uiify-number-field]:dir(rtl) > [data-part="group"] > [data-part="increment"]:empty::before,
[data-uiify-number-field]:dir(rtl) > [data-part="group"] > [data-part="decrement"]:empty::before {
scale: -1 1;
}
[data-uiify-number-field] > button:first-child,
[data-uiify-number-field] > [data-part="group"] > button:first-child,
[data-uiify-number-field] > [data-part="group"] > [data-part="decrement"]:first-child {
border-inline-start: none;
border-inline-end: var(--border-width) solid var(--border);
}
[data-uiify-number-field] > button:hover,
[data-uiify-number-field] > [data-part="group"] > button:hover,
[data-uiify-number-field] > [data-part="group"] > [data-part="increment"]:hover,
[data-uiify-number-field] > [data-part="group"] > [data-part="decrement"]:hover {
background-color: color-mix(in oklch, var(--foreground) 8%, transparent);
}
[data-uiify-number-field] > button[data-disabled],
[data-uiify-number-field] > [data-part="group"] > button[data-disabled],
[data-uiify-number-field] > [data-part="group"] > [data-part="increment"][data-disabled],
[data-uiify-number-field] > [data-part="group"] > [data-part="decrement"][data-disabled] {
opacity: 0.5;
cursor: not-allowed;
}
[data-uiify-number-field] > [data-part="group"] {
display: inline-flex;
align-items: stretch;
}
}import { NumberField } from "@gunkin/uiify";
export default function Example() {
return (
<NumberField.Root
className="
inline-flex items-stretch border-[length:var(--border-width)] border-solid border-input rounded-md bg-card
overflow-hidden focus-within:[outline:2px_solid_var(--ring)] focus-within:[outline-offset:2px]
"
defaultValue={1}
min={0}
max={10}
>
<NumberField.Decrement
className={
"inline-flex items-center justify-center flex-none [inline-size:36px] [block-size:36px] p-0 border-0 borde" +
"r-current border-none [border-inline-start-width:var(--border-width)] [border-inline-start-style:solid] [" +
"border-inline-start-color:var(--border)] bg-transparent text-foreground text-lg leading-none cursor-point" +
"er [transition:var(--transition-colors)] hover:[background-color:color-mix(in_oklch,_var(--foreground)_8%" +
",_transparent)] data-[disabled]:opacity-50 data-[disabled]:cursor-not-allowed empty:before:block first:[b" +
"order-inline-start:none] first:[border-inline-end-width:var(--border-width)] first:[border-inline-end-sty" +
"le:solid] first:[border-inline-end-color:var(--border)] empty:before:content-[\"←\"_/_\"\"] rtl:empty:before:" +
"[scale:-1_1]"
}
aria-label="Decrease"
/>
<NumberField.Input
className="
[inline-size:4rem] [min-block-size:36px] leading-5 py-0 px-md border-0 border-current border-none bg-none
bg-transparent text-foreground [font-size:var(--uiify-control-text)] text-center outline-none
"
aria-label="Quantity"
/>
<NumberField.Increment
className={
"inline-flex items-center justify-center flex-none [inline-size:36px] [block-size:36px] p-0 border-0 borde" +
"r-current border-none [border-inline-start-width:var(--border-width)] [border-inline-start-style:solid] [" +
"border-inline-start-color:var(--border)] bg-transparent text-foreground text-lg leading-none cursor-point" +
"er [transition:var(--transition-colors)] hover:[background-color:color-mix(in_oklch,_var(--foreground)_8%" +
",_transparent)] data-[disabled]:opacity-50 data-[disabled]:cursor-not-allowed empty:before:block empty:be" +
"fore:content-[\"→\"_/_\"\"] rtl:empty:before:[scale:-1_1]"
}
aria-label="Increase"
/>
</NumberField.Root>
);
}API
NumberField.Root
| מאפיין | טיפוס | ברירת מחדל | תיאור |
|---|---|---|---|
value | number | — | המספר הנוכחי, ההופך את השדה למבוקר. |
defaultValue | number | — | המספר ההתחלתי של השדה הלא מבוקר. |
onValueChange | (value: number | undefined) => void | — | נקראת עם המספר שפוענח, או undefined כשהקלט ריק. |
min | number | — | הערך הנמוך ביותר המותר. |
max | number | — | הערך הגבוה ביותר המותר. |
step | number | 1 | הכמות שמוסיפים או מפחיתים כפתורי ההגדלה וההקטנה. |
formatOptions | Intl.NumberFormatOptions | — | אפשרויות עבור Intl.NumberFormat המשמש להצגת הערך. |
clampValueOnBlur | boolean | true | מחזיר ערך החורג מהטווח אל בין min ו-max כשהקלט מאבד מיקוד. |
disabled | boolean | false | משבית את הקלט ואת שני כפתורי שינוי הערך. |
readOnly | boolean | false | הופך את הערך לקריאה בלבד, תוך שמירה על האפשרות למקד את הקלט. |
required | boolean | false | מסמן את הקלט כנדרש לצורך אימות הטופס. |
render | ReactElement | ((props, state) => ReactElement) | — | החלפת האלמנט המוצג תוך שימור ההתנהגות וקישורי הנגישות. |
NumberField.Group
| מאפיין | טיפוס | ברירת מחדל | תיאור |
|---|---|---|---|
children | ReactNode | — | הקלט וכפתורי שינוי הערך העטופים בקבוצה. |
render | ReactElement | ((props, state) => ReactElement) | — | החלפת האלמנט המוצג תוך שימור ההתנהגות וקישורי הנגישות. |
NumberField.Input
| מאפיין | טיפוס | ברירת מחדל | תיאור |
|---|---|---|---|
render | ReactElement | ((props, state) => ReactElement) | — | החלפת האלמנט המוצג תוך שימור ההתנהגות וקישורי הנגישות. |
NumberField.Increment
| מאפיין | טיפוס | ברירת מחדל | תיאור |
|---|---|---|---|
children | ReactNode | — | תוכן כפתור ההגדלה. |
render | ReactElement | ((props, state) => ReactElement) | — | החלפת האלמנט המוצג תוך שימור ההתנהגות וקישורי הנגישות. |
NumberField.Decrement
| מאפיין | טיפוס | ברירת מחדל | תיאור |
|---|---|---|---|
children | ReactNode | — | תוכן כפתור ההקטנה. |
render | ReactElement | ((props, state) => ReactElement) | — | החלפת האלמנט המוצג תוך שימור ההתנהגות וקישורי הנגישות. |
מקלדת
| מקש | פעולה |
|---|---|
| Tab | העברת המיקוד אל הפקד או ממנו |
| Enter / Space | הפעלה כשהפקד ממוקד (פקדים דמויי כפתור) |
נגישות
משתמש ב-HTML סמנטי ככל האפשר. בדקו את הסימון המרונדר במגרש הניסויים — ARIA נוסף רק כאשר האלמנטים המובנים אינם מספיקים.
נקודות חיבור לעיצוב
data-uiify-number-fielddata-disabled