Repository navigation
cn hx components Utilities
@hx/components 导出的工具函数、上下文 Provider 和模式工具包。
从操作/分组定义构建操作菜单内容。
import { buildContent } from '@hx/components';
const menu = buildContent([
{ label: '编辑', onClick: handleEdit },
{ type: 'separator' },
{ label: '删除', onClick: handleDelete, disabled: true },
]);输入事件处理器的工厂函数。
import {
createHxInputFocusHandler,
createHxInputKeyDownHandler,
createHxInputSelectAllHandler,
} from '@hx/components';根据原始条目/页数计算 HxPaginationData:
import { computePaginationData } from '@hx/components';
const data = computePaginationData(150, 20, 1);
// => { pageSize: 20, pageNumber: 1, totalPages: 8, totalItems: 150 }import {
parseFileName, // (name: string) => { name: string, ext: string }
mapError, // (error: unknown) => 用户友好的字符串
isImage, // (file: HxUploadFile) => boolean
toImageSrc, // (bytes: ArrayBuffer) => data: URL 字符串
releaseImage, // (src: string) => undefined —— 释放 object URL
} from '@hx/components';将 accept 字符串/数组规范化为验证函数:
import { computeAccept } from '@hx/components';
const check = computeAccept(['.pdf', 'image/*']);
check({ name: 'doc.pdf', mimeType: 'application/pdf' }); // true
check({ name: 'photo.jpg', mimeType: 'image/jpeg' }); // true
check({ name: 'data.exe', mimeType: 'application/x-msdownload' }); // falseimport { computeSvgIconDefaults } from '@hx/components';
// 根据设置计算默认尺寸和样式内部 Provider,使用 EventEmitter 进行跨组件通信:
| Provider | 提供的状态 |
|---|---|
HxPanelProvider |
{ collapsed, toggle } |
HxTabProvider |
{ isActive, mark, disabled, activate } |
HxTabsProvider |
{ tabs, activeMark, switchToTab, restoreScroll } |
HxUploadProvider |
{ files, errors, uploading, addFiles, removeFile, uploadAll, clearFiles } |
HxSelectOptionsProvider |
{ options, selectedValue, searchText, selectOption } |
HxOverlayInternalProvider |
生命周期:entering → entered → exiting → exited
|
HxFormatInput 的抽象基类和内置实现:
import {
AbstractHxFormatInputPatternKit,
HxFormatInputNumberPatternKit,
HxFormatInputDateTimePatternKit,
HxFormatInputPatternKitsInner, // 注册表:@n → NumberKit,@d → DateTimeKit
} from '@hx/components';
class MyKit extends AbstractHxFormatInputPatternKit {
parse(raw: string): ParsedValue { /* ... */ }
format(parsed: ParsedValue): string { /* ... */ }
}DateLocaleFormatUtils 使用 Intl.DateTimeFormat.formatToParts() 提供各日期/时间部分的本地化格式化。所有格式化均为 UTC 语义——日期以 UTCDate(基于 JS Date 的无时区包装)传入,宿主时区不会影响输出。
import { DateLocaleFormatUtils, UTCDate } from '@hx/components';
const date = UTCDate.of(2025, 6, 6); // 2025-07-06
// 按 locale 格式化各部分(返回带字面量后缀的字符串)
DateLocaleFormatUtils.formatYear(date, 'ja-JP', false); // "令和7年"
DateLocaleFormatUtils.formatYear(date, 'zh-CN', true); // "2025年"(强制公历)
DateLocaleFormatUtils.formatMonth(date, 'zh-CN', false); // "7月"
DateLocaleFormatUtils.formatDay(date, 'en-US', true); // "6"
DateLocaleFormatUtils.formatWeekday(date, 'zh-CN', true); // "周日"非公历历法(日本、民国、佛历、韩语、科普特、埃塞俄比亚、希伯来、伊斯兰 ×3、波斯、印度、中国)通过实现 DateLocaleNotGregorianProvider 接口的插件系统管理。每个插件声明自己的 accept()、calendar()、supportedLanguages() 以及可选的 eraAs() / yearAs() / yearHeaderLabel() / monthHeaderLabel() / eraOfDays() / monthsOfYear() / yearsAround() 方法。历法导航还需要实现 DateMoveNotGregorianProvider 的移动插件(moveYear / moveMonth / 边界钩子),通过 DateMoveUtils.enableNotGregorianMoveProvider() 注册。
启用 locale 特定历法支持:
import {
DateBuddhistUtils, DateChineseUtils, DateCopticUtils, DateEthiopicUtils,
DateHebrewUtils, DateIndianUtils, DateIslamicUtils, DateIslamicCivilUtils,
DateIslamicUmalquraUtils, DateJapaneseUtils, DateKoreanUtils, DateMinguoUtils,
DatePersianUtils
} from '@hx/components';
DateCopticUtils.enable(); // ar-EG → coptic(科普特殉教纪年)
DateEthiopicUtils.enable(); // am-ET / ti-ET → ethiopic(道成肉身纪元)
DateJapaneseUtils.enable(); // ja / ja-JP → japanese(日本历)
DateMinguoUtils.enable(); // zh-TW / zh-Hant-TW → roc(民国纪年)
DateKoreanUtils.enable(); // ko / ko-KR / ko-KP → 公历(无特殊历法)
DateBuddhistUtils.enable(); // th / th-TH → buddhist(佛历)
DateHebrewUtils.enable(); // he / he-IL → hebrew(希伯来历)
DateIslamicUtils.enable(); // ar-DZ / ar-MA / ar-TN → islamic
DateIslamicCivilUtils.enable(); // ar-AE / ar-IQ / ar-SY / ... → islamic-civil
DateIslamicUmalquraUtils.enable(); // ar-SA / ar-OM / ar-YE / ... → islamic-umalqura
DateIndianUtils.enable(); // hi / hi-IN / en-IN → indian(印度国定历)
DatePersianUtils.enable(); // fa / fa-IR / ckb-IR / ... → persian(波斯历)
DateChineseUtils.enable(); // zh-CN → chinese(农历)
DateCopticUtils.disable(); // 移除科普特插件(每个插件也提供 disable())科普特历法跨两个纪元:殉教纪元(AM,公元 284 年起)和戴克里先纪元前(显示为 "B.D." 前缀,如 "B.D. 185")。插件实现了 yearAs() 以自动处理纪元前缀。
埃塞俄比亚历法跨两个纪元:道成肉身纪元(A.I.,公元 8 年起)和道成肉身纪元前(显示为 "B.I." 前缀,如 "B.I. 5493")。B.I. 纪元年份范围为 5493–5500(公元 1–8 年)。插件实现了 yearAs() 以自动处理纪元前缀。
波斯历的闰年规则与 ICU(persncal.cpp)一致:基础为 33 年周期 8 闰(年份余数 ∈ {1, 5, 9, 13, 17, 22, 26, 30}),并在波斯历 1502–2987 年由闰日平移表覆盖——每个条目 X 使 X 年变平年、X+1 年变闰年,闰日整体后移一年;2988 年起回到纯 mod-33 规则。移动提供者实现同一规则,保证导航与格式化始终与运行环境 Intl 一致。
历法解析 — 当 gregorian 为 false 时,DateLocaleFormatUtils 通过 CALENDAR_MAP 从 locale 解析对应历法,该映射由每个已启用插件的 supportedLanguages() 填充:
-
ar-AE/ar-BH/ar-IQ/ar-KW/ar-LB/ar-QA/ar-SY→islamic-civil -
ar-DZ/ar-MA/ar-TN→islamic -
ar-OM/ar-SA/ar-SD/ar-YE→islamic-umalqura -
fa/fa-AF/fa-IR/ckb-IR→persian -
ps/ps-AF→persian -
mzn/mzn-IR/lrc/lrc-IR→persian -
uz-Arab/uz-Arab-AF→persian -
hi-IN/en-IN/hi→indian -
he-IL/he→hebrew - 由插件管理:
am-ET/ti-ET→ethiopic,ar-EG→coptic,ja/ja-JP→japanese,zh-TW/zh-Hant-TW→roc,th/th-TH→buddhist
HxDateTimeFormatCalendar 支持全部 18 个 ECMA-402 历法值:
type HxDateTimeFormatCalendar =
| 'gregory' | 'buddhist' | 'chinese' | 'coptic' | 'dangi'
| 'ethioaa' | 'ethiopic' | 'hebrew' | 'indian'
| 'islamic' | 'islamic-civil' | 'islamic-umalqura'
| 'islamic-tbla' | 'islamic-rgsa'
| 'iso8601' | 'japanese' | 'persian' | 'roc'
| string; // 可扩展,支持插件自定义历法实现 DateLocaleNotGregorianProvider 接口添加自定义历法支持:
import type { DateLocaleNotGregorianProvider } from '@hx/components';
import { DateLocaleFormatUtils } from '@hx/components';
const myPlugin: DateLocaleNotGregorianProvider = {
accept(lang) { return lang === 'my-LOCALE'; },
calendar() { return 'dangi'; },
supportedLanguages() { return ['my-LOCALE']; },
eraAs(date, partsOf, lang) { /* 自定义年号格式化 */ },
yearAs(date, partsOf, lang) { /* 自定义年份格式化 */ },
yearHeaderLabel(value, era, year, lang) { /* 自定义年份标签 */ },
monthHeaderLabel(value, era, year, month, lang) { /* 自定义月份标签 */ },
eraOfDays(days, lang) { /* 每日年号标记 */ },
};
DateLocaleFormatUtils.enableNotGregorianLocaleProvider(myPlugin);
DateLocaleFormatUtils.disableNotGregorianLocaleProvider(myPlugin);历法导航还需注册实现 DateMoveNotGregorianProvider 的移动插件:
import { DateMoveUtils, type DateMoveNotGregorianProvider } from '@hx/components';
const myMovePlugin: DateMoveNotGregorianProvider = {
accept(lang) { return lang === 'my-LOCALE'; },
moveYear(date, yearOffset, lang) { /* ... */ },
moveMonth(date, monthOffset, lang) { /* ... */ },
isPreviousYearAllowed(lang, firstDayOfCurrentMonthOfGregory) { /* ... */ },
// isNextYearAllowed / isPreviousMonthAllowed / isNextMonthAllowed ...
};
DateMoveUtils.enableNotGregorianMoveProvider(myMovePlugin);DateLocaleFormatUtils.getWeekInfo() 从 CLDR 数据读取 locale 的周末和每周第一天:
const { weekends, firstDayOfWeek } = DateLocaleFormatUtils.getWeekInfo('ar-SA');
// weekends: ['fri', 'sat'], firstDayOfWeek: 'sat'
const { weekends, firstDayOfWeek } = DateLocaleFormatUtils.getWeekInfo('en-US');
// weekends: ['sat', 'sun'], firstDayOfWeek: 'sun'当 gregorian 为 true 时,所有格式化均使用公历。当 gregorian 为 false 时,使用 CALENDAR_MAP 中对应的 locale 历法,未映射时回退到公历。
- Overview
- Common Concepts
- I18n
- Data Attributes
- Form Components
- Layout Components
- Display Components
- Overlay Components
- Structure Components
- Validation
- Hooks
- Utilities