FAQ とトラブルシューティング
インストール
UI に色がなく、システムフォントで表示される
CSS が読み込まれていません。アプリのエントリーポイントで一度だけ追加してください。
import '@thl-ui/styles/thl-ui.css';Angular: angular.json の styles に node_modules/@thl-ui/styles/dist/thl-ui.css を追加します。さらに <body> に thl-body クラスを付けると、フォントと背景色が適用されます。
npm install で peer dependency エラーが出る
thl-ui には Vue ≥ 3.5.2、React ≥ 18、または Angular ≥ 20 が必要です。それより古いバージョンはサポートしていません。Angular 19 ではライブラリをコンパイルできず、Vue < 3.5.2 では TypeScript の型エラーが発生します。フレームワークをアップグレードするか、どうしても必要な場合は --legacy-peer-deps を付けてインストールしてください(非推奨)。
TypeScript がコンポーネントの型を見つけられない
tsconfig.json で "moduleResolution": "Bundler"(または "NodeNext")を使ってください。旧来の "node" モードではパッケージの exports フィールドを読めません。
Bootstrap、jQuery、Google Fonts は必要ですか?
不要です。thl-ui の CSS はすべてゼロから書かれており、Open Sans フォントは @thl-ui/styles に同梱されています(セルフホスト、外部リクエストなし)。
テーマ
ブランドカラーを変更する
thl-ui.css を読み込んだ後に CSS 変数を上書きします。
:root {
--thl-theme: #7c3aed; /* ボタンやアクティブなタブなどの背景 */
--thl-on-theme: #fff; /* その色の上に置くテキスト */
--thl-theme-text: #6d28d9; /* 白背景上でテキストとして使うときの色 */
}--thl-on-theme と --thl-theme の間、および --thl-theme-text と白の間で、コントラスト比 4.5:1 以上を保ってください。テーマとダークモード を参照してください。
一部の領域だけテーマを変える
<section data-thl-theme="red" data-thl-color-mode="dark">…</section>自分の CSS がライブラリの CSS に上書きされる(またはその逆)
すべてのクラスには thl- の prefix が付いており、デフォルトのリンク色は詳細度ゼロ(:where(...))なので、通常のクラスセレクターであればあなたの CSS が優先されます。衝突を避けるために prefix を変更するには、設定で prefix: 'my' を指定し、さらに SCSS を $prefix: my で再ビルドします(@use "@thl-ui/styles/scss/index" with ($prefix: "my"))。
バンドルサイズが大きすぎる
- Vue: デフォルトの
app.use(ThlUI)はすべてのコンポーネントを登録するので避けてください。設定にはimport { ThlUI } from '@thl-ui/vue'を使い、必要なコンポーネントだけを import します。Button だけを使う場合、約 230 KB ではなく約 120 KB になります。 - React と Angular: コンポーネントを個別に import すれば、残りはバンドラーが tree-shaking します。
- コンポーネント別 CSS:
@thl-ui/styles/components/button.css…(@thl-ui/styles/tokens.cssと@thl-ui/styles/fonts.cssも忘れずに追加してください)。
動作
ユーザー設定(言語、スキン、ダークモード)が保存されない
設定で persist: true を有効にしてください。データは localStorage の thl-ui-config キーに保存されます(キー名を変えるには persist: { key: 'my-app-ui' })。保存された値は次回読み込み時に設定値を上書きする点に注意してください。
トーストや confirm() が表示されない
AppLayout はすでにホストをマウントしています。AppLayout を使わない場合は、アプリのルートに次を一度だけ配置してください。
<ThlToaster />
<ThlConfirmHost />(React: <Toaster /> と <ConfirmHost />、Angular: <thl-toaster /> と <thl-confirm-host />。)ConfirmHost がない場合、confirm() はブラウザの window.confirm にフォールバックします。
サイドバーのメニューをクリックするとページ全体が再読み込みされる
サイドバーはデフォルトで <a href> を使います。ルーターのリンクを使うには、link スロット(Vue)、renderLink prop(React)、thlMenuLink テンプレート(Angular)を渡してください。チュートリアル のステップ 3 を参照してください。
フォームのエラーが表示されない
エラーは最初の送信後にのみ表示されます。各 ThlField には name、value、rules が必要で、:values を持つ ThlForm の中に置く必要があります。サーバー側のエラーを表示するには、ThlField に error="…" を渡します。
バリデーションメッセージが英語のまま
メッセージは現在の言語に従います。設定の locale、または persist が有効な場合は localStorage に保存された値を確認してください。翻訳のない言語は fallbackLocale(デフォルト en)にフォールバックします。
新しい言語を追加する
app.use(ThlUI, {
locales: ['vi', 'en', 'ko'],
messages: { ko: { common: { ok: '확인', cancel: '취소' } /* … */ } },
});未翻訳のキーは fallbackLocale にフォールバックします。右から左に書く言語(ar、he、fa、ur)では自動的に dir="rtl" が設定され、レイアウトが反転します。
アクセシビリティ
アイコンのみのボタン
スクリーンリーダー向けに必ずラベルを付けてください。
<ThlButton icon="trash-2" aria-label="削除" />表示ラベルのない入力欄
ThlField label="…" で囲む(ラベルは自動的に入力欄に関連付けられます)か、aria-label を渡してください。
それでも解決しない場合
対応するプレイグラウンド(npm run dev:vue / dev:react / dev:angular)を開き、apps/playground-* にあるサンプルページのソースと比較してください。すべてのコンポーネントに動作する例があります。