Skip to content

无头(headless)核心 ​

每个有状态的组件都只是 @thl-ui/core 中与框架无关的状态机之上的一层薄绑定。你可以直接使用这些状态机来构建自己的组件——在任何框架中,甚至不使用框架。

Store ​

所有状态机都暴露一个极简的可观察 store:

ts
interface Store<T> {
  get(): T;
  set(next: T | ((prev: T) => T)): void;
  subscribe(fn: (value: T, prev: T) => void): () => void;
}

每个框架只需一行即可桥接:

ts
// React
const state = useStore(machine.state);              // 由 @thl-ui/react 导出
// Vue
const state = useStore(machine.state);              // 由 @thl-ui/vue 导出 → Ref<T>
// Angular
readonly state = storeSignal(machine.state);         // 由 @thl-ui/angular 导出 → Signal<T>

状态机 ​

工厂函数要点
createTable({ data, columns, pageSize, rowKey, manual })排序、搜索、筛选、分页、选择、行内编辑、服务端模式
createSelect({ options, multiple, searchable, creatable })键盘导航、分组、可创建标签
createTabs({ items, active })roving tabindex、跳过禁用项
createSteps({ count, current, linear })每一步的状态
createCarousel({ count, interval, loop })自动播放、暂停
createDisclosure() / createAccordion()折叠、面板
createSidebar({ breakpoint })mini / mobile / user-mini 状态,感知窗口尺寸变化
createToastManager({ duration, max })位置、常驻、最大队列
createUpload({ accept, maxSize, request })校验(i18n)、进度、预览
createIdleTimer({ warnAfter, expireAfter })活动事件
paginate({ page, total, pageSize, maxPages })带省略号的页码项
monthGrid(), weekdayNames(), presetRanges()支持 Intl 的日历
rules.*, validate(), validateAll()返回 i18n key

示例:用原生 TS 实现自定义表格 ​

ts
import { createTable, createThl } from '@thl-ui/core';

const thl = createThl({ locale: 'zh' });
const table = createTable({
  data: employees,
  columns: [{ key: 'name', sortable: true }, { key: 'salary', sortable: true }],
  pageSize: 5,
  rowKey: 'id',
});

table.state.subscribe(render);
table.toggleSort('salary');
table.setSearch('tokyo');

function render() {
  const { rows, total, page, pageCount } = table.view();
  footer.textContent = thl.t('pagination.showing', { from: (page - 1) * 5 + 1, to: Math.min(page * 5, total), total });
  // …渲染 rows.map(r => r.row)
}

校验规则 ​

ts
import { rules, validate, validateAll } from '@thl-ui/core';

validate('', [rules.required()]);                       // { key: 'validation.required' }
validate('ab', [rules.minLength(3)]);                   // { key: 'validation.minLength', params: { min: 3 } }
validateAll({ pw: 'x', confirm: 'y' }, { confirm: [rules.match('pw')] });

可用规则:required、email、minLength、maxLength、min、max、number、pattern(re)、match(field)。规则只是一个 (value, allValues) => { key, params } | null 函数,因此编写自定义规则非常简单——而且其文案会像内置规则一样被翻译。

工具函数 ​

bem(block, prefix) · cx(...classes) · uid() · focusTrap(el) · scrollLock() · clickOutside(els, fn) · computePosition(anchor, float, placement) · breakpoints · skins · palette。