@autional/ui 0.1.0-rc.48 → 0.1.0-rc.49

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@autional/ui",
3
- "version": "0.1.0-rc.48",
4
- "description": "Autional shared React component library (atoms + molecules) �?the canonical home of the component layer",
3
+ "version": "0.1.0-rc.49",
4
+ "description": "Autional shared React component library (atoms + molecules) …the canonical home of the component layer",
5
5
  "license": "AGPL-3.0",
6
6
  "main": "./src/index.ts",
7
7
  "module": "./src/index.ts",
@@ -82,7 +82,7 @@
82
82
  "react-i18next": "17.0.7",
83
83
  "typescript": "5.8.3",
84
84
  "vitest": "3.2.0",
85
- "@autional/tokens": "0.1.0-rc.16"
85
+ "@autional/tokens": "0.1.0-rc.17"
86
86
  },
87
87
  "scripts": {
88
88
  "typecheck": "tsc --noEmit",
@@ -32,6 +32,14 @@ export const uiI18nResources: Record<'zh-CN' | 'en-US', Record<string, string>>
32
32
  // ThemeToggle 默认文案(UP-04:原为组件内硬编码中文,EN 站点顶栏出现中文标签)
33
33
  'theme.toggleDark': '切换到深色模式',
34
34
  'theme.toggleLight': '切换到浅色模式',
35
+ // 组件默认文案(语言问题审计 2026-10-13):原为组件内硬编码中文默认 ——
36
+ // EN 站裸露中文(trust 加载态「加载中...」线上实测)。文案逐字保留原硬编码值。
37
+ 'loadingScreen.message': '加载中...',
38
+ 'emptyState.title': '暂无数据',
39
+ 'emptyState.description': '当前没有可显示的内容。',
40
+ 'confirmDialog.confirm': '确认',
41
+ 'confirmDialog.cancel': '取消',
42
+ 'alert.close': '关闭',
35
43
  },
36
44
  'en-US': {
37
45
  'portal.switcher': 'Switch portal',
@@ -52,5 +60,12 @@ export const uiI18nResources: Record<'zh-CN' | 'en-US', Record<string, string>>
52
60
  'pageStatus.retry': 'Retry',
53
61
  'theme.toggleDark': 'Switch to dark mode',
54
62
  'theme.toggleLight': 'Switch to light mode',
63
+ // EN 词汇对齐舰队既有口径(Loading... / No data / Confirm / Cancel / Close)
64
+ 'loadingScreen.message': 'Loading...',
65
+ 'emptyState.title': 'No data',
66
+ 'emptyState.description': 'Nothing to display yet.',
67
+ 'confirmDialog.confirm': 'Confirm',
68
+ 'confirmDialog.cancel': 'Cancel',
69
+ 'alert.close': 'Close',
55
70
  },
56
71
  };
@@ -2,7 +2,9 @@
2
2
 
3
3
  import React from 'react';
4
4
  import { AlertTriangle, CheckCircle2, Info, X, XCircle } from 'lucide-react';
5
+ import { useTranslation } from 'react-i18next';
5
6
  import { SOFT_BORDER, SOFT_TEXT, type SemanticVariant } from '../internal/semantic-styles';
7
+ import { UI_I18N_NS, uiText } from '../i18n';
6
8
 
7
9
  // Alert —— 区块级提示(着色块)。
8
10
  //
@@ -67,9 +69,14 @@ export const Alert = React.memo(function Alert({
67
69
  action,
68
70
  closable = false,
69
71
  onClose,
70
- closeLabel = '关闭',
72
+ closeLabel,
71
73
  className = ''
72
74
  }: AlertProps) {
75
+ const { t, i18n } = useTranslation();
76
+ // 文案解析链与 Modal / ThemeToggle 同构(语言问题审计 2026-10-13):原为硬编码中文默认。
77
+ const closeLabelText =
78
+ closeLabel ??
79
+ t('alert.close', { ns: UI_I18N_NS, defaultValue: uiText(i18n.language, 'alert.close') ?? '关闭' });
73
80
  const glyph = icon === null ? null : (icon ?? DEFAULT_ICONS[variant]);
74
81
  return (
75
82
  // role="alert" 与 antd 的 Alert 一致:这些块绝大多数是**动作之后**才出现的(结果/失败原因),
@@ -89,7 +96,7 @@ export const Alert = React.memo(function Alert({
89
96
  <button
90
97
  type="button"
91
98
  onClick={onClose}
92
- aria-label={closeLabel}
99
+ aria-label={closeLabelText}
93
100
  className="-mr-1 -mt-1 shrink-0 rounded-md p-1 opacity-70 transition-opacity hover:opacity-100 focus-visible:outline focus-visible:outline-2"
94
101
  >
95
102
  <X className="h-4 w-4" />
@@ -1,6 +1,8 @@
1
1
  import React, { useCallback, useEffect } from 'react';
2
2
  import { createPortal } from 'react-dom';
3
3
  import { AlertTriangle, X } from 'lucide-react';
4
+ import { useTranslation } from 'react-i18next';
5
+ import { UI_I18N_NS, uiText } from '../i18n';
4
6
 
5
7
  interface ConfirmDialogProps {
6
8
  open: boolean;
@@ -32,12 +34,22 @@ export const ConfirmDialog = React.memo(function ConfirmDialog({
32
34
  open,
33
35
  title,
34
36
  description,
35
- confirmText = '确认',
36
- cancelText = '取消',
37
+ confirmText,
38
+ cancelText,
37
39
  variant = 'neutral',
38
40
  onConfirm,
39
41
  onCancel,
40
42
  }: ConfirmDialogProps) {
43
+ const { t, i18n } = useTranslation();
44
+ // 文案解析链与 Modal / ThemeToggle 同构(语言问题审计 2026-10-13):原为硬编码
45
+ // 中文默认('确认' / '取消' / X 按钮 '关闭')—— user 门户 5 处裸调用 EN 站裸露中文。
46
+ const resolve = (key: string, fallback: string): string =>
47
+ t(key, { ns: UI_I18N_NS, defaultValue: uiText(i18n.language, key) ?? fallback });
48
+ const confirmLabel = confirmText ?? resolve('confirmDialog.confirm', '确认');
49
+ const cancelLabel = cancelText ?? resolve('confirmDialog.cancel', '取消');
50
+ // X 按钮与 Modal 同键(同为对话框关闭,文案一致)
51
+ const closeLabel = resolve('modal.close', '关闭');
52
+
41
53
  const handleKeyDown = useCallback(
42
54
  (e: KeyboardEvent) => {
43
55
  if (e.key === 'Escape') onCancel();
@@ -69,7 +81,7 @@ export const ConfirmDialog = React.memo(function ConfirmDialog({
69
81
  <button
70
82
  onClick={onCancel}
71
83
  className="absolute right-4 top-4 text-[var(--color-text-muted)] hover:text-[var(--color-text-secondary)]"
72
- aria-label="关闭"
84
+ aria-label={closeLabel}
73
85
  >
74
86
  <X className="h-4 w-4" />
75
87
  </button>
@@ -89,13 +101,13 @@ export const ConfirmDialog = React.memo(function ConfirmDialog({
89
101
  onClick={onCancel}
90
102
  className="rounded-md border border-[var(--color-border-subtle)] bg-[var(--color-bg-surface)] px-4 py-2 text-sm font-medium text-[var(--color-text-primary)] transition-colors hover:bg-[var(--color-bg-muted)]"
91
103
  >
92
- {cancelText}
104
+ {cancelLabel}
93
105
  </button>
94
106
  <button
95
107
  onClick={onConfirm}
96
108
  className={`rounded-md px-4 py-2 text-sm font-medium transition-colors ${style.confirm}`}
97
109
  >
98
- {confirmText}
110
+ {confirmLabel}
99
111
  </button>
100
112
  </div>
101
113
  </div>
@@ -1,5 +1,7 @@
1
1
  import React from 'react';
2
2
  import { Inbox } from 'lucide-react';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { UI_I18N_NS, uiText } from '../i18n';
3
5
 
4
6
  interface EmptyStateProps {
5
7
  title?: string;
@@ -8,17 +10,24 @@ interface EmptyStateProps {
8
10
  }
9
11
 
10
12
  export const EmptyState = React.memo(function EmptyState({
11
- title = '暂无数据',
12
- description = '当前没有可显示的内容。',
13
+ title,
14
+ description,
13
15
  icon,
14
16
  }: EmptyStateProps) {
17
+ const { t, i18n } = useTranslation();
18
+ // 文案解析链与 Modal / ThemeToggle 同构(语言问题审计 2026-10-13):原为硬编码中文默认。
19
+ const resolve = (key: string, fallback: string): string =>
20
+ t(key, { ns: UI_I18N_NS, defaultValue: uiText(i18n.language, key) ?? fallback });
21
+ const titleText = title ?? resolve('emptyState.title', '暂无数据');
22
+ const descriptionText = description ?? resolve('emptyState.description', '当前没有可显示的内容。');
23
+
15
24
  return (
16
25
  <div className="flex flex-col items-center justify-center rounded-xl border border-dashed border-[var(--color-border-subtle)] bg-[var(--color-bg-muted)] px-4 py-12 text-center">
17
26
  <div className="flex h-12 w-12 items-center justify-center rounded-full bg-[var(--color-bg-muted)] text-[var(--color-text-muted)]">
18
27
  {icon ?? <Inbox className="h-6 w-6" />}
19
28
  </div>
20
- <h3 className="mt-4 text-base font-semibold text-[var(--color-text-primary)]">{title}</h3>
21
- <p className="mt-1 text-sm text-[var(--color-text-secondary)]">{description}</p>
29
+ <h3 className="mt-4 text-base font-semibold text-[var(--color-text-primary)]">{titleText}</h3>
30
+ <p className="mt-1 text-sm text-[var(--color-text-secondary)]">{descriptionText}</p>
22
31
  </div>
23
32
  );
24
33
  });
@@ -1,4 +1,6 @@
1
1
  import { Loader2 } from 'lucide-react';
2
+ import { useTranslation } from 'react-i18next';
3
+ import { UI_I18N_NS, uiText } from '../i18n';
2
4
 
3
5
  export interface LoadingScreenProps {
4
6
  message?: string;
@@ -7,14 +9,24 @@ export interface LoadingScreenProps {
7
9
  }
8
10
 
9
11
  export function LoadingScreen({
10
- message = '加载中...',
12
+ message,
11
13
  fullScreen = false,
12
14
  className = '',
13
15
  }: LoadingScreenProps) {
16
+ const { t, i18n } = useTranslation();
17
+ // 文案解析链与 Modal / ThemeToggle 同构(语言问题审计 2026-10-13):
18
+ // 原为硬编码中文默认,EN 站加载态裸露「加载中...」(trust 线上实测)。
19
+ const text =
20
+ message ??
21
+ t('loadingScreen.message', {
22
+ ns: UI_I18N_NS,
23
+ defaultValue: uiText(i18n.language, 'loadingScreen.message') ?? '加载中...',
24
+ });
25
+
14
26
  const content = (
15
27
  <div className="flex flex-col items-center justify-center gap-3">
16
28
  <Loader2 size={fullScreen ? 32 : 24} className="animate-spin text-[var(--color-brand)]" />
17
- <p className="text-sm text-[var(--color-text-secondary)]">{message}</p>
29
+ <p className="text-sm text-[var(--color-text-secondary)]">{text}</p>
18
30
  </div>
19
31
  );
20
32