@gaozh1024/rn-kit 0.3.4 → 0.4.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
@@ -16,6 +16,13 @@
16
16
  - `OverlayProvider`
17
17
  - `AppStatusBar`
18
18
 
19
+ 另外在**开发环境**下,`AppProvider` 默认会启用一套轻量的开发日志基础设施:
20
+
21
+ - `LoggerProvider`
22
+ - CLI 彩色日志输出
23
+ - App 内 `LogOverlay` 浮层
24
+ - `AppErrorBoundary` React 渲染错误兜底
25
+
19
26
  这样页面切换、主题切换时,状态栏会自动跟随全局主题变化。
20
27
 
21
28
  ## 📦 安装
@@ -149,6 +156,7 @@ import {
149
156
  AppScrollView,
150
157
  AppText,
151
158
  AppPressable,
159
+ KeyboardDismissView,
152
160
  AppInput, // 原子组件
153
161
  Row,
154
162
  Col,
@@ -168,6 +176,7 @@ import {
168
176
  Radio,
169
177
  Switch,
170
178
  Select,
179
+ Picker,
171
180
  DatePicker, // 表单
172
181
  } from '@gaozh1024/rn-kit';
173
182
  ```
@@ -179,6 +188,11 @@ import {
179
188
  - `SafeScreen` / `AppScreen` 同时支持:
180
189
  - `bg="primary-500"` 这类显式颜色
181
190
  - `surface="background" | "card" | "muted"` 这类语义背景
191
+ - `dismissKeyboardOnPressOutside`:点击非输入区域时收起键盘
192
+ - `AppScrollView` 支持 `dismissKeyboardOnPressOutside`
193
+ - 开启后会自动启用点击空白收起键盘
194
+ - 并默认补上 `keyboardShouldPersistTaps="handled"`
195
+ - `KeyboardDismissView` 适合非页面容器、自定义布局场景下单独包裹使用
182
196
 
183
197
  #### Button 颜色语义
184
198
 
@@ -201,6 +215,46 @@ import {
201
215
  <AppButton color="danger">删除</AppButton>
202
216
  ```
203
217
 
218
+ #### 键盘收起交互
219
+
220
+ `AppButton` 新增:
221
+
222
+ - `dismissKeyboardOnPress?: boolean`
223
+ - 默认值:`true`
224
+
225
+ 也就是说,大多数提交/保存/登录按钮在点击前会先自动收起键盘:
226
+
227
+ ```tsx
228
+ <AppButton onPress={handleSubmit}>提交</AppButton>
229
+
230
+ <AppButton dismissKeyboardOnPress={false} onPress={handleToolbarAction}>
231
+ 保持键盘
232
+ </AppButton>
233
+ ```
234
+
235
+ 容器侧推荐这样使用:
236
+
237
+ ```tsx
238
+ <AppScreen dismissKeyboardOnPressOutside>
239
+ <AppScrollView dismissKeyboardOnPressOutside>
240
+ <AppInput placeholder="请输入手机号" />
241
+ <AppInput placeholder="请输入密码" secureTextEntry />
242
+ <AppButton onPress={handleLogin}>登录</AppButton>
243
+ </AppScrollView>
244
+ </AppScreen>
245
+ ```
246
+
247
+ 如果不是整页容器,而是局部自定义布局,也可以单独使用:
248
+
249
+ ```tsx
250
+ <KeyboardDismissView>
251
+ <AppView p={4} gap={3}>
252
+ <AppInput placeholder="搜索内容" />
253
+ <AppButton onPress={handleSearch}>搜索</AppButton>
254
+ </AppView>
255
+ </KeyboardDismissView>
256
+ ```
257
+
204
258
  #### 可本地化文案参数(i18n 推荐)
205
259
 
206
260
  - `AppList`
@@ -213,17 +267,20 @@ import {
213
267
  - `emptyText`:空状态文案
214
268
  - `selectedCountText`:多选计数模板,支持 `{{count}}`
215
269
  - `confirmText`:多选确认按钮文案
270
+ - `Picker`
271
+ - `pickerTitle` / `cancelText` / `confirmText`:弹窗文案
272
+ - `renderDisplayText`:自定义触发区展示文本
273
+ - `renderFooter`:自定义底部区域,适合扩展省市区、级联选择等场景
216
274
  - `DatePicker`
217
275
  - `cancelText` / `confirmText`:弹窗操作按钮文案
218
276
  - `pickerTitle`:弹窗标题文案
219
- - `pickerDateFormat`:弹窗顶部日期格式
220
277
  - `yearLabel` / `monthLabel` / `dayLabel`:列标题文案
221
278
  - `todayText` / `minDateText` / `maxDateText`:快捷按钮文案
222
279
 
223
280
  #### 表单与反馈 Hook 当前 API
224
281
 
225
282
  ```tsx
226
- import { useForm, useToast, useLoading, useAlert } from '@gaozh1024/rn-kit';
283
+ import { useForm, useToast, useLoading, useAlert, useLogger } from '@gaozh1024/rn-kit';
227
284
 
228
285
  const form = useForm({
229
286
  schema,
@@ -250,6 +307,10 @@ loading.hide();
250
307
  const alert = useAlert();
251
308
  alert.alert({ title: '提示', message: '操作完成' });
252
309
  alert.confirm({ title: '确认删除', message: '删除后不可恢复' });
310
+
311
+ const logger = useLogger('auth');
312
+ logger.info('开始登录', { page: 'Login' });
313
+ logger.error('登录失败', { code: 401 });
253
314
  ```
254
315
 
255
316
  说明:
@@ -259,6 +320,135 @@ alert.confirm({ title: '确认删除', message: '删除后不可恢复' });
259
320
  - `useToast` 当前签名为 `show(message, type?, duration?)`
260
321
  - `useLoading` 当前签名为 `show(text?)` / `hide()`
261
322
  - `useAlert` 当前提供 `alert()` / `confirm()`,不包含 `prompt()` / `custom()`
323
+ - `useLogger(namespace?)` 提供 `debug / info / warn / error / clear / entries`
324
+
325
+ #### 开发日志 / 可观测性基础设施
326
+
327
+ 框架现在内置了一套**开发态可观测性基础设施**,目标是帮助排查问题,而不是直接做线上监控平台。
328
+
329
+ 默认能力:
330
+
331
+ - `useLogger(namespace?)`:组件内打点
332
+ - 内存日志缓冲:保留最近若干条日志
333
+ - Console Transport:CLI 中按 level 彩色输出
334
+ - `LogOverlay`:App 内浮动日志面板
335
+ - 浮层增强:level 筛选 / namespace 筛选 / 关键字搜索 / 导出当前日志
336
+
337
+ ##### 1. 最简单用法:直接跟随 `AppProvider`
338
+
339
+ ```tsx
340
+ import { AppProvider, useLogger, AppButton } from '@gaozh1024/rn-kit';
341
+
342
+ function LoginButton() {
343
+ const logger = useLogger('login');
344
+
345
+ return (
346
+ <AppButton
347
+ onPress={() => {
348
+ logger.info('点击登录按钮');
349
+ }}
350
+ >
351
+ 登录
352
+ </AppButton>
353
+ );
354
+ }
355
+
356
+ export default function App() {
357
+ return (
358
+ <AppProvider>
359
+ <LoginButton />
360
+ </AppProvider>
361
+ );
362
+ }
363
+ ```
364
+
365
+ 说明:
366
+
367
+ - `AppProvider` 在开发环境下默认 `enableLogger = true`
368
+ - 生产环境默认关闭
369
+ - 开启后会同时启用 console 输出和 App 内日志浮层
370
+
371
+ ##### 2. 显式控制是否启用
372
+
373
+ ```tsx
374
+ <AppProvider
375
+ enableLogger
376
+ enableErrorBoundary
377
+ loggerProps={{
378
+ level: 'info',
379
+ maxEntries: 300,
380
+ consoleEnabled: true,
381
+ defaultExpanded: false,
382
+ }}
383
+ >
384
+ <App />
385
+ </AppProvider>
386
+ ```
387
+
388
+ 常用 `loggerProps`:
389
+
390
+ - `enabled`
391
+ - `level`: `'debug' | 'info' | 'warn' | 'error'`
392
+ - `maxEntries`
393
+ - `consoleEnabled`
394
+ - `overlayEnabled`
395
+ - `defaultExpanded`
396
+ - `exportEnabled`
397
+ - `onExport`
398
+
399
+ `onExport` 会收到:
400
+
401
+ ```tsx
402
+ {
403
+ entries: LogEntry[];
404
+ serialized: string;
405
+ }
406
+ ```
407
+
408
+ 错误边界相关:
409
+
410
+ - `enableErrorBoundary`:是否启用 React 错误边界
411
+ - `errorBoundaryProps.title`:兜底标题
412
+ - `errorBoundaryProps.description`:兜底说明
413
+ - `errorBoundaryProps.showDetails`:是否显示错误详情
414
+ - `errorBoundaryProps.resetText`:重试按钮文案
415
+
416
+ 当错误边界与 logger 同时开启时,组件渲染异常会自动写入 `react` 命名空间日志,便于在控制台和 `LogOverlay` 中回看。
417
+
418
+ ##### 3. 单独使用 `OverlayProvider` / `LoggerProvider`
419
+
420
+ 如果你不是通过 `AppProvider` 接入,而是自己手动包 Provider,需要注意:
421
+
422
+ - `LoggerProvider` 默认 `enabled = false`
423
+ - `OverlayProvider` 里传入的 logger 也默认不主动开启
424
+
425
+ 所以需要显式打开:
426
+
427
+ ```tsx
428
+ import { OverlayProvider } from '@gaozh1024/rn-kit';
429
+
430
+ <OverlayProvider
431
+ loggerProps={{
432
+ enabled: true,
433
+ overlayEnabled: true,
434
+ consoleEnabled: true,
435
+ }}
436
+ >
437
+ <App />
438
+ </OverlayProvider>;
439
+ ```
440
+
441
+ 或者:
442
+
443
+ ```tsx
444
+ import { AppErrorBoundary, LoggerProvider } from '@gaozh1024/rn-kit';
445
+
446
+ <LoggerProvider enabled overlayEnabled consoleEnabled>
447
+ <AppErrorBoundary enabled showDetails>
448
+ <App />
449
+ </AppErrorBoundary>
450
+ </LoggerProvider>;
451
+ ```
262
452
 
263
453
  ### 🪝 Hooks
264
454
 
@@ -437,7 +627,7 @@ import { DrawerContent, DrawerNavigator } from '@gaozh1024/rn-kit';
437
627
  ### 🔌 API 工厂
438
628
 
439
629
  ```tsx
440
- import { createAPI, z, storage, ErrorCode } from '@gaozh1024/rn-kit';
630
+ import { createAPI, createApiLoggerTransport, z, storage, ErrorCode } from '@gaozh1024/rn-kit';
441
631
 
442
632
  const api = createAPI({
443
633
  baseURL: 'https://api.example.com',
@@ -450,6 +640,85 @@ const api = createAPI({
450
640
  });
451
641
  ```
452
642
 
643
+ #### API 自动打点(request / response / error)
644
+
645
+ `createAPI` 已支持开发态自动打点。
646
+
647
+ 默认行为:
648
+
649
+ - 开发环境下 `observability.enabled` 默认开启
650
+ - 如果当前 App 已通过 `AppProvider` / `LoggerProvider` 启用了 logger
651
+ - 那么 API 请求会自动写入 `api` 命名空间日志
652
+
653
+ 记录阶段:
654
+
655
+ - request
656
+ - response
657
+ - error
658
+
659
+ ```tsx
660
+ const api = createAPI({
661
+ baseURL: 'https://api.example.com',
662
+ observability: {
663
+ enabled: true,
664
+ includeInput: true,
665
+ includeResponseData: false,
666
+ },
667
+ endpoints: {
668
+ getProfile: {
669
+ method: 'GET',
670
+ path: '/profile',
671
+ },
672
+ },
673
+ });
674
+ ```
675
+
676
+ 也可以添加自定义 transport:
677
+
678
+ ```tsx
679
+ const api = createAPI({
680
+ baseURL: 'https://api.example.com',
681
+ observability: {
682
+ enabled: true,
683
+ transports: [
684
+ event => {
685
+ console.log('api event', event.stage, event.endpointName);
686
+ },
687
+ ],
688
+ },
689
+ endpoints: {
690
+ getProfile: {
691
+ method: 'GET',
692
+ path: '/profile',
693
+ },
694
+ },
695
+ });
696
+ ```
697
+
698
+ 如果你想手动指定写到某个 logger,也可以:
699
+
700
+ ```tsx
701
+ const transport = createApiLoggerTransport({
702
+ namespace: 'network',
703
+ includeInput: true,
704
+ includeResponseData: true,
705
+ });
706
+
707
+ const api = createAPI({
708
+ baseURL: 'https://api.example.com',
709
+ observability: {
710
+ enabled: true,
711
+ transports: [transport],
712
+ },
713
+ endpoints: {
714
+ getProfile: {
715
+ method: 'GET',
716
+ path: '/profile',
717
+ },
718
+ },
719
+ });
720
+ ```
721
+
453
722
  ## 📄 文档
454
723
 
455
724
  - [框架文档](../../docs/README.md) - 完整文档索引