diff --git a/apps/dashboard/src/@/components/ui/inline-code.tsx b/apps/dashboard/src/@/components/ui/inline-code.tsx index 1b61ec81317..1426ede4d7f 100644 --- a/apps/dashboard/src/@/components/ui/inline-code.tsx +++ b/apps/dashboard/src/@/components/ui/inline-code.tsx @@ -7,7 +7,7 @@ export function InlineCode({ return ( diff --git a/apps/dashboard/src/components/contract-components/published-contract/index.tsx b/apps/dashboard/src/components/contract-components/published-contract/index.tsx index 61510d9efbc..6986104184b 100644 --- a/apps/dashboard/src/components/contract-components/published-contract/index.tsx +++ b/apps/dashboard/src/components/contract-components/published-contract/index.tsx @@ -131,10 +131,8 @@ export const PublishedContract: React.FC = ({ )} diff --git a/apps/dashboard/src/components/contract-components/published-contract/markdown-renderer.stories.tsx b/apps/dashboard/src/components/contract-components/published-contract/markdown-renderer.stories.tsx new file mode 100644 index 00000000000..8dbf0e170ba --- /dev/null +++ b/apps/dashboard/src/components/contract-components/published-contract/markdown-renderer.stories.tsx @@ -0,0 +1,160 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { mobileViewport } from "../../../stories/utils"; +import { MarkdownRenderer } from "./markdown-renderer"; + +const meta = { + title: "blocks/MarkdownRenderer", + component: Story, + parameters: { + nextjs: { + appDirectory: true, + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Desktop: Story = { + args: {}, +}; + +export const DisableCodeHighlight: Story = { + args: { + disableCodeHighlight: true, + }, +}; + +export const Mobile: Story = { + args: {}, + parameters: { + viewport: mobileViewport("iphone14"), + }, +}; + +const markdownExample = `\ +# Heading 1 +## Heading 2 +### Heading 3 +#### Heading 4 +##### Heading 5 +###### Heading 6 + + +This a paragraph + +This is another paragraph + +This a very long paragraph lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam nec pur us. Donec euismod, nunc nec vehicula. +ipsum dolor sit amet, consectetur adipiscing elit. Nullam nec pur us. Donec euismod, nunc nec vehicula. + + +## Empasis + +*Italic text* +_Also italic text_ + +**Bold text** +__Also bold text__ + +***Bold and italic*** +___Also bold and italic___ + +## Blockquote +> This is a blockquote. + +## Lists + +### Unordered list +- Item 1 +- Item 2 + - Nested Item 1 + - Nested Item 2 + +### Ordered list +1. First item +2. Second item + 1. Sub-item 1 + 2. Sub-item 2 + +### Mixed Nested lists + +- Item 1 +- Item 2 + 1. Sub-item 1 + 2. Sub-item 2 + + +1. First item +2. Second item + - Sub-item 1 + - Sub-item 2 + +### Code +This a a paragraph with some \`inlineCode()\` + +This a \`const longerCodeSnippet = "Example. This should be able to handle line breaks as well, it should not be overflowing the page";\` + +\`\`\`javascript +// Code block with syntax highlighting +function example() { + console.log("Hello, world!"); +} +\`\`\` + +### Links +[thirdweb](https://www.thirdweb.com) + +### Images +![Alt text](https://picsum.photos/2000/500) + + +### Horizontal Rule + + + +--- + + + +### Tables +| Header 1 | Header 2 | Header 3 | +|----------|----------|----------| +| Row 1 | Data | More Data| +| Row 2 | Data | More Data| + + +| Column 1 | Column 2 | Column 3 | Column 4 | Column 5 | +|--------------|------------------|--------------|------------------|--------------| +| Row 1 Cell 1 | Row 1 Cell 2 | Row 1 Cell 3 | Row 1 Cell 4 | Row 1 Cell 5 | +| Row 2 Cell 1 | Row 2 Cell 2 | Row 2 Cell 3 | Row 2 Cell 4 | Row 2 Cell 5 | +| Row 3 Cell 1 | Row 3 Cell 2 | Row 3 Cell 3 | Row 3 Cell 4 | Row 3 Cell 5 | +| Row 4 Cell 1 | Row 4 Cell 2 | Row 4 Cell 3 | Row 4 Cell 4 | Row 4 Cell 5 | +| Row 5 Cell 1 | Row 5 Cell 2 | Row 5 Cell 3 | Row 5 Cell 4 | Row 5 Cell 5 | + + +### Task List +- [ ] Task 1 +- [x] Task 2 (completed) + +### Escaping special characters +\\*This text is not italicized.\\* + +### Strikethrough +~~This is strikethrough text.~~ + + +`; + +function Story(props: { + disableCodeHighlight?: boolean; +}) { + return ( +
+ +
+ ); +} diff --git a/apps/dashboard/src/components/contract-components/published-contract/markdown-renderer.tsx b/apps/dashboard/src/components/contract-components/published-contract/markdown-renderer.tsx index c66c792917a..88b6c3a47d0 100644 --- a/apps/dashboard/src/components/contract-components/published-contract/markdown-renderer.tsx +++ b/apps/dashboard/src/components/contract-components/published-contract/markdown-renderer.tsx @@ -1,217 +1,173 @@ import { CodeClient } from "@/components/ui/code/code.client"; +import { PlainTextCodeBlock } from "@/components/ui/code/plaintext-code"; +import { InlineCode } from "@/components/ui/inline-code"; import { - Box, - type BoxProps, - Link, - ListItem, - OrderedList, Table, - Tbody, - Td, - Th, - Thead, - Tr, - UnorderedList, - chakra, -} from "@chakra-ui/react"; + TableBody, + TableCell, + TableContainer, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; +import { cn } from "@/lib/utils"; +import Link from "next/link"; import { onlyText } from "react-children-utilities"; import ReactMarkdown from "react-markdown"; import remarkGfm from "remark-gfm"; -import { Heading, Text } from "tw-components"; -const ChakraReactMarkdown = chakra(ReactMarkdown); - -export const MarkdownRenderer: React.FC< - BoxProps & { markdownText: string } -> = ({ markdownText, ...restProps }) => { - const commonHeadingProps = { - lineHeight: "1.25", - mb: 2, - pb: 2, - }; +export const MarkdownRenderer: React.FC<{ + markdownText: string; + className?: string; + disableCodeHighlight?: boolean; +}> = ({ markdownText, className, disableCodeHighlight }) => { + const commonHeadingClassName = + "mb-2 pb-2 leading-5 font-semibold tracking-tight"; return ( - ( - - ), - - h2: (props) => ( - - ), +
+ ( +

+ ), - h3: (props) => ( - - ), + h2: (props) => ( +

+ ), - h4: (props) => ( - - ), + h3: (props) => ( +

+ ), - h5: (props) => ( - - ), + h4: (props) => ( +
+ ), - h6: (props) => ( - - ), + h5: (props) => ( +
+ ), - a: (props) => ( - - ), + h6: (props) => ( +

+ ), - code: ({ ...props }) => { - if (props?.className) { - const language = props.className.replace("language-", ""); + a: (props) => ( + + ), + + code: ({ ...props }) => { + if (props?.className) { + if (disableCodeHighlight) { + return ( + + ); + } + const language = props.className.replace("language-", ""); + return ( +

+ +
+ ); + } + + return ; + }, + + p: (props) => ( +

+ ), + + table: (props) => ( +

+ + + + + ), + + th: ({ children: c, ...props }) => ( + + {c} + + ), + + td: (props) => ( + + ), + thead: (props) => , + tbody: (props) => , + tr: (props) => , + ul: (props) => { return ( -
- -
+
    ); - } - - return ( - ( +
      - ); - }, - - p: (props) => ( - - ), - - table: (props) => ( - -
- - ), - - th: ({ children: c, ...props }) => ( - - ), - - td: (props) => ( - , - tbody: (props) => , - tr: (props) => ( - - ), - ul: (props) => { - return ; - }, - ol: (props) => , - li: ({ children: c, ...props }) => ( - - {/* hydration error - can not render p > p, so use span instead - remove extra span when we move to tailwind */} - {c} - - ), - }} - > - {markdownText} - + + ), + }} + > + {markdownText} + + ); };
- + ), + li: ({ children: c, ...props }) => ( +
  • {c} - -
  • - ), - thead: (props) =>