react-native-x-components 0.2.0 → 0.2.1
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/AGENTS.md +128 -0
- package/README.md +44 -0
- package/dist/XTheme/ThemeControls.js +9 -5
- package/package.json +10 -3
- package/wechat-qrcode.png +0 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# AGENTS.md — AI 编码工具使用指南
|
|
2
|
+
|
|
3
|
+
> 本文件供 AI 编码工具(Cursor / Copilot / Claude Code / WorkBuddy 等)在使用
|
|
4
|
+
> react-native-x-components 时参考。人也可以读,但写法面向 AI。
|
|
5
|
+
|
|
6
|
+
## 0. 安装与前置依赖
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm install react-native-x-components dayjs zustand
|
|
10
|
+
# 必需 peer(Expo 项目):
|
|
11
|
+
npx expo install react-native-reanimated react-native-safe-area-context react-native-svg react-native-gesture-handler
|
|
12
|
+
# 可选 peer(用到哪个装哪个):
|
|
13
|
+
# @shopify/react-native-skia → XSignatureSkia
|
|
14
|
+
# expo-audio → XRecord
|
|
15
|
+
# expo-image-picker + expo-image-manipulator + expo-file-system → XUpload*
|
|
16
|
+
# expo-video → XVideoPreview
|
|
17
|
+
# react-native-zoom-toolkit → XImagePreview 缩放
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
原生依赖安装后需要 `npx expo prebuild --clean`(裸项目则重新构建原生包),
|
|
21
|
+
否则录音/拍照权限弹窗、Skia、视频编解码不会生效。
|
|
22
|
+
|
|
23
|
+
## 1. 必须的 App 根部接线(漏掉 = 命令式 API 静默失效)
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
27
|
+
import { XPopupProvider } from 'react-native-x-components';
|
|
28
|
+
|
|
29
|
+
export default function App() {
|
|
30
|
+
return (
|
|
31
|
+
<GestureHandlerRootView style={{flex: 1}}>
|
|
32
|
+
<XPopupProvider>
|
|
33
|
+
{/* 整个 App */}
|
|
34
|
+
</XPopupProvider>
|
|
35
|
+
</GestureHandlerRootView>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
XPopupProvider 内部挂载:XTopView(弹层宿主)、XConfirmForm、XActionSheet 全局实例、
|
|
41
|
+
XToast / XLoadingModal / XImagePreview 的 Provider。以下命令式 API 全部依赖它:
|
|
42
|
+
|
|
43
|
+
- `XToastService.show({ message, type, position })`
|
|
44
|
+
- `confirm({ title, content, danger })` → `Promise<boolean>`
|
|
45
|
+
- `showXActionSheet({ title, options })` → `Promise<value | null>`
|
|
46
|
+
- `XLoadingModalService.show({ message }) / hide()`
|
|
47
|
+
- `XImagePreviewService.show({ images, initialIndex })`
|
|
48
|
+
|
|
49
|
+
## 2. 常见错误对照表
|
|
50
|
+
|
|
51
|
+
| 症状 | 原因 | 修复 |
|
|
52
|
+
|---|---|---|
|
|
53
|
+
| Toast / confirm / ActionSheet 无反应 | XPopupProvider 未挂根 | App 根部包 `<XPopupProvider>` |
|
|
54
|
+
| 上传报 adapter 错误 | 未注入上传适配器 | `setXUploadAdapter(createMinioPresignedAdapter({...}))` |
|
|
55
|
+
| 手势 / 滚轮不响应 | 缺 gesture-handler | install + GestureHandlerRootView 包根 |
|
|
56
|
+
| Skia 签名报错 | 未装 skia | `npx expo install @shopify/react-native-skia` |
|
|
57
|
+
| 录音/拍照无权限弹窗 | prebuild 未重跑 | `npx expo prebuild --clean` |
|
|
58
|
+
| 暗黑切换全局不生效 | mode 被手动写死 | `setXThemeMode('system')` 恢复跟随 |
|
|
59
|
+
| 主题色不生效 | 组件硬编码颜色 | 颜色一律取 `useXTheme()` token |
|
|
60
|
+
|
|
61
|
+
## 3. 最小代码骨架
|
|
62
|
+
|
|
63
|
+
### 上传(MinIO 预签名直传)
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
import { setXUploadAdapter, createMinioPresignedAdapter, XUploadImage } from 'react-native-x-components';
|
|
67
|
+
|
|
68
|
+
setXUploadAdapter(createMinioPresignedAdapter({
|
|
69
|
+
getUploadUrl: async ({ name }) => {
|
|
70
|
+
const res = await fetch(API + '/file/getUploadUrl?fileName=' + name);
|
|
71
|
+
const { data } = await res.json();
|
|
72
|
+
return { objectKey: data.objectKey, preSignedUrl: data.preSignedUrl };
|
|
73
|
+
},
|
|
74
|
+
getPreviewUrl: async objectKey => fetchPreviewUrl(objectKey),
|
|
75
|
+
}));
|
|
76
|
+
|
|
77
|
+
<XUploadImage value={imgs} onChange={setImgs} max={9} />
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### 表单
|
|
81
|
+
|
|
82
|
+
```tsx
|
|
83
|
+
import { XForm, XInput, XButton } from 'react-native-x-components';
|
|
84
|
+
|
|
85
|
+
const [form] = XForm.useForm();
|
|
86
|
+
<XForm form={form} onFinish={console.log}>
|
|
87
|
+
<XForm.Item label="姓名" name="name" trigger="onChangeText"
|
|
88
|
+
rules={[{ required: true, message: '必填' }]}>
|
|
89
|
+
<XInput placeholder="请输入姓名" />
|
|
90
|
+
</XForm.Item>
|
|
91
|
+
<XButton type="primary" onPress={() => form.submit()}>提交</XButton>
|
|
92
|
+
</XForm>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
注意:输入类控件 `trigger="onChangeText"`,选择类 `trigger="onChange"`(默认),写错则值不同步。
|
|
96
|
+
|
|
97
|
+
### 主题 / 语言
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
import { useXTheme, setXThemeMode, setXBrandByName, setXLocale } from 'react-native-x-components';
|
|
101
|
+
|
|
102
|
+
setXThemeMode('dark'); // 'light' | 'dark' | 'system'(默认跟随系统)
|
|
103
|
+
setXBrandByName('薰衣紫'); // 4 套预设品牌色,深浅色各自适配
|
|
104
|
+
setXLocale('en-US'); // 组件文案即时切换
|
|
105
|
+
|
|
106
|
+
const t = useXTheme(); // 组件内取 token,禁硬编码颜色
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## 4. 设计约定(生成代码前遵守)
|
|
110
|
+
|
|
111
|
+
1. **弹层一律用本库体系**:XPullView(side: bottom/top/left/right/center)+ 全局 XTopView 宿主;**不要用 RN Modal**。
|
|
112
|
+
2. **命令式服务统一 `XxxService.show()` 风格**,不再自己 setState 管 visible(除非用受控形态组件)。
|
|
113
|
+
3. **颜色/圆角一律 `useXTheme()`**:浅深两套 token 自动切换,硬编码颜色是 bug。
|
|
114
|
+
4. **XRadio / XCheckbox 的 onChange 事件对象与 antd 同构**:`e.target.value / e.target.checked`。
|
|
115
|
+
5. XForm.Item 的 trigger:输入类 `onChangeText`,其余 `onChange`。
|
|
116
|
+
6. 上传适配器协议:`upload(file, onProgress) => Promise<XUploadResult>`;`XUploadResult` 至少含 `url`(或 `objectKey`)。
|
|
117
|
+
7. XSignatureSkia 需要 Skia;XRecord 需要 expo-audio;这些可选 peer 没装时不要 import 对应组件。
|
|
118
|
+
|
|
119
|
+
## 5. 组件速查(36 个)
|
|
120
|
+
|
|
121
|
+
基础:XButton · XDivider · XInput(customKeyboard 数字键盘) · XTag · XProgress · XRadio · XCheckbox
|
|
122
|
+
表单:XForm · XFormPro · XCascadeSelect · XMultiSelect
|
|
123
|
+
弹层:XPullView · XActionSheet · XPicker · XPickerDate · XModalForm · XConfirmForm · XAnimatedView · XToast · XLoadingModal
|
|
124
|
+
交互:XTabs · XDropdownMenu · XAnimatedSearchPanel · XNumberKeyboard · XLicensePlate
|
|
125
|
+
媒体:XCalendar · XCalendarPopup · XRecord · XSignature · XSignatureSkia · XUploadImage · XUploadVideo · XVideoPreview · XImage · XImagePreview
|
|
126
|
+
数据:XChart
|
|
127
|
+
|
|
128
|
+
完整用法与 props 表:https://react-native-x-components.dev(AI 可抓取 /llms-full.txt 获取全量文档)。
|
package/README.md
CHANGED
|
@@ -1,7 +1,51 @@
|
|
|
1
1
|
# react-native-x-components
|
|
2
2
|
|
|
3
|
+
<div align="center">
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/react-native-x-components)
|
|
6
|
+
[](./LICENSE)
|
|
7
|
+
[](https://github.com/TimSpan/rn-x-components)
|
|
8
|
+
|
|
9
|
+
</div>
|
|
10
|
+
|
|
3
11
|
Ant Design 风格的 React Native (Expo) 组件库。对齐 antd v5 设计 token,内置**暗黑模式**与**中英双语**,弹层体系基于自研 TopView(比 RN Modal 更快),覆盖表单、选择器、日历、录音、签名(Skia 逐字签名)、上传(MinIO 预签名适配器)、轻量图表等 40+ 组件。
|
|
4
12
|
|
|
13
|
+
- 📦 GitHub:https://github.com/TimSpan/rn-x-components
|
|
14
|
+
- 📖 文档:https://react-native-x-components.dev(AI 可抓取 `/llms-full.txt` 全量文档)
|
|
15
|
+
- 💬 微信交流(问题反馈 / 技术交流 / 定制咨询):
|
|
16
|
+
|
|
17
|
+
<div align="center">
|
|
18
|
+
<img src="./wechat-qrcode.png" alt="微信添加 Otis 为好友" width="260" />
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
> 🤖 **AI 编码工具(Cursor/Copilot/Claude 等)请先读包内 [AGENTS.md](./AGENTS.md)** ——
|
|
22
|
+
> 前置接线清单、常见错误对照表、最小代码骨架,能避开 90% 的集成坑。
|
|
23
|
+
|
|
24
|
+
## 30 秒最小骨架
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
import { GestureHandlerRootView } from 'react-native-gesture-handler';
|
|
28
|
+
import { XPopupProvider, XButton, XToastService, confirm } from 'react-native-x-components';
|
|
29
|
+
|
|
30
|
+
export default function App() {
|
|
31
|
+
return (
|
|
32
|
+
<GestureHandlerRootView style={{flex: 1}}>
|
|
33
|
+
<XPopupProvider> {/* 必挂!否则命令式 API 静默失效 */}
|
|
34
|
+
<XButton
|
|
35
|
+
type="primary"
|
|
36
|
+
onPress={async () => {
|
|
37
|
+
const ok = await confirm({ title: '确认提交?', danger: true });
|
|
38
|
+
if (ok) XToastService.show({ message: '已提交', type: 'success' });
|
|
39
|
+
}}
|
|
40
|
+
>
|
|
41
|
+
点我
|
|
42
|
+
</XButton>
|
|
43
|
+
</XPopupProvider>
|
|
44
|
+
</GestureHandlerRootView>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
5
49
|
## 特性
|
|
6
50
|
|
|
7
51
|
- 🌗 **暗黑模式**:`useXTheme()` 全组件自适应,`setXThemeMode('light' | 'dark' | 'system')` 一行切换
|
|
@@ -2,6 +2,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { Pressable, StyleSheet, Text, View } from 'react-native';
|
|
3
3
|
import { useXTheme, useXThemeMode, setXThemeMode } from '../theme';
|
|
4
4
|
import { useXBrandStore, setXBrandByName, X_BRAND_PRESETS } from './BrandColor';
|
|
5
|
+
import { showXActionSheet } from '../XActionSheet/global';
|
|
5
6
|
import { useXLocale, setXLocale } from '../XLocale';
|
|
6
7
|
/**
|
|
7
8
|
* 暗黑切换:三态循环 📱跟随系统 → 🌙暗 → ☀️亮 → 📱。
|
|
@@ -16,14 +17,17 @@ function ThemeModeButton({ compact }) {
|
|
|
16
17
|
{ borderColor: t.colorBorder, backgroundColor: pressed ? t.colorBgLayout : 'transparent' },
|
|
17
18
|
], children: _jsx(Text, { style: [compact ? styles.icon : styles.iconBig, { color: t.colorText }], children: mode === 'system' ? '📱' : mode === 'dark' ? '🌙' : '☀️' }) }));
|
|
18
19
|
}
|
|
19
|
-
/**
|
|
20
|
+
/** 主题色选择:点击弹 ActionSheet(当前色打勾),选中即时生效 */
|
|
20
21
|
function BrandColorButton({ compact }) {
|
|
21
22
|
const t = useXTheme();
|
|
22
23
|
const brand = useXBrandStore(s => s.brand);
|
|
23
|
-
return (_jsx(Pressable, { onPress: () => {
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
return (_jsx(Pressable, { onPress: async () => {
|
|
25
|
+
const picked = await showXActionSheet({
|
|
26
|
+
title: '选择主题色',
|
|
27
|
+
options: X_BRAND_PRESETS.map(p => ({ label: `⬤ ${p.name}`, value: p.name })),
|
|
28
|
+
});
|
|
29
|
+
if (picked)
|
|
30
|
+
setXBrandByName(picked);
|
|
27
31
|
}, hitSlop: 8, style: ({ pressed }) => [
|
|
28
32
|
compact ? styles.btnCompact : styles.btn,
|
|
29
33
|
{ borderColor: t.colorBorder, backgroundColor: pressed ? t.colorBgLayout : 'transparent' },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-x-components",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Ant Design 风格的 React Native (Expo) 组件库:表单/弹层(TopView)/日历/Skia逐字签名/上传适配器(MinIO预签名)/轻量图表,内置暗黑模式与中英双语。",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"react-native": "dist/index.js",
|
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
"types": "dist/index.d.ts",
|
|
9
9
|
"files": [
|
|
10
10
|
"dist",
|
|
11
|
-
"README.md"
|
|
11
|
+
"README.md",
|
|
12
|
+
"AGENTS.md",
|
|
13
|
+
"wechat-qrcode.png"
|
|
12
14
|
],
|
|
13
15
|
"sideEffects": false,
|
|
14
16
|
"keywords": [
|
|
@@ -31,9 +33,14 @@
|
|
|
31
33
|
"popup"
|
|
32
34
|
],
|
|
33
35
|
"license": "MIT",
|
|
36
|
+
"author": "KevinMao (maoyuxiang)",
|
|
34
37
|
"repository": {
|
|
35
38
|
"type": "git",
|
|
36
|
-
"url": "git+https://github.com/
|
|
39
|
+
"url": "git+https://github.com/TimSpan/rn-x-components.git"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/TimSpan/rn-x-components#readme",
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/TimSpan/rn-x-components/issues"
|
|
37
44
|
},
|
|
38
45
|
"peerDependencies": {
|
|
39
46
|
"react": ">=18.0.0",
|
|
Binary file
|