@unif/react-native-chat-markdown 0.1.0 → 0.1.2

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 (52) hide show
  1. package/README.md +103 -0
  2. package/lib/commonjs/index.js +41 -0
  3. package/lib/commonjs/index.js.map +1 -0
  4. package/lib/commonjs/markdown-bubble/MarkdownBubble.js +90 -0
  5. package/lib/commonjs/markdown-bubble/MarkdownBubble.js.map +1 -0
  6. package/lib/commonjs/markdown-bubble/index.md +61 -0
  7. package/lib/commonjs/package.json +1 -0
  8. package/lib/commonjs/streaming-bubble/StreamingBubble.js +64 -0
  9. package/lib/commonjs/streaming-bubble/StreamingBubble.js.map +1 -0
  10. package/lib/commonjs/streaming-bubble/index.md +47 -0
  11. package/lib/commonjs/think-block/ThinkBlock.js +92 -0
  12. package/lib/commonjs/think-block/ThinkBlock.js.map +1 -0
  13. package/lib/commonjs/think-block/index.md +57 -0
  14. package/lib/commonjs/utils/thinkTagParser.js +42 -0
  15. package/lib/commonjs/utils/thinkTagParser.js.map +1 -0
  16. package/lib/module/index.js +12 -0
  17. package/lib/module/index.js.map +1 -0
  18. package/lib/module/markdown-bubble/MarkdownBubble.js +84 -0
  19. package/lib/module/markdown-bubble/MarkdownBubble.js.map +1 -0
  20. package/lib/module/markdown-bubble/index.md +61 -0
  21. package/lib/module/package.json +1 -0
  22. package/lib/module/streaming-bubble/StreamingBubble.js +59 -0
  23. package/lib/module/streaming-bubble/StreamingBubble.js.map +1 -0
  24. package/lib/module/streaming-bubble/index.md +47 -0
  25. package/lib/module/think-block/ThinkBlock.js +87 -0
  26. package/lib/module/think-block/ThinkBlock.js.map +1 -0
  27. package/lib/module/think-block/index.md +57 -0
  28. package/lib/module/utils/thinkTagParser.js +37 -0
  29. package/lib/module/utils/thinkTagParser.js.map +1 -0
  30. package/lib/typescript/commonjs/index.d.ts +13 -0
  31. package/lib/typescript/commonjs/index.d.ts.map +1 -0
  32. package/lib/typescript/commonjs/markdown-bubble/MarkdownBubble.d.ts +15 -0
  33. package/lib/typescript/commonjs/markdown-bubble/MarkdownBubble.d.ts.map +1 -0
  34. package/lib/typescript/commonjs/package.json +1 -0
  35. package/lib/typescript/commonjs/streaming-bubble/StreamingBubble.d.ts +16 -0
  36. package/lib/typescript/commonjs/streaming-bubble/StreamingBubble.d.ts.map +1 -0
  37. package/lib/typescript/commonjs/think-block/ThinkBlock.d.ts +24 -0
  38. package/lib/typescript/commonjs/think-block/ThinkBlock.d.ts.map +1 -0
  39. package/lib/typescript/commonjs/utils/thinkTagParser.d.ts +20 -0
  40. package/lib/typescript/commonjs/utils/thinkTagParser.d.ts.map +1 -0
  41. package/lib/typescript/module/index.d.ts +13 -0
  42. package/lib/typescript/module/index.d.ts.map +1 -0
  43. package/lib/typescript/module/markdown-bubble/MarkdownBubble.d.ts +15 -0
  44. package/lib/typescript/module/markdown-bubble/MarkdownBubble.d.ts.map +1 -0
  45. package/lib/typescript/module/package.json +1 -0
  46. package/lib/typescript/module/streaming-bubble/StreamingBubble.d.ts +16 -0
  47. package/lib/typescript/module/streaming-bubble/StreamingBubble.d.ts.map +1 -0
  48. package/lib/typescript/module/think-block/ThinkBlock.d.ts +24 -0
  49. package/lib/typescript/module/think-block/ThinkBlock.d.ts.map +1 -0
  50. package/lib/typescript/module/utils/thinkTagParser.d.ts +20 -0
  51. package/lib/typescript/module/utils/thinkTagParser.d.ts.map +1 -0
  52. package/package.json +41 -10
package/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # @unif/react-native-chat-markdown
2
+
3
+ Markdown 渲染组件库 — ThinkBlock 思考折叠、StreamingBubble 流式气泡、MarkdownBubble Markdown 渲染。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ yarn add @unif/react-native-chat-markdown
9
+ ```
10
+
11
+ ### peerDependencies
12
+
13
+ ```bash
14
+ yarn add react react-native @ronradtke/react-native-markdown-display
15
+ ```
16
+
17
+ ## 组件
18
+
19
+ ### MarkdownBubble
20
+
21
+ Markdown 渲染气泡,自动解析 `<think>` 标签为 ThinkBlock。
22
+
23
+ ```tsx
24
+ import {MarkdownBubble} from '@unif/react-native-chat-markdown';
25
+
26
+ <MarkdownBubble text="**加粗** 和 `代码`" />
27
+
28
+ // 包含思考内容
29
+ <MarkdownBubble text="<think>让我想想...</think>答案是 42" />
30
+ ```
31
+
32
+ | 属性 | 类型 | 说明 |
33
+ |------|------|------|
34
+ | text | `string` | Markdown 文本 |
35
+ | markdownStyles | `Record<string, any>` | 覆盖默认样式 |
36
+ | style | `ViewStyle` | 容器样式 |
37
+
38
+ ### StreamingBubble
39
+
40
+ 流式气泡,文本 + 闪烁光标动画。
41
+
42
+ ```tsx
43
+ import {StreamingBubble} from '@unif/react-native-chat-markdown';
44
+
45
+ <StreamingBubble text={streamingText} />
46
+ ```
47
+
48
+ | 属性 | 类型 | 说明 |
49
+ |------|------|------|
50
+ | text | `string` | 当前累积文本 |
51
+ | cursorColor | `string` | 光标颜色 |
52
+ | cursorChar | `string` | 光标字符(默认 `▌`) |
53
+
54
+ ### ThinkBlock
55
+
56
+ 思考折叠块,可展开/收起。
57
+
58
+ ```tsx
59
+ import {ThinkBlock} from '@unif/react-native-chat-markdown';
60
+
61
+ <ThinkBlock content="这是 AI 的思考过程..." />
62
+ ```
63
+
64
+ | 属性 | 类型 | 说明 |
65
+ |------|------|------|
66
+ | content | `string` | 思考内容 |
67
+ | defaultExpanded | `boolean` | 默认展开(默认 false) |
68
+ | label | `string` | 标签文字(默认 '深度思考') |
69
+
70
+ ## 工具函数
71
+
72
+ ### parseThinkTags
73
+
74
+ 解析 `<think>` 标签,拆分为思考内容和正文。
75
+
76
+ ```typescript
77
+ import {parseThinkTags} from '@unif/react-native-chat-markdown';
78
+
79
+ const result = parseThinkTags('<think>思考中</think>正文内容');
80
+ // result.sections = [{type: 'think', content: '思考中'}, {type: 'text', content: '正文内容'}]
81
+ ```
82
+
83
+ ### hasUnclosedThink
84
+
85
+ 检测是否有未关闭的 `<think>` 标签(用于流式渲染判断)。
86
+
87
+ ```typescript
88
+ import {hasUnclosedThink} from '@unif/react-native-chat-markdown';
89
+
90
+ hasUnclosedThink('<think>还在思考'); // true
91
+ hasUnclosedThink('<think>完成</think>'); // false
92
+ ```
93
+
94
+ ## 兼容性
95
+
96
+ | @unif/react-native-chat-markdown | React Native | React | 状态 |
97
+ |----------------------------------|-------------|-------|------|
98
+ | 0.1.x | >= 0.71 | >= 18 | ✅ |
99
+ | 0.1.x | 0.74.x | 18.x | ✅ 已验证(PECPortal) |
100
+
101
+ ## 许可证
102
+
103
+ MIT
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "MarkdownBubble", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _MarkdownBubble.default;
10
+ }
11
+ });
12
+ Object.defineProperty(exports, "StreamingBubble", {
13
+ enumerable: true,
14
+ get: function () {
15
+ return _StreamingBubble.default;
16
+ }
17
+ });
18
+ Object.defineProperty(exports, "ThinkBlock", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _ThinkBlock.default;
22
+ }
23
+ });
24
+ Object.defineProperty(exports, "hasUnclosedThink", {
25
+ enumerable: true,
26
+ get: function () {
27
+ return _thinkTagParser.hasUnclosedThink;
28
+ }
29
+ });
30
+ Object.defineProperty(exports, "parseThinkTags", {
31
+ enumerable: true,
32
+ get: function () {
33
+ return _thinkTagParser.parseThinkTags;
34
+ }
35
+ });
36
+ var _ThinkBlock = _interopRequireDefault(require("./think-block/ThinkBlock"));
37
+ var _StreamingBubble = _interopRequireDefault(require("./streaming-bubble/StreamingBubble"));
38
+ var _MarkdownBubble = _interopRequireDefault(require("./markdown-bubble/MarkdownBubble"));
39
+ var _thinkTagParser = require("./utils/thinkTagParser");
40
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
41
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_ThinkBlock","_interopRequireDefault","require","_StreamingBubble","_MarkdownBubble","_thinkTagParser","e","__esModule","default"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,IAAAA,WAAA,GAAAC,sBAAA,CAAAC,OAAA;AAGA,IAAAC,gBAAA,GAAAF,sBAAA,CAAAC,OAAA;AAGA,IAAAE,eAAA,GAAAH,sBAAA,CAAAC,OAAA;AAGA,IAAAG,eAAA,GAAAH,OAAA;AAAwE,SAAAD,uBAAAK,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA","ignoreList":[]}
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _reactNative = require("react-native");
9
+ var _reactNativeMarkdownDisplay = _interopRequireDefault(require("@ronradtke/react-native-markdown-display"));
10
+ var _thinkTagParser = require("../utils/thinkTagParser");
11
+ var _ThinkBlock = _interopRequireDefault(require("../think-block/ThinkBlock"));
12
+ var _jsxRuntime = require("react/jsx-runtime");
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
15
+ /**
16
+ * MarkdownBubble — Markdown 渲染气泡
17
+ * 完成的消息用 Markdown 渲染 + think 折叠
18
+ */
19
+
20
+ const defaultMarkdownStyles = {
21
+ body: {
22
+ fontSize: 15,
23
+ color: '#1F2937',
24
+ lineHeight: 22
25
+ },
26
+ paragraph: {
27
+ marginTop: 0,
28
+ marginBottom: 6
29
+ },
30
+ code_inline: {
31
+ backgroundColor: '#F5F5F5',
32
+ borderRadius: 3,
33
+ paddingHorizontal: 4,
34
+ fontSize: 13,
35
+ color: '#E8550A'
36
+ },
37
+ fence: {
38
+ backgroundColor: '#F5F5F5',
39
+ borderRadius: 6,
40
+ padding: 10,
41
+ fontSize: 13
42
+ },
43
+ link: {
44
+ color: '#1677FF'
45
+ },
46
+ strong: {
47
+ fontWeight: '600'
48
+ },
49
+ list_item: {
50
+ marginBottom: 4
51
+ },
52
+ blockquote: {
53
+ borderLeftWidth: 3,
54
+ borderLeftColor: '#E5E7EB',
55
+ paddingLeft: 10,
56
+ marginLeft: 0
57
+ }
58
+ };
59
+ const MarkdownBubble = ({
60
+ text,
61
+ markdownStyles,
62
+ style,
63
+ testID = 'markdown-bubble'
64
+ }) => {
65
+ const {
66
+ body,
67
+ thinks
68
+ } = (0, _react.useMemo)(() => (0, _thinkTagParser.parseThinkTags)(text), [text]);
69
+ const mergedStyles = (0, _react.useMemo)(() => ({
70
+ ...defaultMarkdownStyles,
71
+ ...markdownStyles
72
+ }), [markdownStyles]);
73
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
74
+ style: [defaultContainerStyles.container, style],
75
+ testID: testID,
76
+ children: [thinks.map((think, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_ThinkBlock.default, {
77
+ content: think
78
+ }, index)), body.length > 0 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNativeMarkdownDisplay.default, {
79
+ style: mergedStyles,
80
+ children: body
81
+ })]
82
+ });
83
+ };
84
+ const defaultContainerStyles = _reactNative.StyleSheet.create({
85
+ container: {
86
+ paddingVertical: 4
87
+ }
88
+ });
89
+ var _default = exports.default = /*#__PURE__*/_react.default.memo(MarkdownBubble);
90
+ //# sourceMappingURL=MarkdownBubble.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_reactNativeMarkdownDisplay","_interopRequireDefault","_thinkTagParser","_ThinkBlock","_jsxRuntime","e","__esModule","default","t","WeakMap","r","n","o","i","f","__proto__","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","defaultMarkdownStyles","body","fontSize","color","lineHeight","paragraph","marginTop","marginBottom","code_inline","backgroundColor","borderRadius","paddingHorizontal","fence","padding","link","strong","fontWeight","list_item","blockquote","borderLeftWidth","borderLeftColor","paddingLeft","marginLeft","MarkdownBubble","text","markdownStyles","style","testID","thinks","useMemo","parseThinkTags","mergedStyles","jsxs","View","defaultContainerStyles","container","children","map","think","index","jsx","content","length","StyleSheet","create","paddingVertical","_default","exports","React","memo"],"sourceRoot":"../../../src","sources":["markdown-bubble/MarkdownBubble.tsx"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,61 @@
1
+ ---
2
+ title: MarkdownBubble Markdown 渲染
3
+ nav:
4
+ title: 组件
5
+ path: /components
6
+ ---
7
+
8
+ # MarkdownBubble Markdown 渲染
9
+
10
+ 完整的 Markdown 渲染气泡,自动解析 `<think>` 标签并渲染为 ThinkBlock。
11
+
12
+ ## 何时使用
13
+
14
+ - AI 回复完成后(status === 'success')渲染完整内容
15
+ - 内容包含 Markdown 格式(标题、代码、链接、列表等)
16
+ - 内容包含 `<think>` 标签需要折叠展示
17
+
18
+ ## 代码示例
19
+
20
+ ### 基本用法
21
+
22
+ ```tsx
23
+ import { MarkdownBubble } from '@unif/react-native-chat-markdown';
24
+
25
+ <MarkdownBubble text="**加粗** 和 `代码` 以及[链接](https://example.com)" />
26
+ ```
27
+
28
+ ### 包含思考内容
29
+
30
+ ```tsx
31
+ <MarkdownBubble
32
+ text="<think>分析用户意图...</think>根据您的需求,推荐以下方案..."
33
+ />
34
+ ```
35
+
36
+ ### 自定义 Markdown 样式
37
+
38
+ ```tsx
39
+ <MarkdownBubble
40
+ text={messageText}
41
+ markdownStyles={{
42
+ body: { fontSize: 16, color: '#333' },
43
+ code_inline: { backgroundColor: '#F0F0F0' },
44
+ }}
45
+ />
46
+ ```
47
+
48
+ ## API
49
+
50
+ ### MarkdownBubbleProps
51
+
52
+ | 属性 | 说明 | 类型 | 默认值 |
53
+ |------|------|------|--------|
54
+ | text | Markdown 文本 | `string` | - |
55
+ | markdownStyles | 覆盖默认 Markdown 样式 | `Record<string, unknown>` | 内置样式 |
56
+ | style | 容器样式 | `ViewStyle` | - |
57
+ | testID | 测试标识 | `string` | `'markdown-bubble'` |
58
+
59
+ ### 依赖
60
+
61
+ - `@ronradtke/react-native-markdown-display` — Markdown 渲染引擎
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _reactNative = require("react-native");
9
+ var _jsxRuntime = require("react/jsx-runtime");
10
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
11
+ /**
12
+ * StreamingBubble — 流式文本气泡
13
+ * 显示正在流入的文本 + 呼吸动画光标
14
+ */
15
+
16
+ const StreamingBubble = ({
17
+ text,
18
+ cursorColor = '#1677FF',
19
+ cursorChar = '▌',
20
+ style,
21
+ testID = 'streaming-bubble'
22
+ }) => {
23
+ const opacity = (0, _react.useRef)(new _reactNative.Animated.Value(1)).current;
24
+ (0, _react.useEffect)(() => {
25
+ const animation = _reactNative.Animated.loop(_reactNative.Animated.sequence([_reactNative.Animated.timing(opacity, {
26
+ toValue: 0,
27
+ duration: 400,
28
+ useNativeDriver: true
29
+ }), _reactNative.Animated.timing(opacity, {
30
+ toValue: 1,
31
+ duration: 400,
32
+ useNativeDriver: true
33
+ })]));
34
+ animation.start();
35
+ return () => animation.stop();
36
+ }, [opacity]);
37
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
38
+ style: [defaultStyles.container, style],
39
+ testID: testID,
40
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
41
+ style: defaultStyles.text,
42
+ children: [text, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Animated.Text, {
43
+ style: [{
44
+ color: cursorColor
45
+ }, {
46
+ opacity
47
+ }],
48
+ children: cursorChar
49
+ })]
50
+ })
51
+ });
52
+ };
53
+ const defaultStyles = _reactNative.StyleSheet.create({
54
+ container: {
55
+ paddingVertical: 4
56
+ },
57
+ text: {
58
+ fontSize: 15,
59
+ color: '#1F2937',
60
+ lineHeight: 22
61
+ }
62
+ });
63
+ var _default = exports.default = /*#__PURE__*/_react.default.memo(StreamingBubble);
64
+ //# sourceMappingURL=StreamingBubble.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","StreamingBubble","text","cursorColor","cursorChar","style","testID","opacity","useRef","Animated","Value","current","useEffect","animation","loop","sequence","timing","toValue","duration","useNativeDriver","start","stop","jsx","View","defaultStyles","container","children","jsxs","Text","color","StyleSheet","create","paddingVertical","fontSize","lineHeight","_default","exports","React","memo"],"sourceRoot":"../../../src","sources":["streaming-bubble/StreamingBubble.tsx"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,47 @@
1
+ ---
2
+ title: StreamingBubble 流式气泡
3
+ nav:
4
+ title: 组件
5
+ path: /components
6
+ ---
7
+
8
+ # StreamingBubble 流式气泡
9
+
10
+ 展示正在流入的文本内容,附带闪烁光标动画。
11
+
12
+ ## 何时使用
13
+
14
+ - AI 正在流式输出回复时(status === 'updating')
15
+ - 需要视觉上表示内容仍在生成中
16
+
17
+ ## 代码示例
18
+
19
+ ### 基本用法
20
+
21
+ ```tsx
22
+ import { StreamingBubble } from '@unif/react-native-chat-markdown';
23
+
24
+ <StreamingBubble text="正在生成的文本内容..." />
25
+ ```
26
+
27
+ ### 自定义光标
28
+
29
+ ```tsx
30
+ <StreamingBubble
31
+ text={streamingText}
32
+ cursorColor="#FF6B00"
33
+ cursorChar="●"
34
+ />
35
+ ```
36
+
37
+ ## API
38
+
39
+ ### StreamingBubbleProps
40
+
41
+ | 属性 | 说明 | 类型 | 默认值 |
42
+ |------|------|------|--------|
43
+ | text | 当前流式文本 | `string` | - |
44
+ | cursorColor | 光标颜色 | `string` | `'#1677FF'` |
45
+ | cursorChar | 光标字符 | `string` | `'▌'` |
46
+ | style | 容器样式 | `ViewStyle` | - |
47
+ | testID | 测试标识 | `string` | `'streaming-bubble'` |
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireWildcard(require("react"));
8
+ var _reactNative = require("react-native");
9
+ var _jsxRuntime = require("react/jsx-runtime");
10
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
11
+ /**
12
+ * ThinkBlock — 思考折叠块
13
+ * 卡片式,圆角 12px
14
+ * 标题:🧠 已深度思考(展开) ▾
15
+ */
16
+
17
+ const ThinkBlock = ({
18
+ content,
19
+ defaultExpanded = false,
20
+ label = '深度思考',
21
+ style,
22
+ styles: semanticStyles,
23
+ testID = 'think-block'
24
+ }) => {
25
+ const [expanded, setExpanded] = (0, _react.useState)(defaultExpanded);
26
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
27
+ style: [defaultStyles.container, semanticStyles?.root, style],
28
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
29
+ style: [defaultStyles.header, semanticStyles?.header],
30
+ onPress: () => setExpanded(!expanded),
31
+ activeOpacity: 0.7,
32
+ testID: `${testID}-toggle`,
33
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
34
+ style: defaultStyles.titleRow,
35
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
36
+ style: defaultStyles.brainIcon,
37
+ children: "\uD83E\uDDE0"
38
+ }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
39
+ style: [defaultStyles.label, semanticStyles?.label],
40
+ children: ["\u5DF2", label, expanded ? '(展开)' : '(收起)']
41
+ })]
42
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
43
+ style: defaultStyles.chevron,
44
+ children: expanded ? '▲' : '▼'
45
+ })]
46
+ }), expanded && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
47
+ style: [defaultStyles.content, semanticStyles?.content],
48
+ testID: `${testID}-content`,
49
+ children: content
50
+ })]
51
+ });
52
+ };
53
+ const defaultStyles = _reactNative.StyleSheet.create({
54
+ container: {
55
+ backgroundColor: '#F9FAFB',
56
+ borderRadius: 12,
57
+ marginBottom: 8,
58
+ overflow: 'hidden'
59
+ },
60
+ header: {
61
+ flexDirection: 'row',
62
+ alignItems: 'center',
63
+ justifyContent: 'space-between',
64
+ paddingHorizontal: 14,
65
+ paddingVertical: 10
66
+ },
67
+ titleRow: {
68
+ flexDirection: 'row',
69
+ alignItems: 'center'
70
+ },
71
+ brainIcon: {
72
+ fontSize: 14
73
+ },
74
+ label: {
75
+ marginLeft: 6,
76
+ fontSize: 12,
77
+ color: '#6B7280'
78
+ },
79
+ chevron: {
80
+ fontSize: 10,
81
+ color: '#6B7280'
82
+ },
83
+ content: {
84
+ fontSize: 12,
85
+ color: '#6B7280',
86
+ lineHeight: 20,
87
+ paddingHorizontal: 14,
88
+ paddingBottom: 12
89
+ }
90
+ });
91
+ var _default = exports.default = /*#__PURE__*/_react.default.memo(ThinkBlock);
92
+ //# sourceMappingURL=ThinkBlock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","ThinkBlock","content","defaultExpanded","label","style","styles","semanticStyles","testID","expanded","setExpanded","useState","jsxs","View","defaultStyles","container","root","children","TouchableOpacity","header","onPress","activeOpacity","titleRow","jsx","Text","brainIcon","chevron","StyleSheet","create","backgroundColor","borderRadius","marginBottom","overflow","flexDirection","alignItems","justifyContent","paddingHorizontal","paddingVertical","fontSize","marginLeft","color","lineHeight","paddingBottom","_default","exports","React","memo"],"sourceRoot":"../../../src","sources":["think-block/ThinkBlock.tsx"],"mappings":";;;;;;AAMA,IAAAA,MAAA,GAAAC,uBAAA,CAAAC,OAAA;AACA,IAAAC,YAAA,GAAAD,OAAA;AAOsB,IAAAE,WAAA,GAAAF,OAAA;AAAA,SAAAD,wBAAAI,CAAA,EAAAC,CAAA,6BAAAC,OAAA,MAAAC,CAAA,OAAAD,OAAA,IAAAE,CAAA,OAAAF,OAAA,YAAAN,uBAAA,YAAAA,CAAAI,CAAA,EAAAC,CAAA,SAAAA,CAAA,IAAAD,CAAA,IAAAA,CAAA,CAAAK,UAAA,SAAAL,CAAA,MAAAM,CAAA,EAAAC,CAAA,EAAAC,CAAA,KAAAC,SAAA,QAAAC,OAAA,EAAAV,CAAA,iBAAAA,CAAA,uBAAAA,CAAA,yBAAAA,CAAA,SAAAQ,CAAA,MAAAF,CAAA,GAAAL,CAAA,GAAAG,CAAA,GAAAD,CAAA,QAAAG,CAAA,CAAAK,GAAA,CAAAX,CAAA,UAAAM,CAAA,CAAAM,GAAA,CAAAZ,CAAA,GAAAM,CAAA,CAAAO,GAAA,CAAAb,CAAA,EAAAQ,CAAA,gBAAAP,CAAA,IAAAD,CAAA,gBAAAC,CAAA,OAAAa,cAAA,CAAAC,IAAA,CAAAf,CAAA,EAAAC,CAAA,OAAAM,CAAA,IAAAD,CAAA,GAAAU,MAAA,CAAAC,cAAA,KAAAD,MAAA,CAAAE,wBAAA,CAAAlB,CAAA,EAAAC,CAAA,OAAAM,CAAA,CAAAK,GAAA,IAAAL,CAAA,CAAAM,GAAA,IAAAP,CAAA,CAAAE,CAAA,EAAAP,CAAA,EAAAM,CAAA,IAAAC,CAAA,CAAAP,CAAA,IAAAD,CAAA,CAAAC,CAAA,WAAAO,CAAA,KAAAR,CAAA,EAAAC,CAAA;AAdtB;AACA;AACA;AACA;AACA;;AA4BA,MAAMkB,UAAqC,GAAGA,CAAC;EAC7CC,OAAO;EACPC,eAAe,GAAG,KAAK;EACvBC,KAAK,GAAG,MAAM;EACdC,KAAK;EACLC,MAAM,EAAEC,cAAc;EACtBC,MAAM,GAAG;AACX,CAAC,KAAK;EACJ,MAAM,CAACC,QAAQ,EAAEC,WAAW,CAAC,GAAG,IAAAC,eAAQ,EAACR,eAAe,CAAC;EAEzD,oBACE,IAAAtB,WAAA,CAAA+B,IAAA,EAAChC,YAAA,CAAAiC,IAAI;IAACR,KAAK,EAAE,CAACS,aAAa,CAACC,SAAS,EAAER,cAAc,EAAES,IAAI,EAAEX,KAAK,CAAE;IAAAY,QAAA,gBAClE,IAAApC,WAAA,CAAA+B,IAAA,EAAChC,YAAA,CAAAsC,gBAAgB;MACfb,KAAK,EAAE,CAACS,aAAa,CAACK,MAAM,EAAEZ,cAAc,EAAEY,MAAM,CAAE;MACtDC,OAAO,EAAEA,CAAA,KAAMV,WAAW,CAAC,CAACD,QAAQ,CAAE;MACtCY,aAAa,EAAE,GAAI;MACnBb,MAAM,EAAE,GAAGA,MAAM,SAAU;MAAAS,QAAA,gBAC3B,IAAApC,WAAA,CAAA+B,IAAA,EAAChC,YAAA,CAAAiC,IAAI;QAACR,KAAK,EAAES,aAAa,CAACQ,QAAS;QAAAL,QAAA,gBAClC,IAAApC,WAAA,CAAA0C,GAAA,EAAC3C,YAAA,CAAA4C,IAAI;UAACnB,KAAK,EAAES,aAAa,CAACW,SAAU;UAAAR,QAAA,EAAC;QAAE,CAAM,CAAC,eAC/C,IAAApC,WAAA,CAAA+B,IAAA,EAAChC,YAAA,CAAA4C,IAAI;UACHnB,KAAK,EAAE,CAACS,aAAa,CAACV,KAAK,EAAEG,cAAc,EAAEH,KAAK,CAAE;UAAAa,QAAA,GAAC,QACpD,EAACb,KAAK,EAAEK,QAAQ,GAAG,MAAM,GAAG,MAAM;QAAA,CAC/B,CAAC;MAAA,CACH,CAAC,eACP,IAAA5B,WAAA,CAAA0C,GAAA,EAAC3C,YAAA,CAAA4C,IAAI;QAACnB,KAAK,EAAES,aAAa,CAACY,OAAQ;QAAAT,QAAA,EAChCR,QAAQ,GAAG,GAAG,GAAG;MAAG,CACjB,CAAC;IAAA,CACS,CAAC,EAClBA,QAAQ,iBACP,IAAA5B,WAAA,CAAA0C,GAAA,EAAC3C,YAAA,CAAA4C,IAAI;MACHnB,KAAK,EAAE,CAACS,aAAa,CAACZ,OAAO,EAAEK,cAAc,EAAEL,OAAO,CAAE;MACxDM,MAAM,EAAE,GAAGA,MAAM,UAAW;MAAAS,QAAA,EAC3Bf;IAAO,CACJ,CACP;EAAA,CACG,CAAC;AAEX,CAAC;AAED,MAAMY,aAAa,GAAGa,uBAAU,CAACC,MAAM,CAAC;EACtCb,SAAS,EAAE;IACTc,eAAe,EAAE,SAAS;IAC1BC,YAAY,EAAE,EAAE;IAChBC,YAAY,EAAE,CAAC;IACfC,QAAQ,EAAE;EACZ,CAAC;EACDb,MAAM,EAAE;IACNc,aAAa,EAAE,KAAK;IACpBC,UAAU,EAAE,QAAQ;IACpBC,cAAc,EAAE,eAAe;IAC/BC,iBAAiB,EAAE,EAAE;IACrBC,eAAe,EAAE;EACnB,CAAC;EACDf,QAAQ,EAAE;IACRW,aAAa,EAAE,KAAK;IACpBC,UAAU,EAAE;EACd,CAAC;EACDT,SAAS,EAAE;IACTa,QAAQ,EAAE;EACZ,CAAC;EACDlC,KAAK,EAAE;IACLmC,UAAU,EAAE,CAAC;IACbD,QAAQ,EAAE,EAAE;IACZE,KAAK,EAAE;EACT,CAAC;EACDd,OAAO,EAAE;IACPY,QAAQ,EAAE,EAAE;IACZE,KAAK,EAAE;EACT,CAAC;EACDtC,OAAO,EAAE;IACPoC,QAAQ,EAAE,EAAE;IACZE,KAAK,EAAE,SAAS;IAChBC,UAAU,EAAE,EAAE;IACdL,iBAAiB,EAAE,EAAE;IACrBM,aAAa,EAAE;EACjB;AACF,CAAC,CAAC;AAAC,IAAAC,QAAA,GAAAC,OAAA,CAAApD,OAAA,gBAEYqD,cAAK,CAACC,IAAI,CAAC7C,UAAU,CAAC","ignoreList":[]}
@@ -0,0 +1,57 @@
1
+ ---
2
+ title: ThinkBlock 思考折叠块
3
+ nav:
4
+ title: 组件
5
+ path: /components
6
+ ---
7
+
8
+ # ThinkBlock 思考折叠块
9
+
10
+ 展示 AI 的思考过程,可折叠/展开。
11
+
12
+ ## 何时使用
13
+
14
+ - AI 回复中包含 `<think>` 标签的思考内容
15
+ - 需要可折叠展示推理过程(如 DeepSeek 的 reasoning_content)
16
+
17
+ ## 代码示例
18
+
19
+ ### 基本用法
20
+
21
+ ```tsx
22
+ import { ThinkBlock } from '@unif/react-native-chat-markdown';
23
+
24
+ <ThinkBlock content="用户询问的是账户余额,需要调用查询接口..." />
25
+ ```
26
+
27
+ ### 默认展开
28
+
29
+ ```tsx
30
+ <ThinkBlock
31
+ content="分析用户意图..."
32
+ defaultExpanded={true}
33
+ label="思考过程"
34
+ />
35
+ ```
36
+
37
+ ## API
38
+
39
+ ### ThinkBlockProps
40
+
41
+ | 属性 | 说明 | 类型 | 默认值 |
42
+ |------|------|------|--------|
43
+ | content | 思考内容 | `string` | - |
44
+ | defaultExpanded | 默认展开 | `boolean` | `false` |
45
+ | label | 标题文字 | `string` | `'深度思考'` |
46
+ | style | 容器样式 | `ViewStyle` | - |
47
+ | styles | 语义样式 | `Partial<ThinkBlockSemanticStyles>` | - |
48
+ | testID | 测试标识 | `string` | `'think-block'` |
49
+
50
+ ### ThinkBlockSemanticStyles
51
+
52
+ | 属性 | 说明 | 类型 |
53
+ |------|------|------|
54
+ | root | 外层容器 | `ViewStyle` |
55
+ | header | 标题栏 | `ViewStyle` |
56
+ | label | 标题文字 | `TextStyle` |
57
+ | content | 内容文字 | `TextStyle` |
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.hasUnclosedThink = hasUnclosedThink;
7
+ exports.parseThinkTags = parseThinkTags;
8
+ /**
9
+ * <think> 标签解析器
10
+ * 将文本中的 <think>...</think> 提取出来,分离为普通内容和思考内容
11
+ */
12
+
13
+ const THINK_REGEX = /<think>([\s\S]*?)<\/think>/g;
14
+
15
+ /**
16
+ * 解析文本中的 <think> 标签
17
+ * 支持多个 <think> 块,返回分离后的正文和思考内容
18
+ */
19
+ function parseThinkTags(text) {
20
+ const thinks = [];
21
+ const body = text.replace(THINK_REGEX, (_match, content) => {
22
+ const trimmed = content.trim();
23
+ if (trimmed) {
24
+ thinks.push(trimmed);
25
+ }
26
+ return '';
27
+ }).trim();
28
+ return {
29
+ body,
30
+ thinks
31
+ };
32
+ }
33
+
34
+ /**
35
+ * 检查文本中是否包含未闭合的 <think> 标签(流式场景)
36
+ */
37
+ function hasUnclosedThink(text) {
38
+ const opens = (text.match(/<think>/g) || []).length;
39
+ const closes = (text.match(/<\/think>/g) || []).length;
40
+ return opens > closes;
41
+ }
42
+ //# sourceMappingURL=thinkTagParser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["THINK_REGEX","parseThinkTags","text","thinks","body","replace","_match","content","trimmed","trim","push","hasUnclosedThink","opens","match","length","closes"],"sourceRoot":"../../../src","sources":["utils/thinkTagParser.ts"],"mappings":";;;;;;;AAAA;AACA;AACA;AACA;;AASA,MAAMA,WAAW,GAAG,6BAA6B;;AAEjD;AACA;AACA;AACA;AACO,SAASC,cAAcA,CAACC,IAAY,EAAiB;EAC1D,MAAMC,MAAgB,GAAG,EAAE;EAC3B,MAAMC,IAAI,GAAGF,IAAI,CACdG,OAAO,CAACL,WAAW,EAAE,CAACM,MAAM,EAAEC,OAAe,KAAK;IACjD,MAAMC,OAAO,GAAGD,OAAO,CAACE,IAAI,CAAC,CAAC;IAC9B,IAAID,OAAO,EAAE;MACXL,MAAM,CAACO,IAAI,CAACF,OAAO,CAAC;IACtB;IACA,OAAO,EAAE;EACX,CAAC,CAAC,CACDC,IAAI,CAAC,CAAC;EAET,OAAO;IAACL,IAAI;IAAED;EAAM,CAAC;AACvB;;AAEA;AACA;AACA;AACO,SAASQ,gBAAgBA,CAACT,IAAY,EAAW;EACtD,MAAMU,KAAK,GAAG,CAACV,IAAI,CAACW,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,EAAEC,MAAM;EACnD,MAAMC,MAAM,GAAG,CAACb,IAAI,CAACW,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,EAAEC,MAAM;EACtD,OAAOF,KAAK,GAAGG,MAAM;AACvB","ignoreList":[]}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * @unif/react-native-chat-markdown
5
+ * Markdown 渲染、ThinkBlock、流式气泡
6
+ */
7
+
8
+ export { default as ThinkBlock } from "./think-block/ThinkBlock.js";
9
+ export { default as StreamingBubble } from "./streaming-bubble/StreamingBubble.js";
10
+ export { default as MarkdownBubble } from "./markdown-bubble/MarkdownBubble.js";
11
+ export { parseThinkTags, hasUnclosedThink } from "./utils/thinkTagParser.js";
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["default","ThinkBlock","StreamingBubble","MarkdownBubble","parseThinkTags","hasUnclosedThink"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA;AACA;AACA;AACA;;AAEA,SAAQA,OAAO,IAAIC,UAAU,QAAO,6BAA0B;AAG9D,SAAQD,OAAO,IAAIE,eAAe,QAAO,uCAAoC;AAG7E,SAAQF,OAAO,IAAIG,cAAc,QAAO,qCAAkC;AAG1E,SAAQC,cAAc,EAAEC,gBAAgB,QAAO,2BAAwB","ignoreList":[]}