nfx-ui 0.1.4 → 0.2.0

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
@@ -1,198 +1,293 @@
1
- # NFX-UI — Unified Frontend UI Library
2
- # NFX-UI — 统一前端 UI 库
1
+ # NFX-UI — Unified Frontend UI Library
3
2
 
4
- **NFX-UI = NebulaForgeX UI Library**
5
- **NFX-UI = NebulaForgeX 前端 UI 库**
3
+ **NFX-UI** is the shared frontend UI library of the NebulaForgeX ecosystem. It provides React components, design tokens, theme system, layout primitives, i18n, and utilities for a consistent look and behavior across NFX Console and other applications. Built with **React 18/19**, **TypeScript**, and **Vite** (library mode), NFX-UI is distributed as ESM/CJS with inlined styles and full type definitions—no separate CSS import required.
6
4
 
7
5
  <div align="center">
8
6
  <img src="https://github.com/NebulaForgeX/NFX-UI/raw/main/docs/image1.png" alt="NFX-UI Logo" width="200">
9
7
  </div>
10
8
 
11
- **English:**
12
- **NFX-UI** is the shared frontend UI library of the NebulaForgeX ecosystem. It provides React components, design tokens, theme system, layout primitives, i18n, and utilities for a consistent look and behavior across NFX Console and other applications. Built with **React 18/19**, **TypeScript**, and **Vite** (library mode), NFX-UI is distributed as ESM/CJS with inlined styles and full type definitions—no separate CSS import required.
9
+ ---
10
+
11
+ ## How to use in your app
12
+
13
+ ### 1. Install
14
+
15
+ - **Option A:** After publishing to npm, run `npm install nfx-ui` in your app.
16
+ - **Option B:** When unpublished, run `npm run build` and `npm link` in NFX-UI, then `npm link nfx-ui` in your app.
17
+ - If your environment requires a script (e.g. `source /volume1/use-menv.sh`) before npm, run it first.
18
+
19
+ ```bash
20
+ # Option A (in your app)
21
+ npm install nfx-ui
22
+
23
+ # Option B
24
+ # Step 1: in NFX-UI repo
25
+ cd /path/to/NFX-UI
26
+ npm run link
27
+
28
+ # Step 2: in your app
29
+ cd /path/to/your-app
30
+ npm link nfx-ui
31
+ ```
32
+
33
+ ### 2. Peer dependencies
34
+
35
+ Your project must have `react` and `react-dom` (^18.0.0 or ^19.0.0). For themes, charts, etc., you may need `lucide-react`, `recharts`, `@tanstack/react-query`, `zustand` (see NFX-UI `package.json` peerDependencies).
36
+
37
+ ### 3. Usage
38
+
39
+ Use **subpath imports**; no separate CSS import. Components have typed props; use `import type { ... } from "nfx-ui/..."` for types; styles are inlined.
40
+
41
+ ```tsx
42
+ import { ThemeProvider } from "nfx-ui/themes";
43
+ import { LanguageProvider } from "nfx-ui/languages";
44
+ import { LayoutProvider } from "nfx-ui/layouts";
45
+ import { Button, Input } from "nfx-ui/components";
46
+ import type { LanguageEnum } from "nfx-ui/languages";
47
+ import type { ApiErrorBody } from "nfx-ui/types";
48
+
49
+ export function App() {
50
+ return (
51
+ <ThemeProvider defaultTheme="default">
52
+ <LanguageProvider>
53
+ <LayoutProvider>
54
+ <Button>Confirm</Button>
55
+ <Input placeholder="Enter" />
56
+ </LayoutProvider>
57
+ </LanguageProvider>
58
+ </ThemeProvider>
59
+ );
60
+ }
61
+ ```
62
+
63
+ ### 4. Full steps in another project
64
+
65
+ 1. **Environment:** If required, run `source /volume1/use-menv.sh` (or your local equivalent) before any npm commands.
66
+ 2. **Install or link:** Published: `npm install nfx-ui`. Unpublished: run `npm run link` in NFX-UI, then `npm link nfx-ui` in this project.
67
+ 3. **Peer deps:** Ensure `react` and `react-dom` (v18 or v19) are in your project.
68
+ 4. **Optional runtime deps:** When using themes, icons, charts, etc., install `lucide-react`, `@tanstack/react-query`, `recharts`, `zustand` in your app (versions compatible with NFX-UI’s `package.json`).
69
+ 5. **Wrap with Providers:** Wrap your root with `ThemeProvider`, `LanguageProvider`, `LayoutProvider`, etc. (see code above).
70
+ 6. **Import by subpath:** `import { Button } from "nfx-ui/components"`, `import { useTheme } from "nfx-ui/themes"`, etc.; use `import type { ... } from "nfx-ui/types"` for types.
71
+ 7. **Build & run:** Use your usual scripts (`npm run dev` / `npm run build`); the bundler will resolve nfx-ui and tree-shake unused exports.
72
+
73
+ ---
74
+
75
+ ## What’s included
76
+
77
+ Main modules and contents below; full component and API docs: [docs/](./docs/).
78
+
79
+ | Module | Contents |
80
+ |---------------|----------|
81
+ | **themes** | ThemeProvider, useTheme, theme vars |
82
+ | **languages** | LanguageProvider, i18n, useLanguageLabel, useThemeLabel |
83
+ | **layouts** | LayoutProvider, Sidebar, Header, Footer, Background |
84
+ | **components**| Button, Input, Dropdown, Slider, VirtualList, SlideDownSwitcher, etc. |
85
+ | **animations**| WaveBackground, ECGLoading, TruckLoading, BounceLoading, etc. |
86
+ | **hooks** | makeUnifiedQuery, makeUnifiedInfiniteQuery |
87
+ | **preference**| User preference (e.g. profile.preference) |
88
+ | **types** | Shared TypeScript types |
89
+ | **utils** | getApiErrorMessage, formatDisplayDate, retry, etc. |
90
+ | **constants** | Query key factories, defineEnum |
91
+
92
+ ---
93
+
94
+ ## Development (this repo)
95
+
96
+ ### Setup
97
+
98
+ This repo is library-only: no dev server or demo; test via `npm link` in a real app. Run `npm install` after clone.
99
+
100
+ ```bash
101
+ npm install
102
+ ```
103
+
104
+ ### Build
105
+
106
+ Run `npm run build`. Output in `dist/`: ESM (`.mjs`), CJS (`.cjs`), and `.d.ts`; styles inlined.
107
+
108
+ ```bash
109
+ npm run build
110
+ ```
111
+
112
+ ### Build messages and warnings
113
+
114
+ You may see these during build; both are safe to ignore:
115
+ 1. **TypeScript version:** vite-plugin-dts uses an older TS in API Extractor; the “consider upgrading API Extractor” message does not affect type output.
116
+ 2. **PLUGIN_TIMINGS:** Plugin timing breakdown; informational only.
117
+
118
+ ### Test locally (npm link)
119
+
120
+ 1. In NFX-UI: `npm run link`.
121
+ 2. In your app: `npm link nfx-ui`.
122
+ 3. After changing NFX-UI, run `npm run build` in NFX-UI again.
123
+
124
+ ### Lint & format
125
+
126
+ `npm run lint` for ESLint; `npm run lint:code-format` for Prettier check; `npm run format` for Prettier write.
127
+
128
+ ```bash
129
+ npm run lint
130
+ npm run lint:code-format
131
+ npm run format
132
+ ```
133
+
134
+ ---
135
+
136
+ ## Project structure
137
+
138
+ `src/` contains entry and modules; path alias `@/` (points to `src/`) is used in this repo.
139
+
140
+ ```
141
+ src/
142
+ ├── designs/ # layouts, components, animations
143
+ ├── languages/ # i18n, LanguageProvider, useLanguageLabel, etc.
144
+ ├── themes/ # ThemeProvider, useTheme, theme data
145
+ ├── hooks/ # makeUnifiedQuery, makeUnifiedInfiniteQuery
146
+ ├── preference/ # User preference
147
+ ├── types/ # Shared types
148
+ ├── utils/ # Helpers
149
+ ├── constants/ # Query keys, enums
150
+ ├── stores/ # Zustand stores
151
+ ├── events/ # EventEmitter
152
+ ├── apis/ # API path helpers
153
+ └── ...
154
+ ```
155
+
156
+ ---
157
+
158
+ ## License
159
+
160
+ UNLICENSED (private use). Change the license in `package.json` if you publish.
161
+
162
+ ---
163
+
164
+ ---
165
+
166
+ # NFX-UI — 统一前端 UI 库
13
167
 
14
- **中文:**
15
168
  **NFX-UI** 是 NebulaForgeX 生态的统一前端 UI 库,提供 React 组件、设计令牌、主题系统、布局基元、多语言与工具函数,为 NFX 控制台及其他应用提供一致的外观与交互。基于 **React 18/19**、**TypeScript** 与 **Vite**(库模式)构建,以 ESM/CJS 发布,样式内联、类型完整,使用方无需单独引入 CSS。
16
169
 
17
170
  ---
18
171
 
19
- ## 外部项目如何使用 / How to use in your app
172
+ ## 外部项目如何使用
20
173
 
21
- ### 1. 安装 / Install
174
+ ### 1. 安装
22
175
 
23
- **中文:**
24
- - **方式 A**:发布到 npm 后,在业务项目中执行 `npm install nfx-ui`。
25
- - **方式 B**:未发布时,在 NFX-UI 目录执行 `npm run build` 与 `npm link`,在业务项目目录执行 `npm link nfx-ui`。
176
+ - **方式 A**:发布到 npm 后,在业务项目中执行 `npm install nfx-ui`。
177
+ - **方式 B**:未发布时,在 NFX-UI 目录执行 `npm run build` 与 `npm link`,在业务项目目录执行 `npm link nfx-ui`。
26
178
  - 若本机约定先加载环境(如 `source /volume1/use-menv.sh`),请在执行任何 npm 命令前先执行。
27
179
 
28
- **English:**
29
- - **Option A:** After publishing to npm, run `npm install nfx-ui` in your app.
30
- - **Option B:** When unpublished, run `npm run build` and `npm link` in NFX-UI, then `npm link nfx-ui` in your app.
31
- - If your environment requires a script (e.g. `source /volume1/use-menv.sh`) before npm, run it first.
32
-
33
180
  ```bash
34
- # 方式 A / Option A(在业务项目 / in your app)
181
+ # 方式 A(在业务项目)
35
182
  npm install nfx-ui
36
183
 
37
- # 方式 B / Option B
38
- # 步骤 1:在 NFX-UI 仓库 / Step 1: in NFX-UI repo
184
+ # 方式 B
185
+ # 步骤 1:在 NFX-UI 仓库
39
186
  cd /path/to/NFX-UI
40
187
  npm run link
41
188
 
42
- # 步骤 2:在要使用 NFX-UI 的项目 / Step 2: in your app
189
+ # 步骤 2:在要使用 NFX-UI 的项目
43
190
  cd /path/to/your-app
44
191
  npm link nfx-ui
45
192
  ```
46
193
 
47
- ### 2. 依赖要求 / Peer dependencies
194
+ ### 2. 依赖要求
48
195
 
49
- **中文:**
50
- 你的项目需已安装 `react`、`react-dom`(^18.0.0 或 ^19.0.0)。若使用主题、图表等,可能还需按需安装 `lucide-react`、`recharts`、`@tanstack/react-query` 等(见 NFX-UI 的 `package.json`)。
196
+ 你的项目需已安装 `react`、`react-dom`(^18.0.0 或 ^19.0.0)。若使用主题、图表等,可能还需按需安装 `lucide-react`、`recharts`、`@tanstack/react-query`、`zustand` 等(见 NFX-UI 的 `package.json` peerDependencies)。
51
197
 
52
- **English:**
53
- Your project must have `react` and `react-dom` (^18.0.0 or ^19.0.0). For themes, charts, etc., you may need `lucide-react`, `recharts`, `@tanstack/react-query` (see NFX-UI `package.json`).
198
+ ### 3. 在代码里使用
54
199
 
55
- ### 3. 在代码里使用 / Usage
56
-
57
- **中文:**
58
- 只需从 `nfx-ui` 引入组件或类型,无需单独引入 CSS。组件直接使用即有 props 类型提示;类型通过 `import type { ... } from "nfx-ui"` 获取;样式已内联,无需 `import "nfx-ui/dist/xxx.css"`。
59
-
60
- **English:**
61
- Import components or types from `nfx-ui`; no separate CSS import. Components have typed props; use `import type { ... } from "nfx-ui"` for types; styles are inlined.
200
+ 使用**子路径导入**,无需单独引入 CSS。组件直接使用即有 props 类型提示;类型通过 `import type { ... } from "nfx-ui/..."` 获取;样式已内联。
62
201
 
63
202
  ```tsx
64
- import {
65
- Button,
66
- Input,
67
- ThemeProvider,
68
- LanguageProvider,
69
- type LanguageEnum,
70
- type ApiErrorBody,
71
- } from "nfx-ui";
203
+ import { ThemeProvider } from "nfx-ui/themes";
204
+ import { LanguageProvider } from "nfx-ui/languages";
205
+ import { LayoutProvider } from "nfx-ui/layouts";
206
+ import { Button, Input } from "nfx-ui/components";
207
+ import type { LanguageEnum } from "nfx-ui/languages";
208
+ import type { ApiErrorBody } from "nfx-ui/types";
72
209
 
73
210
  export function App() {
74
211
  return (
75
- <ThemeProvider>
212
+ <ThemeProvider defaultTheme="default">
76
213
  <LanguageProvider>
77
- <Button>确定 / Confirm</Button>
78
- <Input placeholder="请输入 / Enter" />
214
+ <LayoutProvider>
215
+ <Button>确定</Button>
216
+ <Input placeholder="请输入" />
217
+ </LayoutProvider>
79
218
  </LanguageProvider>
80
219
  </ThemeProvider>
81
220
  );
82
221
  }
83
222
  ```
84
223
 
85
- ### 4. 其他项目中的完整步骤示例 / Full steps in another project
224
+ ### 4. 其他项目中的完整步骤示例
86
225
 
87
- **中文:**
88
226
  在「别的项目」里从零用上 NFX-UI 的推荐顺序:
89
227
 
90
- 1. **确保环境**:若团队要求,先执行 `source /volume1/use-menv.sh`(或你本机的等价命令)。
91
- 2. **安装或链接**:
92
- - 已发布:`npm install nfx-ui`
93
- - 未发布:在 NFX-UI 里执行 `npm run link`,再在本项目执行 `npm link nfx-ui`
94
- 3. **确认 peer**:项目里已有 `react`、`react-dom`(版本 18 或 19)。
95
- 4. **按需装运行时依赖**:用到主题/图标/图表等时,在业务项目安装 `lucide-react`、`@tanstack/react-query`、`recharts` 等(与 NFX-UI `package.json` 一致或兼容)。
96
- 5. **在入口外包一层 Provider**:在根组件外包上 `ThemeProvider`、`LanguageProvider` 等(见上面代码)。
97
- 6. **按需按名引入**:`import { Button, Input, ... } from "nfx-ui"`;类型用 `import type { ... } from "nfx-ui"`。
98
- 7. **构建与运行**:按你项目原有方式(如 `npm run dev` / `npm run build`)即可,打包器会从 `nfx-ui` 的 `main`/`module` 解析,并做 tree-shaking。
99
-
100
- **English:**
101
- Recommended order to use NFX-UI in “another project” from scratch:
102
-
103
- 1. **Environment:** If required, run `source /volume1/use-menv.sh` (or your local equivalent) before any npm commands.
104
- 2. **Install or link:**
105
- - Published: `npm install nfx-ui`
106
- - Unpublished: run `npm run link` in NFX-UI, then `npm link nfx-ui` in this project
107
- 3. **Peer deps:** Ensure `react` and `react-dom` (v18 or v19) are in your project.
108
- 4. **Optional runtime deps:** When using themes, icons, charts, etc., install `lucide-react`, `@tanstack/react-query`, `recharts` in your app (versions compatible with NFX-UI’s `package.json`).
109
- 5. **Wrap with Providers:** Wrap your root with `ThemeProvider`, `LanguageProvider`, etc. (see code above).
110
- 6. **Import by name:** `import { Button, Input, ... } from "nfx-ui"`; use `import type { ... } from "nfx-ui"` for types.
111
- 7. **Build & run:** Use your usual scripts (`npm run dev` / `npm run build`); the bundler will resolve `nfx-ui` and tree-shake unused exports.
228
+ 1. **确保环境**:若团队要求,先执行 `source /volume1/use-menv.sh`(或你本机的等价命令)。
229
+ 2. **安装或链接**:已发布:`npm install nfx-ui`。未发布:在 NFX-UI 里执行 `npm run link`,再在本项目执行 `npm link nfx-ui`。
230
+ 3. **确认 peer**:项目里已有 `react`、`react-dom`(版本 18 19)。
231
+ 4. **按需装运行时依赖**:用到主题/图标/图表等时,在业务项目安装 `lucide-react`、`@tanstack/react-query`、`recharts`、`zustand` 等(与 NFX-UI `package.json` 一致或兼容)。
232
+ 5. **在入口外包一层 Provider**:在根组件外包上 `ThemeProvider`、`LanguageProvider`、`LayoutProvider` 等(见上面代码)。
233
+ 6. **按子路径引入**:`import { Button } from "nfx-ui/components"`,`import { useTheme } from "nfx-ui/themes"` 等;类型用 `import type { ... } from "nfx-ui/types"`。
234
+ 7. **构建与运行**:按你项目原有方式(如 `npm run dev` / `npm run build`)即可,打包器会从 nfx-ui 解析并做 tree-shaking。
112
235
 
113
236
  ---
114
237
 
115
- ## 包含模块 / What’s included
238
+ ## 包含模块
116
239
 
117
- **中文:**
118
240
  下表为包内主要模块与内容;完整组件与 API 见 [docs/](./docs/)。
119
241
 
120
- **English:**
121
- Main modules and contents below; full component and API docs: [docs/](./docs/).
122
-
123
- | 模块 Module | 内容 Contents |
124
- |---------------|----------------|
125
- | **themes** | ThemeProviderThemeSwitcher、主题变量 / Theme vars |
126
- | **languages** | LanguageProvideri18nLanguageSwitcher |
127
- | **layouts** | LayoutProviderSidebar、Header、Footer、Background |
128
- | **components**| Button、Input、Dropdown、Slider、VirtualList / etc. |
129
- | **animations**| WaveBackground、ECGLoading、TruckLoading、BounceLoading / etc. |
130
- | **hooks** | makeUnifiedQuerymakeUnifiedInfiniteQuerymakeCursorFetchFunction |
131
- | **preference**| 用户偏好 / User preference (e.g. profile.preference) |
132
- | **types** | 共享 TypeScript 类型 / Shared types |
133
- | **utils** | 地址、电话、价格、时间、Result、retry 等 / Helpers |
134
- | **constants** | Query key 工厂、defineEnum 等 / Query keys, defineEnum |
242
+ | 模块 | 内容 |
243
+ |--------------|------|
244
+ | **themes** | ThemeProvider、useTheme、主题变量 |
245
+ | **languages**| LanguageProvider、i18n、useLanguageLabel、useThemeLabel |
246
+ | **layouts** | LayoutProvider、Sidebar、Header、Footer、Background |
247
+ | **components** | ButtonInput、Dropdown、Slider、VirtualList、SlideDownSwitcher |
248
+ | **animations** | WaveBackgroundECGLoadingTruckLoading、BounceLoading |
249
+ | **hooks** | makeUnifiedQuerymakeUnifiedInfiniteQuery |
250
+ | **preference** | 用户偏好(如 profile.preference) |
251
+ | **types** | 共享 TypeScript 类型 |
252
+ | **utils** | getApiErrorMessageformatDisplayDateretry |
253
+ | **constants**| Query key 工厂、defineEnum |
135
254
 
136
255
  ---
137
256
 
138
- ## 本仓库开发 / Development (this repo)
257
+ ## 本仓库开发
139
258
 
140
- ### 安装依赖 / Setup
259
+ ### 安装依赖
141
260
 
142
- **中文:**
143
261
  本仓库为纯库,无 dev 服务器或 demo,需在真实应用中通过 `npm link` 测试。克隆后执行 `npm install` 安装依赖。
144
262
 
145
- **English:**
146
- This repo is library-only: no dev server or demo; test via `npm link` in a real app. Run `npm install` after clone.
147
-
148
263
  ```bash
149
264
  npm install
150
265
  ```
151
266
 
152
- ### 构建 / Build
153
-
154
- **中文:**
155
- 执行 `npm run build`,产物在 `dist/`:ESM(index.mjs)、CJS(index.cjs)、类型(index.d.ts),样式已内联。
267
+ ### 构建
156
268
 
157
- **English:**
158
- Run `npm run build`. Output in `dist/`: ESM, CJS, and `.d.ts`; styles inlined.
269
+ 执行 `npm run build`,产物在 `dist/`:ESM(.mjs)、CJS(.cjs)、类型(.d.ts),样式已内联。
159
270
 
160
271
  ```bash
161
272
  npm run build
162
273
  ```
163
274
 
164
- ### 构建时的提示与警告 / Build messages and warnings
275
+ ### 构建时的提示与警告
165
276
 
166
- **中文:**
167
- 构建过程中可能出现以下提示,均可忽略,不影响产物:
168
- 1. **TypeScript 版本提示**:vite-plugin-dts 内置的 API Extractor 使用较旧 TS 版本,项目使用 5.9.x 时会提示 “consider upgrading API Extractor”,类型仍会正确生成。
169
- 2. **PLUGIN_TIMINGS**:Vite 输出的插件耗时统计(如 vite:dts 占 47%),仅作参考,无需处理。
277
+ 构建过程中可能出现以下提示,均可忽略,不影响产物:
278
+ 1. **TypeScript 版本提示**:vite-plugin-dts 内置的 API Extractor 使用较旧 TS 版本,项目使用 5.9.x 时会提示 “consider upgrading API Extractor”,类型仍会正确生成。
279
+ 2. **PLUGIN_TIMINGS**:Vite 输出的插件耗时统计,仅作参考,无需处理。
170
280
 
171
- **English:**
172
- You may see these during build; both are safe to ignore:
173
- 1. **TypeScript version**: vite-plugin-dts uses an older TS in API Extractor; the “consider upgrading API Extractor” message does not affect type output.
174
- 2. **PLUGIN_TIMINGS**: Plugin timing breakdown (e.g. vite:dts 47%); informational only.
281
+ ### 本地联调(npm link)
175
282
 
176
- ### 本地联调 / Test locally (npm link)
177
-
178
- **中文:**
179
- 1. 在 NFX-UI 目录执行 `npm run link`。
180
- 2. 在消费项目中执行 `npm link nfx-ui`。
283
+ 1. NFX-UI 目录执行 `npm run link`。
284
+ 2. 在消费项目中执行 `npm link nfx-ui`。
181
285
  3. 修改 NFX-UI 后需在 NFX-UI 目录再次执行 `npm run build` 才能生效。
182
286
 
183
- **English:**
184
- 1. In NFX-UI: `npm run link`.
185
- 2. In your app: `npm link nfx-ui`.
186
- 3. After changing NFX-UI, run `npm run build` in NFX-UI again.
187
-
188
- ### 代码检查与格式化 / Lint & format
287
+ ### 代码检查与格式化
189
288
 
190
- **中文:**
191
289
  `npm run lint` 运行 ESLint;`npm run lint:code-format` 检查 Prettier;`npm run format` 执行 Prettier 格式化。
192
290
 
193
- **English:**
194
- `npm run lint` for ESLint; `npm run lint:code-format` for Prettier check; `npm run format` for Prettier write.
195
-
196
291
  ```bash
197
292
  npm run lint
198
293
  npm run lint:code-format
@@ -201,35 +296,28 @@ npm run format
201
296
 
202
297
  ---
203
298
 
204
- ## 项目结构 / Project structure
299
+ ## 项目结构
205
300
 
206
- **中文:**
207
301
  `src/` 下为入口与各模块;本仓库内使用路径别名 `@/`(指向 `src/`)。
208
302
 
209
- **English:**
210
- `src/` contains entry and modules; path alias `@/` (points to `src/`) is used in this repo.
211
-
212
303
  ```
213
304
  src/
214
- ├── index.ts # 包入口 / Package entry
215
- ├── languages/ # i18n、LanguageProvider、LanguageSwitcher
216
- ├── themes/ # ThemeProvider、ThemeSwitcher、主题数据 / theme data
217
- ├── layouts/ # LayoutProviderSidebar、Header、Footer
218
- ├── components/ # Button、Input、Dropdown、…
219
- ├── animations/ # WaveBackground、loaders
220
- ├── hooks/ # Query、form、layout hooks
221
- ├── preference/ # 用户偏好 / User preference
222
- ├── types/ # 共享类型 / Shared types
223
- ├── utils/ # 工具函数 / Helpers
224
- └── constants/ # Query keys、枚举等 / Query keys, enums
305
+ ├── designs/ # layouts、components、animations
306
+ ├── languages/ # i18n、LanguageProvider、useLanguageLabel 等
307
+ ├── themes/ # ThemeProvider、useTheme、主题数据
308
+ ├── hooks/ # makeUnifiedQuerymakeUnifiedInfiniteQuery
309
+ ├── preference/ # 用户偏好
310
+ ├── types/ # 共享类型
311
+ ├── utils/ # 工具函数
312
+ ├── constants/ # Query keys、枚举等
313
+ ├── stores/ # Zustand stores
314
+ ├── events/ # EventEmitter
315
+ ├── apis/ # API path
316
+ └── ...
225
317
  ```
226
318
 
227
319
  ---
228
320
 
229
- ## License 许可证
321
+ ## 许可证
230
322
 
231
- **中文:**
232
323
  UNLICENSED(仅内部使用)。若对外发布请在 `package.json` 中修改许可证。
233
-
234
- **English:**
235
- UNLICENSED (private use). Change the license in `package.json` if you publish.
@@ -1 +1 @@
1
- {"version":3,"file":"events.cjs","names":[],"sources":["../src/events/EventEmitter.ts"],"sourcesContent":["/**\n * 通用事件发射器(按事件名注册/注销/触发)\n * Generic event emitter: subscribe, unsubscribe, and emit by event name.\n *\n * @example\n * ```ts\n * import { EventEmitter, defineEvents, type EventNamesOf } from \"@/events\";\n * const events = defineEvents({ FOO: \"MY:FOO\", BAR: \"MY:BAR\" });\n * type MyEvent = EventNamesOf<typeof events>;\n * class MyEmitter extends EventEmitter<MyEvent> { constructor() { super(events); } }\n * const em = new MyEmitter();\n * em.on(events.FOO, (x) => console.log(x));\n * em.emit(events.FOO, \"hello\");\n * ```\n */\n\nimport type { Defined } from \"@/types\";\n\n/** 事件回调类型:用于 on / off。Callback for on / off. */\ntype EventCallback = (...args: unknown[]) => void;\n\n/** 由 defineEvents 返回的「已规范事件名对象」类型;constructor 只接受此类型。 */\ntype DefinedEvents<T extends Record<string, string>> = Defined<T, \"events\">;\n\n/** 从 events 对象推导出事件名联合类型。Event name union from an events key-value object. */\ntype EventNamesOf<T> = T extends Defined<infer O, \"events\"> ? O[keyof O] : T extends Record<string, string> ? T[keyof T] : never;\n\n/**\n * 规范创建「一级 key-value」事件名对象:仅允许 key → 字符串 value,禁止嵌套(类型约束)。\n * 返回 DefinedEvents<T>,供 EventEmitter 构造使用。\n * Define events object: one-level key-value (string values), no nested objects (type-only). Returns DefinedEvents<T> for EventEmitter.\n *\n * @param events - 事件名 key-value 对象。Event name key-value object (e.g. { FOO: \"DOMAIN:FOO\" }).\n * @returns DefinedEvents<E>,仅此类型可传入 EventEmitter 构造。DefinedEvents<E>; only this type is accepted by EventEmitter constructor.\n * @example\n * ```ts\n * const routerEvents = defineEvents({ NAVIGATE: \"ROUTER:NAVIGATE\", NAVIGATE_BACK: \"ROUTER:NAVIGATE_BACK\" });\n * class RouterEmitter extends EventEmitter<EventNamesOf<typeof routerEvents>> { constructor() { super(routerEvents); } }\n * ```\n */\nfunction defineEvents<E extends Record<string, string>>(events: E): DefinedEvents<E> {\n return events as DefinedEvents<E>;\n}\n\nfunction createListenersMap<E extends string>(eventNames: readonly E[]): Record<E, Set<EventCallback>> {\n const map = {} as Record<E, Set<EventCallback>>;\n for (const e of eventNames) {\n map[e] = new Set();\n }\n return map;\n}\n\n/**\n * 泛型 EventEmitter:构造函数仅接受 defineEvents 返回的 DefinedEvents 类型,提供 on / off / emit。\n * Generic EventEmitter: constructor accepts only DefinedEvents (returned by defineEvents), provides on / off / emit.\n *\n * @param events - 须为 defineEvents(...) 的返回值(DefinedEvents)。Must be the return value of defineEvents(...) (DefinedEvents).\n */\nclass EventEmitter<E extends string> {\n private listeners: Record<E, Set<EventCallback>>;\n\n constructor(events: DefinedEvents<Record<string, E>>) {\n this.listeners = createListenersMap(Object.values(events as Record<string, E>));\n }\n\n /**\n * 注册事件监听。Register a listener for an event.\n *\n * @param event - 事件名。Event name.\n * @param callback - 回调。Callback (...args) => void.\n */\n on(event: E, callback: EventCallback): void {\n this.listeners[event].add(callback);\n }\n\n /**\n * 移除事件监听。Remove a listener for an event.\n *\n * @param event - 事件名。Event name.\n * @param callback - 要移除的回调(需与 on 时同一引用)。Callback to remove (same reference as passed to on).\n */\n off(event: E, callback: EventCallback): void {\n this.listeners[event].delete(callback);\n }\n\n /**\n * 触发事件,同步调用该事件所有监听器。Emit an event; synchronously invoke all listeners.\n *\n * @param event - 事件名。Event name.\n * @param args - 传给监听器的参数。Arguments passed to listeners.\n */\n emit(event: E, ...args: unknown[]): void {\n this.listeners[event].forEach((cb) => cb(...args));\n }\n}\n\nexport { EventEmitter, defineEvents };\nexport type { EventCallback, DefinedEvents, EventNamesOf };\n"],"mappings":"mEAwCA,SAAS,EAA+C,EAA6B,CACnF,OAAO,EAGT,SAAS,EAAqC,EAAyD,CACrG,MAAM,EAAM,CAAA,EACZ,UAAW,KAAK,EACd,EAAI,CAAA,EAAK,IAAI,IAEf,OAAO,EAST,IAAM,EAAN,KAAqC,CACnC,UAEA,YAAY,EAA0C,CACpD,KAAK,UAAY,EAAmB,OAAO,OAAO,CAAA,CAA4B,EAShF,GAAG,EAAU,EAA+B,CAC1C,KAAK,UAAU,CAAA,EAAO,IAAI,CAAA,EAS5B,IAAI,EAAU,EAA+B,CAC3C,KAAK,UAAU,CAAA,EAAO,OAAO,CAAA,EAS/B,KAAK,KAAa,EAAuB,CACvC,KAAK,UAAU,CAAA,EAAO,QAAS,GAAO,EAAG,GAAG,CAAA,CAAK"}
1
+ {"version":3,"file":"events.cjs","names":[],"sources":["../src/events/EventEmitter.ts"],"sourcesContent":["/**\n * 通用事件发射器(按事件名注册/注销/触发)\n * Generic event emitter: subscribe, unsubscribe, and emit by event name.\n *\n * @example\n * ```ts\n * import { EventEmitter, defineEvents, type EventNamesOf } from \"@/events\";\n * const events = defineEvents({ FOO: \"MY:FOO\", BAR: \"MY:BAR\" });\n * type MyEvent = EventNamesOf<typeof events>;\n * class MyEmitter extends EventEmitter<MyEvent> { constructor() { super(events); } }\n * const em = new MyEmitter();\n * em.on(events.FOO, (x) => console.log(x));\n * em.emit(events.FOO, \"hello\");\n * ```\n */\n\nimport type { Defined } from \"@/types\";\n\n/** 内部存储用回调类型(on/off 对外暴露泛型回调)。Internal storage type for listeners. */\ntype EventCallback<Args extends unknown[] = unknown[]> = (...args: Args) => void;\n\n/** 由 defineEvents 返回的「已规范事件名对象」类型;constructor 只接受此类型。 */\ntype DefinedEvents<T extends Record<string, string>> = Defined<T, \"events\">;\n\n/** 从 events 对象推导出事件名联合类型。Event name union from an events key-value object. */\ntype EventNamesOf<T> = T extends Defined<infer O, \"events\"> ? O[keyof O] : T extends Record<string, string> ? T[keyof T] : never;\n\n/**\n * 事件名到 payload 类型的映射;未指定时默认为 unknown,on/off 回调参数为 unknown。\n * Map event name to payload type; default unknown so callback is (payload: unknown) => void.\n */\ntype DefaultPayloadMap<E extends string> = Record<E, unknown>;\n\n/**\n * 规范创建「一级 key-value」事件名对象:仅允许 key → 字符串 value,禁止嵌套(类型约束)。\n * 返回 DefinedEvents<T>,供 EventEmitter 构造使用。\n * Define events object: one-level key-value (string values), no nested objects (type-only). Returns DefinedEvents<T> for EventEmitter.\n *\n * @param events - 事件名 key-value 对象。Event name key-value object (e.g. { FOO: \"DOMAIN:FOO\" }).\n * @returns DefinedEvents<E>,仅此类型可传入 EventEmitter 构造。DefinedEvents<E>; only this type is accepted by EventEmitter constructor.\n * @example\n * ```ts\n * const routerEvents = defineEvents({ NAVIGATE: \"ROUTER:NAVIGATE\", NAVIGATE_BACK: \"ROUTER:NAVIGATE_BACK\" });\n * class RouterEmitter extends EventEmitter<EventNamesOf<typeof routerEvents>> { constructor() { super(routerEvents); } }\n * ```\n */\nfunction defineEvents<E extends Record<string, string>>(events: E): DefinedEvents<E> {\n return events as DefinedEvents<E>;\n}\n\nfunction createListenersMap<E extends string>(eventNames: readonly E[]): Record<E, Set<EventCallback>> {\n const map = {} as Record<E, Set<EventCallback>>;\n for (const e of eventNames) {\n map[e] = new Set();\n }\n return map;\n}\n\n/**\n * 泛型 EventEmitter:构造函数仅接受 defineEvents 返回的 DefinedEvents 类型,提供 on / off / emit。\n * 第二泛型 PayloadMap 为「事件名 → payload 类型」映射,未传则全部为 unknown。\n * Generic EventEmitter: constructor accepts only DefinedEvents (returned by defineEvents), provides on / off / emit.\n * Second generic PayloadMap maps event name to payload type; omitted then all payloads are unknown.\n *\n * @param events - 须为 defineEvents(...) 的返回值(DefinedEvents)。Must be the return value of defineEvents(...) (DefinedEvents).\n */\nclass EventEmitter<E extends string, PayloadMap extends Record<E, unknown> = DefaultPayloadMap<E>> {\n private listeners: Record<E, Set<EventCallback>>;\n\n constructor(events: DefinedEvents<Record<string, E>>) {\n this.listeners = createListenersMap(Object.values(events as Record<string, E>));\n }\n\n /**\n * 注册事件监听;回调参数类型由 PayloadMap[event] 推断。\n * Register a listener; callback argument type is inferred from PayloadMap[event].\n */\n on<K extends E>(event: K, callback: (payload: PayloadMap[K]) => void): void {\n this.listeners[event].add(callback as EventCallback);\n }\n\n /**\n * 移除事件监听(需与 on 时同一引用)。\n * Remove a listener (same reference as passed to on).\n */\n off<K extends E>(event: K, callback: (payload: PayloadMap[K]) => void): void {\n this.listeners[event].delete(callback as EventCallback);\n }\n\n /**\n * 触发事件;无 payload PayloadMap[K] void 则只传 event。\n * Emit an event; when PayloadMap[K] is void, only event is passed.\n */\n emit<K extends E>(event: K, ...args: PayloadMap[K] extends void ? [] : [PayloadMap[K]]): void {\n this.listeners[event].forEach((cb) => cb(...args));\n }\n}\n\nexport { EventEmitter, defineEvents };\nexport type { EventCallback, DefinedEvents, EventNamesOf };\n"],"mappings":"mEA8CA,SAAS,EAA+C,EAA6B,CACnF,OAAO,EAGT,SAAS,EAAqC,EAAyD,CACrG,MAAM,EAAM,CAAA,EACZ,UAAW,KAAK,EACd,EAAI,CAAA,EAAK,IAAI,IAEf,OAAO,EAWT,IAAM,EAAN,KAAmG,CACjG,UAEA,YAAY,EAA0C,CACpD,KAAK,UAAY,EAAmB,OAAO,OAAO,CAAA,CAA4B,EAOhF,GAAgB,EAAU,EAAkD,CAC1E,KAAK,UAAU,CAAA,EAAO,IAAI,CAAA,EAO5B,IAAiB,EAAU,EAAkD,CAC3E,KAAK,UAAU,CAAA,EAAO,OAAO,CAAA,EAO/B,KAAkB,KAAa,EAA+D,CAC5F,KAAK,UAAU,CAAA,EAAO,QAAS,GAAO,EAAG,GAAG,CAAA,CAAK"}
package/dist/events.d.ts CHANGED
@@ -1,3 +1,9 @@
1
+ /**
2
+ * 事件名到 payload 类型的映射;未指定时默认为 unknown,on/off 回调参数为 unknown。
3
+ * Map event name to payload type; default unknown so callback is (payload: unknown) => void.
4
+ */
5
+ declare type DefaultPayloadMap<E extends string> = Record<E, unknown>;
6
+
1
7
  /**
2
8
  * 定义品牌类型:用于 defineXxx 返回值,仅对应 createXxx/constructor 可接受;Tag 区分不同 define(如 "events" | "router")。
3
9
  * Define brand type: for defineXxx return value, only the matching createXxx accepts; Tag discriminates (e.g. "events" | "router").
@@ -25,39 +31,35 @@ export declare type DefinedEvents<T extends Record<string, string>> = Defined<T,
25
31
  */
26
32
  export declare function defineEvents<E extends Record<string, string>>(events: E): DefinedEvents<E>;
27
33
 
28
- /** 事件回调类型:用于 on / off。Callback for on / off. */
29
- export declare type EventCallback = (...args: unknown[]) => void;
34
+ /** 内部存储用回调类型(on/off 对外暴露泛型回调)。Internal storage type for listeners. */
35
+ export declare type EventCallback<Args extends unknown[] = unknown[]> = (...args: Args) => void;
30
36
 
31
37
  /**
32
38
  * 泛型 EventEmitter:构造函数仅接受 defineEvents 返回的 DefinedEvents 类型,提供 on / off / emit。
39
+ * 第二泛型 PayloadMap 为「事件名 → payload 类型」映射,未传则全部为 unknown。
33
40
  * Generic EventEmitter: constructor accepts only DefinedEvents (returned by defineEvents), provides on / off / emit.
41
+ * Second generic PayloadMap maps event name to payload type; omitted then all payloads are unknown.
34
42
  *
35
43
  * @param events - 须为 defineEvents(...) 的返回值(DefinedEvents)。Must be the return value of defineEvents(...) (DefinedEvents).
36
44
  */
37
- export declare class EventEmitter<E extends string> {
45
+ export declare class EventEmitter<E extends string, PayloadMap extends Record<E, unknown> = DefaultPayloadMap<E>> {
38
46
  private listeners;
39
47
  constructor(events: DefinedEvents<Record<string, E>>);
40
48
  /**
41
- * 注册事件监听。Register a listener for an event.
42
- *
43
- * @param event - 事件名。Event name.
44
- * @param callback - 回调。Callback (...args) => void.
49
+ * 注册事件监听;回调参数类型由 PayloadMap[event] 推断。
50
+ * Register a listener; callback argument type is inferred from PayloadMap[event].
45
51
  */
46
- on(event: E, callback: EventCallback): void;
52
+ on<K extends E>(event: K, callback: (payload: PayloadMap[K]) => void): void;
47
53
  /**
48
- * 移除事件监听。Remove a listener for an event.
49
- *
50
- * @param event - 事件名。Event name.
51
- * @param callback - 要移除的回调(需与 on 时同一引用)。Callback to remove (same reference as passed to on).
54
+ * 移除事件监听(需与 on 时同一引用)。
55
+ * Remove a listener (same reference as passed to on).
52
56
  */
53
- off(event: E, callback: EventCallback): void;
57
+ off<K extends E>(event: K, callback: (payload: PayloadMap[K]) => void): void;
54
58
  /**
55
- * 触发事件,同步调用该事件所有监听器。Emit an event; synchronously invoke all listeners.
56
- *
57
- * @param event - 事件名。Event name.
58
- * @param args - 传给监听器的参数。Arguments passed to listeners.
59
+ * 触发事件;无 payload PayloadMap[K] void 则只传 event。
60
+ * Emit an event; when PayloadMap[K] is void, only event is passed.
59
61
  */
60
- emit(event: E, ...args: unknown[]): void;
62
+ emit<K extends E>(event: K, ...args: PayloadMap[K] extends void ? [] : [PayloadMap[K]]): void;
61
63
  }
62
64
 
63
65
  /** 从 events 对象推导出事件名联合类型。Event name union from an events key-value object. */
@@ -1 +1 @@
1
- {"version":3,"file":"events.mjs","names":[],"sources":["../src/events/EventEmitter.ts"],"sourcesContent":["/**\n * 通用事件发射器(按事件名注册/注销/触发)\n * Generic event emitter: subscribe, unsubscribe, and emit by event name.\n *\n * @example\n * ```ts\n * import { EventEmitter, defineEvents, type EventNamesOf } from \"@/events\";\n * const events = defineEvents({ FOO: \"MY:FOO\", BAR: \"MY:BAR\" });\n * type MyEvent = EventNamesOf<typeof events>;\n * class MyEmitter extends EventEmitter<MyEvent> { constructor() { super(events); } }\n * const em = new MyEmitter();\n * em.on(events.FOO, (x) => console.log(x));\n * em.emit(events.FOO, \"hello\");\n * ```\n */\n\nimport type { Defined } from \"@/types\";\n\n/** 事件回调类型:用于 on / off。Callback for on / off. */\ntype EventCallback = (...args: unknown[]) => void;\n\n/** 由 defineEvents 返回的「已规范事件名对象」类型;constructor 只接受此类型。 */\ntype DefinedEvents<T extends Record<string, string>> = Defined<T, \"events\">;\n\n/** 从 events 对象推导出事件名联合类型。Event name union from an events key-value object. */\ntype EventNamesOf<T> = T extends Defined<infer O, \"events\"> ? O[keyof O] : T extends Record<string, string> ? T[keyof T] : never;\n\n/**\n * 规范创建「一级 key-value」事件名对象:仅允许 key → 字符串 value,禁止嵌套(类型约束)。\n * 返回 DefinedEvents<T>,供 EventEmitter 构造使用。\n * Define events object: one-level key-value (string values), no nested objects (type-only). Returns DefinedEvents<T> for EventEmitter.\n *\n * @param events - 事件名 key-value 对象。Event name key-value object (e.g. { FOO: \"DOMAIN:FOO\" }).\n * @returns DefinedEvents<E>,仅此类型可传入 EventEmitter 构造。DefinedEvents<E>; only this type is accepted by EventEmitter constructor.\n * @example\n * ```ts\n * const routerEvents = defineEvents({ NAVIGATE: \"ROUTER:NAVIGATE\", NAVIGATE_BACK: \"ROUTER:NAVIGATE_BACK\" });\n * class RouterEmitter extends EventEmitter<EventNamesOf<typeof routerEvents>> { constructor() { super(routerEvents); } }\n * ```\n */\nfunction defineEvents<E extends Record<string, string>>(events: E): DefinedEvents<E> {\n return events as DefinedEvents<E>;\n}\n\nfunction createListenersMap<E extends string>(eventNames: readonly E[]): Record<E, Set<EventCallback>> {\n const map = {} as Record<E, Set<EventCallback>>;\n for (const e of eventNames) {\n map[e] = new Set();\n }\n return map;\n}\n\n/**\n * 泛型 EventEmitter:构造函数仅接受 defineEvents 返回的 DefinedEvents 类型,提供 on / off / emit。\n * Generic EventEmitter: constructor accepts only DefinedEvents (returned by defineEvents), provides on / off / emit.\n *\n * @param events - 须为 defineEvents(...) 的返回值(DefinedEvents)。Must be the return value of defineEvents(...) (DefinedEvents).\n */\nclass EventEmitter<E extends string> {\n private listeners: Record<E, Set<EventCallback>>;\n\n constructor(events: DefinedEvents<Record<string, E>>) {\n this.listeners = createListenersMap(Object.values(events as Record<string, E>));\n }\n\n /**\n * 注册事件监听。Register a listener for an event.\n *\n * @param event - 事件名。Event name.\n * @param callback - 回调。Callback (...args) => void.\n */\n on(event: E, callback: EventCallback): void {\n this.listeners[event].add(callback);\n }\n\n /**\n * 移除事件监听。Remove a listener for an event.\n *\n * @param event - 事件名。Event name.\n * @param callback - 要移除的回调(需与 on 时同一引用)。Callback to remove (same reference as passed to on).\n */\n off(event: E, callback: EventCallback): void {\n this.listeners[event].delete(callback);\n }\n\n /**\n * 触发事件,同步调用该事件所有监听器。Emit an event; synchronously invoke all listeners.\n *\n * @param event - 事件名。Event name.\n * @param args - 传给监听器的参数。Arguments passed to listeners.\n */\n emit(event: E, ...args: unknown[]): void {\n this.listeners[event].forEach((cb) => cb(...args));\n }\n}\n\nexport { EventEmitter, defineEvents };\nexport type { EventCallback, DefinedEvents, EventNamesOf };\n"],"mappings":"AAwCA,SAAS,EAA+C,GAA6B;AACnF,SAAO;;AAGT,SAAS,EAAqC,GAAyD;AACrG,QAAM,IAAM,CAAA;AACZ,aAAW,KAAK,EACd,CAAA,EAAI,CAAA,IAAK,oBAAI,IAAA;AAEf,SAAO;;AAST,IAAM,IAAN,MAAqC;AAAA,EACnC;AAAA,EAEA,YAAY,GAA0C;AACpD,SAAK,YAAY,EAAmB,OAAO,OAAO,CAAA,CAA4B;AAAA;EAShF,GAAG,GAAU,GAA+B;AAC1C,SAAK,UAAU,CAAA,EAAO,IAAI,CAAA;AAAA;EAS5B,IAAI,GAAU,GAA+B;AAC3C,SAAK,UAAU,CAAA,EAAO,OAAO,CAAA;AAAA;EAS/B,KAAK,MAAa,GAAuB;AACvC,SAAK,UAAU,CAAA,EAAO,QAAA,CAAS,MAAO,EAAG,GAAG,CAAA,CAAK;AAAA"}
1
+ {"version":3,"file":"events.mjs","names":[],"sources":["../src/events/EventEmitter.ts"],"sourcesContent":["/**\n * 通用事件发射器(按事件名注册/注销/触发)\n * Generic event emitter: subscribe, unsubscribe, and emit by event name.\n *\n * @example\n * ```ts\n * import { EventEmitter, defineEvents, type EventNamesOf } from \"@/events\";\n * const events = defineEvents({ FOO: \"MY:FOO\", BAR: \"MY:BAR\" });\n * type MyEvent = EventNamesOf<typeof events>;\n * class MyEmitter extends EventEmitter<MyEvent> { constructor() { super(events); } }\n * const em = new MyEmitter();\n * em.on(events.FOO, (x) => console.log(x));\n * em.emit(events.FOO, \"hello\");\n * ```\n */\n\nimport type { Defined } from \"@/types\";\n\n/** 内部存储用回调类型(on/off 对外暴露泛型回调)。Internal storage type for listeners. */\ntype EventCallback<Args extends unknown[] = unknown[]> = (...args: Args) => void;\n\n/** 由 defineEvents 返回的「已规范事件名对象」类型;constructor 只接受此类型。 */\ntype DefinedEvents<T extends Record<string, string>> = Defined<T, \"events\">;\n\n/** 从 events 对象推导出事件名联合类型。Event name union from an events key-value object. */\ntype EventNamesOf<T> = T extends Defined<infer O, \"events\"> ? O[keyof O] : T extends Record<string, string> ? T[keyof T] : never;\n\n/**\n * 事件名到 payload 类型的映射;未指定时默认为 unknown,on/off 回调参数为 unknown。\n * Map event name to payload type; default unknown so callback is (payload: unknown) => void.\n */\ntype DefaultPayloadMap<E extends string> = Record<E, unknown>;\n\n/**\n * 规范创建「一级 key-value」事件名对象:仅允许 key → 字符串 value,禁止嵌套(类型约束)。\n * 返回 DefinedEvents<T>,供 EventEmitter 构造使用。\n * Define events object: one-level key-value (string values), no nested objects (type-only). Returns DefinedEvents<T> for EventEmitter.\n *\n * @param events - 事件名 key-value 对象。Event name key-value object (e.g. { FOO: \"DOMAIN:FOO\" }).\n * @returns DefinedEvents<E>,仅此类型可传入 EventEmitter 构造。DefinedEvents<E>; only this type is accepted by EventEmitter constructor.\n * @example\n * ```ts\n * const routerEvents = defineEvents({ NAVIGATE: \"ROUTER:NAVIGATE\", NAVIGATE_BACK: \"ROUTER:NAVIGATE_BACK\" });\n * class RouterEmitter extends EventEmitter<EventNamesOf<typeof routerEvents>> { constructor() { super(routerEvents); } }\n * ```\n */\nfunction defineEvents<E extends Record<string, string>>(events: E): DefinedEvents<E> {\n return events as DefinedEvents<E>;\n}\n\nfunction createListenersMap<E extends string>(eventNames: readonly E[]): Record<E, Set<EventCallback>> {\n const map = {} as Record<E, Set<EventCallback>>;\n for (const e of eventNames) {\n map[e] = new Set();\n }\n return map;\n}\n\n/**\n * 泛型 EventEmitter:构造函数仅接受 defineEvents 返回的 DefinedEvents 类型,提供 on / off / emit。\n * 第二泛型 PayloadMap 为「事件名 → payload 类型」映射,未传则全部为 unknown。\n * Generic EventEmitter: constructor accepts only DefinedEvents (returned by defineEvents), provides on / off / emit.\n * Second generic PayloadMap maps event name to payload type; omitted then all payloads are unknown.\n *\n * @param events - 须为 defineEvents(...) 的返回值(DefinedEvents)。Must be the return value of defineEvents(...) (DefinedEvents).\n */\nclass EventEmitter<E extends string, PayloadMap extends Record<E, unknown> = DefaultPayloadMap<E>> {\n private listeners: Record<E, Set<EventCallback>>;\n\n constructor(events: DefinedEvents<Record<string, E>>) {\n this.listeners = createListenersMap(Object.values(events as Record<string, E>));\n }\n\n /**\n * 注册事件监听;回调参数类型由 PayloadMap[event] 推断。\n * Register a listener; callback argument type is inferred from PayloadMap[event].\n */\n on<K extends E>(event: K, callback: (payload: PayloadMap[K]) => void): void {\n this.listeners[event].add(callback as EventCallback);\n }\n\n /**\n * 移除事件监听(需与 on 时同一引用)。\n * Remove a listener (same reference as passed to on).\n */\n off<K extends E>(event: K, callback: (payload: PayloadMap[K]) => void): void {\n this.listeners[event].delete(callback as EventCallback);\n }\n\n /**\n * 触发事件;无 payload PayloadMap[K] void 则只传 event。\n * Emit an event; when PayloadMap[K] is void, only event is passed.\n */\n emit<K extends E>(event: K, ...args: PayloadMap[K] extends void ? [] : [PayloadMap[K]]): void {\n this.listeners[event].forEach((cb) => cb(...args));\n }\n}\n\nexport { EventEmitter, defineEvents };\nexport type { EventCallback, DefinedEvents, EventNamesOf };\n"],"mappings":"AA8CA,SAAS,EAA+C,GAA6B;AACnF,SAAO;;AAGT,SAAS,EAAqC,GAAyD;AACrG,QAAM,IAAM,CAAA;AACZ,aAAW,KAAK,EACd,CAAA,EAAI,CAAA,IAAK,oBAAI,IAAA;AAEf,SAAO;;AAWT,IAAM,IAAN,MAAmG;AAAA,EACjG;AAAA,EAEA,YAAY,GAA0C;AACpD,SAAK,YAAY,EAAmB,OAAO,OAAO,CAAA,CAA4B;AAAA;EAOhF,GAAgB,GAAU,GAAkD;AAC1E,SAAK,UAAU,CAAA,EAAO,IAAI,CAAA;AAAA;EAO5B,IAAiB,GAAU,GAAkD;AAC3E,SAAK,UAAU,CAAA,EAAO,OAAO,CAAA;AAAA;EAO/B,KAAkB,MAAa,GAA+D;AAC5F,SAAK,UAAU,CAAA,EAAO,QAAA,CAAS,MAAO,EAAG,GAAG,CAAA,CAAK;AAAA"}
package/package.json CHANGED
@@ -1,12 +1,16 @@
1
1
  {
2
2
  "name": "nfx-ui",
3
- "version": "0.1.4",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "description": "Unified frontend UI library for the NFX product family: shared React components, design tokens, theme variables, and layout primitives for a consistent look and behavior across NFX console and other apps.",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "https://github.com/NebulaForgeX/NFX-UI"
9
9
  },
10
+ "homepage": "https://github.com/NebulaForgeX/NFX-UI#readme",
11
+ "bugs": {
12
+ "url": "https://github.com/NebulaForgeX/NFX-UI/issues"
13
+ },
10
14
  "exports": {
11
15
  "./themes": {
12
16
  "types": "./dist/themes.d.ts",
@@ -129,6 +133,8 @@
129
133
  "ui",
130
134
  "components",
131
135
  "nfx",
136
+ "NebulaForgeX",
137
+ "NFX-UI",
132
138
  "design-system"
133
139
  ],
134
140
  "license": "UNLICENSED",