mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 01:45:10 +03:00
## Context We've gotten some requests for a better markdown editing experience in the Explorer so this PR adds a proper live preview markdown editor, similar UX to how you'd edit notion or obsidian documents. Opting to use `lexical` as the main library to support this UI for its size and composability without going too low level like prose mirror <img width="933" height="452" alt="image" src="https://github.com/user-attachments/assets/7161ae6c-3dff-4b36-818f-01b5e573f121" /> Actual file changes are just this size excluding the package-lock <img width="150" height="39" alt="image" src="https://github.com/user-attachments/assets/bb01f2cf-8ef7-4daf-975b-614b2d817b54" /> ## Changes involved This adjusts the UX for markdown cells a little - Clicking on a markdown cell immediately allows you to edit - Instead of the existing behaviour which requires a double click to enter "Edit" state - Editing doesn't eject you into a monaco editor, but rather inline editor - Nicer transition - Clicking out of the cell persists the cell's content - No more "Cancel" or "Save" buttons ## To test - [ ] Verify that editing markdown cells are still working - [ ] Verify that tabs do get marked with unsaved changes if you edit a markdown cell <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Replaced the previous Markdown editing workflow with an always-visible inline editor. - Added rich Markdown editing for headings, lists, links, blockquotes, code blocks, inline code, and text formatting. - Changes are saved automatically when leaving the editor. - Markdown formatting shortcuts take precedence within the editor. - **Bug Fixes** - Avoids unnecessary saves when content has not changed. - **Tests** - Added coverage verifying Markdown formatting conversions remain consistent and repeatable. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
53 lines
1.8 KiB
TypeScript
53 lines
1.8 KiB
TypeScript
import { cn } from 'ui'
|
|
|
|
import { AddCellDropdown } from './AddCellDropdown'
|
|
import { MoveCellDropdownContent } from './MoveCellDropdownContent'
|
|
import { MarkdownEditor } from '@/components/ui/MarkdownEditor/MarkdownEditor'
|
|
import { SortableSection } from '@/components/ui/SortableSection'
|
|
import { type MarkdownCell as MarkdownCellSchema } from '@/data/content/notebooks/notebook-schema'
|
|
import { useCurrentNotebook, useNotebooksStateSnapshot } from '@/state/notebooks/notebooks-state'
|
|
|
|
interface MarkdownCellProps {
|
|
cell: MarkdownCellSchema
|
|
onEdit?: () => void
|
|
}
|
|
|
|
export const MarkdownCell = ({ cell, onEdit }: MarkdownCellProps) => {
|
|
const snap = useNotebooksStateSnapshot()
|
|
const currentNotebook = useCurrentNotebook()
|
|
const cells = currentNotebook?.notebook.content?.cells ?? []
|
|
|
|
const handleUpdateMarkdown = (text: string) => {
|
|
const notebookId = currentNotebook?.notebook.id
|
|
if (!notebookId || text === cell.text) return
|
|
|
|
onEdit?.()
|
|
const nextCells = cells.map((c) => (c._id === cell._id ? { ...c, text } : c))
|
|
snap.updateCells({ id: notebookId, cells: nextCells })
|
|
}
|
|
|
|
return (
|
|
<SortableSection
|
|
id={cell._id}
|
|
sectionWidth="48rem"
|
|
actions={<AddCellDropdown cellId={cell._id} />}
|
|
gripDropdownContent={<MoveCellDropdownContent cellId={cell._id} />}
|
|
gripClassName="mt-1.5 sm:opacity-0 group-hover:opacity-100 has-[[data-state=open]]:opacity-100 transition"
|
|
>
|
|
<div
|
|
className={cn(
|
|
'w-full transition',
|
|
'border border-transparent rounded-md',
|
|
'hover:border-default focus-within:border-default'
|
|
)}
|
|
>
|
|
<MarkdownEditor
|
|
value={cell.text}
|
|
onBlur={handleUpdateMarkdown}
|
|
placeholder="This cell has no content"
|
|
/>
|
|
</div>
|
|
</SortableSection>
|
|
)
|
|
}
|