@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.
Files changed (97) hide show
  1. package/lib/commonjs/bubble/Bubble.js +131 -0
  2. package/lib/commonjs/bubble/Bubble.js.map +1 -0
  3. package/lib/commonjs/bubble/BubbleList.js +73 -0
  4. package/lib/commonjs/bubble/BubbleList.js.map +1 -0
  5. package/lib/commonjs/bubble/index.md +111 -0
  6. package/lib/commonjs/card-wrapper/CardWrapper.js +65 -0
  7. package/lib/commonjs/card-wrapper/CardWrapper.js.map +1 -0
  8. package/lib/commonjs/card-wrapper/index.md +78 -0
  9. package/lib/commonjs/conversations/Conversations.js +184 -0
  10. package/lib/commonjs/conversations/Conversations.js.map +1 -0
  11. package/lib/commonjs/conversations/index.md +90 -0
  12. package/lib/commonjs/index.js +69 -0
  13. package/lib/commonjs/index.js.map +1 -0
  14. package/lib/commonjs/package.json +1 -0
  15. package/lib/commonjs/prompts/Prompts.js +87 -0
  16. package/lib/commonjs/prompts/Prompts.js.map +1 -0
  17. package/lib/commonjs/prompts/index.md +81 -0
  18. package/lib/commonjs/sender/Sender.js +352 -0
  19. package/lib/commonjs/sender/Sender.js.map +1 -0
  20. package/lib/commonjs/sender/index.md +131 -0
  21. package/lib/commonjs/theme/tokens.js +77 -0
  22. package/lib/commonjs/theme/tokens.js.map +1 -0
  23. package/lib/commonjs/types/react-native-vector-icons.d.js +2 -0
  24. package/lib/commonjs/types/react-native-vector-icons.d.js.map +1 -0
  25. package/lib/commonjs/welcome/Welcome.js +152 -0
  26. package/lib/commonjs/welcome/Welcome.js.map +1 -0
  27. package/lib/commonjs/welcome/index.md +95 -0
  28. package/lib/module/bubble/Bubble.js +126 -0
  29. package/lib/module/bubble/Bubble.js.map +1 -0
  30. package/lib/module/bubble/BubbleList.js +68 -0
  31. package/lib/module/bubble/BubbleList.js.map +1 -0
  32. package/lib/module/bubble/index.md +111 -0
  33. package/lib/module/card-wrapper/CardWrapper.js +60 -0
  34. package/lib/module/card-wrapper/CardWrapper.js.map +1 -0
  35. package/lib/module/card-wrapper/index.md +78 -0
  36. package/lib/module/conversations/Conversations.js +179 -0
  37. package/lib/module/conversations/Conversations.js.map +1 -0
  38. package/lib/module/conversations/index.md +90 -0
  39. package/lib/module/index.js +23 -0
  40. package/lib/module/index.js.map +1 -0
  41. package/lib/module/package.json +1 -0
  42. package/lib/module/prompts/Prompts.js +82 -0
  43. package/lib/module/prompts/Prompts.js.map +1 -0
  44. package/lib/module/prompts/index.md +81 -0
  45. package/lib/module/sender/Sender.js +346 -0
  46. package/lib/module/sender/Sender.js.map +1 -0
  47. package/lib/module/sender/index.md +131 -0
  48. package/lib/module/theme/tokens.js +72 -0
  49. package/lib/module/theme/tokens.js.map +1 -0
  50. package/lib/module/types/react-native-vector-icons.d.js +2 -0
  51. package/lib/module/types/react-native-vector-icons.d.js.map +1 -0
  52. package/lib/module/welcome/Welcome.js +147 -0
  53. package/lib/module/welcome/Welcome.js.map +1 -0
  54. package/lib/module/welcome/index.md +95 -0
  55. package/lib/typescript/commonjs/bubble/Bubble.d.ts +29 -0
  56. package/lib/typescript/commonjs/bubble/Bubble.d.ts.map +1 -0
  57. package/lib/typescript/commonjs/bubble/BubbleList.d.ts +20 -0
  58. package/lib/typescript/commonjs/bubble/BubbleList.d.ts.map +1 -0
  59. package/lib/typescript/commonjs/card-wrapper/CardWrapper.d.ts +22 -0
  60. package/lib/typescript/commonjs/card-wrapper/CardWrapper.d.ts.map +1 -0
  61. package/lib/typescript/commonjs/conversations/Conversations.d.ts +37 -0
  62. package/lib/typescript/commonjs/conversations/Conversations.d.ts.map +1 -0
  63. package/lib/typescript/commonjs/index.d.ts +20 -0
  64. package/lib/typescript/commonjs/index.d.ts.map +1 -0
  65. package/lib/typescript/commonjs/package.json +1 -0
  66. package/lib/typescript/commonjs/prompts/Prompts.d.ts +27 -0
  67. package/lib/typescript/commonjs/prompts/Prompts.d.ts.map +1 -0
  68. package/lib/typescript/commonjs/sender/Sender.d.ts +58 -0
  69. package/lib/typescript/commonjs/sender/Sender.d.ts.map +1 -0
  70. package/lib/typescript/commonjs/theme/tokens.d.ts +57 -0
  71. package/lib/typescript/commonjs/theme/tokens.d.ts.map +1 -0
  72. package/lib/typescript/commonjs/welcome/Welcome.d.ts +39 -0
  73. package/lib/typescript/commonjs/welcome/Welcome.d.ts.map +1 -0
  74. package/lib/typescript/module/bubble/Bubble.d.ts +29 -0
  75. package/lib/typescript/module/bubble/Bubble.d.ts.map +1 -0
  76. package/lib/typescript/module/bubble/BubbleList.d.ts +20 -0
  77. package/lib/typescript/module/bubble/BubbleList.d.ts.map +1 -0
  78. package/lib/typescript/module/card-wrapper/CardWrapper.d.ts +22 -0
  79. package/lib/typescript/module/card-wrapper/CardWrapper.d.ts.map +1 -0
  80. package/lib/typescript/module/conversations/Conversations.d.ts +37 -0
  81. package/lib/typescript/module/conversations/Conversations.d.ts.map +1 -0
  82. package/lib/typescript/module/index.d.ts +20 -0
  83. package/lib/typescript/module/index.d.ts.map +1 -0
  84. package/lib/typescript/module/package.json +1 -0
  85. package/lib/typescript/module/prompts/Prompts.d.ts +27 -0
  86. package/lib/typescript/module/prompts/Prompts.d.ts.map +1 -0
  87. package/lib/typescript/module/sender/Sender.d.ts +58 -0
  88. package/lib/typescript/module/sender/Sender.d.ts.map +1 -0
  89. package/lib/typescript/module/theme/tokens.d.ts +57 -0
  90. package/lib/typescript/module/theme/tokens.d.ts.map +1 -0
  91. package/lib/typescript/module/welcome/Welcome.d.ts +39 -0
  92. package/lib/typescript/module/welcome/Welcome.d.ts.map +1 -0
  93. package/package.json +41 -9
  94. package/src/index.tsx +24 -13
  95. package/src/sender/Sender.tsx +46 -38
  96. package/src/theme/tokens.ts +14 -2
  97. package/src/types/react-native-vector-icons.d.ts +12 -0
@@ -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 = true,
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
- <Text style={defaultStyles.iconText}>🎤</Text>
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
- <Text style={defaultStyles.iconText}>+</Text>
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
- <Text style={defaultStyles.sendIcon}>⏹</Text>
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
- <Text style={defaultStyles.sendIcon}>↑</Text>
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
- <Text style={defaultStyles.iconText}>
277
- {isVoice ? '⌨' : '🎤'}
278
- </Text>
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
- <Text style={defaultStyles.iconText}>+</Text>
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: Platform.OS === 'ios' ? chatTokens.spaceSm : chatTokens.space,
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);
@@ -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: '#1677FF',
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
+ }