niuma-ui 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/README.en.md +1 -1
- package/README.md +1 -1
- package/dist/brand-icons.css +40 -0
- package/dist/components/_shared/src/resolve-radius.js +1 -1
- package/dist/components/button/src/RsButton.impl.js +1 -1
- package/dist/components/cascader/src/RsCascader.css +20 -20
- package/dist/components/cascader/src/RsCascader.js +1 -1
- package/dist/components/code-block/src/RsCodeBlock.d.ts +1 -1
- package/dist/components/code-editor/src/code-editor-utils.js +2 -2
- package/dist/components/code-editor/src/code-mirror-lang.js +1 -1
- package/dist/components/config-provider/src/RsConfigProvider.css +2 -2
- package/dist/components/config-provider/src/RsConfigProvider.d.ts +6 -3
- package/dist/components/config-provider/src/RsConfigProvider.impl.js +47 -7
- package/dist/components/config-provider/src/RsConfigProvider.js +1 -1
- package/dist/components/context-menu/src/RsContextMenu.css +2 -2
- package/dist/components/date-picker/src/RsDatePicker.css +17 -17
- package/dist/components/date-picker/src/RsDatePicker.impl.js +1 -1
- package/dist/components/date-picker/src/RsDatePicker.js +1 -1
- package/dist/components/dialog/src/RsDialog.css +1 -2
- package/dist/components/divider/src/RsDivider.css +13 -13
- package/dist/components/divider/src/RsDivider.js +1 -1
- package/dist/components/drawer/src/RsDrawer.css +2 -4
- package/dist/components/dropdown/src/RsDropdown.css +2 -2
- package/dist/components/dropdown/src/RsDropdownItemView.impl.js +1 -1
- package/dist/components/icon/src/RsIcon.css +4 -4
- package/dist/components/icon/src/RsIcon.impl.js +6 -1
- package/dist/components/icon/src/RsIcon.js +1 -1
- package/dist/components/input/src/RsInput.css +86 -86
- package/dist/components/input/src/RsInput.js +1 -1
- package/dist/components/input-number/src/RsInputNumber.css +32 -32
- package/dist/components/input-number/src/RsInputNumber.js +1 -1
- package/dist/components/label/src/RsLabel.css +7 -7
- package/dist/components/label/src/RsLabel.js +1 -1
- package/dist/components/loading-bar/src/RsLoadingBar.css +4 -5
- package/dist/components/loading-bar/src/RsLoadingBar.js +1 -1
- package/dist/components/log/src/RsLog.css +39 -39
- package/dist/components/log/src/RsLog.d.ts +1 -1
- package/dist/components/log/src/RsLog.impl.js +1 -1
- package/dist/components/log/src/RsLog.js +1 -1
- package/dist/components/markdown/src/RsMarkdown.css +9 -7
- package/dist/components/menu/src/RsMenu.css +5 -5
- package/dist/components/pagination/src/RsPagination.css +18 -18
- package/dist/components/pagination/src/RsPagination.impl.js +1 -1
- package/dist/components/pagination/src/RsPagination.js +1 -1
- package/dist/components/select/src/RsSelect.css +42 -42
- package/dist/components/select/src/RsSelect.impl.js +1 -1
- package/dist/components/select/src/RsSelect.js +1 -1
- package/dist/components/steps/src/RsSteps.css +18 -18
- package/dist/components/steps/src/RsSteps.js +1 -1
- package/dist/components/switch/src/RsSwitch.css +4 -6
- package/dist/components/table/style/rs-table.css +15 -15
- package/dist/components/terminal/src/RsTerminal.css +24 -24
- package/dist/components/terminal/src/RsTerminal.js +1 -1
- package/dist/components/textarea/src/RsTextarea.css +26 -26
- package/dist/components/textarea/src/RsTextarea.js +1 -1
- package/dist/components/time-picker/src/RsTimePicker.css +20 -20
- package/dist/components/time-picker/src/RsTimePicker.impl.js +1 -1
- package/dist/components/time-picker/src/RsTimePicker.js +1 -1
- package/dist/components/toaster/src/RsToaster.css +6 -6
- package/dist/components/toaster/src/RsToaster.impl.js +3 -6
- package/dist/components/tree/src/RsTree.css +72 -73
- package/dist/components/tree/src/RsTree.js +1 -1
- package/dist/components/tree-select/src/RsTreeSelect.css +11 -11
- package/dist/components/tree-select/src/RsTreeSelect.js +1 -1
- package/dist/components/virtual-list/src/RsVirtualList.css +7 -8
- package/dist/components/virtual-list/src/RsVirtualList.js +1 -1
- package/dist/composables/createRsDialog.js +4 -3
- package/dist/composables/useRsConfig.d.ts +11 -3
- package/dist/composables/useRsConfig.js +17 -5
- package/dist/composables/useRsI18n.js +2 -2
- package/dist/icons/brand.d.ts +6 -0
- package/dist/icons/brand.js +26 -0
- package/dist/icons/registry.d.ts +2 -0
- package/dist/icons/registry.js +2 -1
- package/dist/index.d.ts +7 -4
- package/dist/index.js +16 -0
- package/dist/locale/apply.d.ts +8 -0
- package/dist/locale/apply.js +20 -0
- package/dist/locale/interpolate.d.ts +4 -3
- package/dist/locale/interpolate.js +96 -5
- package/dist/locale/messages.d.ts +0 -4
- package/dist/locale/messages.js +5 -9
- package/dist/locale/registry-public.d.ts +2 -0
- package/dist/locale/registry.d.ts +19 -0
- package/dist/locale/registry.js +50 -0
- package/dist/locale/types.d.ts +11 -2
- package/dist/locale/types.js +4 -1
- package/dist/styles.css +245 -250
- package/dist/theme/apply.d.ts +15 -3
- package/dist/theme/apply.js +41 -4
- package/dist/theme/brand.example.css +5 -1
- package/dist/theme/presets.d.ts +6 -5
- package/dist/theme/presets.js +4 -3
- package/dist/theme/types.d.ts +15 -7
- package/dist/theme/types.js +4 -1
- package/dist/vite-plugins/niuma-ui-host.js +7 -0
- package/package.json +2 -1
package/dist/icons/registry.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { LUCIDE_ATTRIBUTION, LUCIDE_LICENSE, isRsIconName, lucideIconCount, resolveLucideIcon } from "./lucide.js";
|
|
2
|
+
import { isRsBrandIconName, rsBrandIconAccentVar, rsBrandIconNames } from "./brand.js";
|
|
2
3
|
//#region src/icons/registry.ts
|
|
3
4
|
/** Playground / 文档常用图标(Lucide 全库约 1600+;kebab-case,如 `house`、`trash-2`) */
|
|
4
5
|
var rsCommonIconNames = [
|
|
@@ -28,4 +29,4 @@ var rsCommonIconNames = [
|
|
|
28
29
|
"shield-check"
|
|
29
30
|
];
|
|
30
31
|
//#endregion
|
|
31
|
-
export { LUCIDE_ATTRIBUTION, LUCIDE_LICENSE, isRsIconName, lucideIconCount, resolveLucideIcon, rsCommonIconNames };
|
|
32
|
+
export { LUCIDE_ATTRIBUTION, LUCIDE_LICENSE, isRsBrandIconName, isRsIconName, lucideIconCount, resolveLucideIcon, rsBrandIconAccentVar, rsBrandIconNames, rsCommonIconNames };
|
package/dist/index.d.ts
CHANGED
|
@@ -214,13 +214,16 @@ export { useRsI18n, createTranslator } from './composables/useRsI18n';
|
|
|
214
214
|
export type { RsTranslateFn } from './composables/useRsI18n';
|
|
215
215
|
export { useRsToast } from './composables/useRsToast';
|
|
216
216
|
export type { RsToastInput } from './composables/useRsToast';
|
|
217
|
-
export { rsCommonIconNames, LUCIDE_ATTRIBUTION, LUCIDE_LICENSE, lucideIconCount, isRsIconName, } from './icons/registry';
|
|
218
|
-
export type {
|
|
217
|
+
export { rsCommonIconNames, rsBrandIconNames, rsBrandIconAccentVar, LUCIDE_ATTRIBUTION, LUCIDE_LICENSE, lucideIconCount, isRsIconName, isRsBrandIconName, } from './icons/registry';
|
|
218
|
+
export type { RsBrandIconName } from './icons/registry';
|
|
219
|
+
export type { RsThemeMode, RsResolvedTheme, RsThemeTokens, RsComponentSize, RsRadius, RsFontSize, RsFontWeight, } from './theme/types';
|
|
219
220
|
export { RS_COMPONENT_SIZES, RS_COMPONENT_SIZE_ICON_PX, RS_RADII, RS_RADIUS_CSS, RS_FONT_SIZES, RS_FONT_SIZE_CSS, RS_FONT_WEIGHTS, RS_FONT_WEIGHT_CSS, } from './theme/types';
|
|
220
|
-
export type { RsLocale } from './locale/types';
|
|
221
|
+
export type { RsBuiltinLocale, RsDirMode, RsLocale, RsLocaleMessages, RsTextDirection, } from './locale/types';
|
|
222
|
+
export { defaultLocale, fallbackLocale } from './locale/types';
|
|
223
|
+
export { applyLocale, inferRsLocaleDir, isRsLocaleRegistered, listRsLocales, registerRsLocale, resolveRsLocaleDir, resolveRsMessage, } from './locale/registry-public';
|
|
221
224
|
export { useRsConfig, useRsConfigOptional, createRsConfigState } from './composables/useRsConfig';
|
|
222
225
|
export { useResolvedRsComponentSize, resolveRsComponentSize } from './components/_shared';
|
|
223
226
|
export { useResolvedRsRadius, rsRadiusCss } from './components/_shared';
|
|
224
227
|
export { themePresets } from './theme/presets';
|
|
225
|
-
export { applyTheme } from './theme/apply';
|
|
228
|
+
export { applyTheme, prefersColorSchemeDark, readResolvedTheme, resolveThemeMode, subscribePreferredColorScheme, } from './theme/apply';
|
|
226
229
|
export { parseCssLengthToPx, readCodeFontFamily, readCodeFontSizePx, readCssLengthPx, readCssVar, readRootFontSizePx, readTerminalFontFamily, readTerminalFontSizePx, readTerminalFontWeight, readTerminalFontWeightBold, } from './theme/css-token';
|
package/dist/index.js
CHANGED
|
@@ -129,6 +129,7 @@ export { default as RsVirtualList } from './components/virtual-list/src/RsVirtua
|
|
|
129
129
|
export { TIME_HOUR_OPTIONS } from './components/time-picker/src/time-picker-utils.js'
|
|
130
130
|
export { TIME_SECOND_OPTIONS } from './components/time-picker/src/time-picker-utils.js'
|
|
131
131
|
export { aggregateColumnSummary } from './components/table/src/utils/table-summary-utils.js'
|
|
132
|
+
export { applyLocale } from './locale/apply.js'
|
|
132
133
|
export { applyMonacoDebugDecorations } from './monaco/debug-decorations2.js'
|
|
133
134
|
export { applySplitResize } from './components/split-pane/src/split-pane-utils.js'
|
|
134
135
|
export { applyTheme } from './theme/apply.js'
|
|
@@ -182,11 +183,13 @@ export { createRsTableViewContext } from './components/table/src/context/rs-tabl
|
|
|
182
183
|
export { createToolbarTableFeature } from './components/table/src/features/table-features.js'
|
|
183
184
|
export { createTranslator } from './composables/useRsI18n.js'
|
|
184
185
|
export { createUploadFileFromContent } from './components/upload/src/upload-utils.js'
|
|
186
|
+
export { defaultLocale } from './locale/types.js'
|
|
185
187
|
export { defaultTreeFilterNode } from './components/tree/src/tree-utils.js'
|
|
186
188
|
export { downloadUploadFile } from './components/upload/src/upload-utils.js'
|
|
187
189
|
export { ensureMongodbShellLanguage } from './monaco/languages/mongodb-shell.js'
|
|
188
190
|
export { escapeHtml } from './components/markdown/src/markdown-utils.js'
|
|
189
191
|
export { expandSplitPane } from './components/split-pane/src/split-pane-utils.js'
|
|
192
|
+
export { fallbackLocale } from './locale/types.js'
|
|
190
193
|
export { filterLogLines } from './components/log/src/log-utils.js'
|
|
191
194
|
export { filterTableRows } from './components/table/src/utils/table-utils.js'
|
|
192
195
|
export { filterTableTreeRows } from './components/table/src/utils/table-utils.js'
|
|
@@ -239,6 +242,7 @@ export { hasTableTreeChildren } from './components/table/src/utils/table-utils.j
|
|
|
239
242
|
export { hasTreeChildren } from './components/tree/src/tree-utils.js'
|
|
240
243
|
export { hrefToAnchorId } from './components/anchor/src/anchor-utils.js'
|
|
241
244
|
export { inferLogLevel } from './components/log/src/log-utils.js'
|
|
245
|
+
export { inferRsLocaleDir } from './locale/registry.js'
|
|
242
246
|
export { injectExpandRows } from './components/table/src/utils/table-utils.js'
|
|
243
247
|
export { inputRuleMessageKeys } from './components/input/src/input-rules.js'
|
|
244
248
|
export { isCodeMirrorLightTheme } from './components/code-editor/src/code-mirror-lang.js'
|
|
@@ -250,10 +254,12 @@ export { isIndexSegment } from './components/form/src/form-path.js'
|
|
|
250
254
|
export { isNearScrollBottom } from './components/table/src/utils/table-utils.js'
|
|
251
255
|
export { isNullDraft } from './components/table/src/utils/table-edit-utils.js'
|
|
252
256
|
export { isNumberInputInterim } from './components/input-number/src/input-number-utils.js'
|
|
257
|
+
export { isRsBrandIconName } from './icons/brand.js'
|
|
253
258
|
export { isRsButtonFilledVariant } from './components/button/src/button-utils.js'
|
|
254
259
|
export { isRsDialogWidthPreset } from './components/dialog/src/dialog-utils.js'
|
|
255
260
|
export { isRsFormItemBoundControl } from './components/form/src/form-utils.js'
|
|
256
261
|
export { isRsIconName } from './icons/lucide.js'
|
|
262
|
+
export { isRsLocaleRegistered } from './locale/registry.js'
|
|
257
263
|
export { isRsLogLevel } from './components/log/src/log-utils.js'
|
|
258
264
|
export { isRsSplitPaneAutoSize } from './components/split-pane/src/split-pane-utils.js'
|
|
259
265
|
export { isRsTableApi } from './components/table/src/rs-table-api.js'
|
|
@@ -273,6 +279,7 @@ export { isTreeAncestorKey } from './components/tree/src/tree-utils.js'
|
|
|
273
279
|
export { joinLogLines } from './components/log/src/log-utils.js'
|
|
274
280
|
export { listBatchColumnTargets } from './components/table/src/utils/table-edit-utils.js'
|
|
275
281
|
export { listEditableCells } from './components/table/src/utils/table-edit-utils.js'
|
|
282
|
+
export { listRsLocales } from './locale/registry.js'
|
|
276
283
|
export { looksLikeIsoDateTimeWithTz } from './utils/iso-local-datetime.js'
|
|
277
284
|
export { lucideIconCount } from './icons/lucide.js'
|
|
278
285
|
export { mapRsTableSeriesToEChartsOption } from './components/table/src/utils/rs-table-echarts-adapter.js'
|
|
@@ -305,6 +312,7 @@ export { parseRsLogLevel } from './components/log/src/log-utils.js'
|
|
|
305
312
|
export { parseTimeValue } from './components/time-picker/src/time-picker-utils.js'
|
|
306
313
|
export { pickActiveAnchorHref } from './components/anchor/src/anchor-utils.js'
|
|
307
314
|
export { placeAnchoredPopup } from './components/_shared/src/overlay-utils.js'
|
|
315
|
+
export { prefersColorSchemeDark } from './theme/apply.js'
|
|
308
316
|
export { prefetchClipboardText } from './utils/rs-clipboard.js'
|
|
309
317
|
export { prewarmCodeMirrorEditor } from './components/code-editor/src/code-mirror-lang.js'
|
|
310
318
|
export { provideRsFormItemContext } from './components/form/src/form-utils.js'
|
|
@@ -316,12 +324,14 @@ export { readCodeFontSizePx } from './theme/css-token.js'
|
|
|
316
324
|
export { readCssLengthPx } from './theme/css-token.js'
|
|
317
325
|
export { readCssVar } from './theme/css-token.js'
|
|
318
326
|
export { readDocumentTheme } from './components/code-editor/src/code-editor-utils.js'
|
|
327
|
+
export { readResolvedTheme } from './theme/apply.js'
|
|
319
328
|
export { readRootFontSizePx } from './theme/css-token.js'
|
|
320
329
|
export { readTerminalFontFamily } from './theme/css-token.js'
|
|
321
330
|
export { readTerminalFontSizePx } from './theme/css-token.js'
|
|
322
331
|
export { readTerminalFontWeight } from './theme/css-token.js'
|
|
323
332
|
export { readTerminalFontWeightBold } from './theme/css-token.js'
|
|
324
333
|
export { readTerminalThemeFromCss } from './components/terminal/src/terminal-utils.js'
|
|
334
|
+
export { registerRsLocale } from './locale/registry.js'
|
|
325
335
|
export { removeUploadFileAt } from './components/upload/src/upload-utils.js'
|
|
326
336
|
export { renderMarkdown } from './components/markdown/src/markdown-utils.js'
|
|
327
337
|
export { renderMarkdownInline } from './components/markdown/src/markdown-utils.js'
|
|
@@ -358,6 +368,8 @@ export { resolveRsDialogWidthPx } from './components/dialog/src/dialog-utils.js'
|
|
|
358
368
|
export { resolveRsDrawerDimensionCss } from './components/drawer/src/drawer-utils.js'
|
|
359
369
|
export { resolveRsDrawerSizeCss } from './components/drawer/src/drawer-utils.js'
|
|
360
370
|
export { resolveRsDrawerSizePx } from './components/drawer/src/drawer-utils.js'
|
|
371
|
+
export { resolveRsLocaleDir } from './locale/registry.js'
|
|
372
|
+
export { resolveRsMessage } from './locale/registry.js'
|
|
361
373
|
export { resolveRuleMessage } from './components/form/src/form-rules.js'
|
|
362
374
|
export { resolveSelectAllState } from './components/table/src/utils/table-utils.js'
|
|
363
375
|
export { resolveSelectableRowKeys } from './components/table/src/utils/table-utils.js'
|
|
@@ -371,6 +383,7 @@ export { resolveTableTreeRowKey } from './components/table/src/utils/table-utils
|
|
|
371
383
|
export { resolveTableVirtualEnabled } from './components/table/src/utils/table-utils.js'
|
|
372
384
|
export { resolveTabsToClose } from './components/tabs/src/tabs-utils.js'
|
|
373
385
|
export { resolveTerminalTheme } from './components/terminal/src/terminal-utils.js'
|
|
386
|
+
export { resolveThemeMode } from './theme/apply.js'
|
|
374
387
|
export { resolveTreeCheckState } from './components/tree/src/tree-utils.js'
|
|
375
388
|
export { resolveTreeFieldNames } from './components/tree/src/tree-utils.js'
|
|
376
389
|
export { resolveTreeFocusKey } from './components/tree/src/tree-utils.js'
|
|
@@ -382,6 +395,8 @@ export { resolveVirtualListHeight } from './components/virtual-list/src/virtual-
|
|
|
382
395
|
export { resolveVisibleTabValues } from './components/tabs/src/tabs-utils.js'
|
|
383
396
|
export { restoreSelectValue } from './components/select/src/select-utils.js'
|
|
384
397
|
export { roundToPrecision } from './components/input-number/src/input-number-utils.js'
|
|
398
|
+
export { rsBrandIconAccentVar } from './icons/brand.js'
|
|
399
|
+
export { rsBrandIconNames } from './icons/brand.js'
|
|
385
400
|
export { rsCommonIconNames } from './icons/registry.js'
|
|
386
401
|
export { rsConfirm } from './composables/createRsDialog.js'
|
|
387
402
|
export { rsFeedbackIconClass } from './components/_shared/src/overlay-utils.js'
|
|
@@ -411,6 +426,7 @@ export { splitSizesEqual } from './components/split-pane/src/split-pane-utils.js
|
|
|
411
426
|
export { splitTreeLabelHighlight } from './components/tree/src/tree-utils.js'
|
|
412
427
|
export { stepEnabledIndex } from './components/_shared/src/overlay-utils.js'
|
|
413
428
|
export { stepNumberValue } from './components/input-number/src/input-number-utils.js'
|
|
429
|
+
export { subscribePreferredColorScheme } from './theme/apply.js'
|
|
414
430
|
export { supportsRsButtonTone } from './components/button/src/button-utils.js'
|
|
415
431
|
export { syslogSeverityOf } from './components/log/src/log-utils.js'
|
|
416
432
|
export { terminalShortcutLabel } from './components/terminal/src/terminal-utils.js'
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type RsDirMode, type RsLocale, type RsTextDirection } from './types';
|
|
2
|
+
export declare function resolveDirMode(mode: RsDirMode, locale: RsLocale): RsTextDirection;
|
|
3
|
+
/**
|
|
4
|
+
* 写入语言与书写方向。色值不在这里。
|
|
5
|
+
* `dir` 同时写元素的 HTML `dir` 与 `data-rs-dir`,Portal 跟 document 时才能翻。
|
|
6
|
+
*/
|
|
7
|
+
export declare function applyLocale(locale: RsLocale, dir?: RsDirMode, el?: HTMLElement): void;
|
|
8
|
+
export declare function readDocumentLocale(el?: HTMLElement | null): RsLocale;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { dirAttribute, localeAttribute } from "./types.js";
|
|
2
|
+
import { resolveRsLocaleDir } from "./registry.js";
|
|
3
|
+
//#region src/locale/apply.ts
|
|
4
|
+
function resolveDirMode(mode, locale) {
|
|
5
|
+
if (mode === "ltr" || mode === "rtl") return mode;
|
|
6
|
+
return resolveRsLocaleDir(locale);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* 写入语言与书写方向。色值不在这里。
|
|
10
|
+
* `dir` 同时写元素的 HTML `dir` 与 `data-rs-dir`,Portal 跟 document 时才能翻。
|
|
11
|
+
*/
|
|
12
|
+
function applyLocale(locale, dir = "auto", el = document.documentElement) {
|
|
13
|
+
const resolvedDir = resolveDirMode(dir, locale);
|
|
14
|
+
el.setAttribute(localeAttribute, locale);
|
|
15
|
+
el.setAttribute("lang", locale);
|
|
16
|
+
el.setAttribute("dir", resolvedDir);
|
|
17
|
+
el.setAttribute(dirAttribute, resolvedDir);
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { applyLocale, resolveDirMode };
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
export type RsI18nVars = Record<string, string | number>;
|
|
2
2
|
export type RsTranslateFn = (key: string, fallbackOrVars?: string | RsI18nVars, vars?: RsI18nVars) => string;
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* 插值:`{name}` 换成 vars。
|
|
5
|
+
* 复数(ICU 子集):`{count, plural, one {# item} other {# items}}`,
|
|
6
|
+
* 可用 `=0` / `=1`。`#` 换成数字。类别由 `Intl.PluralRules(locale)` 决定。
|
|
6
7
|
*/
|
|
7
|
-
export declare function interpolateRsMessage(template: string, vars?: RsI18nVars): string;
|
|
8
|
+
export declare function interpolateRsMessage(template: string, vars?: RsI18nVars, locale?: string): string;
|
|
8
9
|
/**
|
|
9
10
|
* 解析 t() 的第 2、3 参:既兼容 `t(key, fallback)`,也支持 `t(key, vars)`。
|
|
10
11
|
*/
|
|
@@ -1,15 +1,106 @@
|
|
|
1
1
|
//#region src/locale/interpolate.ts
|
|
2
|
+
var PLURAL_HEAD = /^\{(\w+),\s*plural\s*,/;
|
|
2
3
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
4
|
+
* 插值:`{name}` 换成 vars。
|
|
5
|
+
* 复数(ICU 子集):`{count, plural, one {# item} other {# items}}`,
|
|
6
|
+
* 可用 `=0` / `=1`。`#` 换成数字。类别由 `Intl.PluralRules(locale)` 决定。
|
|
5
7
|
*/
|
|
6
|
-
function interpolateRsMessage(template, vars) {
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
function interpolateRsMessage(template, vars, locale = "en-US") {
|
|
9
|
+
const withPlural = expandPluralBlocks(template, vars, locale);
|
|
10
|
+
if (!vars) return withPlural;
|
|
11
|
+
return withPlural.replace(/\{(\w+)\}/g, (matched, key) => {
|
|
9
12
|
const value = vars[key];
|
|
10
13
|
return value == null ? matched : String(value);
|
|
11
14
|
});
|
|
12
15
|
}
|
|
16
|
+
function expandPluralBlocks(template, vars, locale) {
|
|
17
|
+
let i = 0;
|
|
18
|
+
let out = "";
|
|
19
|
+
while (i < template.length) {
|
|
20
|
+
if (template[i] !== "{") {
|
|
21
|
+
out += template[i];
|
|
22
|
+
i += 1;
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
const parsed = parsePluralBlock(template, i);
|
|
26
|
+
if (!parsed) {
|
|
27
|
+
const end = template.indexOf("}", i);
|
|
28
|
+
if (end === -1) {
|
|
29
|
+
out += template.slice(i);
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
out += template.slice(i, end + 1);
|
|
33
|
+
i = end + 1;
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const raw = vars?.[parsed.name];
|
|
37
|
+
const n = typeof raw === "number" ? raw : Number(raw);
|
|
38
|
+
const clause = pickPluralClause(locale, n, parsed.clauses);
|
|
39
|
+
const numeral = Number.isFinite(n) ? String(n) : raw == null ? "" : String(raw);
|
|
40
|
+
out += clause.replace(/#/g, numeral);
|
|
41
|
+
i = parsed.end;
|
|
42
|
+
}
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
function parsePluralBlock(source, start) {
|
|
46
|
+
const head = PLURAL_HEAD.exec(source.slice(start));
|
|
47
|
+
if (!head) return null;
|
|
48
|
+
let i = start + head[0].length;
|
|
49
|
+
const clauses = /* @__PURE__ */ new Map();
|
|
50
|
+
while (i < source.length) {
|
|
51
|
+
while (source[i] === " " || source[i] === "\n" || source[i] === " ") i += 1;
|
|
52
|
+
if (source[i] === "}") return {
|
|
53
|
+
name: head[1],
|
|
54
|
+
clauses,
|
|
55
|
+
end: i + 1
|
|
56
|
+
};
|
|
57
|
+
let selector = "";
|
|
58
|
+
if (source[i] === "=") {
|
|
59
|
+
let j = i + 1;
|
|
60
|
+
while (j < source.length && source[j] >= "0" && source[j] <= "9") j += 1;
|
|
61
|
+
selector = source.slice(i, j);
|
|
62
|
+
i = j;
|
|
63
|
+
} else {
|
|
64
|
+
let j = i;
|
|
65
|
+
while (j < source.length && source[j] >= "a" && source[j] <= "z") j += 1;
|
|
66
|
+
selector = source.slice(i, j);
|
|
67
|
+
i = j;
|
|
68
|
+
}
|
|
69
|
+
if (!selector) return null;
|
|
70
|
+
while (source[i] === " " || source[i] === " ") i += 1;
|
|
71
|
+
if (source[i] !== "{") return null;
|
|
72
|
+
const inner = readBalanced(source, i);
|
|
73
|
+
if (!inner) return null;
|
|
74
|
+
clauses.set(selector, inner.text);
|
|
75
|
+
i = inner.end;
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
function readBalanced(source, open) {
|
|
80
|
+
if (source[open] !== "{") return null;
|
|
81
|
+
let depth = 0;
|
|
82
|
+
for (let i = open; i < source.length; i += 1) if (source[i] === "{") depth += 1;
|
|
83
|
+
else if (source[i] === "}") {
|
|
84
|
+
depth -= 1;
|
|
85
|
+
if (depth === 0) return {
|
|
86
|
+
text: source.slice(open + 1, i),
|
|
87
|
+
end: i + 1
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
function pickPluralClause(locale, n, clauses) {
|
|
93
|
+
if (Number.isFinite(n)) {
|
|
94
|
+
const exact = clauses.get(`=${n}`);
|
|
95
|
+
if (exact != null) return exact;
|
|
96
|
+
try {
|
|
97
|
+
const category = new Intl.PluralRules(locale).select(n);
|
|
98
|
+
const matched = clauses.get(category);
|
|
99
|
+
if (matched != null) return matched;
|
|
100
|
+
} catch {}
|
|
101
|
+
}
|
|
102
|
+
return clauses.get("other") ?? "";
|
|
103
|
+
}
|
|
13
104
|
/**
|
|
14
105
|
* 解析 t() 的第 2、3 参:既兼容 `t(key, fallback)`,也支持 `t(key, vars)`。
|
|
15
106
|
*/
|
package/dist/locale/messages.js
CHANGED
|
@@ -70,7 +70,7 @@ var zhCN = {
|
|
|
70
70
|
"pagination.prev": "上一页",
|
|
71
71
|
"pagination.next": "下一页",
|
|
72
72
|
"pagination.page": "页",
|
|
73
|
-
"pagination.summary": "
|
|
73
|
+
"pagination.summary": "{total, plural, other {共 # 条}}",
|
|
74
74
|
"pagination.jumpTo": "跳至",
|
|
75
75
|
"pagination.jumpPageSuffix": "页",
|
|
76
76
|
"pagination.jumpConfirm": "确定",
|
|
@@ -167,7 +167,7 @@ var zhCN = {
|
|
|
167
167
|
"log.copied": "已复制",
|
|
168
168
|
"log.copyFailed": "复制失败,请用 HTTPS 或手动选择正文",
|
|
169
169
|
"log.filter": "按级别过滤",
|
|
170
|
-
"log.newLines": "
|
|
170
|
+
"log.newLines": "{count, plural, other {新增 # 行}}",
|
|
171
171
|
"log.lineNo": "第 {n} 行",
|
|
172
172
|
"log.level.trace": "跟踪",
|
|
173
173
|
"log.level.debug": "调试",
|
|
@@ -303,7 +303,7 @@ var enUS = {
|
|
|
303
303
|
"pagination.prev": "Previous",
|
|
304
304
|
"pagination.next": "Next",
|
|
305
305
|
"pagination.page": "page",
|
|
306
|
-
"pagination.summary": "
|
|
306
|
+
"pagination.summary": "{total, plural, one {# item} other {# items}}",
|
|
307
307
|
"pagination.jumpTo": "Go to",
|
|
308
308
|
"pagination.jumpPageSuffix": "page",
|
|
309
309
|
"pagination.jumpConfirm": "Go",
|
|
@@ -400,7 +400,7 @@ var enUS = {
|
|
|
400
400
|
"log.copied": "Copied",
|
|
401
401
|
"log.copyFailed": "Copy failed. Use HTTPS or select the log text.",
|
|
402
402
|
"log.filter": "Filter levels",
|
|
403
|
-
"log.newLines": "{count} new lines",
|
|
403
|
+
"log.newLines": "{count, plural, one {# new line} other {# new lines}}",
|
|
404
404
|
"log.lineNo": "Line {n}",
|
|
405
405
|
"log.level.trace": "Trace",
|
|
406
406
|
"log.level.debug": "Debug",
|
|
@@ -465,9 +465,5 @@ var enUS = {
|
|
|
465
465
|
"markdown.placeholder": "Markdown supported (headings, lists, links, code…)",
|
|
466
466
|
"markdown.empty": "Nothing to preview"
|
|
467
467
|
};
|
|
468
|
-
var localeMap = {
|
|
469
|
-
"zh-CN": zhCN,
|
|
470
|
-
"en-US": enUS
|
|
471
|
-
};
|
|
472
468
|
//#endregion
|
|
473
|
-
export { enUS,
|
|
469
|
+
export { enUS, zhCN };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type RsLocale, type RsLocaleMessages, type RsTextDirection } from './types';
|
|
2
|
+
export interface RsLocalePack {
|
|
3
|
+
messages: RsLocaleMessages;
|
|
4
|
+
dir: RsTextDirection;
|
|
5
|
+
}
|
|
6
|
+
export declare function inferRsLocaleDir(code: string): RsTextDirection;
|
|
7
|
+
/**
|
|
8
|
+
* 登记或合并一种语言。第二次调用同码会覆盖已给的 key,并保留未改的 dir(除非这次传了 dir)。
|
|
9
|
+
* 内置 `zh-CN` / `en-US` 启动时已登记;第三方只调这一次即可被 `RsConfigProvider.locale` 使用。
|
|
10
|
+
*/
|
|
11
|
+
export declare function registerRsLocale(code: RsLocale, messages: RsLocaleMessages, options?: {
|
|
12
|
+
dir?: RsTextDirection;
|
|
13
|
+
}): void;
|
|
14
|
+
export declare function isRsLocaleRegistered(code: string): boolean;
|
|
15
|
+
export declare function listRsLocales(): string[];
|
|
16
|
+
export declare function resolveRsLocalePack(code: string): RsLocalePack;
|
|
17
|
+
export declare function resolveRsLocaleDir(code: string): RsTextDirection;
|
|
18
|
+
/** 缺 key:当前语言 → en-US → zh-CN。 */
|
|
19
|
+
export declare function resolveRsMessage(code: string, key: string): string | undefined;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { enUS, zhCN } from "./messages.js";
|
|
2
|
+
import "./types.js";
|
|
3
|
+
//#region src/locale/registry.ts
|
|
4
|
+
var packs = /* @__PURE__ */ new Map();
|
|
5
|
+
var RTL_LANG = /* @__PURE__ */ new Set([
|
|
6
|
+
"ar",
|
|
7
|
+
"he",
|
|
8
|
+
"fa",
|
|
9
|
+
"ur",
|
|
10
|
+
"ps",
|
|
11
|
+
"sd",
|
|
12
|
+
"yi"
|
|
13
|
+
]);
|
|
14
|
+
function inferRsLocaleDir(code) {
|
|
15
|
+
const base = code.trim().split(/[-_]/)[0]?.toLowerCase() ?? "";
|
|
16
|
+
return RTL_LANG.has(base) ? "rtl" : "ltr";
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 登记或合并一种语言。第二次调用同码会覆盖已给的 key,并保留未改的 dir(除非这次传了 dir)。
|
|
20
|
+
* 内置 `zh-CN` / `en-US` 启动时已登记;第三方只调这一次即可被 `RsConfigProvider.locale` 使用。
|
|
21
|
+
*/
|
|
22
|
+
function registerRsLocale(code, messages, options) {
|
|
23
|
+
const id = code.trim();
|
|
24
|
+
if (!id) throw new Error("registerRsLocale: code is required");
|
|
25
|
+
const prev = packs.get(id);
|
|
26
|
+
packs.set(id, {
|
|
27
|
+
messages: prev ? {
|
|
28
|
+
...prev.messages,
|
|
29
|
+
...messages
|
|
30
|
+
} : { ...messages },
|
|
31
|
+
dir: options?.dir ?? prev?.dir ?? inferRsLocaleDir(id)
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function isRsLocaleRegistered(code) {
|
|
35
|
+
return packs.has(code);
|
|
36
|
+
}
|
|
37
|
+
function listRsLocales() {
|
|
38
|
+
return [...packs.keys()];
|
|
39
|
+
}
|
|
40
|
+
function resolveRsLocaleDir(code) {
|
|
41
|
+
return packs.get(code)?.dir ?? inferRsLocaleDir(code);
|
|
42
|
+
}
|
|
43
|
+
/** 缺 key:当前语言 → en-US → zh-CN。 */
|
|
44
|
+
function resolveRsMessage(code, key) {
|
|
45
|
+
return packs.get(code)?.messages[key] ?? packs.get("en-US")?.messages[key] ?? packs.get("zh-CN")?.messages[key];
|
|
46
|
+
}
|
|
47
|
+
registerRsLocale("zh-CN", zhCN, { dir: "ltr" });
|
|
48
|
+
registerRsLocale("en-US", enUS, { dir: "ltr" });
|
|
49
|
+
//#endregion
|
|
50
|
+
export { inferRsLocaleDir, isRsLocaleRegistered, listRsLocales, registerRsLocale, resolveRsLocaleDir, resolveRsMessage };
|
package/dist/locale/types.d.ts
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
/** 内置语言。第三方用 `registerRsLocale` 加 BCP-47 码。 */
|
|
2
|
+
export type RsBuiltinLocale = 'zh-CN' | 'en-US';
|
|
3
|
+
/** BCP-47。内置码可自动补全;注册后的任意码也合法。 */
|
|
4
|
+
export type RsLocale = RsBuiltinLocale | (string & {});
|
|
2
5
|
export type RsLocaleMessages = Record<string, string>;
|
|
3
|
-
export
|
|
6
|
+
export type RsTextDirection = 'ltr' | 'rtl';
|
|
7
|
+
/** 书写方向:auto 跟当前 locale 的 dir。 */
|
|
8
|
+
export type RsDirMode = RsTextDirection | 'auto';
|
|
9
|
+
export declare const defaultLocale: RsBuiltinLocale;
|
|
10
|
+
export declare const fallbackLocale: RsBuiltinLocale;
|
|
11
|
+
export declare const localeAttribute = "data-rs-locale";
|
|
12
|
+
export declare const dirAttribute = "data-rs-dir";
|
package/dist/locale/types.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
//#region src/locale/types.ts
|
|
2
2
|
var defaultLocale = "zh-CN";
|
|
3
|
+
var fallbackLocale = "en-US";
|
|
4
|
+
var localeAttribute = "data-rs-locale";
|
|
5
|
+
var dirAttribute = "data-rs-dir";
|
|
3
6
|
//#endregion
|
|
4
|
-
export { defaultLocale };
|
|
7
|
+
export { defaultLocale, dirAttribute, fallbackLocale, localeAttribute };
|