zkit-ui 1.0.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 +267 -0
- package/dist/ComponentLibProvider.d.ts +15 -0
- package/dist/ComponentLibProvider.d.ts.map +1 -0
- package/dist/ComponentLibProvider.js +18 -0
- package/dist/assets/animations/spinner.json +1 -0
- package/dist/assets/icons/check.svg +4 -0
- package/dist/assets/icons/toast/error.webp +0 -0
- package/dist/assets/icons/toast/success.webp +0 -0
- package/dist/assets/icons/toast/warning.webp +0 -0
- package/dist/config.d.ts +16 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +42 -0
- package/dist/i18n/I18nProvider.d.ts +11 -0
- package/dist/i18n/I18nProvider.d.ts.map +1 -0
- package/dist/i18n/I18nProvider.js +84 -0
- package/dist/i18n/locale.d.ts +7 -0
- package/dist/i18n/locale.d.ts.map +1 -0
- package/dist/i18n/locale.js +87 -0
- package/dist/i18n/locales/de.d.ts +51 -0
- package/dist/i18n/locales/de.d.ts.map +1 -0
- package/dist/i18n/locales/de.js +62 -0
- package/dist/i18n/locales/en-US.d.ts +51 -0
- package/dist/i18n/locales/en-US.d.ts.map +1 -0
- package/dist/i18n/locales/en-US.js +62 -0
- package/dist/i18n/locales/index.d.ts +9 -0
- package/dist/i18n/locales/index.d.ts.map +1 -0
- package/dist/i18n/locales/index.js +23 -0
- package/dist/i18n/locales/ja.d.ts +51 -0
- package/dist/i18n/locales/ja.d.ts.map +1 -0
- package/dist/i18n/locales/ja.js +62 -0
- package/dist/i18n/locales/zh-CN.d.ts +51 -0
- package/dist/i18n/locales/zh-CN.d.ts.map +1 -0
- package/dist/i18n/locales/zh-CN.js +62 -0
- package/dist/i18n/locales/zh-TW.d.ts +51 -0
- package/dist/i18n/locales/zh-TW.d.ts.map +1 -0
- package/dist/i18n/locales/zh-TW.js +62 -0
- package/dist/i18n/types.d.ts +11 -0
- package/dist/i18n/types.d.ts.map +1 -0
- package/dist/i18n/types.js +2 -0
- package/dist/i18n/useI18n.d.ts +2 -0
- package/dist/i18n/useI18n.d.ts.map +1 -0
- package/dist/i18n/useI18n.js +41 -0
- package/dist/index.d.ts +57 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +90 -0
- package/dist/services/ActionDialogService/ActionDialog.d.ts +4 -0
- package/dist/services/ActionDialogService/ActionDialog.d.ts.map +1 -0
- package/dist/services/ActionDialogService/ActionDialog.js +531 -0
- package/dist/services/ActionDialogService/index.d.ts +4 -0
- package/dist/services/ActionDialogService/index.d.ts.map +1 -0
- package/dist/services/ActionDialogService/index.js +8 -0
- package/dist/services/ActionDialogService/service.d.ts +7 -0
- package/dist/services/ActionDialogService/service.d.ts.map +1 -0
- package/dist/services/ActionDialogService/service.js +309 -0
- package/dist/services/ActionDialogService/shared.d.ts +17 -0
- package/dist/services/ActionDialogService/shared.d.ts.map +1 -0
- package/dist/services/ActionDialogService/shared.js +167 -0
- package/dist/services/ActionDialogService/types.d.ts +160 -0
- package/dist/services/ActionDialogService/types.d.ts.map +1 -0
- package/dist/services/ActionDialogService/types.js +2 -0
- package/dist/services/CardToastService/index.d.ts +115 -0
- package/dist/services/CardToastService/index.d.ts.map +1 -0
- package/dist/services/CardToastService/index.js +899 -0
- package/dist/services/ImagePreviewService/index.d.ts +179 -0
- package/dist/services/ImagePreviewService/index.d.ts.map +1 -0
- package/dist/services/ImagePreviewService/index.js +1383 -0
- package/dist/services/LoadingService/index.d.ts +146 -0
- package/dist/services/LoadingService/index.d.ts.map +1 -0
- package/dist/services/LoadingService/index.js +827 -0
- package/dist/services/PermissionPurposeDialogService/index.d.ts +99 -0
- package/dist/services/PermissionPurposeDialogService/index.d.ts.map +1 -0
- package/dist/services/PermissionPurposeDialogService/index.js +360 -0
- package/dist/services/PickerService/index.d.ts +128 -0
- package/dist/services/PickerService/index.d.ts.map +1 -0
- package/dist/services/PickerService/index.js +250 -0
- package/dist/theme/ThemeProvider.d.ts +15 -0
- package/dist/theme/ThemeProvider.d.ts.map +1 -0
- package/dist/theme/ThemeProvider.js +61 -0
- package/dist/theme/defaultTheme.d.ts +3 -0
- package/dist/theme/defaultTheme.d.ts.map +1 -0
- package/dist/theme/defaultTheme.js +28 -0
- package/dist/theme/mergeTheme.d.ts +3 -0
- package/dist/theme/mergeTheme.d.ts.map +1 -0
- package/dist/theme/mergeTheme.js +19 -0
- package/dist/theme/types.d.ts +17 -0
- package/dist/theme/types.d.ts.map +1 -0
- package/dist/theme/types.js +2 -0
- package/dist/theme/useTheme.d.ts +2 -0
- package/dist/theme/useTheme.d.ts.map +1 -0
- package/dist/theme/useTheme.js +46 -0
- package/dist/ui/Accordion/index.d.ts +99 -0
- package/dist/ui/Accordion/index.d.ts.map +1 -0
- package/dist/ui/Accordion/index.js +777 -0
- package/dist/ui/AddressCascader/index.d.ts +58 -0
- package/dist/ui/AddressCascader/index.d.ts.map +1 -0
- package/dist/ui/AddressCascader/index.js +710 -0
- package/dist/ui/BetweenTime/index.d.ts +82 -0
- package/dist/ui/BetweenTime/index.d.ts.map +1 -0
- package/dist/ui/BetweenTime/index.js +702 -0
- package/dist/ui/Button/index.d.ts +93 -0
- package/dist/ui/Button/index.d.ts.map +1 -0
- package/dist/ui/Button/index.js +832 -0
- package/dist/ui/Checkbox/index.d.ts +103 -0
- package/dist/ui/Checkbox/index.d.ts.map +1 -0
- package/dist/ui/Checkbox/index.js +694 -0
- package/dist/ui/DatePicker/index.d.ts +5 -0
- package/dist/ui/DatePicker/index.d.ts.map +1 -0
- package/dist/ui/DatePicker/index.js +157 -0
- package/dist/ui/DatePicker/types.d.ts +99 -0
- package/dist/ui/DatePicker/types.d.ts.map +1 -0
- package/dist/ui/DatePicker/types.js +2 -0
- package/dist/ui/DatePicker/utils.d.ts +32 -0
- package/dist/ui/DatePicker/utils.d.ts.map +1 -0
- package/dist/ui/DatePicker/utils.js +316 -0
- package/dist/ui/LinkedScroll/index.d.ts +78 -0
- package/dist/ui/LinkedScroll/index.d.ts.map +1 -0
- package/dist/ui/LinkedScroll/index.js +470 -0
- package/dist/ui/LoadingSpinner/index.d.ts +8 -0
- package/dist/ui/LoadingSpinner/index.d.ts.map +1 -0
- package/dist/ui/LoadingSpinner/index.js +122 -0
- package/dist/ui/Picker/actionBar.d.ts +14 -0
- package/dist/ui/Picker/actionBar.d.ts.map +1 -0
- package/dist/ui/Picker/actionBar.js +28 -0
- package/dist/ui/Picker/index.d.ts +5 -0
- package/dist/ui/Picker/index.d.ts.map +1 -0
- package/dist/ui/Picker/index.js +412 -0
- package/dist/ui/Picker/types.d.ts +80 -0
- package/dist/ui/Picker/types.d.ts.map +1 -0
- package/dist/ui/Picker/types.js +2 -0
- package/dist/ui/Picker/utils.d.ts +27 -0
- package/dist/ui/Picker/utils.d.ts.map +1 -0
- package/dist/ui/Picker/utils.js +182 -0
- package/dist/ui/Radio/index.d.ts +95 -0
- package/dist/ui/Radio/index.d.ts.map +1 -0
- package/dist/ui/Radio/index.js +633 -0
- package/dist/ui/Sheet/index.d.ts +12 -0
- package/dist/ui/Sheet/index.d.ts.map +1 -0
- package/dist/ui/Sheet/index.js +832 -0
- package/dist/ui/Sheet/nativeBottom.d.ts +52 -0
- package/dist/ui/Sheet/nativeBottom.d.ts.map +1 -0
- package/dist/ui/Sheet/nativeBottom.js +442 -0
- package/dist/ui/Sheet/nativeBottom.web.d.ts +18 -0
- package/dist/ui/Sheet/nativeBottom.web.d.ts.map +1 -0
- package/dist/ui/Sheet/nativeBottom.web.js +46 -0
- package/dist/ui/Sheet/slots.d.ts +5 -0
- package/dist/ui/Sheet/slots.d.ts.map +1 -0
- package/dist/ui/Sheet/slots.js +40 -0
- package/dist/ui/Sheet/types.d.ts +131 -0
- package/dist/ui/Sheet/types.d.ts.map +1 -0
- package/dist/ui/Sheet/types.js +2 -0
- package/dist/ui/SliderCaptcha/index.d.ts +57 -0
- package/dist/ui/SliderCaptcha/index.d.ts.map +1 -0
- package/dist/ui/SliderCaptcha/index.js +586 -0
- package/dist/ui/Switch/index.d.ts +72 -0
- package/dist/ui/Switch/index.d.ts.map +1 -0
- package/dist/ui/Switch/index.js +671 -0
- package/dist/ui/Text/index.d.ts +41 -0
- package/dist/ui/Text/index.d.ts.map +1 -0
- package/dist/ui/Text/index.js +325 -0
- package/dist/ui/TextInput/TextInputPrimitive.d.ts +8 -0
- package/dist/ui/TextInput/TextInputPrimitive.d.ts.map +1 -0
- package/dist/ui/TextInput/TextInputPrimitive.js +54 -0
- package/dist/ui/TextInput/index.d.ts +89 -0
- package/dist/ui/TextInput/index.d.ts.map +1 -0
- package/dist/ui/TextInput/index.js +545 -0
- package/dist/ui/WheelColumn/ZKitWheelPickerNativeComponent.d.ts +39 -0
- package/dist/ui/WheelColumn/ZKitWheelPickerNativeComponent.d.ts.map +1 -0
- package/dist/ui/WheelColumn/ZKitWheelPickerNativeComponent.js +60 -0
- package/dist/ui/WheelColumn/constants.d.ts +2 -0
- package/dist/ui/WheelColumn/constants.d.ts.map +1 -0
- package/dist/ui/WheelColumn/constants.js +4 -0
- package/dist/ui/WheelColumn/index.d.ts +59 -0
- package/dist/ui/WheelColumn/index.d.ts.map +1 -0
- package/dist/ui/WheelColumn/index.js +547 -0
- package/ios/ZKitWheelPicker.h +18 -0
- package/ios/ZKitWheelPicker.mm +230 -0
- package/ios/ZKitWheelPickerLabel.h +10 -0
- package/ios/ZKitWheelPickerLabel.mm +31 -0
- package/ios/ZKitWheelPickerManager.h +5 -0
- package/ios/ZKitWheelPickerManager.mm +53 -0
- package/package.json +75 -0
- package/react-native.config.js +10 -0
- package/src/ComponentLibProvider.tsx +56 -0
- package/src/assets/animations/spinner.json +1 -0
- package/src/assets/icons/check.svg +4 -0
- package/src/assets/icons/toast/error.webp +0 -0
- package/src/assets/icons/toast/success.webp +0 -0
- package/src/assets/icons/toast/warning.webp +0 -0
- package/src/config.ts +65 -0
- package/src/i18n/I18nProvider.tsx +69 -0
- package/src/i18n/locale.ts +108 -0
- package/src/i18n/locales/de.ts +67 -0
- package/src/i18n/locales/en-US.ts +67 -0
- package/src/i18n/locales/index.ts +19 -0
- package/src/i18n/locales/ja.ts +67 -0
- package/src/i18n/locales/zh-CN.ts +67 -0
- package/src/i18n/locales/zh-TW.ts +67 -0
- package/src/i18n/types.ts +21 -0
- package/src/i18n/useI18n.ts +7 -0
- package/src/index.ts +395 -0
- package/src/services/ActionDialogService/ActionDialog.tsx +756 -0
- package/src/services/ActionDialogService/README.md +146 -0
- package/src/services/ActionDialogService/index.tsx +39 -0
- package/src/services/ActionDialogService/service.tsx +355 -0
- package/src/services/ActionDialogService/shared.ts +204 -0
- package/src/services/ActionDialogService/types.ts +197 -0
- package/src/services/CardToastService/README.md +128 -0
- package/src/services/CardToastService/index.tsx +1284 -0
- package/src/services/ImagePreviewService/README.md +67 -0
- package/src/services/ImagePreviewService/index.tsx +2148 -0
- package/src/services/LoadingService/README.md +128 -0
- package/src/services/LoadingService/index.tsx +1113 -0
- package/src/services/PermissionPurposeDialogService/README.md +80 -0
- package/src/services/PermissionPurposeDialogService/index.tsx +449 -0
- package/src/services/PickerService/README.md +154 -0
- package/src/services/PickerService/index.tsx +410 -0
- package/src/theme/ThemeProvider.tsx +40 -0
- package/src/theme/defaultTheme.ts +30 -0
- package/src/theme/mergeTheme.ts +16 -0
- package/src/theme/types.ts +36 -0
- package/src/theme/useTheme.ts +10 -0
- package/src/types/svg.d.ts +9 -0
- package/src/types/vant-area-data.d.ts +19 -0
- package/src/ui/Accordion/README.md +67 -0
- package/src/ui/Accordion/index.tsx +1221 -0
- package/src/ui/AddressCascader/README.md +144 -0
- package/src/ui/AddressCascader/index.tsx +1084 -0
- package/src/ui/BetweenTime/README.md +490 -0
- package/src/ui/BetweenTime/index.tsx +1001 -0
- package/src/ui/Button/README.md +186 -0
- package/src/ui/Button/index.tsx +1356 -0
- package/src/ui/Checkbox/README.md +211 -0
- package/src/ui/Checkbox/index.tsx +1231 -0
- package/src/ui/DatePicker/README.md +117 -0
- package/src/ui/DatePicker/index.tsx +295 -0
- package/src/ui/DatePicker/types.ts +115 -0
- package/src/ui/DatePicker/utils.ts +405 -0
- package/src/ui/LinkedScroll/README.md +55 -0
- package/src/ui/LinkedScroll/index.tsx +809 -0
- package/src/ui/LoadingSpinner/index.tsx +104 -0
- package/src/ui/Picker/README.md +190 -0
- package/src/ui/Picker/actionBar.tsx +70 -0
- package/src/ui/Picker/index.tsx +694 -0
- package/src/ui/Picker/types.ts +94 -0
- package/src/ui/Picker/utils.ts +239 -0
- package/src/ui/Radio/README.md +207 -0
- package/src/ui/Radio/index.tsx +1117 -0
- package/src/ui/Sheet/README.md +82 -0
- package/src/ui/Sheet/index.tsx +1163 -0
- package/src/ui/Sheet/nativeBottom.tsx +683 -0
- package/src/ui/Sheet/nativeBottom.web.tsx +40 -0
- package/src/ui/Sheet/slots.tsx +75 -0
- package/src/ui/Sheet/types.ts +195 -0
- package/src/ui/SliderCaptcha/README.md +61 -0
- package/src/ui/SliderCaptcha/index.tsx +816 -0
- package/src/ui/Switch/README.md +143 -0
- package/src/ui/Switch/index.tsx +1092 -0
- package/src/ui/Text/README.md +157 -0
- package/src/ui/Text/index.tsx +450 -0
- package/src/ui/TextInput/README.md +197 -0
- package/src/ui/TextInput/TextInputPrimitive.tsx +44 -0
- package/src/ui/TextInput/index.tsx +942 -0
- package/src/ui/WheelColumn/README.md +104 -0
- package/src/ui/WheelColumn/ZKitWheelPickerNativeComponent.tsx +68 -0
- package/src/ui/WheelColumn/constants.ts +1 -0
- package/src/ui/WheelColumn/index.tsx +826 -0
- package/zkit-ui.podspec +19 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# PermissionPurposeDialogService
|
|
2
|
+
|
|
3
|
+
权限用途说明 TopSheet。在系统权限申请框弹出前后,于屏幕顶部展示一条白底黑字的非阻塞说明条,告知用户该权限的使用目的。纯展示、不拦截交互、无按钮。
|
|
4
|
+
|
|
5
|
+
## 前置条件
|
|
6
|
+
|
|
7
|
+
确保应用根组件已包裹 `ComponentLibProvider`(已内置 `PermissionPurposeDialogProvider`):
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { ComponentLibProvider } from 'zkit-ui';
|
|
11
|
+
|
|
12
|
+
export default function App() {
|
|
13
|
+
return (
|
|
14
|
+
<ComponentLibProvider>
|
|
15
|
+
{/* 你的应用内容 */}
|
|
16
|
+
</ComponentLibProvider>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 使用方式
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { permissionPurposeDialog } from 'zkit-ui';
|
|
25
|
+
|
|
26
|
+
// 展示说明(与系统权限框同时出现)
|
|
27
|
+
const purpose = permissionPurposeDialog.show({
|
|
28
|
+
permission: 'location',
|
|
29
|
+
message: '该权限仅用于考勤打卡定位,不会用于其他目的。',
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// ... 发起系统权限请求 ...
|
|
33
|
+
|
|
34
|
+
// 请求完成后关闭说明条
|
|
35
|
+
purpose.hide();
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## 内置权限类型
|
|
39
|
+
|
|
40
|
+
| permission | 默认标题 | 默认描述 |
|
|
41
|
+
|---|---|---|
|
|
42
|
+
| `location` | 需要使用位置 | 用于定位、附近内容或位置相关服务... |
|
|
43
|
+
| `camera` | 需要使用相机 | 用于拍照、扫码或上传现场图片... |
|
|
44
|
+
| `microphone` | 需要使用麦克风 | 用于录音、语音输入或通话相关功能... |
|
|
45
|
+
| `photos` | 需要访问相册 | 用于选择图片或视频,并完成上传、预览等操作 |
|
|
46
|
+
| `notification` | 需要发送通知 | 用于接收重要提醒和状态更新... |
|
|
47
|
+
| `contacts` | 需要访问通讯录 | 用于联系人选择、邀请或信息补全... |
|
|
48
|
+
| `calendar` | 需要访问日历 | 用于创建、读取或同步日程提醒... |
|
|
49
|
+
| `bluetooth` | 需要使用蓝牙 | 用于发现、连接或管理附近设备... |
|
|
50
|
+
| `motion` | 需要访问运动数据 | 用于识别运动状态或完成健康相关功能... |
|
|
51
|
+
| `custom` | 权限申请说明 | (需自行传入 title / message) |
|
|
52
|
+
|
|
53
|
+
## API
|
|
54
|
+
|
|
55
|
+
### permissionPurposeDialog.show(options)
|
|
56
|
+
|
|
57
|
+
返回 `PermissionPurposeDialogHandle`,可用于只关闭或更新本次说明,避免旧异步权限流程误关新的说明条。
|
|
58
|
+
|
|
59
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
60
|
+
|---|---|---|---|
|
|
61
|
+
| permission | PermissionPurpose | - | 权限用途,自动填充默认文案 |
|
|
62
|
+
| title | string | - | 自定义标题(优先于默认文案) |
|
|
63
|
+
| message | string | - | 自定义描述(优先于默认文案) |
|
|
64
|
+
| scopeKey | string | - | 作用域标识 |
|
|
65
|
+
| duration | number | - | 自动关闭时长(毫秒)。不传则手动关闭 |
|
|
66
|
+
| topOffset | number | - | 顶部安全区下方额外偏移 |
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
const purpose = permissionPurposeDialog.show({ permission: 'camera' });
|
|
70
|
+
purpose.update({ message: '仅用于本次扫码。' });
|
|
71
|
+
purpose.hide();
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### permissionPurposeDialog.hide()
|
|
75
|
+
|
|
76
|
+
关闭当前说明条。
|
|
77
|
+
|
|
78
|
+
### permissionPurposeDialog.hideByScope(scopeKey)
|
|
79
|
+
|
|
80
|
+
按 scopeKey 关闭特定说明条。
|
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file PermissionPurposeDialogService - 权限用途说明 TopSheet
|
|
3
|
+
* @description 在系统权限申请框弹出前后,于屏幕顶部展示一条白底黑字的非阻塞说明条,
|
|
4
|
+
* 告知用户该权限的使用目的。纯展示、不拦截交互、无按钮。
|
|
5
|
+
* 支持按权限自动填充默认文案,也支持完全自定义。
|
|
6
|
+
* @example
|
|
7
|
+
* ```tsx
|
|
8
|
+
* import { permissionPurposeDialog } from 'zkit-ui';
|
|
9
|
+
*
|
|
10
|
+
* // 展示说明
|
|
11
|
+
* const purpose = permissionPurposeDialog.show({ permission: 'location' });
|
|
12
|
+
* // ... 发起系统权限请求 ...
|
|
13
|
+
* // 请求完成后关闭
|
|
14
|
+
* purpose.hide();
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import * as React from 'react';
|
|
19
|
+
import { Animated, Easing, Platform, StyleSheet, View } from 'react-native';
|
|
20
|
+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
21
|
+
import { wp } from 'zkit-tools';
|
|
22
|
+
import { Text } from '../../ui/Text';
|
|
23
|
+
|
|
24
|
+
/** 内置支持的权限用途类型 */
|
|
25
|
+
export type PermissionPurpose =
|
|
26
|
+
| 'location'
|
|
27
|
+
| 'camera'
|
|
28
|
+
| 'microphone'
|
|
29
|
+
| 'photos'
|
|
30
|
+
| 'notification'
|
|
31
|
+
| 'contacts'
|
|
32
|
+
| 'calendar'
|
|
33
|
+
| 'bluetooth'
|
|
34
|
+
| 'motion'
|
|
35
|
+
| 'custom';
|
|
36
|
+
|
|
37
|
+
/** 弹窗配置 */
|
|
38
|
+
export type PermissionPurposeDialogOptions = {
|
|
39
|
+
/** 作用域标识,用于按标识关闭 */
|
|
40
|
+
scopeKey?: string;
|
|
41
|
+
/** 权限用途,会自动填充默认标题与描述 */
|
|
42
|
+
permission?: PermissionPurpose;
|
|
43
|
+
/** 自定义标题(优先于默认文案) */
|
|
44
|
+
title?: string;
|
|
45
|
+
/** 自定义描述(优先于默认文案) */
|
|
46
|
+
message?: string;
|
|
47
|
+
/** 自动关闭时长(毫秒)。不传则保持显示,直到显式关闭 */
|
|
48
|
+
duration?: number;
|
|
49
|
+
/** 顶部安全区下方额外偏移。默认 `wp(8)` */
|
|
50
|
+
topOffset?: number;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/** `show()` 返回的句柄,用于精确关闭或更新本次说明。 */
|
|
54
|
+
export type PermissionPurposeDialogHandle = {
|
|
55
|
+
/** 本次说明的唯一标识。 */
|
|
56
|
+
id: string;
|
|
57
|
+
/** 只关闭当前 id 对应的说明,避免旧异步流程误关新说明。 */
|
|
58
|
+
hide: () => void;
|
|
59
|
+
/** 只更新当前 id 对应的说明配置。 */
|
|
60
|
+
update: (patch: Partial<PermissionPurposeDialogOptions>) => void;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
type PermissionPurposePreset = Exclude<PermissionPurpose, 'custom'>;
|
|
64
|
+
|
|
65
|
+
type PermissionPurposeCopy = {
|
|
66
|
+
title: string;
|
|
67
|
+
message: string;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
type ResolvedPermissionPurposeDialogOptions = {
|
|
71
|
+
id: string;
|
|
72
|
+
scopeKey?: string;
|
|
73
|
+
permission: PermissionPurpose;
|
|
74
|
+
title: string;
|
|
75
|
+
message: string;
|
|
76
|
+
topOffset: number;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
type PermissionPurposeDialogState = {
|
|
80
|
+
open: boolean;
|
|
81
|
+
options: ResolvedPermissionPurposeDialogOptions;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/** 各权限类型的默认文案 */
|
|
85
|
+
const DEFAULT_PURPOSE_TEXT: Record<
|
|
86
|
+
PermissionPurposePreset,
|
|
87
|
+
PermissionPurposeCopy
|
|
88
|
+
> = {
|
|
89
|
+
location: {
|
|
90
|
+
title: '需要使用位置',
|
|
91
|
+
message: '用于定位、附近内容或位置相关服务。授权只会在相关功能中使用。',
|
|
92
|
+
},
|
|
93
|
+
camera: {
|
|
94
|
+
title: '需要使用相机',
|
|
95
|
+
message: '用于拍照、扫码或上传现场图片。授权只会在相关功能中使用。',
|
|
96
|
+
},
|
|
97
|
+
microphone: {
|
|
98
|
+
title: '需要使用麦克风',
|
|
99
|
+
message: '用于录音、语音输入或通话相关功能。授权只会在相关功能中使用。',
|
|
100
|
+
},
|
|
101
|
+
photos: {
|
|
102
|
+
title: '需要访问相册',
|
|
103
|
+
message: '用于选择图片或视频,并完成上传、预览等操作。',
|
|
104
|
+
},
|
|
105
|
+
notification: {
|
|
106
|
+
title: '需要发送通知',
|
|
107
|
+
message: '用于接收重要提醒和状态更新,你可以随时在系统设置中调整。',
|
|
108
|
+
},
|
|
109
|
+
contacts: {
|
|
110
|
+
title: '需要访问通讯录',
|
|
111
|
+
message: '用于联系人选择、邀请或信息补全。授权只会在相关功能中使用。',
|
|
112
|
+
},
|
|
113
|
+
calendar: {
|
|
114
|
+
title: '需要访问日历',
|
|
115
|
+
message: '用于创建、读取或同步日程提醒。授权只会在相关功能中使用。',
|
|
116
|
+
},
|
|
117
|
+
bluetooth: {
|
|
118
|
+
title: '需要使用蓝牙',
|
|
119
|
+
message: '用于发现、连接或管理附近设备。授权只会在相关功能中使用。',
|
|
120
|
+
},
|
|
121
|
+
motion: {
|
|
122
|
+
title: '需要访问运动数据',
|
|
123
|
+
message: '用于识别运动状态或完成健康相关功能。授权只会在相关功能中使用。',
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const DEFAULT_TITLE = '权限申请说明';
|
|
128
|
+
const DEFAULT_PERMISSION: PermissionPurpose = 'custom';
|
|
129
|
+
const DEFAULT_TOP_OFFSET = wp(8);
|
|
130
|
+
const EXIT_DURATION_MS = 200;
|
|
131
|
+
const PERMISSION_HOST_Z_INDEX = 9999;
|
|
132
|
+
|
|
133
|
+
function isPresetPermission(permission: string): permission is PermissionPurposePreset {
|
|
134
|
+
return Object.prototype.hasOwnProperty.call(DEFAULT_PURPOSE_TEXT, permission);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function normalizeText(value: string | undefined) {
|
|
138
|
+
if (typeof value !== 'string') return undefined;
|
|
139
|
+
return value.trim();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function normalizeDuration(value: number | undefined) {
|
|
143
|
+
if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0) return undefined;
|
|
144
|
+
return value;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function normalizeTopOffset(value: number | undefined) {
|
|
148
|
+
if (typeof value !== 'number' || !Number.isFinite(value)) return DEFAULT_TOP_OFFSET;
|
|
149
|
+
return Math.max(0, value);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function resolveOptions(
|
|
153
|
+
options: PermissionPurposeDialogOptions,
|
|
154
|
+
id: string
|
|
155
|
+
): ResolvedPermissionPurposeDialogOptions {
|
|
156
|
+
const rawPermission = options.permission ?? DEFAULT_PERMISSION;
|
|
157
|
+
const permission: PermissionPurpose =
|
|
158
|
+
rawPermission === 'custom' || isPresetPermission(rawPermission) ? rawPermission : DEFAULT_PERMISSION;
|
|
159
|
+
const preset = isPresetPermission(permission) ? DEFAULT_PURPOSE_TEXT[permission] : null;
|
|
160
|
+
const title = normalizeText(options.title) || preset?.title || DEFAULT_TITLE;
|
|
161
|
+
const message = normalizeText(options.message) ?? preset?.message ?? '';
|
|
162
|
+
|
|
163
|
+
return {
|
|
164
|
+
id,
|
|
165
|
+
scopeKey: options.scopeKey,
|
|
166
|
+
permission,
|
|
167
|
+
title,
|
|
168
|
+
message,
|
|
169
|
+
topOffset: normalizeTopOffset(options.topOffset),
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* 权限用途说明弹窗服务类
|
|
175
|
+
* @internal
|
|
176
|
+
*/
|
|
177
|
+
class PermissionPurposeDialogServiceClass {
|
|
178
|
+
private mounted = false;
|
|
179
|
+
private idSeed = 0;
|
|
180
|
+
private activeId: string | null = null;
|
|
181
|
+
private activeOptions: PermissionPurposeDialogOptions | null = null;
|
|
182
|
+
private hideTimer: ReturnType<typeof setTimeout> | null = null;
|
|
183
|
+
private setState: React.Dispatch<React.SetStateAction<PermissionPurposeDialogState>> | null = null;
|
|
184
|
+
|
|
185
|
+
/** @internal */
|
|
186
|
+
setMounted(mounted: boolean) {
|
|
187
|
+
this.mounted = mounted;
|
|
188
|
+
if (!mounted) {
|
|
189
|
+
this.activeId = null;
|
|
190
|
+
this.activeOptions = null;
|
|
191
|
+
this.clearHideTimer();
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** @internal */
|
|
196
|
+
setStateUpdater(updater: React.Dispatch<React.SetStateAction<PermissionPurposeDialogState>> | null) {
|
|
197
|
+
this.setState = updater;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** 展示权限用途说明 */
|
|
201
|
+
show(options: PermissionPurposeDialogOptions = {}): PermissionPurposeDialogHandle {
|
|
202
|
+
const id = this.createId();
|
|
203
|
+
|
|
204
|
+
if (!this.mounted || !this.setState) {
|
|
205
|
+
console.warn('[permissionPurposeDialog] Provider not mounted');
|
|
206
|
+
return this.createHandle(id);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
this.openWithOptions(id, options);
|
|
210
|
+
return this.createHandle(id);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/** 关闭说明 */
|
|
214
|
+
hide() {
|
|
215
|
+
this.hideInternal();
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/** 按 scopeKey 关闭 */
|
|
219
|
+
hideByScope(scopeKey?: string) {
|
|
220
|
+
if (!scopeKey) return;
|
|
221
|
+
if (this.activeOptions?.scopeKey !== scopeKey) return;
|
|
222
|
+
this.hideById(this.activeId);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/** @internal 清理所有定时器 */
|
|
226
|
+
clearAllTimers() {
|
|
227
|
+
this.clearHideTimer();
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
private openWithOptions(id: string, options: PermissionPurposeDialogOptions) {
|
|
231
|
+
this.clearHideTimer();
|
|
232
|
+
this.activeId = id;
|
|
233
|
+
this.activeOptions = options;
|
|
234
|
+
|
|
235
|
+
const resolvedOptions = resolveOptions(options, id);
|
|
236
|
+
this.setState?.({ open: true, options: resolvedOptions });
|
|
237
|
+
|
|
238
|
+
const duration = normalizeDuration(options.duration);
|
|
239
|
+
if (duration != null) {
|
|
240
|
+
this.hideTimer = setTimeout(() => {
|
|
241
|
+
this.hideById(id);
|
|
242
|
+
}, duration);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
private hideInternal(id?: string) {
|
|
247
|
+
if (id && id !== this.activeId) return;
|
|
248
|
+
|
|
249
|
+
const closingId = this.activeId;
|
|
250
|
+
this.activeId = null;
|
|
251
|
+
this.activeOptions = null;
|
|
252
|
+
this.clearHideTimer();
|
|
253
|
+
|
|
254
|
+
if (!this.mounted || !this.setState) return;
|
|
255
|
+
|
|
256
|
+
this.setState((prev) => {
|
|
257
|
+
if (closingId && prev.options.id !== closingId) return prev;
|
|
258
|
+
if (!prev.open) return prev;
|
|
259
|
+
return { ...prev, open: false };
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/** 只关闭指定 id 的说明,避免旧流程误关新说明。 */
|
|
264
|
+
private hideById(id?: string | null) {
|
|
265
|
+
if (!id || id !== this.activeId) return;
|
|
266
|
+
this.hideInternal(id);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/** 只更新指定 id 的说明。 */
|
|
270
|
+
private updateById(id: string, patch: Partial<PermissionPurposeDialogOptions>) {
|
|
271
|
+
if (!id || id !== this.activeId || !this.activeOptions || !this.mounted || !this.setState) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
this.openWithOptions(id, { ...this.activeOptions, ...patch });
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
private createId() {
|
|
279
|
+
this.idSeed += 1;
|
|
280
|
+
return `permission_purpose_${Date.now()}_${this.idSeed}`;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
private createHandle(id: string): PermissionPurposeDialogHandle {
|
|
284
|
+
return {
|
|
285
|
+
id,
|
|
286
|
+
hide: () => this.hideById(id),
|
|
287
|
+
update: (patch) => this.updateById(id, patch),
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
private clearHideTimer() {
|
|
292
|
+
if (this.hideTimer) {
|
|
293
|
+
clearTimeout(this.hideTimer);
|
|
294
|
+
this.hideTimer = null;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/** 权限用途说明弹窗服务实例 */
|
|
300
|
+
export const permissionPurposeDialog = new PermissionPurposeDialogServiceClass();
|
|
301
|
+
|
|
302
|
+
const initialState: PermissionPurposeDialogState = {
|
|
303
|
+
open: false,
|
|
304
|
+
options: resolveOptions({}, '__initial__'),
|
|
305
|
+
};
|
|
306
|
+
|
|
307
|
+
/** TopSheet 纯展示卡片 */
|
|
308
|
+
function PermissionPurposeCard({
|
|
309
|
+
open,
|
|
310
|
+
options,
|
|
311
|
+
}: {
|
|
312
|
+
open: boolean;
|
|
313
|
+
options: ResolvedPermissionPurposeDialogOptions;
|
|
314
|
+
}) {
|
|
315
|
+
const insets = useSafeAreaInsets();
|
|
316
|
+
const progress = React.useRef(new Animated.Value(open ? 1 : 0)).current;
|
|
317
|
+
const [visible, setVisible] = React.useState(open);
|
|
318
|
+
|
|
319
|
+
const accessibilityLabel = React.useMemo(() => {
|
|
320
|
+
if (!options.message) return options.title;
|
|
321
|
+
return `${options.title},${options.message}`;
|
|
322
|
+
}, [options.message, options.title]);
|
|
323
|
+
|
|
324
|
+
React.useEffect(() => {
|
|
325
|
+
return () => {
|
|
326
|
+
progress.stopAnimation();
|
|
327
|
+
};
|
|
328
|
+
}, [progress]);
|
|
329
|
+
|
|
330
|
+
React.useEffect(() => {
|
|
331
|
+
progress.stopAnimation();
|
|
332
|
+
|
|
333
|
+
if (open) {
|
|
334
|
+
setVisible(true);
|
|
335
|
+
// 入场直接显示,不做过渡。
|
|
336
|
+
// 因为 Android 系统权限弹框弹出后会冻结 App 动画线程,
|
|
337
|
+
// 若此处做动画,权限说明可能停在半透明状态,反而损害稳定性。
|
|
338
|
+
progress.setValue(1);
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
if (!visible) return;
|
|
343
|
+
|
|
344
|
+
// 退场:系统权限框关闭后 App 恢复正常,可以正常跑退出动画
|
|
345
|
+
Animated.timing(progress, {
|
|
346
|
+
toValue: 0,
|
|
347
|
+
duration: EXIT_DURATION_MS,
|
|
348
|
+
easing: Easing.out(Easing.cubic),
|
|
349
|
+
useNativeDriver: true,
|
|
350
|
+
}).start(({ finished }) => {
|
|
351
|
+
if (finished) setVisible(false);
|
|
352
|
+
});
|
|
353
|
+
}, [open, options.id, progress, visible]);
|
|
354
|
+
|
|
355
|
+
const animatedStyle = React.useMemo(
|
|
356
|
+
() => ({
|
|
357
|
+
opacity: progress,
|
|
358
|
+
}),
|
|
359
|
+
[progress]
|
|
360
|
+
);
|
|
361
|
+
|
|
362
|
+
if (!visible) return null;
|
|
363
|
+
|
|
364
|
+
return (
|
|
365
|
+
<View pointerEvents="none" style={[styles.host, { top: (insets.top || 0) + options.topOffset }]}>
|
|
366
|
+
<Animated.View
|
|
367
|
+
accessible={open}
|
|
368
|
+
accessibilityLabel={accessibilityLabel}
|
|
369
|
+
accessibilityLiveRegion="polite"
|
|
370
|
+
accessibilityRole="alert"
|
|
371
|
+
importantForAccessibility={open ? 'yes' : 'no-hide-descendants'}
|
|
372
|
+
renderToHardwareTextureAndroid={Platform.OS === 'android'}
|
|
373
|
+
shouldRasterizeIOS={Platform.OS === 'ios'}
|
|
374
|
+
style={[
|
|
375
|
+
styles.sheet,
|
|
376
|
+
animatedStyle,
|
|
377
|
+
]}
|
|
378
|
+
>
|
|
379
|
+
<View style={styles.content}>
|
|
380
|
+
<Text style={styles.title}>{options.title}</Text>
|
|
381
|
+
{options.message ? <Text style={styles.message}>{options.message}</Text> : null}
|
|
382
|
+
</View>
|
|
383
|
+
</Animated.View>
|
|
384
|
+
</View>
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* 权限用途说明 Provider
|
|
390
|
+
* @description 需要在应用根组件中包裹,已内置于 ComponentLibProvider
|
|
391
|
+
*/
|
|
392
|
+
export function PermissionPurposeDialogProvider({ children }: { children: React.ReactNode }) {
|
|
393
|
+
const [state, setState] = React.useState<PermissionPurposeDialogState>(initialState);
|
|
394
|
+
|
|
395
|
+
React.useEffect(() => {
|
|
396
|
+
permissionPurposeDialog.setMounted(true);
|
|
397
|
+
permissionPurposeDialog.setStateUpdater(setState);
|
|
398
|
+
return () => {
|
|
399
|
+
permissionPurposeDialog.clearAllTimers();
|
|
400
|
+
permissionPurposeDialog.setStateUpdater(null);
|
|
401
|
+
permissionPurposeDialog.setMounted(false);
|
|
402
|
+
};
|
|
403
|
+
}, []);
|
|
404
|
+
|
|
405
|
+
return (
|
|
406
|
+
<>
|
|
407
|
+
{children}
|
|
408
|
+
<PermissionPurposeCard open={state.open} options={state.options} />
|
|
409
|
+
</>
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
const styles = StyleSheet.create({
|
|
414
|
+
host: {
|
|
415
|
+
position: 'absolute',
|
|
416
|
+
left: wp(0),
|
|
417
|
+
right: wp(0),
|
|
418
|
+
alignItems: 'center',
|
|
419
|
+
zIndex: PERMISSION_HOST_Z_INDEX,
|
|
420
|
+
elevation: Platform.OS === 'android' ? PERMISSION_HOST_Z_INDEX : 0,
|
|
421
|
+
},
|
|
422
|
+
sheet: {
|
|
423
|
+
width: wp(340),
|
|
424
|
+
maxWidth: '94%',
|
|
425
|
+
borderRadius: wp(12),
|
|
426
|
+
backgroundColor: '#FFFFFF',
|
|
427
|
+
shadowColor: '#000000',
|
|
428
|
+
shadowOpacity: 0.12,
|
|
429
|
+
shadowOffset: { width: wp(0), height: wp(4) },
|
|
430
|
+
shadowRadius: wp(12),
|
|
431
|
+
elevation: 8,
|
|
432
|
+
},
|
|
433
|
+
content: {
|
|
434
|
+
paddingHorizontal: wp(16),
|
|
435
|
+
paddingVertical: wp(14),
|
|
436
|
+
},
|
|
437
|
+
title: {
|
|
438
|
+
fontSize: wp(15),
|
|
439
|
+
lineHeight: wp(20),
|
|
440
|
+
fontWeight: '600',
|
|
441
|
+
color: '#111111',
|
|
442
|
+
},
|
|
443
|
+
message: {
|
|
444
|
+
marginTop: wp(6),
|
|
445
|
+
fontSize: wp(13),
|
|
446
|
+
lineHeight: wp(18),
|
|
447
|
+
color: '#333333',
|
|
448
|
+
},
|
|
449
|
+
});
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# PickerService
|
|
2
|
+
|
|
3
|
+
命令式调用选择器服务,支持通用选择器、日期选择器、地址选择器和时间区间选择器。
|
|
4
|
+
|
|
5
|
+
## 前置条件
|
|
6
|
+
|
|
7
|
+
确保应用根组件已包裹 `ComponentLibProvider`(已内置 `PickerServiceProvider`):
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
import { ComponentLibProvider } from 'zkit-ui';
|
|
11
|
+
|
|
12
|
+
export default function App() {
|
|
13
|
+
return (
|
|
14
|
+
<ComponentLibProvider>
|
|
15
|
+
{/* 你的应用内容 */}
|
|
16
|
+
</ComponentLibProvider>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 使用方式
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { pickerService } from 'zkit-ui';
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### 通用选择器
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
const result = await pickerService.pick({
|
|
31
|
+
options: [
|
|
32
|
+
{ value: 'zh', label: '中文' },
|
|
33
|
+
{ value: 'en', label: 'English' },
|
|
34
|
+
],
|
|
35
|
+
value: 'zh',
|
|
36
|
+
title: '选择语言',
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
if (result) {
|
|
40
|
+
console.log(result.value); // 'zh' | 'en'
|
|
41
|
+
console.log(result.label); // '中文' | 'English'
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 日期选择器
|
|
46
|
+
|
|
47
|
+
```tsx
|
|
48
|
+
const result = await pickerService.pickDate({
|
|
49
|
+
value: '2024-01-15',
|
|
50
|
+
title: '选择日期',
|
|
51
|
+
min: '2020-01-01',
|
|
52
|
+
max: '2030-12-31',
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
if (result) {
|
|
56
|
+
console.log(result.value); // '2024-01-15'
|
|
57
|
+
console.log(result.label); // '2024-01-15'
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 地址选择器
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
const result = await pickerService.pickAddress({
|
|
65
|
+
value: ['110000', '110100', '110101'],
|
|
66
|
+
title: '选择地址',
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
if (result) {
|
|
70
|
+
console.log(result.value); // ['110000', '110100', '110101']
|
|
71
|
+
console.log(result.label); // '北京市-市辖区-东城区'
|
|
72
|
+
console.log(result.labels); // ['北京市', '市辖区', '东城区']
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 时间区间选择器
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
const result = await pickerService.pickBetweenTime({
|
|
80
|
+
value: ['2024-01-01', '2024-01-31'],
|
|
81
|
+
title: '选择时间范围',
|
|
82
|
+
type: 'day',
|
|
83
|
+
quickDate: ['d', 'w', 'm', '7', '30'],
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
if (result) {
|
|
87
|
+
console.log(result.value); // ['2024-01-01', '2024-01-31']
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## API
|
|
92
|
+
|
|
93
|
+
### pickerService.pick(options)
|
|
94
|
+
|
|
95
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
96
|
+
|------|------|------|------|
|
|
97
|
+
| options | PickerOption[] | ✓ | 选项列表,默认字段为 `value/label/children/disabled` |
|
|
98
|
+
| value | PickerValue | - | 当前值 |
|
|
99
|
+
| defaultValue | PickerValue | - | 默认值 |
|
|
100
|
+
| title | string | - | 标题 |
|
|
101
|
+
| valueMode | `'auto' \| 'single' \| 'path'` | - | 输出值模式 |
|
|
102
|
+
| getOptionValue | function | - | 自定义取值 |
|
|
103
|
+
| getOptionLabel | function | - | 自定义文案 |
|
|
104
|
+
| disabled | boolean | - | 是否禁用 |
|
|
105
|
+
|
|
106
|
+
返回 `Promise<PickerResult>`,取消时返回 `null`。
|
|
107
|
+
|
|
108
|
+
### pickerService.pickDate(options)
|
|
109
|
+
|
|
110
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
111
|
+
|------|------|------|------|
|
|
112
|
+
| value | string | - | 当前日期,格式 YYYY-MM-DD |
|
|
113
|
+
| defaultValue | string | - | 默认日期 |
|
|
114
|
+
| title | string | - | 标题 |
|
|
115
|
+
| precision | 'year' \| 'month' \| 'day' | - | 精度,默认 'day' |
|
|
116
|
+
| min | string \| Date \| Dayjs | - | 最小日期 |
|
|
117
|
+
| max | string \| Date \| Dayjs | - | 最大日期 |
|
|
118
|
+
| labelFormat | string \| function | - | 展示格式 |
|
|
119
|
+
| disabled | boolean | - | 是否禁用 |
|
|
120
|
+
|
|
121
|
+
返回 `Promise<DatePickerResult>`,取消时返回 `null`。
|
|
122
|
+
|
|
123
|
+
### pickerService.pickAddress(options)
|
|
124
|
+
|
|
125
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
126
|
+
|------|------|------|------|
|
|
127
|
+
| list | AddressCascaderOption[] | - | 自定义地址数据,默认使用内置省市区 |
|
|
128
|
+
| value | string[] | - | 当前地址码数组 |
|
|
129
|
+
| defaultValue | string[] | - | 默认地址码数组 |
|
|
130
|
+
| title | string | - | 标题 |
|
|
131
|
+
| separator | string | - | 分隔符,默认 '-' |
|
|
132
|
+
| disabled | boolean | - | 是否禁用 |
|
|
133
|
+
|
|
134
|
+
返回 `Promise<AddressPickerResult>`,取消时返回 `null`。
|
|
135
|
+
|
|
136
|
+
### pickerService.pickBetweenTime(options)
|
|
137
|
+
|
|
138
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
139
|
+
|------|------|------|------|
|
|
140
|
+
| value | string[] | - | 当前时间区间 [开始, 结束] |
|
|
141
|
+
| defaultValue | string[] | - | 默认时间区间 |
|
|
142
|
+
| title | string | - | 标题 |
|
|
143
|
+
| type | 'year' \| 'month' \| 'day' \| 'hour' \| 'minute' \| 'second' | - | 精度,默认 'day' |
|
|
144
|
+
| format | string | - | 显示格式,默认 'YYYY-MM-DD' |
|
|
145
|
+
| start | string | - | 最小时间 |
|
|
146
|
+
| end | string | - | 最大时间 |
|
|
147
|
+
| quickDate | string[] | - | 快捷选项:'d'今天/'w'本周/'m'本月/'y'本年/'q'本季度/数字表示最近N天 |
|
|
148
|
+
| disabled | boolean | - | 是否禁用 |
|
|
149
|
+
|
|
150
|
+
返回 `Promise<BetweenTimePickerResult>`,取消时返回 `null`。
|
|
151
|
+
|
|
152
|
+
### pickerService.close()
|
|
153
|
+
|
|
154
|
+
手动关闭当前打开的选择器。
|