@djangocfg/ui-tools 2.1.92 → 2.1.95
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/README.md +129 -0
- package/dist/index.cjs +267 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +103 -1
- package/dist/index.d.ts +103 -1
- package/dist/index.mjs +267 -30
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/components/markdown/MarkdownMessage.tsx +210 -23
- package/src/components/markdown/index.ts +9 -0
- package/src/components/markdown/useCollapsibleContent.ts +236 -0
package/README.md
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# @djangocfg/ui-tools
|
|
2
|
+
|
|
3
|
+
Heavy React tools with lazy loading (React.lazy + Suspense).
|
|
4
|
+
|
|
5
|
+
**No Next.js dependencies** — works with Electron, Vite, CRA, and any React environment.
|
|
6
|
+
|
|
7
|
+
**Part of [DjangoCFG](https://djangocfg.com)** — modern Django framework for production-ready SaaS applications.
|
|
8
|
+
|
|
9
|
+
**[Live Demo & Props](https://djangocfg.com/demo/)**
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pnpm add @djangocfg/ui-tools
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Why ui-tools?
|
|
18
|
+
|
|
19
|
+
This package contains heavy components that are loaded lazily to keep your initial bundle small. Each tool is loaded only when used.
|
|
20
|
+
|
|
21
|
+
| Package | Use Case |
|
|
22
|
+
|---------|----------|
|
|
23
|
+
| `@djangocfg/ui-core` | Lightweight UI components (60 components) |
|
|
24
|
+
| `@djangocfg/ui-tools` | Heavy tools with lazy loading |
|
|
25
|
+
| `@djangocfg/ui-nextjs` | Next.js apps (extends ui-core) |
|
|
26
|
+
|
|
27
|
+
## Tools (9)
|
|
28
|
+
|
|
29
|
+
| Tool | Bundle Size | Description |
|
|
30
|
+
|------|-------------|-------------|
|
|
31
|
+
| `Mermaid` | ~800KB | Diagram rendering |
|
|
32
|
+
| `PrettyCode` | ~500KB | Code syntax highlighting |
|
|
33
|
+
| `OpenapiViewer` | ~400KB | OpenAPI schema viewer & playground |
|
|
34
|
+
| `JsonForm` | ~300KB | JSON Schema form generator |
|
|
35
|
+
| `LottiePlayer` | ~200KB | Lottie animation player |
|
|
36
|
+
| `AudioPlayer` | ~200KB | Audio player with WaveSurfer.js |
|
|
37
|
+
| `VideoPlayer` | ~150KB | Professional video player with Vidstack |
|
|
38
|
+
| `JsonTree` | ~100KB | JSON visualization |
|
|
39
|
+
| `ImageViewer` | ~50KB | Image viewer with zoom/pan/rotate |
|
|
40
|
+
|
|
41
|
+
## Components
|
|
42
|
+
|
|
43
|
+
| Component | Description |
|
|
44
|
+
|-----------|-------------|
|
|
45
|
+
| `Markdown` | Markdown renderer with GFM support |
|
|
46
|
+
|
|
47
|
+
## Stores
|
|
48
|
+
|
|
49
|
+
| Store | Description |
|
|
50
|
+
|-------|-------------|
|
|
51
|
+
| `useMediaCacheStore` | Media caching for video/audio players |
|
|
52
|
+
|
|
53
|
+
## Usage
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
import { VideoPlayer, AudioPlayer, Mermaid } from '@djangocfg/ui-tools';
|
|
57
|
+
import { Markdown } from '@djangocfg/ui-tools';
|
|
58
|
+
|
|
59
|
+
function Example() {
|
|
60
|
+
return (
|
|
61
|
+
<>
|
|
62
|
+
<VideoPlayer src="https://example.com/video.mp4" />
|
|
63
|
+
<AudioPlayer src="https://example.com/audio.mp3" />
|
|
64
|
+
<Mermaid chart={`graph TD; A-->B;`} />
|
|
65
|
+
<Markdown content="# Hello **World**" />
|
|
66
|
+
</>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## JSON Form Example
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
import { JsonForm } from '@djangocfg/ui-tools';
|
|
75
|
+
|
|
76
|
+
const schema = {
|
|
77
|
+
type: 'object',
|
|
78
|
+
properties: {
|
|
79
|
+
name: { type: 'string', title: 'Name' },
|
|
80
|
+
email: { type: 'string', format: 'email', title: 'Email' },
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
function Form() {
|
|
85
|
+
return (
|
|
86
|
+
<JsonForm
|
|
87
|
+
schema={schema}
|
|
88
|
+
onSubmit={(data) => console.log(data)}
|
|
89
|
+
/>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Code Highlighting Example
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
import { PrettyCode } from '@djangocfg/ui-tools';
|
|
98
|
+
|
|
99
|
+
function CodeBlock() {
|
|
100
|
+
return (
|
|
101
|
+
<PrettyCode
|
|
102
|
+
code={`const hello = "world";`}
|
|
103
|
+
language="typescript"
|
|
104
|
+
/>
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Lazy Loading
|
|
110
|
+
|
|
111
|
+
All tools use React.lazy + Suspense for automatic code splitting:
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
// Each tool is loaded only when rendered
|
|
115
|
+
<Suspense fallback={<Spinner />}>
|
|
116
|
+
<Mermaid chart={diagram} />
|
|
117
|
+
</Suspense>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Requirements
|
|
121
|
+
|
|
122
|
+
- React >= 18 or >= 19
|
|
123
|
+
- Tailwind CSS >= 4
|
|
124
|
+
- Zustand >= 5
|
|
125
|
+
- @djangocfg/ui-core (peer dependency)
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
**[Full documentation & examples](https://djangocfg.com/demo/)**
|
package/dist/index.cjs
CHANGED
|
@@ -4763,6 +4763,121 @@ function ImageViewer({ file, content, src: directSrc, inDialog = false }) {
|
|
|
4763
4763
|
);
|
|
4764
4764
|
}
|
|
4765
4765
|
chunkUQ3XI5MY_cjs.__name(ImageViewer, "ImageViewer");
|
|
4766
|
+
function smartTruncate(content, maxLength) {
|
|
4767
|
+
if (content.length <= maxLength) {
|
|
4768
|
+
return content;
|
|
4769
|
+
}
|
|
4770
|
+
let breakPoint = maxLength;
|
|
4771
|
+
while (breakPoint > maxLength - 50 && breakPoint > 0) {
|
|
4772
|
+
const char = content[breakPoint];
|
|
4773
|
+
if (char === " " || char === "\n" || char === " ") {
|
|
4774
|
+
break;
|
|
4775
|
+
}
|
|
4776
|
+
breakPoint--;
|
|
4777
|
+
}
|
|
4778
|
+
if (breakPoint <= maxLength - 50) {
|
|
4779
|
+
breakPoint = maxLength;
|
|
4780
|
+
}
|
|
4781
|
+
let truncated = content.slice(0, breakPoint).trimEnd();
|
|
4782
|
+
truncated = fixUnclosedMarkdown(truncated);
|
|
4783
|
+
return truncated;
|
|
4784
|
+
}
|
|
4785
|
+
chunkUQ3XI5MY_cjs.__name(smartTruncate, "smartTruncate");
|
|
4786
|
+
function truncateByLines(content, maxLines) {
|
|
4787
|
+
const lines = content.split("\n");
|
|
4788
|
+
if (lines.length <= maxLines) {
|
|
4789
|
+
return content;
|
|
4790
|
+
}
|
|
4791
|
+
let truncated = lines.slice(0, maxLines).join("\n").trimEnd();
|
|
4792
|
+
truncated = fixUnclosedMarkdown(truncated);
|
|
4793
|
+
return truncated;
|
|
4794
|
+
}
|
|
4795
|
+
chunkUQ3XI5MY_cjs.__name(truncateByLines, "truncateByLines");
|
|
4796
|
+
function fixUnclosedMarkdown(content) {
|
|
4797
|
+
let result = content;
|
|
4798
|
+
const countOccurrences = /* @__PURE__ */ chunkUQ3XI5MY_cjs.__name((str, marker) => {
|
|
4799
|
+
const escaped = marker.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4800
|
+
const matches = str.match(new RegExp(escaped, "g"));
|
|
4801
|
+
return matches ? matches.length : 0;
|
|
4802
|
+
}, "countOccurrences");
|
|
4803
|
+
const boldCount = countOccurrences(result, "**");
|
|
4804
|
+
if (boldCount % 2 !== 0) {
|
|
4805
|
+
result += "**";
|
|
4806
|
+
}
|
|
4807
|
+
const withoutBold = result.replace(/\*\*/g, "");
|
|
4808
|
+
const italicCount = countOccurrences(withoutBold, "*");
|
|
4809
|
+
if (italicCount % 2 !== 0) {
|
|
4810
|
+
result += "*";
|
|
4811
|
+
}
|
|
4812
|
+
const codeCount = countOccurrences(result, "`");
|
|
4813
|
+
const tripleCount = countOccurrences(result, "```");
|
|
4814
|
+
const singleCodeCount = codeCount - tripleCount * 3;
|
|
4815
|
+
if (singleCodeCount % 2 !== 0) {
|
|
4816
|
+
result += "`";
|
|
4817
|
+
}
|
|
4818
|
+
if (tripleCount % 2 !== 0) {
|
|
4819
|
+
result += "\n```";
|
|
4820
|
+
}
|
|
4821
|
+
const strikeCount = countOccurrences(result, "~~");
|
|
4822
|
+
if (strikeCount % 2 !== 0) {
|
|
4823
|
+
result += "~~";
|
|
4824
|
+
}
|
|
4825
|
+
const underlineBoldCount = countOccurrences(result, "__");
|
|
4826
|
+
if (underlineBoldCount % 2 !== 0) {
|
|
4827
|
+
result += "__";
|
|
4828
|
+
}
|
|
4829
|
+
const withoutUnderlineBold = result.replace(/__/g, "");
|
|
4830
|
+
const underlineItalicCount = countOccurrences(withoutUnderlineBold, "_");
|
|
4831
|
+
if (underlineItalicCount % 2 !== 0) {
|
|
4832
|
+
result += "_";
|
|
4833
|
+
}
|
|
4834
|
+
return result;
|
|
4835
|
+
}
|
|
4836
|
+
chunkUQ3XI5MY_cjs.__name(fixUnclosedMarkdown, "fixUnclosedMarkdown");
|
|
4837
|
+
function useCollapsibleContent(content, options = {}) {
|
|
4838
|
+
const { maxLength, maxLines, defaultExpanded = false } = options;
|
|
4839
|
+
const [isCollapsed, setIsCollapsed] = React17.useState(!defaultExpanded);
|
|
4840
|
+
const originalLength = content.length;
|
|
4841
|
+
const originalLineCount = content.split("\n").length;
|
|
4842
|
+
const { shouldCollapse, truncatedContent } = React17.useMemo(() => {
|
|
4843
|
+
if (maxLength === void 0 && maxLines === void 0) {
|
|
4844
|
+
return { shouldCollapse: false, truncatedContent: content };
|
|
4845
|
+
}
|
|
4846
|
+
let needsCollapse = false;
|
|
4847
|
+
let result = content;
|
|
4848
|
+
if (maxLines !== void 0 && originalLineCount > maxLines) {
|
|
4849
|
+
needsCollapse = true;
|
|
4850
|
+
result = truncateByLines(result, maxLines);
|
|
4851
|
+
}
|
|
4852
|
+
if (maxLength !== void 0 && result.length > maxLength) {
|
|
4853
|
+
needsCollapse = true;
|
|
4854
|
+
result = smartTruncate(result, maxLength);
|
|
4855
|
+
}
|
|
4856
|
+
return { shouldCollapse: needsCollapse, truncatedContent: result };
|
|
4857
|
+
}, [content, maxLength, maxLines, originalLineCount]);
|
|
4858
|
+
const displayContent = React17.useMemo(() => {
|
|
4859
|
+
if (!shouldCollapse || !isCollapsed) {
|
|
4860
|
+
return content;
|
|
4861
|
+
}
|
|
4862
|
+
return truncatedContent;
|
|
4863
|
+
}, [content, truncatedContent, shouldCollapse, isCollapsed]);
|
|
4864
|
+
const toggleCollapsed = React17.useCallback(() => {
|
|
4865
|
+
setIsCollapsed((prev) => !prev);
|
|
4866
|
+
}, []);
|
|
4867
|
+
const setCollapsed = React17.useCallback((collapsed) => {
|
|
4868
|
+
setIsCollapsed(collapsed);
|
|
4869
|
+
}, []);
|
|
4870
|
+
return {
|
|
4871
|
+
isCollapsed,
|
|
4872
|
+
toggleCollapsed,
|
|
4873
|
+
setCollapsed,
|
|
4874
|
+
displayContent,
|
|
4875
|
+
shouldCollapse,
|
|
4876
|
+
originalLength,
|
|
4877
|
+
originalLineCount
|
|
4878
|
+
};
|
|
4879
|
+
}
|
|
4880
|
+
chunkUQ3XI5MY_cjs.__name(useCollapsibleContent, "useCollapsibleContent");
|
|
4766
4881
|
var extractTextFromChildren = /* @__PURE__ */ chunkUQ3XI5MY_cjs.__name((children) => {
|
|
4767
4882
|
if (typeof children === "string") {
|
|
4768
4883
|
return children;
|
|
@@ -4910,6 +5025,9 @@ var createMarkdownComponents = /* @__PURE__ */ chunkUQ3XI5MY_cjs.__name((isUser
|
|
|
4910
5025
|
};
|
|
4911
5026
|
}, "createMarkdownComponents");
|
|
4912
5027
|
var hasMarkdownSyntax = /* @__PURE__ */ chunkUQ3XI5MY_cjs.__name((text) => {
|
|
5028
|
+
if (text.trim().includes("\n")) {
|
|
5029
|
+
return true;
|
|
5030
|
+
}
|
|
4913
5031
|
const markdownPatterns = [
|
|
4914
5032
|
/^#{1,6}\s/m,
|
|
4915
5033
|
// Headers
|
|
@@ -4944,45 +5062,164 @@ var hasMarkdownSyntax = /* @__PURE__ */ chunkUQ3XI5MY_cjs.__name((text) => {
|
|
|
4944
5062
|
];
|
|
4945
5063
|
return markdownPatterns.some((pattern) => pattern.test(text));
|
|
4946
5064
|
}, "hasMarkdownSyntax");
|
|
5065
|
+
var CollapseToggle = /* @__PURE__ */ chunkUQ3XI5MY_cjs.__name(({
|
|
5066
|
+
isCollapsed,
|
|
5067
|
+
onClick,
|
|
5068
|
+
readMoreLabel,
|
|
5069
|
+
showLessLabel,
|
|
5070
|
+
isUser,
|
|
5071
|
+
isCompact
|
|
5072
|
+
}) => {
|
|
5073
|
+
const textSize = isCompact ? "text-xs" : "text-sm";
|
|
5074
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
5075
|
+
"button",
|
|
5076
|
+
{
|
|
5077
|
+
type: "button",
|
|
5078
|
+
onClick,
|
|
5079
|
+
className: `
|
|
5080
|
+
${textSize} font-medium cursor-pointer
|
|
5081
|
+
transition-colors duration-200
|
|
5082
|
+
${isUser ? "text-white/80 hover:text-white" : "text-primary hover:text-primary/80"}
|
|
5083
|
+
inline-flex items-center gap-1
|
|
5084
|
+
mt-1
|
|
5085
|
+
`,
|
|
5086
|
+
children: isCollapsed ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5087
|
+
readMoreLabel,
|
|
5088
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5089
|
+
"svg",
|
|
5090
|
+
{
|
|
5091
|
+
className: "w-3 h-3",
|
|
5092
|
+
fill: "none",
|
|
5093
|
+
stroke: "currentColor",
|
|
5094
|
+
viewBox: "0 0 24 24",
|
|
5095
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5096
|
+
"path",
|
|
5097
|
+
{
|
|
5098
|
+
strokeLinecap: "round",
|
|
5099
|
+
strokeLinejoin: "round",
|
|
5100
|
+
strokeWidth: 2,
|
|
5101
|
+
d: "M19 9l-7 7-7-7"
|
|
5102
|
+
}
|
|
5103
|
+
)
|
|
5104
|
+
}
|
|
5105
|
+
)
|
|
5106
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5107
|
+
showLessLabel,
|
|
5108
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5109
|
+
"svg",
|
|
5110
|
+
{
|
|
5111
|
+
className: "w-3 h-3",
|
|
5112
|
+
fill: "none",
|
|
5113
|
+
stroke: "currentColor",
|
|
5114
|
+
viewBox: "0 0 24 24",
|
|
5115
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5116
|
+
"path",
|
|
5117
|
+
{
|
|
5118
|
+
strokeLinecap: "round",
|
|
5119
|
+
strokeLinejoin: "round",
|
|
5120
|
+
strokeWidth: 2,
|
|
5121
|
+
d: "M5 15l7-7 7 7"
|
|
5122
|
+
}
|
|
5123
|
+
)
|
|
5124
|
+
}
|
|
5125
|
+
)
|
|
5126
|
+
] })
|
|
5127
|
+
}
|
|
5128
|
+
);
|
|
5129
|
+
}, "CollapseToggle");
|
|
4947
5130
|
var MarkdownMessage = /* @__PURE__ */ chunkUQ3XI5MY_cjs.__name(({
|
|
4948
5131
|
content,
|
|
4949
5132
|
className = "",
|
|
4950
5133
|
isUser = false,
|
|
4951
|
-
isCompact = false
|
|
5134
|
+
isCompact = false,
|
|
5135
|
+
collapsible = false,
|
|
5136
|
+
maxLength,
|
|
5137
|
+
maxLines,
|
|
5138
|
+
readMoreLabel = "Read more...",
|
|
5139
|
+
showLessLabel = "Show less",
|
|
5140
|
+
defaultExpanded = false,
|
|
5141
|
+
onCollapseChange
|
|
4952
5142
|
}) => {
|
|
5143
|
+
const trimmedContent = content.trim();
|
|
5144
|
+
const collapsibleOptions = React17__default.default.useMemo(() => {
|
|
5145
|
+
if (!collapsible) return {};
|
|
5146
|
+
return { maxLength, maxLines, defaultExpanded };
|
|
5147
|
+
}, [collapsible, maxLength, maxLines, defaultExpanded]);
|
|
5148
|
+
const {
|
|
5149
|
+
isCollapsed,
|
|
5150
|
+
toggleCollapsed,
|
|
5151
|
+
displayContent,
|
|
5152
|
+
shouldCollapse
|
|
5153
|
+
} = useCollapsibleContent(
|
|
5154
|
+
trimmedContent,
|
|
5155
|
+
collapsible ? collapsibleOptions : {}
|
|
5156
|
+
);
|
|
5157
|
+
React17__default.default.useEffect(() => {
|
|
5158
|
+
if (collapsible && shouldCollapse && onCollapseChange) {
|
|
5159
|
+
onCollapseChange(isCollapsed);
|
|
5160
|
+
}
|
|
5161
|
+
}, [isCollapsed, collapsible, shouldCollapse, onCollapseChange]);
|
|
4953
5162
|
const components = React17__default.default.useMemo(() => createMarkdownComponents(isUser, isCompact), [isUser, isCompact]);
|
|
4954
5163
|
const textSizeClass = isCompact ? "text-xs" : "text-sm";
|
|
4955
5164
|
const proseClass = isCompact ? "prose-xs" : "prose-sm";
|
|
4956
|
-
const isPlainText = !hasMarkdownSyntax(
|
|
5165
|
+
const isPlainText = !hasMarkdownSyntax(displayContent);
|
|
4957
5166
|
if (isPlainText) {
|
|
4958
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
5167
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `${textSizeClass} leading-relaxed break-words ${className}`, children: [
|
|
5168
|
+
displayContent,
|
|
5169
|
+
collapsible && shouldCollapse && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
5170
|
+
isCollapsed && "... ",
|
|
5171
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5172
|
+
CollapseToggle,
|
|
5173
|
+
{
|
|
5174
|
+
isCollapsed,
|
|
5175
|
+
onClick: toggleCollapsed,
|
|
5176
|
+
readMoreLabel,
|
|
5177
|
+
showLessLabel,
|
|
5178
|
+
isUser,
|
|
5179
|
+
isCompact
|
|
5180
|
+
}
|
|
5181
|
+
)
|
|
5182
|
+
] })
|
|
5183
|
+
] });
|
|
4959
5184
|
}
|
|
4960
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
|
|
4969
|
-
|
|
4970
|
-
|
|
4971
|
-
|
|
4972
|
-
|
|
4973
|
-
|
|
4974
|
-
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4982
|
-
|
|
4983
|
-
|
|
4984
|
-
|
|
4985
|
-
|
|
5185
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
|
|
5186
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5187
|
+
"div",
|
|
5188
|
+
{
|
|
5189
|
+
className: `
|
|
5190
|
+
prose ${proseClass} max-w-none break-words overflow-hidden ${textSizeClass}
|
|
5191
|
+
${isUser ? "prose-invert" : "dark:prose-invert"}
|
|
5192
|
+
`,
|
|
5193
|
+
style: {
|
|
5194
|
+
// Inherit colors from parent - fixes issues with external CSS variables
|
|
5195
|
+
"--tw-prose-body": "inherit",
|
|
5196
|
+
"--tw-prose-headings": "inherit",
|
|
5197
|
+
"--tw-prose-bold": "inherit",
|
|
5198
|
+
"--tw-prose-links": "inherit",
|
|
5199
|
+
color: "inherit"
|
|
5200
|
+
},
|
|
5201
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5202
|
+
ReactMarkdown__default.default,
|
|
5203
|
+
{
|
|
5204
|
+
remarkPlugins: [remarkGfm__default.default],
|
|
5205
|
+
components,
|
|
5206
|
+
children: displayContent
|
|
5207
|
+
}
|
|
5208
|
+
)
|
|
5209
|
+
}
|
|
5210
|
+
),
|
|
5211
|
+
collapsible && shouldCollapse && /* @__PURE__ */ jsxRuntime.jsx(
|
|
5212
|
+
CollapseToggle,
|
|
5213
|
+
{
|
|
5214
|
+
isCollapsed,
|
|
5215
|
+
onClick: toggleCollapsed,
|
|
5216
|
+
readMoreLabel,
|
|
5217
|
+
showLessLabel,
|
|
5218
|
+
isUser,
|
|
5219
|
+
isCompact
|
|
5220
|
+
}
|
|
5221
|
+
)
|
|
5222
|
+
] });
|
|
4986
5223
|
}, "MarkdownMessage");
|
|
4987
5224
|
|
|
4988
5225
|
Object.defineProperty(exports, "useLottie", {
|
|
@@ -5062,6 +5299,7 @@ exports.safeJsonStringify = safeJsonStringify;
|
|
|
5062
5299
|
exports.useAudioCache = useAudioCache;
|
|
5063
5300
|
exports.useAudioVisualization = useAudioVisualization;
|
|
5064
5301
|
exports.useBlobUrlCleanup = useBlobUrlCleanup;
|
|
5302
|
+
exports.useCollapsibleContent = useCollapsibleContent;
|
|
5065
5303
|
exports.useHybridAudio = useHybridAudio;
|
|
5066
5304
|
exports.useHybridAudioAnalysis = useHybridAudioAnalysis;
|
|
5067
5305
|
exports.useHybridAudioContext = useHybridAudioContext;
|