@djangocfg/ui-tools 2.1.94 → 2.1.96
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 +265 -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 +265 -30
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/components/markdown/MarkdownMessage.tsx +204 -22
- package/src/components/markdown/index.ts +9 -0
- package/src/components/markdown/useCollapsibleContent.ts +236 -0
package/dist/index.d.cts
CHANGED
|
@@ -1567,6 +1567,43 @@ interface MarkdownMessageProps {
|
|
|
1567
1567
|
isUser?: boolean;
|
|
1568
1568
|
/** Use compact size (text-xs instead of text-sm) */
|
|
1569
1569
|
isCompact?: boolean;
|
|
1570
|
+
/**
|
|
1571
|
+
* Enable collapsible "Read more..." functionality
|
|
1572
|
+
* When enabled, long content will be truncated with a toggle button
|
|
1573
|
+
* @default false
|
|
1574
|
+
*/
|
|
1575
|
+
collapsible?: boolean;
|
|
1576
|
+
/**
|
|
1577
|
+
* Maximum character length before showing "Read more..."
|
|
1578
|
+
* Only applies when collapsible is true
|
|
1579
|
+
* If both maxLength and maxLines are set, the stricter limit applies
|
|
1580
|
+
*/
|
|
1581
|
+
maxLength?: number;
|
|
1582
|
+
/**
|
|
1583
|
+
* Maximum number of lines before showing "Read more..."
|
|
1584
|
+
* Only applies when collapsible is true
|
|
1585
|
+
* If both maxLength and maxLines are set, the stricter limit applies
|
|
1586
|
+
*/
|
|
1587
|
+
maxLines?: number;
|
|
1588
|
+
/**
|
|
1589
|
+
* Custom "Read more" button text
|
|
1590
|
+
* @default "Read more..."
|
|
1591
|
+
*/
|
|
1592
|
+
readMoreLabel?: string;
|
|
1593
|
+
/**
|
|
1594
|
+
* Custom "Show less" button text
|
|
1595
|
+
* @default "Show less"
|
|
1596
|
+
*/
|
|
1597
|
+
showLessLabel?: string;
|
|
1598
|
+
/**
|
|
1599
|
+
* Start expanded (only applies when collapsible is true)
|
|
1600
|
+
* @default false
|
|
1601
|
+
*/
|
|
1602
|
+
defaultExpanded?: boolean;
|
|
1603
|
+
/**
|
|
1604
|
+
* Callback when collapsed state changes
|
|
1605
|
+
*/
|
|
1606
|
+
onCollapseChange?: (isCollapsed: boolean) => void;
|
|
1570
1607
|
}
|
|
1571
1608
|
/**
|
|
1572
1609
|
* MarkdownMessage - Renders markdown content with syntax highlighting and GFM support
|
|
@@ -1578,6 +1615,7 @@ interface MarkdownMessageProps {
|
|
|
1578
1615
|
* - Tables, lists, blockquotes
|
|
1579
1616
|
* - User/assistant styling modes
|
|
1580
1617
|
* - Plain text optimization (skips ReactMarkdown for simple text)
|
|
1618
|
+
* - Collapsible "Read more..." for long messages
|
|
1581
1619
|
*
|
|
1582
1620
|
* @example
|
|
1583
1621
|
* ```tsx
|
|
@@ -1585,8 +1623,72 @@ interface MarkdownMessageProps {
|
|
|
1585
1623
|
*
|
|
1586
1624
|
* // User message styling
|
|
1587
1625
|
* <MarkdownMessage content="Some content" isUser />
|
|
1626
|
+
*
|
|
1627
|
+
* // Collapsible long content (for chat apps)
|
|
1628
|
+
* <MarkdownMessage
|
|
1629
|
+
* content={longText}
|
|
1630
|
+
* collapsible
|
|
1631
|
+
* maxLength={300}
|
|
1632
|
+
* maxLines={5}
|
|
1633
|
+
* />
|
|
1588
1634
|
* ```
|
|
1589
1635
|
*/
|
|
1590
1636
|
declare const MarkdownMessage: React__default.FC<MarkdownMessageProps>;
|
|
1591
1637
|
|
|
1592
|
-
|
|
1638
|
+
interface UseCollapsibleContentOptions {
|
|
1639
|
+
/**
|
|
1640
|
+
* Maximum character length before collapsing
|
|
1641
|
+
* If both maxLength and maxLines are set, the stricter limit applies
|
|
1642
|
+
*/
|
|
1643
|
+
maxLength?: number;
|
|
1644
|
+
/**
|
|
1645
|
+
* Maximum number of lines before collapsing
|
|
1646
|
+
* If both maxLength and maxLines are set, the stricter limit applies
|
|
1647
|
+
*/
|
|
1648
|
+
maxLines?: number;
|
|
1649
|
+
/**
|
|
1650
|
+
* Start in expanded state (default: false - starts collapsed)
|
|
1651
|
+
*/
|
|
1652
|
+
defaultExpanded?: boolean;
|
|
1653
|
+
}
|
|
1654
|
+
interface UseCollapsibleContentResult {
|
|
1655
|
+
/** Whether content is currently collapsed */
|
|
1656
|
+
isCollapsed: boolean;
|
|
1657
|
+
/** Toggle between collapsed/expanded state */
|
|
1658
|
+
toggleCollapsed: () => void;
|
|
1659
|
+
/** Set collapsed state directly */
|
|
1660
|
+
setCollapsed: (collapsed: boolean) => void;
|
|
1661
|
+
/** Content to display (truncated if collapsed, full if expanded) */
|
|
1662
|
+
displayContent: string;
|
|
1663
|
+
/** Whether the content exceeds limits and should be collapsible */
|
|
1664
|
+
shouldCollapse: boolean;
|
|
1665
|
+
/** Original content length */
|
|
1666
|
+
originalLength: number;
|
|
1667
|
+
/** Original line count */
|
|
1668
|
+
originalLineCount: number;
|
|
1669
|
+
}
|
|
1670
|
+
/**
|
|
1671
|
+
* Hook for managing collapsible content with "Read more..." functionality
|
|
1672
|
+
*
|
|
1673
|
+
* @example
|
|
1674
|
+
* ```tsx
|
|
1675
|
+
* const { isCollapsed, toggleCollapsed, displayContent, shouldCollapse } = useCollapsibleContent(
|
|
1676
|
+
* longText,
|
|
1677
|
+
* { maxLength: 300, maxLines: 5 }
|
|
1678
|
+
* );
|
|
1679
|
+
*
|
|
1680
|
+
* return (
|
|
1681
|
+
* <div>
|
|
1682
|
+
* <Markdown content={displayContent} />
|
|
1683
|
+
* {shouldCollapse && (
|
|
1684
|
+
* <button onClick={toggleCollapsed}>
|
|
1685
|
+
* {isCollapsed ? 'Read more...' : 'Show less'}
|
|
1686
|
+
* </button>
|
|
1687
|
+
* )}
|
|
1688
|
+
* </div>
|
|
1689
|
+
* );
|
|
1690
|
+
* ```
|
|
1691
|
+
*/
|
|
1692
|
+
declare function useCollapsibleContent(content: string, options?: UseCollapsibleContentOptions): UseCollapsibleContentResult;
|
|
1693
|
+
|
|
1694
|
+
export { ArrayFieldItemTemplate, ArrayFieldTemplate, type AspectRatioValue, type AudioLevels, AudioReactiveCover, type AudioReactiveCoverProps, BaseInputTemplate, type BlobSource, COLOR_SCHEMES, COLOR_SCHEME_INFO, CheckboxWidget, ColorWidget, type CreateVideoErrorFallbackOptions, type DASHSource, type DataUrlSource, EFFECT_ANIMATIONS, type EffectColorScheme, type EffectColors, type EffectConfig$1 as EffectConfig, type EffectIntensity, type EffectLayer, type EffectVariant, type EqualizerOptions, type ErrorFallbackProps, ErrorListTemplate, FieldTemplate, GlowEffect, type GlowEffectData, type HLSSource, type HybridAudioContextValue, type HybridAudioControls, HybridAudioPlayer, type HybridAudioPlayerProps, HybridAudioProvider, type HybridAudioProviderProps, type HybridAudioState, HybridSimplePlayer, type HybridSimplePlayerProps, HybridWaveform, type HybridWaveformProps, type HybridWebAudioAPI, INTENSITY_CONFIG, INTENSITY_INFO, type ImageFile, ImageViewer, type ImageViewerProps, JsonSchemaForm, type JsonSchemaFormProps, JsonTreeComponent as JsonTree, type JsonTreeConfig, type LottieDirection, LottiePlayer, type LottiePlayerProps, type LottieSize, type LottieSpeed, MarkdownMessage, type MarkdownMessageProps, Mermaid, MeshEffect, NativeProvider, NumberWidget, ObjectFieldTemplate, Playground as OpenapiViewer, OrbsEffect, type PlayerMode, type PlaygroundConfig, type PlaygroundProps, PrettyCode, type ResolveFileSourceOptions, type SchemaSource, SelectWidget, type SimpleStreamSource, SliderWidget, SpotlightEffect, StreamProvider, type StreamSource, SwitchWidget, TextWidget, type UrlSource, type UseAudioVisualizationReturn, type UseCollapsibleContentOptions, type UseCollapsibleContentResult, type UseHybridAudioOptions, type UseHybridAudioReturn, type UseLottieOptions, type UseLottieReturn, type UseVisualizationReturn, VARIANT_INFO, VideoControls, VideoErrorFallback, type VideoErrorFallbackProps, VideoPlayer, type VideoPlayerContextValue, type VideoPlayerProps, VideoPlayerProvider, type VideoPlayerProviderProps, type VideoPlayerRef, type VideoSourceUnion, VidstackProvider, type VimeoSource, type VisualizationColorScheme, type VisualizationIntensity, VisualizationProvider, type VisualizationProviderProps, type VisualizationSettings, type VisualizationVariant, type YouTubeSource, calculateGlowLayers, calculateMeshGradients, calculateOrbs, calculateSpotlight, createVideoErrorFallback, formatTime, generateContentKey, getColors, getEffectConfig, getRequiredFields, hasRequiredFields, isSimpleStreamSource, mergeDefaults, normalizeFormData, prepareEffectColors, resolveFileSource, resolvePlayerMode, resolveStreamSource, safeJsonParse, safeJsonStringify, useAudioCache, useAudioVisualization, useBlobUrlCleanup, useCollapsibleContent, useHybridAudio, useHybridAudioAnalysis, useHybridAudioContext, useHybridAudioControls, useHybridAudioLevels, useHybridAudioState, useHybridWebAudio, useImageCache, useLottie, useMediaCacheStore, useVideoCache, useVideoPlayerContext, useVideoPlayerSettings, useVisualization, validateRequiredFields, validateSchema };
|
package/dist/index.d.ts
CHANGED
|
@@ -1567,6 +1567,43 @@ interface MarkdownMessageProps {
|
|
|
1567
1567
|
isUser?: boolean;
|
|
1568
1568
|
/** Use compact size (text-xs instead of text-sm) */
|
|
1569
1569
|
isCompact?: boolean;
|
|
1570
|
+
/**
|
|
1571
|
+
* Enable collapsible "Read more..." functionality
|
|
1572
|
+
* When enabled, long content will be truncated with a toggle button
|
|
1573
|
+
* @default false
|
|
1574
|
+
*/
|
|
1575
|
+
collapsible?: boolean;
|
|
1576
|
+
/**
|
|
1577
|
+
* Maximum character length before showing "Read more..."
|
|
1578
|
+
* Only applies when collapsible is true
|
|
1579
|
+
* If both maxLength and maxLines are set, the stricter limit applies
|
|
1580
|
+
*/
|
|
1581
|
+
maxLength?: number;
|
|
1582
|
+
/**
|
|
1583
|
+
* Maximum number of lines before showing "Read more..."
|
|
1584
|
+
* Only applies when collapsible is true
|
|
1585
|
+
* If both maxLength and maxLines are set, the stricter limit applies
|
|
1586
|
+
*/
|
|
1587
|
+
maxLines?: number;
|
|
1588
|
+
/**
|
|
1589
|
+
* Custom "Read more" button text
|
|
1590
|
+
* @default "Read more..."
|
|
1591
|
+
*/
|
|
1592
|
+
readMoreLabel?: string;
|
|
1593
|
+
/**
|
|
1594
|
+
* Custom "Show less" button text
|
|
1595
|
+
* @default "Show less"
|
|
1596
|
+
*/
|
|
1597
|
+
showLessLabel?: string;
|
|
1598
|
+
/**
|
|
1599
|
+
* Start expanded (only applies when collapsible is true)
|
|
1600
|
+
* @default false
|
|
1601
|
+
*/
|
|
1602
|
+
defaultExpanded?: boolean;
|
|
1603
|
+
/**
|
|
1604
|
+
* Callback when collapsed state changes
|
|
1605
|
+
*/
|
|
1606
|
+
onCollapseChange?: (isCollapsed: boolean) => void;
|
|
1570
1607
|
}
|
|
1571
1608
|
/**
|
|
1572
1609
|
* MarkdownMessage - Renders markdown content with syntax highlighting and GFM support
|
|
@@ -1578,6 +1615,7 @@ interface MarkdownMessageProps {
|
|
|
1578
1615
|
* - Tables, lists, blockquotes
|
|
1579
1616
|
* - User/assistant styling modes
|
|
1580
1617
|
* - Plain text optimization (skips ReactMarkdown for simple text)
|
|
1618
|
+
* - Collapsible "Read more..." for long messages
|
|
1581
1619
|
*
|
|
1582
1620
|
* @example
|
|
1583
1621
|
* ```tsx
|
|
@@ -1585,8 +1623,72 @@ interface MarkdownMessageProps {
|
|
|
1585
1623
|
*
|
|
1586
1624
|
* // User message styling
|
|
1587
1625
|
* <MarkdownMessage content="Some content" isUser />
|
|
1626
|
+
*
|
|
1627
|
+
* // Collapsible long content (for chat apps)
|
|
1628
|
+
* <MarkdownMessage
|
|
1629
|
+
* content={longText}
|
|
1630
|
+
* collapsible
|
|
1631
|
+
* maxLength={300}
|
|
1632
|
+
* maxLines={5}
|
|
1633
|
+
* />
|
|
1588
1634
|
* ```
|
|
1589
1635
|
*/
|
|
1590
1636
|
declare const MarkdownMessage: React__default.FC<MarkdownMessageProps>;
|
|
1591
1637
|
|
|
1592
|
-
|
|
1638
|
+
interface UseCollapsibleContentOptions {
|
|
1639
|
+
/**
|
|
1640
|
+
* Maximum character length before collapsing
|
|
1641
|
+
* If both maxLength and maxLines are set, the stricter limit applies
|
|
1642
|
+
*/
|
|
1643
|
+
maxLength?: number;
|
|
1644
|
+
/**
|
|
1645
|
+
* Maximum number of lines before collapsing
|
|
1646
|
+
* If both maxLength and maxLines are set, the stricter limit applies
|
|
1647
|
+
*/
|
|
1648
|
+
maxLines?: number;
|
|
1649
|
+
/**
|
|
1650
|
+
* Start in expanded state (default: false - starts collapsed)
|
|
1651
|
+
*/
|
|
1652
|
+
defaultExpanded?: boolean;
|
|
1653
|
+
}
|
|
1654
|
+
interface UseCollapsibleContentResult {
|
|
1655
|
+
/** Whether content is currently collapsed */
|
|
1656
|
+
isCollapsed: boolean;
|
|
1657
|
+
/** Toggle between collapsed/expanded state */
|
|
1658
|
+
toggleCollapsed: () => void;
|
|
1659
|
+
/** Set collapsed state directly */
|
|
1660
|
+
setCollapsed: (collapsed: boolean) => void;
|
|
1661
|
+
/** Content to display (truncated if collapsed, full if expanded) */
|
|
1662
|
+
displayContent: string;
|
|
1663
|
+
/** Whether the content exceeds limits and should be collapsible */
|
|
1664
|
+
shouldCollapse: boolean;
|
|
1665
|
+
/** Original content length */
|
|
1666
|
+
originalLength: number;
|
|
1667
|
+
/** Original line count */
|
|
1668
|
+
originalLineCount: number;
|
|
1669
|
+
}
|
|
1670
|
+
/**
|
|
1671
|
+
* Hook for managing collapsible content with "Read more..." functionality
|
|
1672
|
+
*
|
|
1673
|
+
* @example
|
|
1674
|
+
* ```tsx
|
|
1675
|
+
* const { isCollapsed, toggleCollapsed, displayContent, shouldCollapse } = useCollapsibleContent(
|
|
1676
|
+
* longText,
|
|
1677
|
+
* { maxLength: 300, maxLines: 5 }
|
|
1678
|
+
* );
|
|
1679
|
+
*
|
|
1680
|
+
* return (
|
|
1681
|
+
* <div>
|
|
1682
|
+
* <Markdown content={displayContent} />
|
|
1683
|
+
* {shouldCollapse && (
|
|
1684
|
+
* <button onClick={toggleCollapsed}>
|
|
1685
|
+
* {isCollapsed ? 'Read more...' : 'Show less'}
|
|
1686
|
+
* </button>
|
|
1687
|
+
* )}
|
|
1688
|
+
* </div>
|
|
1689
|
+
* );
|
|
1690
|
+
* ```
|
|
1691
|
+
*/
|
|
1692
|
+
declare function useCollapsibleContent(content: string, options?: UseCollapsibleContentOptions): UseCollapsibleContentResult;
|
|
1693
|
+
|
|
1694
|
+
export { ArrayFieldItemTemplate, ArrayFieldTemplate, type AspectRatioValue, type AudioLevels, AudioReactiveCover, type AudioReactiveCoverProps, BaseInputTemplate, type BlobSource, COLOR_SCHEMES, COLOR_SCHEME_INFO, CheckboxWidget, ColorWidget, type CreateVideoErrorFallbackOptions, type DASHSource, type DataUrlSource, EFFECT_ANIMATIONS, type EffectColorScheme, type EffectColors, type EffectConfig$1 as EffectConfig, type EffectIntensity, type EffectLayer, type EffectVariant, type EqualizerOptions, type ErrorFallbackProps, ErrorListTemplate, FieldTemplate, GlowEffect, type GlowEffectData, type HLSSource, type HybridAudioContextValue, type HybridAudioControls, HybridAudioPlayer, type HybridAudioPlayerProps, HybridAudioProvider, type HybridAudioProviderProps, type HybridAudioState, HybridSimplePlayer, type HybridSimplePlayerProps, HybridWaveform, type HybridWaveformProps, type HybridWebAudioAPI, INTENSITY_CONFIG, INTENSITY_INFO, type ImageFile, ImageViewer, type ImageViewerProps, JsonSchemaForm, type JsonSchemaFormProps, JsonTreeComponent as JsonTree, type JsonTreeConfig, type LottieDirection, LottiePlayer, type LottiePlayerProps, type LottieSize, type LottieSpeed, MarkdownMessage, type MarkdownMessageProps, Mermaid, MeshEffect, NativeProvider, NumberWidget, ObjectFieldTemplate, Playground as OpenapiViewer, OrbsEffect, type PlayerMode, type PlaygroundConfig, type PlaygroundProps, PrettyCode, type ResolveFileSourceOptions, type SchemaSource, SelectWidget, type SimpleStreamSource, SliderWidget, SpotlightEffect, StreamProvider, type StreamSource, SwitchWidget, TextWidget, type UrlSource, type UseAudioVisualizationReturn, type UseCollapsibleContentOptions, type UseCollapsibleContentResult, type UseHybridAudioOptions, type UseHybridAudioReturn, type UseLottieOptions, type UseLottieReturn, type UseVisualizationReturn, VARIANT_INFO, VideoControls, VideoErrorFallback, type VideoErrorFallbackProps, VideoPlayer, type VideoPlayerContextValue, type VideoPlayerProps, VideoPlayerProvider, type VideoPlayerProviderProps, type VideoPlayerRef, type VideoSourceUnion, VidstackProvider, type VimeoSource, type VisualizationColorScheme, type VisualizationIntensity, VisualizationProvider, type VisualizationProviderProps, type VisualizationSettings, type VisualizationVariant, type YouTubeSource, calculateGlowLayers, calculateMeshGradients, calculateOrbs, calculateSpotlight, createVideoErrorFallback, formatTime, generateContentKey, getColors, getEffectConfig, getRequiredFields, hasRequiredFields, isSimpleStreamSource, mergeDefaults, normalizeFormData, prepareEffectColors, resolveFileSource, resolvePlayerMode, resolveStreamSource, safeJsonParse, safeJsonStringify, useAudioCache, useAudioVisualization, useBlobUrlCleanup, useCollapsibleContent, useHybridAudio, useHybridAudioAnalysis, useHybridAudioContext, useHybridAudioControls, useHybridAudioLevels, useHybridAudioState, useHybridWebAudio, useImageCache, useLottie, useMediaCacheStore, useVideoCache, useVideoPlayerContext, useVideoPlayerSettings, useVisualization, validateRequiredFields, validateSchema };
|
package/dist/index.mjs
CHANGED
|
@@ -4753,6 +4753,121 @@ function ImageViewer({ file, content, src: directSrc, inDialog = false }) {
|
|
|
4753
4753
|
);
|
|
4754
4754
|
}
|
|
4755
4755
|
__name(ImageViewer, "ImageViewer");
|
|
4756
|
+
function smartTruncate(content, maxLength) {
|
|
4757
|
+
if (content.length <= maxLength) {
|
|
4758
|
+
return content;
|
|
4759
|
+
}
|
|
4760
|
+
let breakPoint = maxLength;
|
|
4761
|
+
while (breakPoint > maxLength - 50 && breakPoint > 0) {
|
|
4762
|
+
const char = content[breakPoint];
|
|
4763
|
+
if (char === " " || char === "\n" || char === " ") {
|
|
4764
|
+
break;
|
|
4765
|
+
}
|
|
4766
|
+
breakPoint--;
|
|
4767
|
+
}
|
|
4768
|
+
if (breakPoint <= maxLength - 50) {
|
|
4769
|
+
breakPoint = maxLength;
|
|
4770
|
+
}
|
|
4771
|
+
let truncated = content.slice(0, breakPoint).trimEnd();
|
|
4772
|
+
truncated = fixUnclosedMarkdown(truncated);
|
|
4773
|
+
return truncated;
|
|
4774
|
+
}
|
|
4775
|
+
__name(smartTruncate, "smartTruncate");
|
|
4776
|
+
function truncateByLines(content, maxLines) {
|
|
4777
|
+
const lines = content.split("\n");
|
|
4778
|
+
if (lines.length <= maxLines) {
|
|
4779
|
+
return content;
|
|
4780
|
+
}
|
|
4781
|
+
let truncated = lines.slice(0, maxLines).join("\n").trimEnd();
|
|
4782
|
+
truncated = fixUnclosedMarkdown(truncated);
|
|
4783
|
+
return truncated;
|
|
4784
|
+
}
|
|
4785
|
+
__name(truncateByLines, "truncateByLines");
|
|
4786
|
+
function fixUnclosedMarkdown(content) {
|
|
4787
|
+
let result = content;
|
|
4788
|
+
const countOccurrences = /* @__PURE__ */ __name((str, marker) => {
|
|
4789
|
+
const escaped = marker.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4790
|
+
const matches = str.match(new RegExp(escaped, "g"));
|
|
4791
|
+
return matches ? matches.length : 0;
|
|
4792
|
+
}, "countOccurrences");
|
|
4793
|
+
const boldCount = countOccurrences(result, "**");
|
|
4794
|
+
if (boldCount % 2 !== 0) {
|
|
4795
|
+
result += "**";
|
|
4796
|
+
}
|
|
4797
|
+
const withoutBold = result.replace(/\*\*/g, "");
|
|
4798
|
+
const italicCount = countOccurrences(withoutBold, "*");
|
|
4799
|
+
if (italicCount % 2 !== 0) {
|
|
4800
|
+
result += "*";
|
|
4801
|
+
}
|
|
4802
|
+
const codeCount = countOccurrences(result, "`");
|
|
4803
|
+
const tripleCount = countOccurrences(result, "```");
|
|
4804
|
+
const singleCodeCount = codeCount - tripleCount * 3;
|
|
4805
|
+
if (singleCodeCount % 2 !== 0) {
|
|
4806
|
+
result += "`";
|
|
4807
|
+
}
|
|
4808
|
+
if (tripleCount % 2 !== 0) {
|
|
4809
|
+
result += "\n```";
|
|
4810
|
+
}
|
|
4811
|
+
const strikeCount = countOccurrences(result, "~~");
|
|
4812
|
+
if (strikeCount % 2 !== 0) {
|
|
4813
|
+
result += "~~";
|
|
4814
|
+
}
|
|
4815
|
+
const underlineBoldCount = countOccurrences(result, "__");
|
|
4816
|
+
if (underlineBoldCount % 2 !== 0) {
|
|
4817
|
+
result += "__";
|
|
4818
|
+
}
|
|
4819
|
+
const withoutUnderlineBold = result.replace(/__/g, "");
|
|
4820
|
+
const underlineItalicCount = countOccurrences(withoutUnderlineBold, "_");
|
|
4821
|
+
if (underlineItalicCount % 2 !== 0) {
|
|
4822
|
+
result += "_";
|
|
4823
|
+
}
|
|
4824
|
+
return result;
|
|
4825
|
+
}
|
|
4826
|
+
__name(fixUnclosedMarkdown, "fixUnclosedMarkdown");
|
|
4827
|
+
function useCollapsibleContent(content, options = {}) {
|
|
4828
|
+
const { maxLength, maxLines, defaultExpanded = false } = options;
|
|
4829
|
+
const [isCollapsed, setIsCollapsed] = useState(!defaultExpanded);
|
|
4830
|
+
const originalLength = content.length;
|
|
4831
|
+
const originalLineCount = content.split("\n").length;
|
|
4832
|
+
const { shouldCollapse, truncatedContent } = useMemo(() => {
|
|
4833
|
+
if (maxLength === void 0 && maxLines === void 0) {
|
|
4834
|
+
return { shouldCollapse: false, truncatedContent: content };
|
|
4835
|
+
}
|
|
4836
|
+
let needsCollapse = false;
|
|
4837
|
+
let result = content;
|
|
4838
|
+
if (maxLines !== void 0 && originalLineCount > maxLines) {
|
|
4839
|
+
needsCollapse = true;
|
|
4840
|
+
result = truncateByLines(result, maxLines);
|
|
4841
|
+
}
|
|
4842
|
+
if (maxLength !== void 0 && result.length > maxLength) {
|
|
4843
|
+
needsCollapse = true;
|
|
4844
|
+
result = smartTruncate(result, maxLength);
|
|
4845
|
+
}
|
|
4846
|
+
return { shouldCollapse: needsCollapse, truncatedContent: result };
|
|
4847
|
+
}, [content, maxLength, maxLines, originalLineCount]);
|
|
4848
|
+
const displayContent = useMemo(() => {
|
|
4849
|
+
if (!shouldCollapse || !isCollapsed) {
|
|
4850
|
+
return content;
|
|
4851
|
+
}
|
|
4852
|
+
return truncatedContent;
|
|
4853
|
+
}, [content, truncatedContent, shouldCollapse, isCollapsed]);
|
|
4854
|
+
const toggleCollapsed = useCallback(() => {
|
|
4855
|
+
setIsCollapsed((prev) => !prev);
|
|
4856
|
+
}, []);
|
|
4857
|
+
const setCollapsed = useCallback((collapsed) => {
|
|
4858
|
+
setIsCollapsed(collapsed);
|
|
4859
|
+
}, []);
|
|
4860
|
+
return {
|
|
4861
|
+
isCollapsed,
|
|
4862
|
+
toggleCollapsed,
|
|
4863
|
+
setCollapsed,
|
|
4864
|
+
displayContent,
|
|
4865
|
+
shouldCollapse,
|
|
4866
|
+
originalLength,
|
|
4867
|
+
originalLineCount
|
|
4868
|
+
};
|
|
4869
|
+
}
|
|
4870
|
+
__name(useCollapsibleContent, "useCollapsibleContent");
|
|
4756
4871
|
var extractTextFromChildren = /* @__PURE__ */ __name((children) => {
|
|
4757
4872
|
if (typeof children === "string") {
|
|
4758
4873
|
return children;
|
|
@@ -4937,48 +5052,168 @@ var hasMarkdownSyntax = /* @__PURE__ */ __name((text) => {
|
|
|
4937
5052
|
];
|
|
4938
5053
|
return markdownPatterns.some((pattern) => pattern.test(text));
|
|
4939
5054
|
}, "hasMarkdownSyntax");
|
|
5055
|
+
var CollapseToggle = /* @__PURE__ */ __name(({
|
|
5056
|
+
isCollapsed,
|
|
5057
|
+
onClick,
|
|
5058
|
+
readMoreLabel,
|
|
5059
|
+
showLessLabel,
|
|
5060
|
+
isUser,
|
|
5061
|
+
isCompact
|
|
5062
|
+
}) => {
|
|
5063
|
+
const textSize = isCompact ? "text-xs" : "text-sm";
|
|
5064
|
+
return /* @__PURE__ */ jsx(
|
|
5065
|
+
"button",
|
|
5066
|
+
{
|
|
5067
|
+
type: "button",
|
|
5068
|
+
onClick,
|
|
5069
|
+
className: `
|
|
5070
|
+
${textSize} font-medium cursor-pointer
|
|
5071
|
+
transition-colors duration-200
|
|
5072
|
+
${isUser ? "text-white/80 hover:text-white" : "text-primary hover:text-primary/80"}
|
|
5073
|
+
inline-flex items-center gap-1
|
|
5074
|
+
mt-1
|
|
5075
|
+
`,
|
|
5076
|
+
children: isCollapsed ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5077
|
+
readMoreLabel,
|
|
5078
|
+
/* @__PURE__ */ jsx(
|
|
5079
|
+
"svg",
|
|
5080
|
+
{
|
|
5081
|
+
className: "w-3 h-3",
|
|
5082
|
+
fill: "none",
|
|
5083
|
+
stroke: "currentColor",
|
|
5084
|
+
viewBox: "0 0 24 24",
|
|
5085
|
+
children: /* @__PURE__ */ jsx(
|
|
5086
|
+
"path",
|
|
5087
|
+
{
|
|
5088
|
+
strokeLinecap: "round",
|
|
5089
|
+
strokeLinejoin: "round",
|
|
5090
|
+
strokeWidth: 2,
|
|
5091
|
+
d: "M19 9l-7 7-7-7"
|
|
5092
|
+
}
|
|
5093
|
+
)
|
|
5094
|
+
}
|
|
5095
|
+
)
|
|
5096
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5097
|
+
showLessLabel,
|
|
5098
|
+
/* @__PURE__ */ jsx(
|
|
5099
|
+
"svg",
|
|
5100
|
+
{
|
|
5101
|
+
className: "w-3 h-3",
|
|
5102
|
+
fill: "none",
|
|
5103
|
+
stroke: "currentColor",
|
|
5104
|
+
viewBox: "0 0 24 24",
|
|
5105
|
+
children: /* @__PURE__ */ jsx(
|
|
5106
|
+
"path",
|
|
5107
|
+
{
|
|
5108
|
+
strokeLinecap: "round",
|
|
5109
|
+
strokeLinejoin: "round",
|
|
5110
|
+
strokeWidth: 2,
|
|
5111
|
+
d: "M5 15l7-7 7 7"
|
|
5112
|
+
}
|
|
5113
|
+
)
|
|
5114
|
+
}
|
|
5115
|
+
)
|
|
5116
|
+
] })
|
|
5117
|
+
}
|
|
5118
|
+
);
|
|
5119
|
+
}, "CollapseToggle");
|
|
4940
5120
|
var MarkdownMessage = /* @__PURE__ */ __name(({
|
|
4941
5121
|
content,
|
|
4942
5122
|
className = "",
|
|
4943
5123
|
isUser = false,
|
|
4944
|
-
isCompact = false
|
|
5124
|
+
isCompact = false,
|
|
5125
|
+
collapsible = false,
|
|
5126
|
+
maxLength,
|
|
5127
|
+
maxLines,
|
|
5128
|
+
readMoreLabel = "Read more...",
|
|
5129
|
+
showLessLabel = "Show less",
|
|
5130
|
+
defaultExpanded = false,
|
|
5131
|
+
onCollapseChange
|
|
4945
5132
|
}) => {
|
|
4946
5133
|
const trimmedContent = content.trim();
|
|
5134
|
+
const collapsibleOptions = React17.useMemo(() => {
|
|
5135
|
+
if (!collapsible) return {};
|
|
5136
|
+
const effectiveMaxLength = maxLength ?? 1e3;
|
|
5137
|
+
const effectiveMaxLines = maxLines ?? 10;
|
|
5138
|
+
return { maxLength: effectiveMaxLength, maxLines: effectiveMaxLines, defaultExpanded };
|
|
5139
|
+
}, [collapsible, maxLength, maxLines, defaultExpanded]);
|
|
5140
|
+
const {
|
|
5141
|
+
isCollapsed,
|
|
5142
|
+
toggleCollapsed,
|
|
5143
|
+
displayContent,
|
|
5144
|
+
shouldCollapse
|
|
5145
|
+
} = useCollapsibleContent(
|
|
5146
|
+
trimmedContent,
|
|
5147
|
+
collapsible ? collapsibleOptions : {}
|
|
5148
|
+
);
|
|
5149
|
+
React17.useEffect(() => {
|
|
5150
|
+
if (collapsible && shouldCollapse && onCollapseChange) {
|
|
5151
|
+
onCollapseChange(isCollapsed);
|
|
5152
|
+
}
|
|
5153
|
+
}, [isCollapsed, collapsible, shouldCollapse, onCollapseChange]);
|
|
4947
5154
|
const components = React17.useMemo(() => createMarkdownComponents(isUser, isCompact), [isUser, isCompact]);
|
|
4948
5155
|
const textSizeClass = isCompact ? "text-xs" : "text-sm";
|
|
4949
5156
|
const proseClass = isCompact ? "prose-xs" : "prose-sm";
|
|
4950
|
-
const isPlainText = !hasMarkdownSyntax(
|
|
5157
|
+
const isPlainText = !hasMarkdownSyntax(displayContent);
|
|
4951
5158
|
if (isPlainText) {
|
|
4952
|
-
return /* @__PURE__ */
|
|
5159
|
+
return /* @__PURE__ */ jsxs("span", { className: `${textSizeClass} leading-relaxed break-words ${className}`, children: [
|
|
5160
|
+
displayContent,
|
|
5161
|
+
collapsible && shouldCollapse && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5162
|
+
isCollapsed && "... ",
|
|
5163
|
+
/* @__PURE__ */ jsx(
|
|
5164
|
+
CollapseToggle,
|
|
5165
|
+
{
|
|
5166
|
+
isCollapsed,
|
|
5167
|
+
onClick: toggleCollapsed,
|
|
5168
|
+
readMoreLabel,
|
|
5169
|
+
showLessLabel,
|
|
5170
|
+
isUser,
|
|
5171
|
+
isCompact
|
|
5172
|
+
}
|
|
5173
|
+
)
|
|
5174
|
+
] })
|
|
5175
|
+
] });
|
|
4953
5176
|
}
|
|
4954
|
-
return /* @__PURE__ */
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
|
|
4965
|
-
|
|
4966
|
-
|
|
4967
|
-
|
|
4968
|
-
|
|
4969
|
-
|
|
4970
|
-
|
|
4971
|
-
|
|
4972
|
-
|
|
4973
|
-
|
|
4974
|
-
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
5177
|
+
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
5178
|
+
/* @__PURE__ */ jsx(
|
|
5179
|
+
"div",
|
|
5180
|
+
{
|
|
5181
|
+
className: `
|
|
5182
|
+
prose ${proseClass} max-w-none break-words overflow-hidden ${textSizeClass}
|
|
5183
|
+
${isUser ? "prose-invert" : "dark:prose-invert"}
|
|
5184
|
+
`,
|
|
5185
|
+
style: {
|
|
5186
|
+
// Inherit colors from parent - fixes issues with external CSS variables
|
|
5187
|
+
"--tw-prose-body": "inherit",
|
|
5188
|
+
"--tw-prose-headings": "inherit",
|
|
5189
|
+
"--tw-prose-bold": "inherit",
|
|
5190
|
+
"--tw-prose-links": "inherit",
|
|
5191
|
+
color: "inherit"
|
|
5192
|
+
},
|
|
5193
|
+
children: /* @__PURE__ */ jsx(
|
|
5194
|
+
ReactMarkdown,
|
|
5195
|
+
{
|
|
5196
|
+
remarkPlugins: [remarkGfm],
|
|
5197
|
+
components,
|
|
5198
|
+
children: displayContent
|
|
5199
|
+
}
|
|
5200
|
+
)
|
|
5201
|
+
}
|
|
5202
|
+
),
|
|
5203
|
+
collapsible && shouldCollapse && /* @__PURE__ */ jsx(
|
|
5204
|
+
CollapseToggle,
|
|
5205
|
+
{
|
|
5206
|
+
isCollapsed,
|
|
5207
|
+
onClick: toggleCollapsed,
|
|
5208
|
+
readMoreLabel,
|
|
5209
|
+
showLessLabel,
|
|
5210
|
+
isUser,
|
|
5211
|
+
isCompact
|
|
5212
|
+
}
|
|
5213
|
+
)
|
|
5214
|
+
] });
|
|
4980
5215
|
}, "MarkdownMessage");
|
|
4981
5216
|
|
|
4982
|
-
export { ArrayFieldItemTemplate, ArrayFieldTemplate, AudioReactiveCover, BaseInputTemplate, COLOR_SCHEMES2 as COLOR_SCHEMES, COLOR_SCHEME_INFO, CheckboxWidget, ColorWidget, EFFECT_ANIMATIONS, ErrorListTemplate, FieldTemplate, GlowEffect, HybridAudioPlayer, HybridAudioProvider, HybridSimplePlayer, HybridWaveform, INTENSITY_CONFIG, INTENSITY_INFO, ImageViewer, JsonSchemaForm, LottiePlayer, MarkdownMessage, Mermaid_default as Mermaid, MeshEffect, NativeProvider, NumberWidget, ObjectFieldTemplate, OpenapiViewer_default as OpenapiViewer, OrbsEffect, SelectWidget, SliderWidget, SpotlightEffect, StreamProvider, SwitchWidget, TextWidget, VARIANT_INFO, VideoControls, VideoErrorFallback, VideoPlayer, VideoPlayerProvider, VidstackProvider, VisualizationProvider, calculateGlowLayers, calculateMeshGradients, calculateOrbs, calculateSpotlight, createVideoErrorFallback, formatTime, generateContentKey, getColors, getEffectConfig, getRequiredFields, hasRequiredFields, isSimpleStreamSource, mergeDefaults, normalizeFormData, prepareEffectColors, resolveFileSource, resolvePlayerMode, resolveStreamSource, safeJsonParse, safeJsonStringify, useAudioCache, useAudioVisualization, useBlobUrlCleanup, useHybridAudio, useHybridAudioAnalysis, useHybridAudioContext, useHybridAudioControls, useHybridAudioLevels, useHybridAudioState, useHybridWebAudio, useImageCache, useMediaCacheStore, useVideoCache, useVideoPlayerContext, useVideoPlayerSettings, useVisualization, validateRequiredFields, validateSchema };
|
|
5217
|
+
export { ArrayFieldItemTemplate, ArrayFieldTemplate, AudioReactiveCover, BaseInputTemplate, COLOR_SCHEMES2 as COLOR_SCHEMES, COLOR_SCHEME_INFO, CheckboxWidget, ColorWidget, EFFECT_ANIMATIONS, ErrorListTemplate, FieldTemplate, GlowEffect, HybridAudioPlayer, HybridAudioProvider, HybridSimplePlayer, HybridWaveform, INTENSITY_CONFIG, INTENSITY_INFO, ImageViewer, JsonSchemaForm, LottiePlayer, MarkdownMessage, Mermaid_default as Mermaid, MeshEffect, NativeProvider, NumberWidget, ObjectFieldTemplate, OpenapiViewer_default as OpenapiViewer, OrbsEffect, SelectWidget, SliderWidget, SpotlightEffect, StreamProvider, SwitchWidget, TextWidget, VARIANT_INFO, VideoControls, VideoErrorFallback, VideoPlayer, VideoPlayerProvider, VidstackProvider, VisualizationProvider, calculateGlowLayers, calculateMeshGradients, calculateOrbs, calculateSpotlight, createVideoErrorFallback, formatTime, generateContentKey, getColors, getEffectConfig, getRequiredFields, hasRequiredFields, isSimpleStreamSource, mergeDefaults, normalizeFormData, prepareEffectColors, resolveFileSource, resolvePlayerMode, resolveStreamSource, safeJsonParse, safeJsonStringify, useAudioCache, useAudioVisualization, useBlobUrlCleanup, useCollapsibleContent, useHybridAudio, useHybridAudioAnalysis, useHybridAudioContext, useHybridAudioControls, useHybridAudioLevels, useHybridAudioState, useHybridWebAudio, useImageCache, useMediaCacheStore, useVideoCache, useVideoPlayerContext, useVideoPlayerSettings, useVisualization, validateRequiredFields, validateSchema };
|
|
4983
5218
|
//# sourceMappingURL=index.mjs.map
|
|
4984
5219
|
//# sourceMappingURL=index.mjs.map
|