数字输入框
数字输入组件为用户提供一个用于整数值的字段,以及用于增加或减少值的按钮。
简介
数字输入是一种 UI 元素,它接受用户输入的数值。MUI Base 的数字输入组件是原生 HTML <input type="number">
的可自定义替代品,它解决了其原生对应物常见的可用性问题,例如
- 步进按钮在不同浏览器中的外观和行为不一致
- 允许某些非数字字符 ('e', '+', '-', '.') 并静默丢弃其他字符
- 与辅助技术不兼容且可访问性功能有限
组件
import { Unstable_NumberInput as NumberInput } from '@mui/base/Unstable_NumberInput';
以下演示展示了如何创建一个数字输入组件,应用一些样式,并使用 onChange
prop 将最新值写入状态变量
结构
MUI Base 数字输入组件由四个 slot 组成
root
:一个包含其他内部 slot 的外部<div>
input
:一个<input>
元素incrementButton
:一个用于增加值的<button>
decrementButton
:一个用于减少值的<button>
<div class="base-NumberInput-root">
<button class="base-NumberInput-decrementButton" />
<button class="base-NumberInput-incrementButton" />
<input class="base-NumberInput-input" />
</div>
自定义结构
使用 slots
prop 来覆盖 root slot 或任何内部 slot
<NumberInput
slots={{
root: 'aside',
incrementButton: CustomButton,
decrementButton: CustomButton,
}}
/>
使用 slotProps
prop 将自定义 props 传递给内部 slot。以下代码片段
- 将名为
my-num-input
的 CSS class 应用于 input slot - 将
direction
prop 传递给 increment 和 decrement button slot 中的CustomButton
组件
<NumberInput
slotProps={{
input: { className: 'my-num-input' },
incrementButton: { direction: 'UP' },
decrementButton: { direction: 'DOWN' },
}}
/>
Hook
import { unstable_useNumberInput as useNumberInput } from '@mui/base/unstable_useNumberInput';
useNumberInput
hook 允许您将数字输入的功能应用于完全自定义的组件。它返回要放置在自定义组件上的 props,以及表示组件内部状态的字段。
Hook 不支持 slot props,但它们支持 customization props。
这是一个使用 useNumberInput
hook 和所有必需 props 构建的自定义组件的示例
这是一个使用 hook 的“紧凑型”数字输入组件的示例,该组件仅包含步进按钮。在此演示中,onChange
用于将组件的最新值写入状态变量。
Current value:
自定义
最小值和最大值
使用 min
和 max
props 定义可接受值的范围。如果您只定义其中一个,则范围的另一端将是开放式的。
// accepts any value:
<NumberInput />
// only accepts values between -10 and 10:
<NumberInput min={-10} max={10} />
// only accepts values greater than 0:
<NumberInput min={0} />
下面的演示展示了一个可接受范围为 1 到 99 的数字输入
增量步长
使用 step
prop 定义在增加或减少值时值变化的粒度。例如,如果 min={0}
且 step={2}
,则组件的有效值将为 0、2、4 等,因为值只能以 2 的增量更改。
// valid values: 0, 2, 4, 6, 8...
<NumberInput min={0} step={2} />
当输入字段处于焦点时,您可以输入超出有效范围的值。一旦输入字段失去焦点,该值将根据 min
、max
和 step
进行 clamp。
Shift 乘数
在与步进按钮交互时按住 Shift 键会将乘数(默认为 10 倍)应用于每个步长的值变化。
您可以使用 shiftMultiplier
prop 自定义此行为。在以下代码片段中,如果在单击 increment 按钮时按住 Shift 键,则值将从 0 变为 5 变为 10,依此类推。
<NumberInput min={0} step={1} shiftMultiplier={5} />
事件
数字输入组件和 hook 提供了两个 props——onChange
和 onInputChange
——它们接受组件值更改时的事件处理程序。
onChange
onChange
接受一个自定义事件处理程序,该处理程序使用两个参数调用:底层事件和最新的“clamped”值。
onChange: (
event: React.FocusEvent<HTMLInputElement> | React.PointerEvent | React.KeyboardEvent,
value: number | undefined,
) => void;
当 <input>
元素失去焦点且值已更改时,或在单击步进按钮时调用它。这是在值已根据 min
、max
或 step
props 进行 clamp 之后。
// ✅ Works
<NumberInput
onChange={(event, newValue) => console.log(`${event.type} event: the new value is ${newValue}`)}
/>
// ❌ Doesn't work
<NumberInput
slotProps={{
input: {
// expects a native input change event handler, newValue is always undefined
onChange: (event, newValue) => { ... },
},
}}
/>
onInputChange
onInputChange
接受传递给 <input>
元素的本机输入更改处理程序
onInputChange: React.ChangeEventHandler<HTMLInputElement>;
每当文本框的值更改时都会调用它——例如,在键入到其中的每个击键上,在应用 clamp 之前。
换句话说,event.target.value
可能包含超出范围的值或非数字字符。
// ✅ Works
<NumberInput
onInputChange={(event) => console.log(`the input value is: ${event.target.value}`)}
/>
// ✅ Works
<NumberInput
slotProps={{
input: {
// this exactly the same as onInputChange above
onChange: (event) => console.log(`the input value is: ${event.target.value}`),
},
}}
/>
// ❌ Doesn't work
<NumberInput
slotProps={{
input: {
// This will throw "unknown event handler"
onInputChange: () => {},
},
}}
/>
装饰
您可以使用 startAdornment
和 endAdornment
props 分别为数字输入添加前缀或后缀。装饰对于显示度量单位(如重量或货币)以及值非常有用。