operp-print-designer 1.1.4 → 1.1.6

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/README.md CHANGED
@@ -58,6 +58,83 @@ function Previewer() {
58
58
  | `dataSource` | `PrintDesignerDataSource` | 否 | 外部数据源,传入后优先于模板内部数据源用于渲染和打印 |
59
59
  | `onSave` | `(data: TemplateData) => void` | 否 | 保存回调函数,当用户点击保存按钮时触发 |
60
60
  | `onPrint` | `() => void` | 否 | 打印回调函数,当用户点击打印按钮时触发 |
61
+ | `locale` | `'zh-CN' \| 'en-US' \| 'ja-JP' \| 'auto'` | 否 | 界面语言,默认 `'zh-CN'`;传 `'auto'` 自动跟随宿主应用语言 |
62
+
63
+ ## 多语言(i18n)
64
+
65
+ 组件内置基于 [i18next](https://www.i18next.com/) 的多语言支持,目前提供 **简体中文 / English / 日本語** 三种语言。
66
+ 只需传入 `locale` 属性即可切换语言,组件内部全部界面文案(工具栏、面板标题、属性项、按钮、提示、弹窗等)以及 antd 内置文案(ColorPicker、Empty、Popconfirm 等)都会同步切换。
67
+
68
+ ```tsx
69
+ import { useState } from 'react';
70
+ import PrintDesigner, { type Locale } from 'operp-print-designer';
71
+
72
+ function App() {
73
+ const [locale, setLocale] = useState<Locale>('zh-CN');
74
+
75
+ return (
76
+ <PrintDesigner
77
+ locale={locale} // 'zh-CN' | 'en-US' | 'ja-JP'
78
+ initialTemplateData={templateData}
79
+ onSave={(data) => console.log(data)}
80
+ />
81
+ );
82
+ }
83
+ ```
84
+
85
+ ### 切换语言
86
+
87
+ `locale` 是响应式属性,改变后组件会立即重新渲染并切换文案:
88
+
89
+ ```tsx
90
+ <button onClick={() => setLocale(locale === 'zh-CN' ? 'en-US' : 'zh-CN')}>切换语言</button>
91
+ ```
92
+
93
+ ### 自动跟随宿主语言(`locale="auto"`)
94
+
95
+ 宿主应用自己有多语言切换时,传 `'auto'` 即可让设计器跟随,**无需自己同步状态**:
96
+
97
+ ```tsx
98
+ <PrintDesigner locale="auto" />
99
+ ```
100
+
101
+ 探测优先级(高 → 低):
102
+
103
+ 1. 宿主的 i18next 实例(`<I18nextProvider>` 注入的、或 `i18next.use(initReactI18next).init()` 初始化的、或仅 `i18next.init()` 的全局单例),并订阅其 `languageChanged` 事件实时跟随;
104
+ 2. `<html lang>`(监听其变化);
105
+ 3. `navigator.language`(监听浏览器的 `languagechange` 事件);
106
+ 4. 都未命中时回退 `'zh-CN'`。
107
+
108
+ 语言写法兼容 `'zh'` / `'en'` / `'ja'` / `'zh_CN'` / `'zh-Hant'` 等,自动归一化到最近的支持语言。
109
+ 不使用 i18next 的宿主也可以显式传具体语言:`<PrintDesigner locale={currentLang} />`。
110
+
111
+ ### 语言相关导出
112
+
113
+ ```tsx
114
+ import {
115
+ printDesignerI18n, // 组件库内部独立的 i18next 实例
116
+ DEFAULT_LOCALE, // 'zh-CN'
117
+ SUPPORTED_LOCALES, // ['zh-CN', 'en-US', 'ja-JP']
118
+ LOCALE_NAMES, // { 'zh-CN': '简体中文', 'en-US': 'English', 'ja-JP': '日本語' }
119
+ matchLocale, // 匹配不到返回 null(不做兜底),供自定义探测逻辑使用
120
+ normalizeLocale, // 兼容 'zh' / 'zh_cn' / 'en' 等写法,归一化为标准 locale
121
+ detectEnvironmentLocale, // 从 <html lang> / navigator 探测当前环境语言
122
+ useResolvedLocale, // 完整的解析 hook(含跟随宿主变化的逻辑)
123
+ useHostI18nInstance, // 读取宿主的 i18next 实例
124
+ } from 'operp-print-designer';
125
+ ```
126
+
127
+ ### 注意
128
+
129
+ - 组件库使用 **独立的 i18next 实例**(`createInstance`)并通过 `I18nextProvider` 注入,不会影响宿主应用自身的 i18n 配置,也不会注册为 react-i18next 的全局实例。
130
+ - `i18next` / `react-i18next` 是 **peerDependencies**(不重复打包),与宿主共用同一份模块实例——这也是 `locale="auto"` 能读到宿主语言的前提。npm 7+ 会自动安装;如使用 pnpm 并关闭了 `auto-install-peers`,请确保宿主已安装这两个包。
131
+ - 语言包使用**平铺键值对**(如 `'toolbar.new'`),需要扩展/覆盖文案时可调用:
132
+
133
+ ```tsx
134
+ printDesignerI18n.addResourceBundle('en-US', 'translation', {
135
+ 'toolbar.new': 'Create',
136
+ }, true, true);
137
+ ```
61
138
 
62
139
  ## 类型定义
63
140
 
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { PrintDesignerDataSource, TemplateData } from '../../types';
3
+ import { type LocaleOption } from '../../i18n';
3
4
  export interface PrintDesignerProps {
4
5
  /** 是否为预览模式(只读) */
5
6
  isPreview?: boolean;
@@ -11,6 +12,22 @@ export interface PrintDesignerProps {
11
12
  onSave?: (templateData: TemplateData) => void;
12
13
  /** 打印回调 */
13
14
  onPrint?: () => void;
15
+ /**
16
+ * 界面语言。
17
+ * - 具体语言:`'zh-CN' | 'en-US' | 'ja-JP'`,也兼容 `'zh'` / `'en'` / `'zh_CN'` 等简写
18
+ * - `'auto'`:自动跟随宿主应用(宿主 i18next 实例 → `<html lang>` → `navigator.language`)
19
+ * @default 'zh-CN'
20
+ */
21
+ locale?: LocaleOption | (string & {});
14
22
  }
23
+ /**
24
+ * 打印设计器入口。
25
+ *
26
+ * `locale` 支持三种用法:
27
+ * - `'zh-CN' | 'en-US' | 'ja-JP'`(默认 `'zh-CN'`):固定语言;
28
+ * - `'auto'`:自动跟随宿主应用的语言(宿主 i18next 实例 → `<html lang>` → `navigator.language`),
29
+ * 宿主切换语言时同步切换;此时无需传 `i18n.language`,宿主零改动即可跟随;
30
+ * - 其它语言简写(`'zh'` / `'en'` / `'ja'` / `'zh_CN'` 等):自动归一化。
31
+ */
15
32
  declare const PrintDesigner: React.FC<PrintDesignerProps>;
16
33
  export default PrintDesigner;
@@ -1,11 +1,16 @@
1
- import { PaperSizePreset } from '../types';
1
+ import { PaperSizePreset, CanvasComponentType } from '../types';
2
2
  /** 纸张预设尺寸 - 宽高 mm (portrait) */
3
3
  export declare const PAPER_SIZES: Record<Exclude<PaperSizePreset, 'custom'>, {
4
4
  width: number;
5
5
  height: number;
6
6
  }>;
7
- /** 默认页面设置 */
8
- export declare const DEFAULT_PAGE_SETTINGS: {
7
+ /**
8
+ * 创建默认页面设置。
9
+ *
10
+ * 以函数形式提供,保证页眉/页脚/页码等种子文案随当前语言实时生成,
11
+ * 而不是在模块加载时被固定成某一种语言。
12
+ */
13
+ export declare function createDefaultPageSettings(): {
9
14
  paperSize: PaperSizePreset;
10
15
  customWidth: number;
11
16
  customHeight: number;
@@ -28,51 +33,7 @@ export declare const DEFAULT_GRID_SETTINGS: {
28
33
  cellSize: number;
29
34
  cols: number;
30
35
  };
31
- /** 组件类型中文名 */
32
- export declare const COMPONENT_TYPE_LABELS: Record<string, string>;
33
- /** 组件类型默认属性 */
34
- export declare const COMPONENT_DEFAULTS: {
35
- text: {
36
- content: string;
37
- fontSize: number;
38
- fontWeight: "normal";
39
- fontStyle: "normal";
40
- textAlign: "left";
41
- color: string;
42
- backgroundColor: string;
43
- format: string;
44
- };
45
- image: {
46
- src: string;
47
- fit: "contain";
48
- content: string;
49
- };
50
- table: {
51
- rows: number;
52
- cols: number;
53
- borderWidth: number;
54
- borderColor: string;
55
- headerBackgroundColor: string;
56
- headerColor: string;
57
- headerFontSize: number;
58
- content: string;
59
- };
60
- barcode: {
61
- value: string;
62
- format: "CODE128";
63
- content: string;
64
- };
65
- qrcode: {
66
- value: string;
67
- errorLevel: "M";
68
- color: string;
69
- backgroundColor: string;
70
- content: string;
71
- };
72
- line: {
73
- color: string;
74
- thickness: number;
75
- style: "solid";
76
- content: string;
77
- };
78
- };
36
+ /** 获取组件类型名称(跟随当前语言) */
37
+ export declare function getComponentTypeLabel(type: CanvasComponentType | string): string;
38
+ /** 创建组件类型默认属性(跟随当前语言) */
39
+ export declare function createComponentDefaults(type: CanvasComponentType): Record<string, unknown>;
@@ -0,0 +1,7 @@
1
+ import type { Locale as AntdLocale } from 'antd/es/locale';
2
+ import type { Locale } from './index';
3
+ /**
4
+ * antd 内置文案(ColorPicker、Empty、Table、Popconfirm 等)对应的语言包。
5
+ * 通过 antd ConfigProvider 注入,使第三方组件文案跟随 locale 切换。
6
+ */
7
+ export declare const ANTD_LOCALES: Record<Locale, AntdLocale>;
@@ -0,0 +1,37 @@
1
+ import { type i18n as I18nInstance } from 'i18next';
2
+ /** 支持的Locale */
3
+ export type Locale = 'zh-CN' | 'en-US' | 'ja-JP';
4
+ /** 默认Locale */
5
+ export declare const DEFAULT_LOCALE: Locale;
6
+ /** 全部支持的Locale列表 */
7
+ export declare const SUPPORTED_LOCALES: Locale[];
8
+ /** 各Locale对应的显示名称 */
9
+ export declare const LOCALE_NAMES: Record<Locale, string>;
10
+ /** locale 属性的可取值:具体语言,或 'auto'(自动跟随宿主运行环境) */
11
+ export type LocaleOption = Locale | 'auto';
12
+ /**
13
+ * 尝试把输入匹配到受支持的 Locale(兼容 zh、zh-CN、zh_cn、zh-Hant、en、ja 等写法)。
14
+ * 匹配不到返回 null,不做兜底 —— 供「自动探测」按优先级逐个候选源尝试。
15
+ */
16
+ export declare function matchLocale(locale?: string | null): Locale | null;
17
+ /** 归一化外部传入的 locale(兼容 zh、zh-CN、zh_cn、en、ja 等写法),匹配不到时回退默认语言 */
18
+ export declare function normalizeLocale(locale?: string | null): Locale;
19
+ /**
20
+ * 从运行环境(DOM / 浏览器)探测语言,作为宿主 i18next 实例不可用时的兜底:
21
+ * `<html lang>` → `navigator.language` → `navigator.languages`。
22
+ */
23
+ export declare function detectEnvironmentLocale(): Locale | null;
24
+ /**
25
+ * 组件库独立 i18n 实例。
26
+ *
27
+ * 使用 `createInstance` 而不是 i18next 的默认单例,避免污染宿主应用自己的 i18next 实例。
28
+ * 组件内部通过 `<I18nextProvider i18n={printDesignerI18n}>` 使用该实例。
29
+ *
30
+ * 注意:这里【不能】调用 `.use(initReactI18next)` —— 那会把本实例注册为 react-i18next 的
31
+ * 全局实例(`setI18n`),导致宿主未初始化 i18n 时 `getI18n()` 读到组件库自己,
32
+ * 干扰 `locale="auto"` 对宿主语言的探测。组件内部统一由 I18nextProvider 提供实例。
33
+ */
34
+ export declare const printDesignerI18n: I18nInstance;
35
+ /** 非 React 模块(store / constants)中使用的翻译函数 */
36
+ export declare const t: typeof printDesignerI18n.t;
37
+ export default printDesignerI18n;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * English (US) language pack (flat key-value pairs)
3
+ */
4
+ declare const enUS: Record<string, unknown>;
5
+ export default enUS;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * 日本語(ja-JP)言語パック(フラットなキー・バリュー形式)
3
+ */
4
+ declare const jaJP: Record<string, unknown>;
5
+ export default jaJP;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * 简体中文语言包(平铺键值对)
3
+ */
4
+ declare const zhCN: Record<string, unknown>;
5
+ export default zhCN;
@@ -0,0 +1,23 @@
1
+ import type { i18n as I18nInstance } from 'i18next';
2
+ import { type Locale, type LocaleOption } from './index';
3
+ /**
4
+ * 读取宿主应用的 i18next 实例,并在宿主切换语言时触发重渲染。
5
+ *
6
+ * 取值优先级:
7
+ * 1. React 上下文里的实例(宿主使用 `<I18nextProvider>` 的场景);
8
+ * 2. `initReactI18next` 注册的实例(宿主使用 `i18next.use(initReactI18next).init()` 的场景);
9
+ * 3. i18next 全局单例(宿主仅 `i18next.init()` 的场景,且已初始化)。
10
+ *
11
+ * 前提:组件库把 i18next / react-i18next 声明为 peerDependency(不重复打包),
12
+ * 这样宿主与组件库指向同一份模块实例,才能读到宿主的语言。
13
+ */
14
+ export declare function useHostI18nInstance(): I18nInstance | null;
15
+ /**
16
+ * 解析最终生效的界面语言。
17
+ *
18
+ * - 传入具体语言:归一化后直接使用(兼容 'zh' / 'en' / 'zh_CN' 等写法);
19
+ * - 传入 `'auto'`:按「宿主 i18next 实例 → `<html lang>` → `navigator.language`」顺序探测,
20
+ * 并持续跟随宿主变化(宿主实例的 languageChanged 事件、`<html lang>` 的变更、浏览器语言变化)。
21
+ */
22
+ export declare function useResolvedLocale(locale?: string): Locale;
23
+ export type { Locale, LocaleOption };
package/dist/index.d.ts CHANGED
@@ -5,3 +5,6 @@ export type { PrintDesignerProps } from './components/PrintDesigner';
5
5
  export type { CanvasComponent, CanvasComponentType, PageSettings, GridSettings, TemplateData, DataSource, DataSourceType, PrintDesignerDataSource, TableColumnConfig, DataBinding, DataBindingConfig, } from './types';
6
6
  export { getRenderValue, getObjectFromDataSource, getArrayFromDataSource, formatRenderValue, safeParseJSON, getValueByPath, } from './utils/dataHelper';
7
7
  export { useDesignerStore } from './store';
8
+ export { printDesignerI18n, DEFAULT_LOCALE, SUPPORTED_LOCALES, LOCALE_NAMES, matchLocale, normalizeLocale, detectEnvironmentLocale, } from './i18n';
9
+ export type { Locale, LocaleOption } from './i18n';
10
+ export { useResolvedLocale, useHostI18nInstance } from './i18n/useResolvedLocale';