@unif/react-native-chat 0.2.1 → 0.2.3

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 (63) hide show
  1. package/lib/commonjs/bubble/Bubble.js +74 -72
  2. package/lib/commonjs/bubble/Bubble.js.map +1 -1
  3. package/lib/commonjs/card-wrapper/CardWrapper.js +25 -24
  4. package/lib/commonjs/card-wrapper/CardWrapper.js.map +1 -1
  5. package/lib/commonjs/conversations/Conversations.js +135 -84
  6. package/lib/commonjs/conversations/Conversations.js.map +1 -1
  7. package/lib/commonjs/index.js +0 -6
  8. package/lib/commonjs/index.js.map +1 -1
  9. package/lib/commonjs/prompts/Prompts.js +38 -37
  10. package/lib/commonjs/prompts/Prompts.js.map +1 -1
  11. package/lib/commonjs/sender/Sender.js +120 -122
  12. package/lib/commonjs/sender/Sender.js.map +1 -1
  13. package/lib/commonjs/theme/tokens.js +2 -56
  14. package/lib/commonjs/theme/tokens.js.map +1 -1
  15. package/lib/commonjs/welcome/Welcome.js +89 -90
  16. package/lib/commonjs/welcome/Welcome.js.map +1 -1
  17. package/lib/module/bubble/Bubble.js +73 -71
  18. package/lib/module/bubble/Bubble.js.map +1 -1
  19. package/lib/module/card-wrapper/CardWrapper.js +24 -23
  20. package/lib/module/card-wrapper/CardWrapper.js.map +1 -1
  21. package/lib/module/conversations/Conversations.js +137 -86
  22. package/lib/module/conversations/Conversations.js.map +1 -1
  23. package/lib/module/index.js +3 -1
  24. package/lib/module/index.js.map +1 -1
  25. package/lib/module/prompts/Prompts.js +37 -36
  26. package/lib/module/prompts/Prompts.js.map +1 -1
  27. package/lib/module/sender/Sender.js +121 -123
  28. package/lib/module/sender/Sender.js.map +1 -1
  29. package/lib/module/theme/tokens.js +2 -55
  30. package/lib/module/theme/tokens.js.map +1 -1
  31. package/lib/module/welcome/Welcome.js +88 -89
  32. package/lib/module/welcome/Welcome.js.map +1 -1
  33. package/lib/typescript/commonjs/bubble/Bubble.d.ts.map +1 -1
  34. package/lib/typescript/commonjs/card-wrapper/CardWrapper.d.ts.map +1 -1
  35. package/lib/typescript/commonjs/conversations/Conversations.d.ts +4 -2
  36. package/lib/typescript/commonjs/conversations/Conversations.d.ts.map +1 -1
  37. package/lib/typescript/commonjs/index.d.ts +2 -1
  38. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  39. package/lib/typescript/commonjs/prompts/Prompts.d.ts.map +1 -1
  40. package/lib/typescript/commonjs/sender/Sender.d.ts.map +1 -1
  41. package/lib/typescript/commonjs/theme/tokens.d.ts +1 -45
  42. package/lib/typescript/commonjs/theme/tokens.d.ts.map +1 -1
  43. package/lib/typescript/commonjs/welcome/Welcome.d.ts.map +1 -1
  44. package/lib/typescript/module/bubble/Bubble.d.ts.map +1 -1
  45. package/lib/typescript/module/card-wrapper/CardWrapper.d.ts.map +1 -1
  46. package/lib/typescript/module/conversations/Conversations.d.ts +4 -2
  47. package/lib/typescript/module/conversations/Conversations.d.ts.map +1 -1
  48. package/lib/typescript/module/index.d.ts +2 -1
  49. package/lib/typescript/module/index.d.ts.map +1 -1
  50. package/lib/typescript/module/prompts/Prompts.d.ts.map +1 -1
  51. package/lib/typescript/module/sender/Sender.d.ts.map +1 -1
  52. package/lib/typescript/module/theme/tokens.d.ts +1 -45
  53. package/lib/typescript/module/theme/tokens.d.ts.map +1 -1
  54. package/lib/typescript/module/welcome/Welcome.d.ts.map +1 -1
  55. package/package.json +2 -1
  56. package/src/bubble/Bubble.tsx +85 -80
  57. package/src/card-wrapper/CardWrapper.tsx +31 -29
  58. package/src/conversations/Conversations.tsx +170 -100
  59. package/src/index.tsx +4 -1
  60. package/src/prompts/Prompts.tsx +51 -41
  61. package/src/sender/Sender.tsx +125 -138
  62. package/src/theme/tokens.ts +1 -56
  63. package/src/welcome/Welcome.tsx +109 -108
@@ -3,7 +3,7 @@
3
3
  * 水平 ScrollView + Chip 列表
4
4
  */
5
5
 
6
- import React from 'react';
6
+ import React, { useMemo } from 'react';
7
7
  import {
8
8
  View,
9
9
  Text,
@@ -13,7 +13,7 @@ import {
13
13
  type ViewStyle,
14
14
  type TextStyle,
15
15
  } from 'react-native';
16
- import {chatTokens} from '../theme/tokens';
16
+ import { useTokens } from '@unif/react-native-ui';
17
17
 
18
18
  export interface PromptItem {
19
19
  id: string;
@@ -45,24 +45,62 @@ const Prompts: React.FC<PromptsProps> = ({
45
45
  styles: semanticStyles,
46
46
  testID = 'prompts',
47
47
  }) => {
48
+ const t = useTokens();
49
+
50
+ const ds = useMemo(
51
+ () =>
52
+ StyleSheet.create({
53
+ container: {
54
+ paddingVertical: 8,
55
+ backgroundColor: 'transparent',
56
+ },
57
+ scrollContent: {
58
+ paddingHorizontal: 12,
59
+ gap: 8,
60
+ },
61
+ wrapContainer: {
62
+ flexDirection: 'row',
63
+ flexWrap: 'wrap',
64
+ paddingHorizontal: 12,
65
+ gap: 8,
66
+ },
67
+ chip: {
68
+ backgroundColor: '#F3F4F6',
69
+ borderRadius: 16,
70
+ paddingHorizontal: 14,
71
+ paddingVertical: 8,
72
+ },
73
+ chipText: {
74
+ fontSize: 13,
75
+ color: t.colorText,
76
+ },
77
+ chipTextDisabled: {
78
+ color: t.colorTextPlaceholder,
79
+ },
80
+ }),
81
+ [t]
82
+ );
83
+
48
84
  if (items.length === 0) return null;
49
85
 
50
86
  const renderChips = () =>
51
87
  items.map((item) => (
52
88
  <TouchableOpacity
53
89
  key={item.id}
54
- style={[defaultStyles.chip, semanticStyles?.chip]}
90
+ style={[ds.chip, semanticStyles?.chip]}
55
91
  onPress={() => !disabled && onSelect(item)}
56
92
  activeOpacity={disabled ? 1 : 0.7}
57
93
  disabled={disabled}
58
- testID={`${testID}-${item.id}`}>
94
+ testID={`${testID}-${item.id}`}
95
+ >
59
96
  <Text
60
97
  style={[
61
- defaultStyles.chipText,
98
+ ds.chipText,
62
99
  semanticStyles?.chipText,
63
- disabled && defaultStyles.chipTextDisabled,
100
+ disabled && ds.chipTextDisabled,
64
101
  ]}
65
- numberOfLines={1}>
102
+ numberOfLines={1}
103
+ >
66
104
  {item.label}
67
105
  </Text>
68
106
  </TouchableOpacity>
@@ -71,53 +109,25 @@ const Prompts: React.FC<PromptsProps> = ({
71
109
  if (wrap) {
72
110
  return (
73
111
  <View
74
- style={[defaultStyles.container, defaultStyles.wrapContainer, semanticStyles?.root, style]}
75
- testID={testID}>
112
+ style={[ds.container, ds.wrapContainer, semanticStyles?.root, style]}
113
+ testID={testID}
114
+ >
76
115
  {renderChips()}
77
116
  </View>
78
117
  );
79
118
  }
80
119
 
81
120
  return (
82
- <View style={[defaultStyles.container, semanticStyles?.root, style]} testID={testID}>
121
+ <View style={[ds.container, semanticStyles?.root, style]} testID={testID}>
83
122
  <ScrollView
84
123
  horizontal
85
124
  showsHorizontalScrollIndicator={false}
86
- contentContainerStyle={defaultStyles.scrollContent}>
125
+ contentContainerStyle={ds.scrollContent}
126
+ >
87
127
  {renderChips()}
88
128
  </ScrollView>
89
129
  </View>
90
130
  );
91
131
  };
92
132
 
93
- const defaultStyles = StyleSheet.create({
94
- container: {
95
- paddingVertical: 8,
96
- backgroundColor: 'transparent',
97
- },
98
- scrollContent: {
99
- paddingHorizontal: 12,
100
- gap: 8,
101
- },
102
- wrapContainer: {
103
- flexDirection: 'row',
104
- flexWrap: 'wrap',
105
- paddingHorizontal: 12,
106
- gap: 8,
107
- },
108
- chip: {
109
- backgroundColor: '#F3F4F6',
110
- borderRadius: 16,
111
- paddingHorizontal: 14,
112
- paddingVertical: 8,
113
- },
114
- chipText: {
115
- fontSize: 13,
116
- color: chatTokens.colorText,
117
- },
118
- chipTextDisabled: {
119
- color: chatTokens.colorTextPlaceholder,
120
- },
121
- });
122
-
123
133
  export default React.memo(Prompts);
@@ -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, useMemo } from 'react';
9
9
  import {
10
10
  View,
11
11
  Text,
@@ -15,7 +15,7 @@ import {
15
15
  PanResponder,
16
16
  type ViewStyle,
17
17
  } from 'react-native';
18
- import { chatTokens } from '../theme/tokens';
18
+ import { useTokens } from '@unif/react-native-ui';
19
19
  import Icon from 'react-native-vector-icons/Ionicons';
20
20
 
21
21
  export interface ActionSheetOption {
@@ -47,7 +47,6 @@ export interface SenderProps {
47
47
  style?: ViewStyle;
48
48
  styles?: Partial<SenderSemanticStyles>;
49
49
  testID?: string;
50
- // 渲染注入点(允许使用方注入 UI 库组件)
51
50
  renderInput?: (props: {
52
51
  value: string;
53
52
  onChangeText: (text: string) => void;
@@ -89,6 +88,7 @@ const Sender: React.FC<SenderProps> = ({
89
88
  renderActionSheet,
90
89
  renderWaveAnimation,
91
90
  }) => {
91
+ const t = useTokens();
92
92
  const [mode, setMode] = useState<'text' | 'voice'>('text');
93
93
  const [expanded, setExpanded] = useState(false);
94
94
  const [text, setText] = useState('');
@@ -155,25 +155,117 @@ const Sender: React.FC<SenderProps> = ({
155
155
 
156
156
  const hasText = text.trim().length > 0;
157
157
 
158
+ const ds = useMemo(
159
+ () =>
160
+ StyleSheet.create({
161
+ container: {
162
+ paddingHorizontal: t.space,
163
+ paddingTop: t.spaceSm,
164
+ paddingBottom: Platform.OS === 'ios' ? t.spaceSm : t.space,
165
+ },
166
+ collapsedBar: {
167
+ flexDirection: 'row',
168
+ alignItems: 'center',
169
+ backgroundColor: t.colorBgElevated,
170
+ borderRadius: t.radiusXl,
171
+ height: 46,
172
+ paddingHorizontal: 12,
173
+ ...t.shadow,
174
+ },
175
+ modeButton: {
176
+ padding: 4,
177
+ },
178
+ placeholderArea: {
179
+ flex: 1,
180
+ justifyContent: 'center',
181
+ paddingLeft: 8,
182
+ },
183
+ placeholderText: {
184
+ fontSize: t.fontSize,
185
+ color: t.colorTextPlaceholder,
186
+ },
187
+ voiceArea: {
188
+ flex: 1,
189
+ justifyContent: 'center',
190
+ alignItems: 'center',
191
+ },
192
+ voiceText: {
193
+ fontSize: t.fontSize,
194
+ fontWeight: '500',
195
+ color: t.colorText,
196
+ },
197
+ plusButton: {
198
+ padding: 4,
199
+ },
200
+ expandedFallback: {
201
+ backgroundColor: t.colorBgElevated,
202
+ borderRadius: 12,
203
+ padding: 12,
204
+ ...t.shadow,
205
+ },
206
+ expandedInputArea: {
207
+ minHeight: 40,
208
+ maxHeight: 100,
209
+ },
210
+ expandedText: {
211
+ fontSize: t.fontSize,
212
+ color: t.colorText,
213
+ },
214
+ toolbar: {
215
+ flexDirection: 'row',
216
+ alignItems: 'center',
217
+ },
218
+ toolButton: {
219
+ padding: 4,
220
+ },
221
+ toolbarSpacer: {
222
+ flex: 1,
223
+ },
224
+ sendButton: {
225
+ marginLeft: 8,
226
+ },
227
+ sendCircle: {
228
+ width: 32,
229
+ height: 32,
230
+ borderRadius: 16,
231
+ backgroundColor: t.colorPrimary,
232
+ justifyContent: 'center',
233
+ alignItems: 'center',
234
+ },
235
+ recordingBar: {
236
+ flexDirection: 'row',
237
+ alignItems: 'center',
238
+ justifyContent: 'space-between',
239
+ height: 46,
240
+ borderRadius: t.radiusXl,
241
+ paddingHorizontal: 16,
242
+ },
243
+ recordingHint: {
244
+ fontSize: 14,
245
+ color: '#FFFFFF',
246
+ fontWeight: '500',
247
+ },
248
+ }),
249
+ [t]
250
+ );
251
+
158
252
  // === 录音态 ===
159
253
  if (isRecording && voiceEnabled) {
160
- const bgColor = recordingCancelled
161
- ? chatTokens.colorError
162
- : chatTokens.colorPrimary;
254
+ const bgColor = recordingCancelled ? t.colorError : t.colorPrimary;
163
255
  const hintText = recordingCancelled ? '松手取消' : '松开发送,上划取消';
164
256
 
165
257
  return (
166
- <View style={[defaultStyles.container, semanticStyles?.root, style]}>
258
+ <View style={[ds.container, semanticStyles?.root, style]}>
167
259
  <View
168
260
  style={[
169
- defaultStyles.recordingBar,
261
+ ds.recordingBar,
170
262
  { backgroundColor: bgColor },
171
263
  semanticStyles?.recording,
172
264
  ]}
173
265
  {...panResponder.panHandlers}
174
266
  testID={`${testID}-recording`}
175
267
  >
176
- <Text style={defaultStyles.recordingHint}>{hintText}</Text>
268
+ <Text style={ds.recordingHint}>{hintText}</Text>
177
269
  {renderWaveAnimation?.({ active: true, color: '#FFFFFF' })}
178
270
  </View>
179
271
  </View>
@@ -183,57 +275,52 @@ const Sender: React.FC<SenderProps> = ({
183
275
  // === 展开态 ===
184
276
  if (expanded && mode === 'text') {
185
277
  const toolbar = (
186
- <View style={[defaultStyles.toolbar, semanticStyles?.toolbar]}>
278
+ <View style={[ds.toolbar, semanticStyles?.toolbar]}>
187
279
  {voiceEnabled && (
188
280
  <TouchableOpacity
189
281
  onPress={handleToggleMode}
190
- style={defaultStyles.toolButton}
282
+ style={ds.toolButton}
191
283
  testID={`${testID}-toggle-mode`}
192
284
  >
193
285
  <Icon
194
286
  name="search-outline"
195
287
  size={22}
196
- color={chatTokens.colorTextSecondary}
288
+ color={t.colorTextSecondary}
197
289
  />
198
290
  </TouchableOpacity>
199
291
  )}
200
292
 
201
- <View style={defaultStyles.toolbarSpacer} />
293
+ <View style={ds.toolbarSpacer} />
202
294
 
203
295
  {actionsEnabled && (
204
296
  <TouchableOpacity
205
297
  onPress={() => setShowActions(true)}
206
- style={defaultStyles.toolButton}
298
+ style={ds.toolButton}
207
299
  testID={`${testID}-actions`}
208
300
  >
209
- <Icon name="add" size={22} color={chatTokens.colorTextSecondary} />
301
+ <Icon name="add" size={22} color={t.colorTextSecondary} />
210
302
  </TouchableOpacity>
211
303
  )}
212
304
 
213
305
  {isRequesting ? (
214
306
  <TouchableOpacity
215
307
  testID={`${testID}-stop`}
216
- style={defaultStyles.sendButton}
308
+ style={ds.sendButton}
217
309
  onPress={onStop}
218
310
  activeOpacity={0.7}
219
311
  >
220
- <View
221
- style={[
222
- defaultStyles.sendCircle,
223
- { backgroundColor: chatTokens.colorError },
224
- ]}
225
- >
312
+ <View style={[ds.sendCircle, { backgroundColor: t.colorError }]}>
226
313
  <Icon name="stop" size={14} color="#FFFFFF" />
227
314
  </View>
228
315
  </TouchableOpacity>
229
316
  ) : hasText ? (
230
317
  <TouchableOpacity
231
318
  testID={`${testID}-send`}
232
- style={defaultStyles.sendButton}
319
+ style={ds.sendButton}
233
320
  onPress={handleSend}
234
321
  activeOpacity={0.7}
235
322
  >
236
- <View style={defaultStyles.sendCircle}>
323
+ <View style={ds.sendCircle}>
237
324
  <Icon name="arrow-up" size={18} color="#FFFFFF" />
238
325
  </View>
239
326
  </TouchableOpacity>
@@ -242,7 +329,7 @@ const Sender: React.FC<SenderProps> = ({
242
329
  );
243
330
 
244
331
  return (
245
- <View style={[defaultStyles.container, semanticStyles?.root, style]}>
332
+ <View style={[ds.container, semanticStyles?.root, style]}>
246
333
  {renderInput ? (
247
334
  renderInput({
248
335
  value: text,
@@ -254,12 +341,9 @@ const Sender: React.FC<SenderProps> = ({
254
341
  maxLength,
255
342
  })
256
343
  ) : (
257
- <View style={defaultStyles.expandedFallback}>
258
- {/* 无 UI 库 Input 时的 fallback: 使用原生 TextInput */}
259
- <View style={defaultStyles.expandedInputArea}>
260
- <Text style={defaultStyles.expandedText}>
261
- {text || placeholder}
262
- </Text>
344
+ <View style={ds.expandedFallback}>
345
+ <View style={ds.expandedInputArea}>
346
+ <Text style={ds.expandedText}>{text || placeholder}</Text>
263
347
  </View>
264
348
  {toolbar}
265
349
  </View>
@@ -278,25 +362,25 @@ const Sender: React.FC<SenderProps> = ({
278
362
  const isVoice = mode === 'voice';
279
363
 
280
364
  return (
281
- <View style={[defaultStyles.container, semanticStyles?.root, style]}>
282
- <View style={[defaultStyles.collapsedBar, semanticStyles?.collapsed]}>
365
+ <View style={[ds.container, semanticStyles?.root, style]}>
366
+ <View style={[ds.collapsedBar, semanticStyles?.collapsed]}>
283
367
  {voiceEnabled && (
284
368
  <TouchableOpacity
285
369
  onPress={handleToggleMode}
286
- style={defaultStyles.modeButton}
370
+ style={ds.modeButton}
287
371
  testID={`${testID}-toggle-mode`}
288
372
  >
289
373
  <Icon
290
374
  name={isVoice ? 'keypad-outline' : 'search-outline'}
291
375
  size={22}
292
- color={chatTokens.colorTextSecondary}
376
+ color={t.colorTextSecondary}
293
377
  />
294
378
  </TouchableOpacity>
295
379
  )}
296
380
 
297
381
  {isVoice ? (
298
382
  <TouchableOpacity
299
- style={defaultStyles.voiceArea}
383
+ style={ds.voiceArea}
300
384
  onPressIn={() => {
301
385
  startY.current = 0;
302
386
  setIsRecording(true);
@@ -309,26 +393,26 @@ const Sender: React.FC<SenderProps> = ({
309
393
  activeOpacity={0.7}
310
394
  testID={`${testID}-voice-hold`}
311
395
  >
312
- <Text style={defaultStyles.voiceText}>按住说话</Text>
396
+ <Text style={ds.voiceText}>按住说话</Text>
313
397
  </TouchableOpacity>
314
398
  ) : (
315
399
  <TouchableOpacity
316
- style={defaultStyles.placeholderArea}
400
+ style={ds.placeholderArea}
317
401
  onPress={handleExpand}
318
402
  activeOpacity={0.7}
319
403
  testID={`${testID}-expand`}
320
404
  >
321
- <Text style={defaultStyles.placeholderText}>{placeholder}</Text>
405
+ <Text style={ds.placeholderText}>{placeholder}</Text>
322
406
  </TouchableOpacity>
323
407
  )}
324
408
 
325
409
  {actionsEnabled && (
326
410
  <TouchableOpacity
327
411
  onPress={() => setShowActions(true)}
328
- style={defaultStyles.plusButton}
412
+ style={ds.plusButton}
329
413
  testID={`${testID}-plus`}
330
414
  >
331
- <Icon name="add" size={22} color={chatTokens.colorTextSecondary} />
415
+ <Icon name="add" size={22} color={t.colorTextSecondary} />
332
416
  </TouchableOpacity>
333
417
  )}
334
418
  </View>
@@ -343,101 +427,4 @@ const Sender: React.FC<SenderProps> = ({
343
427
  );
344
428
  };
345
429
 
346
- const defaultStyles = StyleSheet.create({
347
- container: {
348
- paddingHorizontal: chatTokens.space,
349
- paddingTop: chatTokens.spaceSm,
350
- paddingBottom:
351
- Platform.OS === 'ios' ? chatTokens.spaceSm : chatTokens.space,
352
- },
353
-
354
- // 收起态
355
- collapsedBar: {
356
- flexDirection: 'row',
357
- alignItems: 'center',
358
- backgroundColor: chatTokens.colorBgElevated,
359
- borderRadius: chatTokens.radiusXl,
360
- height: 46,
361
- paddingHorizontal: 12,
362
- ...chatTokens.shadow,
363
- },
364
- modeButton: {
365
- padding: 4,
366
- },
367
- placeholderArea: {
368
- flex: 1,
369
- justifyContent: 'center',
370
- paddingLeft: 8,
371
- },
372
- placeholderText: {
373
- fontSize: chatTokens.fontSize,
374
- color: chatTokens.colorTextPlaceholder,
375
- },
376
- voiceArea: {
377
- flex: 1,
378
- justifyContent: 'center',
379
- alignItems: 'center',
380
- },
381
- voiceText: {
382
- fontSize: chatTokens.fontSize,
383
- fontWeight: '500',
384
- color: chatTokens.colorText,
385
- },
386
- plusButton: {
387
- padding: 4,
388
- },
389
-
390
- // 展开态
391
- expandedFallback: {
392
- backgroundColor: chatTokens.colorBgElevated,
393
- borderRadius: chatTokens.radiusMd,
394
- padding: 12,
395
- ...chatTokens.shadow,
396
- },
397
- expandedInputArea: {
398
- minHeight: 40,
399
- maxHeight: 100,
400
- },
401
- expandedText: {
402
- fontSize: chatTokens.fontSize,
403
- color: chatTokens.colorText,
404
- },
405
- toolbar: {
406
- flexDirection: 'row',
407
- alignItems: 'center',
408
- },
409
- toolButton: {
410
- padding: 4,
411
- },
412
- toolbarSpacer: {
413
- flex: 1,
414
- },
415
- sendButton: {
416
- marginLeft: 8,
417
- },
418
- sendCircle: {
419
- width: 32,
420
- height: 32,
421
- borderRadius: 16,
422
- backgroundColor: chatTokens.colorPrimary,
423
- justifyContent: 'center',
424
- alignItems: 'center',
425
- },
426
-
427
- // 录音态
428
- recordingBar: {
429
- flexDirection: 'row',
430
- alignItems: 'center',
431
- justifyContent: 'space-between',
432
- height: 46,
433
- borderRadius: chatTokens.radiusXl,
434
- paddingHorizontal: 16,
435
- },
436
- recordingHint: {
437
- fontSize: 14,
438
- color: '#FFFFFF',
439
- fontWeight: '500',
440
- },
441
- });
442
-
443
430
  export default React.memo(Sender);
@@ -1,18 +1,8 @@
1
1
  /**
2
2
  * Chat 专属 Design Tokens
3
- * 仅定义 Chat 特有的 token,通用 token 从 @unif/react-native-ui 引用
3
+ * 仅定义 Chat 特有的 token,通用 token 从 @unif/react-native-ui 的 useTokens() 获取
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
-
16
6
  export const chatTokens = {
17
7
  // 气泡
18
8
  colorBgUserMsg: '#E8F0FE',
@@ -25,49 +15,4 @@ export const chatTokens = {
25
15
 
26
16
  // 录音
27
17
  colorRecording: '#FF3B30',
28
-
29
- // 通用(colorPrimary 支持运行时注入)
30
- get colorPrimary() {
31
- return _chatConfig.primaryColor || '#1677FF';
32
- },
33
- colorError: '#FF3B30',
34
- colorText: '#1F2937',
35
- colorTextSecondary: '#6B7280',
36
- colorTextPlaceholder: '#9CA3AF',
37
- colorBgElevated: '#FFFFFF',
38
- colorBorder: '#E5E7EB',
39
- colorLink: '#1677FF',
40
-
41
- // 间距
42
- spaceXs: 4,
43
- spaceSm: 8,
44
- space: 12,
45
- spaceMd: 16,
46
-
47
- // 字体
48
- fontSize: 15,
49
- fontSizeSm: 13,
50
- lineHeight: 22,
51
-
52
- // 圆角
53
- radiusSm: 6,
54
- radiusMd: 12,
55
- radiusXl: 23,
56
- radiusFull: 999,
57
-
58
- // 阴影
59
- shadow: {
60
- shadowColor: '#000',
61
- shadowOffset: { width: 0, height: 1 },
62
- shadowOpacity: 0.05,
63
- shadowRadius: 3,
64
- elevation: 2,
65
- },
66
- shadowSm: {
67
- shadowColor: '#000',
68
- shadowOffset: { width: 0, height: 1 },
69
- shadowOpacity: 0.03,
70
- shadowRadius: 2,
71
- elevation: 1,
72
- },
73
18
  };