Skip to content

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: 'ja',
    theme: 'green-dark',
    colorMode: 'auto',
    persist: true,
    components: { Table: { pageSize: 25 }, Toast: { position: 'bottom-right' } },
  }}>
    <App />
  </ThlProvider>,
);

ThlProvider は createThl() で作成済みの instance も受け取れます。React と React 以外のコードで 1 つの設定を共有したいときに便利です。StrictMode でも安全に動作します(再マウント時にリスナーが解除・再登録されます)。

Hooks ​

Hook戻り値
useThlConfig()[config, set] — 現在の設定とセッター(set({ theme: 'red' }))
useT()t(key, params)。t.n()、t.d()、t.locale を持つ
useLocale()[locale, setLocale]
useToast()トーストマネージャー: success、info、warning、error、show、dismiss
useDefaults(name, props)config.components[name] とマージされた props
usePrefix()クラスの prefix(デフォルト 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 キー(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/> を自分で一度だけレンダリングしてください。