From 5d211e8848bd42ada589f08d450e8586bc20b94e Mon Sep 17 00:00:00 2001 From: Nate Kelley Date: Mon, 10 Mar 2025 12:30:26 -0600 Subject: [PATCH] markdown update --- .../AppMarkdown/AppMarkdown.stories.tsx | 47 +++++++++-- .../AppMarkdown/AppMarkdownCommon.tsx | 82 ++++++------------- .../ReasoningMessage_Text.tsx | 4 +- 3 files changed, 69 insertions(+), 64 deletions(-) diff --git a/web/src/components/ui/typography/AppMarkdown/AppMarkdown.stories.tsx b/web/src/components/ui/typography/AppMarkdown/AppMarkdown.stories.tsx index 5dc5f723e..940381328 100644 --- a/web/src/components/ui/typography/AppMarkdown/AppMarkdown.stories.tsx +++ b/web/src/components/ui/typography/AppMarkdown/AppMarkdown.stories.tsx @@ -1,5 +1,9 @@ import type { Meta, StoryObj } from '@storybook/react'; import { AppMarkdown } from './AppMarkdown'; +import { Button } from '@/components/ui/buttons'; +import { useState } from 'react'; +import { Checkbox } from '../../checkbox'; +import { Switch } from '../../switch/Switch'; const meta: Meta = { title: 'UI/Typography/AppMarkdown', @@ -215,9 +219,42 @@ export const WithCustomClass: Story = { } }; -export const WithLoader: Story = { - args: { - markdown: '# Loading Example\n\nThis example shows the loader state.', - showLoader: true - } +const randomMarkdownContent = [ + '# New Section\n\nThis is a new section with some content.', + '## Subheading\n\nHere is a paragraph with **bold** and *italic* text.', + '### Smaller Heading\n\n- List item 1\n- List item 2\n- List item 3', + '#### Tiny Heading\n\n> This is a blockquote with some important information.', + '##### Micro Heading\n\n1. Numbered item 1\n2. Numbered item 2', + '###### Nano Heading\n\n`code example` and more text here.', + '## Table Example\n\n| Header 1 | Header 2 |\n|----------|----------|\n| Cell 1 | Cell 2 |', + '### Mixed Content\n\nHere is some text with [a link](https://example.com) and `inline code`.' +]; + +const InteractiveMarkdown = () => { + const [markdown, setMarkdown] = useState( + '# Interactive Markdown\n\nClick the button to add more content!' + ); + const [stripFormatting, setStripFormatting] = useState(false); + + const addRandomContent = () => { + const randomContent = + randomMarkdownContent[Math.floor(Math.random() * randomMarkdownContent.length)]; + setMarkdown((prev) => `${prev}\n\n${randomContent}`); + }; + + return ( +
+ + +
+ Strip Formatting + +
+ +
+ ); +}; + +export const WithLoader: Story = { + render: () => }; diff --git a/web/src/components/ui/typography/AppMarkdown/AppMarkdownCommon.tsx b/web/src/components/ui/typography/AppMarkdown/AppMarkdownCommon.tsx index 051c3f58c..337a3db05 100644 --- a/web/src/components/ui/typography/AppMarkdown/AppMarkdownCommon.tsx +++ b/web/src/components/ui/typography/AppMarkdown/AppMarkdownCommon.tsx @@ -1,44 +1,13 @@ import React from 'react'; import { ExtraProps } from 'react-markdown'; import { AppCodeBlock } from '../AppCodeBlock/AppCodeBlock'; -import { TextDotLoader } from '@/components/ui/loaders'; import { cva } from 'class-variance-authority'; - -type Element = any; //TODO fix this after migration - -export const commonStreamingCheck = ( - endLine?: number, - startLine?: number, - lastTrackedLine?: number -): boolean => { - const isLineNumber = typeof endLine === 'number' && typeof lastTrackedLine === 'number'; - return isLineNumber && endLine === lastTrackedLine && startLine === lastTrackedLine; -}; +import { cn } from '@/lib/classMerge'; export interface ExtraPropsExtra extends ExtraProps { numberOfLineMarkdown: number; } -export const CommonPulseLoader: React.FC<{ - showLoader: boolean; - numberOfLineMarkdown: number; - node?: Element; -}> = ({ showLoader, numberOfLineMarkdown, node }) => { - const showStreamingLoader = - node && - showLoader && - commonStreamingCheck( - node?.position?.end.line, - node?.position?.start.line, - numberOfLineMarkdown - ); - - if (showStreamingLoader) { - return ; - } - return null; -}; - export const CustomCode: React.FC< { children?: React.ReactNode; @@ -68,12 +37,11 @@ export const CustomParagraph: React.FC< markdown: string; showLoader: boolean; } & ExtraPropsExtra -> = ({ children, markdown, ...rest }) => { +> = ({ children, markdown, showLoader, ...rest }) => { if (Array.isArray(children)) { return ( -

+

{children} -

); } @@ -85,10 +53,7 @@ export const CustomParagraph: React.FC< } return ( -

- {children} - -

+

{children}

); }; @@ -105,6 +70,7 @@ const headingVariants = cva('leading-1.3 my-2', { } } }); + export const CustomHeading: React.FC< { level: 1 | 2 | 3 | 4 | 5 | 6; @@ -114,13 +80,15 @@ export const CustomHeading: React.FC< numberOfLineMarkdown: number; stripFormatting?: boolean; } & ExtraPropsExtra -> = ({ level, children, markdown, stripFormatting = false, ...rest }) => { +> = ({ level, children, markdown, stripFormatting = false, showLoader, ...rest }) => { const HeadingTag = `h${level}` as any; - console.log('heading', HeadingTag, level, children); return ( - + {children} - ); }; @@ -132,12 +100,11 @@ export const CustomList: React.FC< markdown: string; showLoader: boolean; } & ExtraPropsExtra -> = ({ ordered, children, markdown, ...rest }) => { +> = ({ ordered, children, markdown, showLoader, ...rest }) => { const ListTag = ordered ? 'ol' : 'ul'; return ( - + {children} - ); }; @@ -148,11 +115,10 @@ export const CustomListItem: React.FC< markdown: string; showLoader: boolean; } & ExtraPropsExtra -> = ({ children, markdown, ...rest }) => { +> = ({ children, markdown, showLoader, ...rest }) => { return ( -
  • +
  • {children} -
  • ); }; @@ -163,11 +129,10 @@ export const CustomBlockquote: React.FC< markdown: string; showLoader: boolean; } & ExtraPropsExtra -> = ({ children, markdown, ...rest }) => { +> = ({ children, markdown, showLoader, ...rest }) => { return ( -
    +
    {children} -
    ); }; @@ -178,11 +143,10 @@ export const CustomTable: React.FC< markdown: string; showLoader: boolean; } & ExtraPropsExtra -> = ({ children, markdown, ...rest }) => { +> = ({ children, markdown, showLoader, ...rest }) => { return ( - +
    {children} -
    ); }; @@ -193,6 +157,10 @@ export const CustomSpan: React.FC< markdown: string; showLoader: boolean; } & ExtraPropsExtra -> = ({ children, markdown, ...rest }) => { - return {children}; +> = ({ children, markdown, showLoader, ...rest }) => { + return ( + + {children} + + ); }; diff --git a/web/src/controllers/ReasoningController/ReasoningMessages/ReasoningMessage_Text/ReasoningMessage_Text.tsx b/web/src/controllers/ReasoningController/ReasoningMessages/ReasoningMessage_Text/ReasoningMessage_Text.tsx index 57f6b7efe..9eb8a6132 100644 --- a/web/src/controllers/ReasoningController/ReasoningMessages/ReasoningMessage_Text/ReasoningMessage_Text.tsx +++ b/web/src/controllers/ReasoningController/ReasoningMessages/ReasoningMessage_Text/ReasoningMessage_Text.tsx @@ -1,8 +1,8 @@ import React from 'react'; -import { StreamingMessage_Text } from '@/components/ui/streaming/StreamingMessage_Text'; import { ReasoningMessageProps } from '../ReasoningMessageSelector'; import { type BusterChatMessageReasoning_text } from '@/api/asset_interfaces/chat'; import { useMessageIndividual } from '@/context/Chats'; +import { AppMarkdown } from '@/components/ui/typography/AppMarkdown'; export const ReasoningMessage_Text: React.FC = React.memo( ({ reasoningMessageId, messageId, isCompletedStream }) => { @@ -11,7 +11,7 @@ export const ReasoningMessage_Text: React.FC = React.memo (x) => (x?.reasoning_messages[reasoningMessageId] as BusterChatMessageReasoning_text)?.message )!; - return ; + return ; } );