@unif/react-native-chat 0.1.1 → 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/lib/commonjs/bubble/Bubble.js +131 -0
- package/lib/commonjs/bubble/Bubble.js.map +1 -0
- package/lib/commonjs/bubble/BubbleList.js +73 -0
- package/lib/commonjs/bubble/BubbleList.js.map +1 -0
- package/lib/commonjs/bubble/index.md +111 -0
- package/lib/commonjs/card-wrapper/CardWrapper.js +65 -0
- package/lib/commonjs/card-wrapper/CardWrapper.js.map +1 -0
- package/lib/commonjs/card-wrapper/index.md +78 -0
- package/lib/commonjs/conversations/Conversations.js +184 -0
- package/lib/commonjs/conversations/Conversations.js.map +1 -0
- package/lib/commonjs/conversations/index.md +90 -0
- package/lib/commonjs/index.js +69 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/prompts/Prompts.js +87 -0
- package/lib/commonjs/prompts/Prompts.js.map +1 -0
- package/lib/commonjs/prompts/index.md +81 -0
- package/lib/commonjs/sender/Sender.js +352 -0
- package/lib/commonjs/sender/Sender.js.map +1 -0
- package/lib/commonjs/sender/index.md +131 -0
- package/lib/commonjs/theme/tokens.js +77 -0
- package/lib/commonjs/theme/tokens.js.map +1 -0
- package/lib/commonjs/types/react-native-vector-icons.d.js +2 -0
- package/lib/commonjs/types/react-native-vector-icons.d.js.map +1 -0
- package/lib/commonjs/welcome/Welcome.js +152 -0
- package/lib/commonjs/welcome/Welcome.js.map +1 -0
- package/lib/commonjs/welcome/index.md +95 -0
- package/lib/module/bubble/Bubble.js +126 -0
- package/lib/module/bubble/Bubble.js.map +1 -0
- package/lib/module/bubble/BubbleList.js +68 -0
- package/lib/module/bubble/BubbleList.js.map +1 -0
- package/lib/module/bubble/index.md +111 -0
- package/lib/module/card-wrapper/CardWrapper.js +60 -0
- package/lib/module/card-wrapper/CardWrapper.js.map +1 -0
- package/lib/module/card-wrapper/index.md +78 -0
- package/lib/module/conversations/Conversations.js +179 -0
- package/lib/module/conversations/Conversations.js.map +1 -0
- package/lib/module/conversations/index.md +90 -0
- package/lib/module/index.js +23 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/prompts/Prompts.js +82 -0
- package/lib/module/prompts/Prompts.js.map +1 -0
- package/lib/module/prompts/index.md +81 -0
- package/lib/module/sender/Sender.js +346 -0
- package/lib/module/sender/Sender.js.map +1 -0
- package/lib/module/sender/index.md +131 -0
- package/lib/module/theme/tokens.js +72 -0
- package/lib/module/theme/tokens.js.map +1 -0
- package/lib/module/types/react-native-vector-icons.d.js +2 -0
- package/lib/module/types/react-native-vector-icons.d.js.map +1 -0
- package/lib/module/welcome/Welcome.js +147 -0
- package/lib/module/welcome/Welcome.js.map +1 -0
- package/lib/module/welcome/index.md +95 -0
- package/lib/typescript/commonjs/bubble/Bubble.d.ts +29 -0
- package/lib/typescript/commonjs/bubble/Bubble.d.ts.map +1 -0
- package/lib/typescript/commonjs/bubble/BubbleList.d.ts +20 -0
- package/lib/typescript/commonjs/bubble/BubbleList.d.ts.map +1 -0
- package/lib/typescript/commonjs/card-wrapper/CardWrapper.d.ts +22 -0
- package/lib/typescript/commonjs/card-wrapper/CardWrapper.d.ts.map +1 -0
- package/lib/typescript/commonjs/conversations/Conversations.d.ts +37 -0
- package/lib/typescript/commonjs/conversations/Conversations.d.ts.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +20 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/prompts/Prompts.d.ts +27 -0
- package/lib/typescript/commonjs/prompts/Prompts.d.ts.map +1 -0
- package/lib/typescript/commonjs/sender/Sender.d.ts +58 -0
- package/lib/typescript/commonjs/sender/Sender.d.ts.map +1 -0
- package/lib/typescript/commonjs/theme/tokens.d.ts +57 -0
- package/lib/typescript/commonjs/theme/tokens.d.ts.map +1 -0
- package/lib/typescript/commonjs/welcome/Welcome.d.ts +39 -0
- package/lib/typescript/commonjs/welcome/Welcome.d.ts.map +1 -0
- package/lib/typescript/module/bubble/Bubble.d.ts +29 -0
- package/lib/typescript/module/bubble/Bubble.d.ts.map +1 -0
- package/lib/typescript/module/bubble/BubbleList.d.ts +20 -0
- package/lib/typescript/module/bubble/BubbleList.d.ts.map +1 -0
- package/lib/typescript/module/card-wrapper/CardWrapper.d.ts +22 -0
- package/lib/typescript/module/card-wrapper/CardWrapper.d.ts.map +1 -0
- package/lib/typescript/module/conversations/Conversations.d.ts +37 -0
- package/lib/typescript/module/conversations/Conversations.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +20 -0
- package/lib/typescript/module/index.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/prompts/Prompts.d.ts +27 -0
- package/lib/typescript/module/prompts/Prompts.d.ts.map +1 -0
- package/lib/typescript/module/sender/Sender.d.ts +58 -0
- package/lib/typescript/module/sender/Sender.d.ts.map +1 -0
- package/lib/typescript/module/theme/tokens.d.ts +57 -0
- package/lib/typescript/module/theme/tokens.d.ts.map +1 -0
- package/lib/typescript/module/welcome/Welcome.d.ts +39 -0
- package/lib/typescript/module/welcome/Welcome.d.ts.map +1 -0
- package/package.json +41 -9
- package/src/index.tsx +24 -13
- package/src/sender/Sender.tsx +46 -38
- package/src/theme/tokens.ts +14 -2
- package/src/types/react-native-vector-icons.d.ts +12 -0
package/src/sender/Sender.tsx
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* 基于 UI 库 Input + ActionSheet + WaveAnimation + Button 构建
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import React, {useState, useCallback, useRef} from 'react';
|
|
8
|
+
import React, { useState, useCallback, useRef } from 'react';
|
|
9
9
|
import {
|
|
10
10
|
View,
|
|
11
11
|
Text,
|
|
@@ -15,7 +15,8 @@ import {
|
|
|
15
15
|
PanResponder,
|
|
16
16
|
type ViewStyle,
|
|
17
17
|
} from 'react-native';
|
|
18
|
-
import {chatTokens} from '../theme/tokens';
|
|
18
|
+
import { chatTokens } from '../theme/tokens';
|
|
19
|
+
import Icon from 'react-native-vector-icons/Ionicons';
|
|
19
20
|
|
|
20
21
|
export interface ActionSheetOption {
|
|
21
22
|
key: string;
|
|
@@ -54,6 +55,7 @@ export interface SenderProps {
|
|
|
54
55
|
onBlur: () => void;
|
|
55
56
|
toolbar: React.ReactNode;
|
|
56
57
|
autoFocus: boolean;
|
|
58
|
+
maxLength: number;
|
|
57
59
|
}) => React.ReactNode;
|
|
58
60
|
renderActionSheet?: (props: {
|
|
59
61
|
visible: boolean;
|
|
@@ -75,7 +77,7 @@ const Sender: React.FC<SenderProps> = ({
|
|
|
75
77
|
isRequesting = false,
|
|
76
78
|
placeholder = '发消息',
|
|
77
79
|
maxLength = 2000,
|
|
78
|
-
voiceEnabled =
|
|
80
|
+
voiceEnabled = false,
|
|
79
81
|
actionsEnabled = true,
|
|
80
82
|
actions = [],
|
|
81
83
|
onActionSelect,
|
|
@@ -165,13 +167,14 @@ const Sender: React.FC<SenderProps> = ({
|
|
|
165
167
|
<View
|
|
166
168
|
style={[
|
|
167
169
|
defaultStyles.recordingBar,
|
|
168
|
-
{backgroundColor: bgColor},
|
|
170
|
+
{ backgroundColor: bgColor },
|
|
169
171
|
semanticStyles?.recording,
|
|
170
172
|
]}
|
|
171
173
|
{...panResponder.panHandlers}
|
|
172
|
-
testID={`${testID}-recording`}
|
|
174
|
+
testID={`${testID}-recording`}
|
|
175
|
+
>
|
|
173
176
|
<Text style={defaultStyles.recordingHint}>{hintText}</Text>
|
|
174
|
-
{renderWaveAnimation?.({active: true, color: '#FFFFFF'})}
|
|
177
|
+
{renderWaveAnimation?.({ active: true, color: '#FFFFFF' })}
|
|
175
178
|
</View>
|
|
176
179
|
</View>
|
|
177
180
|
);
|
|
@@ -185,8 +188,13 @@ const Sender: React.FC<SenderProps> = ({
|
|
|
185
188
|
<TouchableOpacity
|
|
186
189
|
onPress={handleToggleMode}
|
|
187
190
|
style={defaultStyles.toolButton}
|
|
188
|
-
testID={`${testID}-toggle-mode`}
|
|
189
|
-
|
|
191
|
+
testID={`${testID}-toggle-mode`}
|
|
192
|
+
>
|
|
193
|
+
<Icon
|
|
194
|
+
name="search-outline"
|
|
195
|
+
size={22}
|
|
196
|
+
color={chatTokens.colorTextSecondary}
|
|
197
|
+
/>
|
|
190
198
|
</TouchableOpacity>
|
|
191
199
|
)}
|
|
192
200
|
|
|
@@ -196,8 +204,9 @@ const Sender: React.FC<SenderProps> = ({
|
|
|
196
204
|
<TouchableOpacity
|
|
197
205
|
onPress={() => setShowActions(true)}
|
|
198
206
|
style={defaultStyles.toolButton}
|
|
199
|
-
testID={`${testID}-actions`}
|
|
200
|
-
|
|
207
|
+
testID={`${testID}-actions`}
|
|
208
|
+
>
|
|
209
|
+
<Icon name="add" size={22} color={chatTokens.colorTextSecondary} />
|
|
201
210
|
</TouchableOpacity>
|
|
202
211
|
)}
|
|
203
212
|
|
|
@@ -206,13 +215,15 @@ const Sender: React.FC<SenderProps> = ({
|
|
|
206
215
|
testID={`${testID}-stop`}
|
|
207
216
|
style={defaultStyles.sendButton}
|
|
208
217
|
onPress={onStop}
|
|
209
|
-
activeOpacity={0.7}
|
|
218
|
+
activeOpacity={0.7}
|
|
219
|
+
>
|
|
210
220
|
<View
|
|
211
221
|
style={[
|
|
212
222
|
defaultStyles.sendCircle,
|
|
213
|
-
{backgroundColor: chatTokens.colorError},
|
|
214
|
-
]}
|
|
215
|
-
|
|
223
|
+
{ backgroundColor: chatTokens.colorError },
|
|
224
|
+
]}
|
|
225
|
+
>
|
|
226
|
+
<Icon name="stop" size={14} color="#FFFFFF" />
|
|
216
227
|
</View>
|
|
217
228
|
</TouchableOpacity>
|
|
218
229
|
) : hasText ? (
|
|
@@ -220,9 +231,10 @@ const Sender: React.FC<SenderProps> = ({
|
|
|
220
231
|
testID={`${testID}-send`}
|
|
221
232
|
style={defaultStyles.sendButton}
|
|
222
233
|
onPress={handleSend}
|
|
223
|
-
activeOpacity={0.7}
|
|
234
|
+
activeOpacity={0.7}
|
|
235
|
+
>
|
|
224
236
|
<View style={defaultStyles.sendCircle}>
|
|
225
|
-
<
|
|
237
|
+
<Icon name="arrow-up" size={18} color="#FFFFFF" />
|
|
226
238
|
</View>
|
|
227
239
|
</TouchableOpacity>
|
|
228
240
|
) : null}
|
|
@@ -239,6 +251,7 @@ const Sender: React.FC<SenderProps> = ({
|
|
|
239
251
|
onBlur: handleCollapse,
|
|
240
252
|
toolbar,
|
|
241
253
|
autoFocus: true,
|
|
254
|
+
maxLength,
|
|
242
255
|
})
|
|
243
256
|
) : (
|
|
244
257
|
<View style={defaultStyles.expandedFallback}>
|
|
@@ -266,16 +279,18 @@ const Sender: React.FC<SenderProps> = ({
|
|
|
266
279
|
|
|
267
280
|
return (
|
|
268
281
|
<View style={[defaultStyles.container, semanticStyles?.root, style]}>
|
|
269
|
-
<View
|
|
270
|
-
style={[defaultStyles.collapsedBar, semanticStyles?.collapsed]}>
|
|
282
|
+
<View style={[defaultStyles.collapsedBar, semanticStyles?.collapsed]}>
|
|
271
283
|
{voiceEnabled && (
|
|
272
284
|
<TouchableOpacity
|
|
273
285
|
onPress={handleToggleMode}
|
|
274
286
|
style={defaultStyles.modeButton}
|
|
275
|
-
testID={`${testID}-toggle-mode`}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
287
|
+
testID={`${testID}-toggle-mode`}
|
|
288
|
+
>
|
|
289
|
+
<Icon
|
|
290
|
+
name={isVoice ? 'keypad-outline' : 'search-outline'}
|
|
291
|
+
size={22}
|
|
292
|
+
color={chatTokens.colorTextSecondary}
|
|
293
|
+
/>
|
|
279
294
|
</TouchableOpacity>
|
|
280
295
|
)}
|
|
281
296
|
|
|
@@ -292,7 +307,8 @@ const Sender: React.FC<SenderProps> = ({
|
|
|
292
307
|
setRecordingCancelled(false);
|
|
293
308
|
}}
|
|
294
309
|
activeOpacity={0.7}
|
|
295
|
-
testID={`${testID}-voice-hold`}
|
|
310
|
+
testID={`${testID}-voice-hold`}
|
|
311
|
+
>
|
|
296
312
|
<Text style={defaultStyles.voiceText}>按住说话</Text>
|
|
297
313
|
</TouchableOpacity>
|
|
298
314
|
) : (
|
|
@@ -300,7 +316,8 @@ const Sender: React.FC<SenderProps> = ({
|
|
|
300
316
|
style={defaultStyles.placeholderArea}
|
|
301
317
|
onPress={handleExpand}
|
|
302
318
|
activeOpacity={0.7}
|
|
303
|
-
testID={`${testID}-expand`}
|
|
319
|
+
testID={`${testID}-expand`}
|
|
320
|
+
>
|
|
304
321
|
<Text style={defaultStyles.placeholderText}>{placeholder}</Text>
|
|
305
322
|
</TouchableOpacity>
|
|
306
323
|
)}
|
|
@@ -309,8 +326,9 @@ const Sender: React.FC<SenderProps> = ({
|
|
|
309
326
|
<TouchableOpacity
|
|
310
327
|
onPress={() => setShowActions(true)}
|
|
311
328
|
style={defaultStyles.plusButton}
|
|
312
|
-
testID={`${testID}-plus`}
|
|
313
|
-
|
|
329
|
+
testID={`${testID}-plus`}
|
|
330
|
+
>
|
|
331
|
+
<Icon name="add" size={22} color={chatTokens.colorTextSecondary} />
|
|
314
332
|
</TouchableOpacity>
|
|
315
333
|
)}
|
|
316
334
|
</View>
|
|
@@ -329,7 +347,8 @@ const defaultStyles = StyleSheet.create({
|
|
|
329
347
|
container: {
|
|
330
348
|
paddingHorizontal: chatTokens.space,
|
|
331
349
|
paddingTop: chatTokens.spaceSm,
|
|
332
|
-
paddingBottom:
|
|
350
|
+
paddingBottom:
|
|
351
|
+
Platform.OS === 'ios' ? chatTokens.spaceSm : chatTokens.space,
|
|
333
352
|
},
|
|
334
353
|
|
|
335
354
|
// 收起态
|
|
@@ -404,11 +423,6 @@ const defaultStyles = StyleSheet.create({
|
|
|
404
423
|
justifyContent: 'center',
|
|
405
424
|
alignItems: 'center',
|
|
406
425
|
},
|
|
407
|
-
sendIcon: {
|
|
408
|
-
color: '#FFFFFF',
|
|
409
|
-
fontSize: 16,
|
|
410
|
-
fontWeight: '600',
|
|
411
|
-
},
|
|
412
426
|
|
|
413
427
|
// 录音态
|
|
414
428
|
recordingBar: {
|
|
@@ -424,12 +438,6 @@ const defaultStyles = StyleSheet.create({
|
|
|
424
438
|
color: '#FFFFFF',
|
|
425
439
|
fontWeight: '500',
|
|
426
440
|
},
|
|
427
|
-
|
|
428
|
-
// 通用
|
|
429
|
-
iconText: {
|
|
430
|
-
fontSize: 22,
|
|
431
|
-
color: chatTokens.colorTextSecondary,
|
|
432
|
-
},
|
|
433
441
|
});
|
|
434
442
|
|
|
435
443
|
export default React.memo(Sender);
|
package/src/theme/tokens.ts
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
* 仅定义 Chat 特有的 token,通用 token 从 @unif/react-native-ui 引用
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
interface ChatThemeConfig {
|
|
7
|
+
primaryColor?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
let _chatConfig: ChatThemeConfig = {};
|
|
11
|
+
|
|
12
|
+
export function configure(options: ChatThemeConfig): void {
|
|
13
|
+
_chatConfig = { ..._chatConfig, ...options };
|
|
14
|
+
}
|
|
15
|
+
|
|
6
16
|
export const chatTokens = {
|
|
7
17
|
// 气泡
|
|
8
18
|
colorBgUserMsg: '#E8F0FE',
|
|
@@ -16,8 +26,10 @@ export const chatTokens = {
|
|
|
16
26
|
// 录音
|
|
17
27
|
colorRecording: '#FF3B30',
|
|
18
28
|
|
|
19
|
-
//
|
|
20
|
-
colorPrimary
|
|
29
|
+
// 通用(colorPrimary 支持运行时注入)
|
|
30
|
+
get colorPrimary() {
|
|
31
|
+
return _chatConfig.primaryColor || '#1677FF';
|
|
32
|
+
},
|
|
21
33
|
colorError: '#FF3B30',
|
|
22
34
|
colorText: '#1F2937',
|
|
23
35
|
colorTextSecondary: '#6B7280',
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
declare module 'react-native-vector-icons/Ionicons' {
|
|
2
|
+
import type { Component } from 'react';
|
|
3
|
+
import type { TextProps } from 'react-native';
|
|
4
|
+
|
|
5
|
+
interface IconProps extends TextProps {
|
|
6
|
+
name: string;
|
|
7
|
+
size?: number;
|
|
8
|
+
color?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default class Icon extends Component<IconProps> {}
|
|
12
|
+
}
|