'use client'
import { useState } from 'react'
import { SearchInput } from '@hina-ui/react'
export default function Demo() {
const [query, setQuery] = useState('狼と香辛料')
return (
<SearchInput
value={query}
onValueChange={setQuery}
aria-label="搜索"
placeholder="搜索作品"
className="w-72"
/>
)
}
tsx
用法
import { SearchInput } from '@hina-ui/react'
ts
搜索输入框起始处带搜索图标,有内容时末尾出现清除按钮,value / onValueChange 绑定关键词。按 Enter 调用 onSearch 并传入当前值,按 Esc 清空。未声明的属性都会传给 input。
上次提交:无
'use client'
import { useState } from 'react'
import { SearchInput, Stack, Text } from '@hina-ui/react'
export default function Demo() {
const [query, setQuery] = useState('')
const [submitted, setSubmitted] = useState('')
return (
<Stack className="w-72">
<SearchInput
value={query}
onValueChange={setQuery}
aria-label="搜索"
placeholder="搜索作品"
onSearch={setSubmitted}
/>
<Text tone="muted">上次提交:{submitted || '无'}</Text>
</Stack>
)
}
tsx
示例
加载中
loading 把搜索图标换成加载指示器,用于展示搜索请求正在进行。
import { SearchInput } from '@hina-ui/react'
export default function Demo() {
return <SearchInput defaultValue="星见" loading aria-label="搜索" className="w-72" />
}
tsx
尺寸
三档尺寸与输入框相同。
import { SearchInput, Stack } from '@hina-ui/react'
export default function Demo() {
return (
<Stack className="w-72">
<SearchInput size="sm" defaultValue="星见" aria-label="小号" />
<SearchInput size="md" defaultValue="星见" aria-label="中号" />
<SearchInput size="lg" defaultValue="星见" aria-label="大号" />
</Stack>
)
}
tsx
形态
primary 带边框、背景与阴影;secondary 使用浅色背景;bare 背景透明,不绘制边框、阴影、悬停底色或容器聚焦环,尺寸与内边距仍由原有设置控制。
bare 保留禁用状态与 aria-invalid;错误信息可由 FormField 显示。附属按钮保留自身的悬停与键盘聚焦反馈。
import { SearchInput, Stack } from '@hina-ui/react'
export default function Demo() {
return (
<Stack className="w-full max-w-xs">
<SearchInput variant="primary" aria-label="primary" placeholder="primary" />
<SearchInput variant="secondary" aria-label="secondary" placeholder="secondary" />
<SearchInput variant="bare" aria-label="bare" placeholder="bare" />
</Stack>
)
}
tsx
状态
disabled 不可编辑。关闭 clearable 后不显示清除按钮。
import { SearchInput, Stack } from '@hina-ui/react'
export default function Demo() {
return (
<Stack className="w-72">
<SearchInput disabled defaultValue="星见" aria-label="已禁用" />
<SearchInput clearable={false} defaultValue="星见" aria-label="不带清除按钮" />
</Stack>
)
}
tsx
在表单中
放进 FormField 后,标签指向输入框,错误信息由字段渲染;校验规则与提交交给 Form,回车提交与提交按钮的行为保持默认。
'use client'
import { useState } from 'react'
import * as v from 'valibot'
import { Button, Form, FormField, SearchInput, Text } from '@hina-ui/react'
const schema = v.object({
keyword: v.pipe(
v.string('请输入关键字'),
v.trim(),
v.nonEmpty('请输入关键字'),
v.minLength(2, '关键字至少 2 个字'),
),
})
export default function Demo() {
const [values, setValues] = useState({ keyword: '' })
const [result, setResult] = useState('')
async function search(data: unknown) {
await new Promise(resolve => setTimeout(resolve, 600))
setResult((data as { keyword: string }).keyword)
}
return (
<Form values={values} rules={schema} className="w-80" onSubmit={search}>
{({ submitting }) => (
<>
<FormField name="keyword" label="搜索作品">
<SearchInput
value={values.keyword}
onValueChange={keyword => setValues({ ...values, keyword })}
placeholder="作品名或者别名"
/>
</FormField>
<Button type="submit" loading={submitting} className="self-start">
搜索
</Button>
{result && (
<Text tone="muted" size="sm">
正在搜索「{result}」的结果。
</Text>
)}
</>
)}
</Form>
)
}
tsx
行为
- 清除按钮只在有内容且未禁用时出现,点击后不会让输入区失焦。
- Esc 只在有内容时清空,内容为空时不做处理。
- 悬停、聚焦与禁用的表现与 Input 相同。
无障碍
- 输入区为
type="search",移动端键盘的确认键显示为搜索。 - 清除按钮可以用 Tab 到达,名称随语言包本地化。
loading时根元素设置aria-busy。 - 应当配合
label元素或者aria-label提供名称。
API
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
value | string | '' | 关键词 |
clearable | boolean | true | 是否显示清除按钮 |
loading | boolean | false | 是否显示加载指示器 |
variant | 'primary' | 'secondary' | 'bare' | 'primary' | 形态 |
size | 'sm' | 'md' | 'lg' | 'md' | 尺寸 |
disabled | boolean | false | 是否禁用 |
className | string | — | 追加至根元素的类名 |
| 回调 | 参数 | 说明 |
|---|---|---|
onValueChange | value: string | 关键词变化 |
onSearch | value: string | 按 Enter 提交搜索 |
onClear | — | 关键词被清空 |