Skip to content

Global config ​

All three adapters are driven by one config object, created by createThl() in @thl-ui/core. You pass it to ThlProvider (React), app.use(ThlUI, …) (Vue) or provideThlUI(…) (Angular).

Options ​

OptionTypeDefaultDescription
prefixstring'thl'CSS class and custom-property prefix (.thl-btn, --thl-theme)
themeThlSkin'default'One of 12 skins: default · green · yellow · red · purple · black and each with -dark (dark sidebar)
colorMode'light' | 'dark' | 'auto''light'auto follows prefers-color-scheme live
layout'vertical' | 'mini' | 'horizontal''vertical'AppLayout variant
fixedHeaderbooleantrueSticky topbar
fixedSidebarbooleantrueSticky sidebar
size'sm' | 'md' | 'lg''md'Base font size and control height
radius'sharp' | 'rounded''rounded'sharp sets all radius tokens to 0
zIndexnumber1000Overlay base: dropdown = base, modal = base + 50, toast = base + 80
localestring'en'Active locale
fallbackLocalestring'en'Used when a key is missing
localesstring[]['en','vi','ja','zh']Offered in the language switcher
messagesRecord<locale, Messages>{}Extra / override messages, deep-merged with built-ins
loadLocale(l) => Promise<Messages>—Lazy loader for locales not bundled
componentsPartial<ThlComponentDefaults>see belowPer-component default props
persistboolean | { key }falseSave theme / colorMode / locale / layout / fixed* / size / radius to localStorage (key thl-ui-config)
rootHTMLElement<html>Element that receives the data-thl-* attributes
iconsIconRegistry—Register extra icons (adapter option)

What happens at runtime ​

createThl() writes the config to the root element as data attributes. All styling reacts to these attributes, so changing config never re-renders components unnecessarily:

html
<html lang="vi" dir="ltr"
      data-thl-theme="green-dark" data-thl-color-mode="dark" data-thl-layout="vertical"
      data-thl-size="md" data-thl-radius="rounded" data-thl-fixed-header data-thl-fixed-sidebar>

Changing config at runtime ​

vue
<script setup lang="ts">
import { useThlConfig } from '@thl-ui/vue';
const { config, set } = useThlConfig();
</script>
<template>
  <ThlButton @click="set({ theme: 'purple', colorMode: 'dark' })">Purple · dark</ThlButton>
  <p>Layout: {{ config.layout }}</p>
</template>
tsx
import { useThlConfig, Button } from '@thl-ui/react';
const [config, set] = useThlConfig();
<Button onClick={() => set({ theme: 'purple', colorMode: 'dark' })}>Purple · dark</Button>
ts
import { ThlConfigService } from '@thl-ui/angular';
readonly cfg = inject(ThlConfigService);
// template: {{ cfg.config().layout }}
toPurple() { this.cfg.set({ theme: 'purple', colorMode: 'dark' }); }
Live: change global config

The <SettingsPanel> (built into AppLayout) is just a UI for these same set() calls.

Component defaults ​

components sets default props for every instance. Explicit props always win:

ts
createThl({
  components: {
    Button: { rounded: true, size: 'sm' },
    Table: { pageSize: 25, pageSizes: [25, 50, 100], striped: true },
    Toast: { position: 'bottom-right', duration: 5000, max: 3 },
    Modal: { closeOnBackdrop: false, centered: true },
    Pagination: { maxPages: 5 },
    Sidebar: { breakpoint: 1024 },
  },
});

Built-in defaults:

ts
{
  Toast: { position: 'top-right', duration: 3500, max: 5 },
  Table: { pageSize: 10, pageSizes: [10, 25, 50, 100], hover: true },
  Modal: { closeOnBackdrop: true, closeOnEsc: true },
  Pagination: { maxPages: 7 },
  Sidebar: { breakpoint: 1170 },
}

The type ThlComponentDefaults is extensible through declaration merging:

ts
declare module '@thl-ui/core' {
  interface ThlComponentDefaults {
    MyWidget: { dense?: boolean };
  }
}

Sharing one instance ​

Create the instance yourself to share it with non-UI code (stores, services, micro-frontends):

ts
import { createThl } from '@thl-ui/core';
export const thl = createThl({ locale: 'en', persist: true });

thl.subscribe((c, prev) => { if (c.locale !== prev.locale) api.setLanguage(c.locale); });
thl.t('common.save');          // "Lưu"
tsx
<ThlProvider instance={thl}>…</ThlProvider>          // React
app.use(ThlUI, { instance: thl });                   // Vue
provideThlUI({ instance: thl });                      // Angular

ThlInstance API: get(), set(patch), subscribe(fn), defaults(name, props), t(), setLocale(), resolvedColorMode(), applyToDocument(), attach(), destroy(), plus config (store) and i18n.