Skip to content

Commit c5e1dc2

Browse files
committed
fix(md-render): fix markdown rendering in file viewer
1 parent 6bc34c5 commit c5e1dc2

6 files changed

Lines changed: 52 additions & 33 deletions

File tree

apps/sim/app/workspace/[workspaceId]/files/components/file-viewer/preview-panel.tsx

Lines changed: 44 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
'use client'
22

3-
import { createContext, memo, useContext, useEffect, useMemo, useRef, useState } from 'react'
3+
import {
4+
Children,
5+
cloneElement,
6+
createContext,
7+
isValidElement,
8+
memo,
9+
useContext,
10+
useEffect,
11+
useMemo,
12+
useRef,
13+
useState,
14+
} from 'react'
415
import matter from 'gray-matter'
516
import { useRouter } from 'next/navigation'
617
import rehypeSlug from 'rehype-slug'
@@ -10,7 +21,7 @@ import { Streamdown } from 'streamdown'
1021
import 'streamdown/styles.css'
1122
import { toError } from '@sim/utils/errors'
1223
import { generateShortId } from '@sim/utils/id'
13-
import { Checkbox, CopyCodeButton, highlight, languages, Skeleton } from '@/components/emcn'
24+
import { Checkbox, highlight, languages, Skeleton } from '@/components/emcn'
1425
import '@/components/emcn/components/code/code.css'
1526
import 'prismjs/components/prism-bash'
1627
import 'prismjs/components/prism-css'
@@ -473,7 +484,9 @@ function resolveSimFileUrl(src: string | undefined): string | undefined {
473484
}
474485

475486
const STATIC_MARKDOWN_COMPONENTS = {
476-
pre: ({ children }: { children?: React.ReactNode }) => <>{children}</>,
487+
pre: ({ children }: { children?: React.ReactNode }) => (
488+
<>{isValidElement(children) ? cloneElement(children, { 'data-block': 'true' }) : children}</>
489+
),
477490
'mermaid-diagram': ({ definition }: { definition?: string }) => {
478491
const isStreaming = useContext(MermaidStreamingCtx)
479492
return <MermaidDiagram definition={definition ?? ''} isStreaming={isStreaming} />
@@ -531,20 +544,11 @@ const STATIC_MARKDOWN_COMPONENTS = {
531544
{children}
532545
</h6>
533546
),
534-
inlineCode: ({ children }: { children?: React.ReactNode }) => {
535-
if (typeof children === 'string' && children.includes('\n')) {
536-
return (
537-
<code className='my-4 block overflow-x-auto whitespace-pre-wrap break-words rounded-lg bg-[var(--surface-5)] p-4 font-mono text-[var(--text-primary)] leading-[1.6]'>
538-
{children}
539-
</code>
540-
)
541-
}
542-
return (
543-
<code className='whitespace-normal rounded bg-[var(--surface-5)] px-1.5 py-0.5 font-mono text-[var(--caution)]'>
544-
{children}
545-
</code>
546-
)
547-
},
547+
inlineCode: ({ children }: { children?: React.ReactNode }) => (
548+
<code className='whitespace-normal rounded bg-[var(--surface-5)] px-1.5 py-0.5 font-mono text-[var(--caution)] not-italic'>
549+
{children}
550+
</code>
551+
),
548552
code: ({ children, className }: { children?: React.ReactNode; className?: string }) => {
549553
const langMatch = className?.match(/language-(\w+)/)
550554
const langRaw = langMatch?.[1] ?? ''
@@ -564,21 +568,17 @@ const STATIC_MARKDOWN_COMPONENTS = {
564568

565569
return (
566570
<div className='my-4 overflow-hidden rounded-lg border border-[var(--border)]'>
567-
<div className='flex items-center justify-between border-[var(--border)] border-b bg-[var(--surface-3)] px-3 py-1.5'>
571+
<div className='border-[var(--border)] border-b bg-[var(--surface-3)] px-3 py-1.5'>
568572
<span className='text-[11px] text-[var(--text-tertiary)]'>{langRaw || 'code'}</span>
569-
<CopyCodeButton
570-
code={codeString}
571-
className='-mr-1 text-[var(--text-tertiary)] hover:text-[var(--text-secondary)]'
572-
/>
573573
</div>
574574
<div className='code-editor-theme bg-[var(--surface-5)]'>
575575
{html ? (
576576
<pre
577-
className='m-0 overflow-x-auto whitespace-pre p-4 font-mono text-[13px] leading-[1.6]'
577+
className='m-0 overflow-x-auto whitespace-pre p-4 font-mono text-[13px] not-italic leading-[1.6]'
578578
dangerouslySetInnerHTML={{ __html: html }}
579579
/>
580580
) : (
581-
<pre className='m-0 overflow-x-auto whitespace-pre p-4 font-mono text-[13px] text-[var(--text-primary)] leading-[1.6]'>
581+
<pre className='m-0 overflow-x-auto whitespace-pre p-4 font-mono text-[13px] text-[var(--text-primary)] not-italic leading-[1.6]'>
582582
<code>{codeString.trimEnd()}</code>
583583
</pre>
584584
)}
@@ -634,7 +634,7 @@ const STATIC_MARKDOWN_COMPONENTS = {
634634
<tr className='border-[var(--border)] border-b last:border-b-0'>{children}</tr>
635635
),
636636
th: ({ children }: { children?: React.ReactNode }) => (
637-
<th className='px-3 py-2 text-left font-semibold text-[12px] text-[var(--text-primary)]'>
637+
<th className='px-3 py-2 text-left font-semibold text-[13px] text-[var(--text-primary)]'>
638638
{children}
639639
</th>
640640
),
@@ -684,20 +684,36 @@ function LiRenderer({
684684
const isTaskItem = typeof className === 'string' && className.includes('task-list-item')
685685

686686
if (isTaskItem) {
687+
const [checkboxChild, ...contentChildren] = Children.toArray(children)
688+
const content = <span className='min-w-0 flex-1'>{contentChildren}</span>
689+
687690
if (ctx) {
688691
const offset = node?.position?.start?.offset
689692
if (offset === undefined) {
690-
return <li className='flex items-start gap-2 break-words leading-[1.6]'>{children}</li>
693+
return (
694+
<li className='flex items-start gap-2 break-words leading-[1.6]'>
695+
{checkboxChild}
696+
{content}
697+
</li>
698+
)
691699
}
692700
const before = ctx.contentRef.current.slice(0, offset)
693701
const prior = before.match(/^(\s*(?:[-*+]|\d+[.)]) +)\[([ xX])\]/gm)
694702
return (
695703
<CheckboxIndexCtx.Provider value={prior ? prior.length : 0}>
696-
<li className='flex items-start gap-2 break-words leading-[1.6]'>{children}</li>
704+
<li className='flex items-start gap-2 break-words leading-[1.6]'>
705+
{checkboxChild}
706+
{content}
707+
</li>
697708
</CheckboxIndexCtx.Provider>
698709
)
699710
}
700-
return <li className='flex items-start gap-2 break-words leading-[1.6]'>{children}</li>
711+
return (
712+
<li className='flex items-start gap-2 break-words leading-[1.6]'>
713+
{checkboxChild}
714+
{content}
715+
</li>
716+
)
701717
}
702718

703719
return <li className='break-words leading-[1.6]'>{children}</li>

apps/sim/app/workspace/[workspaceId]/files/files.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ export function Files() {
622622
const mimeType = getMimeTypeFromExtension('md')
623623
const blob = new Blob([''], { type: mimeType })
624624
const file = new File([blob], name, { type: mimeType })
625-
const result = await uploadFile.mutateAsync({ workspaceId, file })
625+
const result = await uploadFile.mutateAsync({ workspaceId, file, skipToast: true })
626626
const fileId = result.file?.id
627627
if (fileId) {
628628
justCreatedFileIdRef.current = fileId

apps/sim/app/workspace/[workspaceId]/tables/components/import-csv-dialog/import-csv-dialog.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ export function ImportCsvDialog({
345345
<ModalBody>
346346
{!parsed ? (
347347
<div className='flex flex-col gap-2'>
348-
<Label>Upload CSV</Label>
348+
<Label>Import CSV</Label>
349349
<Button
350350
type='button'
351351
variant='default'

apps/sim/app/workspace/[workspaceId]/tables/components/tables-list-context-menu/tables-list-context-menu.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ export function TablesListContextMenu({
5959
{onUploadCsv && (
6060
<DropdownMenuItem disabled={disableUpload} onSelect={onUploadCsv}>
6161
<Upload />
62-
Upload CSV
62+
Import CSV
6363
</DropdownMenuItem>
6464
)}
6565
</DropdownMenuContent>

apps/sim/app/workspace/[workspaceId]/tables/tables.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ export function Tables() {
450450
? `${uploadProgress.completed}/${uploadProgress.total}`
451451
: uploading
452452
? 'Uploading...'
453-
: 'Upload CSV'
453+
: 'Import CSV'
454454

455455
const handleCreateTable = useCallback(async () => {
456456
const existingNames = tables.map((t) => t.name)

apps/sim/hooks/queries/workspace-files.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ interface UploadFileParams {
205205
file: File
206206
onProgress?: (event: UploadProgressEvent) => void
207207
signal?: AbortSignal
208+
skipToast?: boolean
208209
}
209210

210211
interface UploadFileResponse {
@@ -324,7 +325,9 @@ export function useUploadWorkspaceFile() {
324325
queryClient.invalidateQueries({ queryKey: workspaceFilesKeys.storageInfo() })
325326
},
326327
onSuccess: (_data, variables) => {
327-
toast.success(`Uploaded "${variables.file.name}"`)
328+
if (!variables.skipToast) {
329+
toast.success(`Uploaded "${variables.file.name}"`)
330+
}
328331
},
329332
onError: (error, variables) => {
330333
logger.error('Failed to upload file:', error)

0 commit comments

Comments
 (0)