React
配置
用 ThlProvider 包裹一次你的应用:
tsx
import { createRoot } from 'react-dom/client';
import { ThlProvider } from '@thl-ui/react';
import '@thl-ui/styles/thl-ui.css';
import { App } from './App';
createRoot(document.getElementById('root')!).render(
<ThlProvider config={{
locale: 'zh',
theme: 'green-dark',
colorMode: 'auto',
persist: true,
components: { Table: { pageSize: 25 }, Toast: { position: 'bottom-right' } },
}}>
<App />
</ThlProvider>,
);ThlProvider 也接受通过 createThl() 创建的现有 instance——便于在 React 与非 React 代码之间共享同一份配置。它在 StrictMode 下是安全的(监听器会在重新挂载时解绑/重新绑定)。
Hooks
| Hook | 返回值 |
|---|---|
useThlConfig() | [config, set]——当前配置和一个 setter(set({ theme: 'red' })) |
useT() | t(key, params),附带 t.n()、t.d()、t.locale |
useLocale() | [locale, setLocale] |
useToast() | toast manager:success、info、warning、error、show、dismiss |
useDefaults(name, props) | 与 config.components[name] 合并后的 props |
usePrefix() | 类名前缀(默认 thl) |
useThl() | 原始的 ThlInstance |
tsx
import { Button, useT, useToast, useThlConfig } from '@thl-ui/react';
export function SaveBar() {
const t = useT();
const toast = useToast();
const [config, set] = useThlConfig();
return (
<>
<Button variant="success" onClick={() => toast.success(t('common.save'))}>{t('common.save')}</Button>
<Button onClick={() => set({ colorMode: config.colorMode === 'dark' ? 'light' : 'dark' })}>🌓</Button>
<span>{t.n(1234.5, { style: 'currency', currency: 'USD' })}</span>
</>
);
}受控输入
控件遵循 React 惯例:value / checked + onChange(value)。原生输入组件(Input、Textarea)会透传所有原生 props 并转发 ref。
tsx
const [country, setCountry] = useState<string | null>('vn');
<Select options={countries} value={country} onChange={setCountry} searchable clearable />
<Switch checked={on} onChange={setOn} />
<DatePicker value={date} onChange={setDate} />表单与校验
tsx
import { Form, Field, Input, Button, rules } from '@thl-ui/react';
<Form values={v} onSubmit={(values, ok) => ok && save(values)}>
<Field label="邮箱" name="email" value={v.email} rules={[rules.required(), rules.email()]} required>
{(id) => <Input id={id} type="email" value={v.email} onChange={(e) => setV({ ...v, email: e.target.value })} />}
</Field>
<Button type="submit" variant="primary">提交</Button>
</Form>错误信息是 i18n key(validation.*),因此会随应用切换语言。
路由(AppLayout)
传入 renderLink,让侧边菜单使用你的路由:
tsx
import { Link, useLocation } from 'react-router';
<AppLayout menu={menu} currentPath={loc.pathname} user={user}
renderLink={(item, children, className) => <Link to={item.href!} className={className}>{children}</Link>}>
<Routes>…</Routes>
</AppLayout>confirm()
tsx
import { confirm } from '@thl-ui/react';
if (await confirm({ icon: 'warning', title: '确定删除?' })) remove();confirm() 使用 AppLayout 渲染的 <ConfirmHost/>;在布局之外,请自行渲染一次 <ConfirmHost/> 和 <Toaster/>。