'use client' import type * as React from 'react' import type { ContentEditorSelectionRequest } from '@admin/utils/editor/content-editor-selection-request' import type { MarkdownHeadingLevel } from '@admin/utils/editor/markdown-heading-level' import type { MarkdownListType } from '@admin/utils/editor/markdown-list-type' import { SourceColorHighlightPopover } from '@admin/components/custom/content-editor/tiptap-ui/color-highlight-popover' import { LinkControlPopover } from '@admin/components/custom/content-editor/tiptap-ui/link-popover' import { Button } from '@admin/components/ui/button' import { DropdownMenuItem } from '@admin/components/ui/dropdown-menu' import { Separator } from '@admin/components/ui/separator' import { useContentEditorSourceMode } from '@admin/hooks/content-editor/use-content-editor-source-mode' import { getContentEditorHighlightColorName } from '@admin/utils/editor/get-content-editor-highlight-color-name' import { MARKDOWN_HEADING_OPTIONS } from '@admin/utils/editor/markdown-heading-options' import { MARKDOWN_LIST_OPTIONS } from '@admin/utils/editor/markdown-list-options' import { cn } from '@admin/utils/shared/cn' import CodeMirror from '@uiw/react-codemirror' import { TextQuoteIcon as BlockquoteIcon, BoldIcon, Code2Icon, SquareCodeIcon as CodeBlockIcon, Heading5Icon as HeadingFiveIcon, Heading4Icon as HeadingFourIcon, HeadingIcon, Heading6Icon as HeadingSixIcon, Heading3Icon as HeadingThreeIcon, Heading2Icon as HeadingTwoIcon, ImagePlusIcon, ItalicIcon, ListIcon, ListOrderedIcon, ListTodoIcon, Minus, Redo2Icon, StrikethroughIcon as StrikeIcon, UnderlineIcon, Undo2Icon } from 'lucide-react' import { EditorToolbar } from './editor-toolbar' import { MathPopoverButton } from './math-popover' import { SourceModeDropdownButton } from './source-mode-dropdown-button' import { TableButton } from './table-button' type SvgIcon = React.ComponentType<{ className?: string }> const HEADING_ICONS: Record = { 2: HeadingTwoIcon, 3: HeadingThreeIcon, 4: HeadingFourIcon, 5: HeadingFiveIcon, 6: HeadingSixIcon } const LIST_ICONS: Record = { bullet: ListIcon, ordered: ListOrderedIcon, task: ListTodoIcon } export interface SourceModeProps { value?: string onChange?: (value: string) => void placeholder?: string disabled?: boolean className?: string toolbarEnd?: React.ReactNode selectionRequest?: ContentEditorSelectionRequest | null onSelectionChange?: (offset: number) => void } export function SourceMode({ value = '', onChange, placeholder, disabled = false, className, toolbarEnd, selectionRequest, onSelectionChange }: SourceModeProps) { const { applyBlockquote, applyBold, applyCode, applyHeading, applyHighlight, applyItalic, applyList, applyStrike, applyUnderline, canRedoMarkdownChange, canUndoMarkdownChange, codeMirrorExtensions, editorRef, editorTheme, handleCreateEditor, handleEditorChange, handleMarkdownLinkPopoverOpenChange, insertCodeBlock, insertDivider, insertMath, insertTable, isMarkdownLinkActive, markdownLinkUrl, openMediaGalleryAtCursor, redoMarkdownChange, removeHighlight, removeMarkdownLink, setMarkdownLink, setMarkdownLinkUrl, undoMarkdownChange } = useContentEditorSourceMode({ value, onChange, disabled, selectionRequest, onSelectionChange }) return (
{MARKDOWN_HEADING_OPTIONS.map((option) => { const Icon = HEADING_ICONS[option.level] return ( applyHeading(option.level)} > {option.label} ) })} {MARKDOWN_LIST_OPTIONS.map((option) => { const Icon = LIST_ICONS[option.type] return ( applyList(option.type)} > {option.label} ) })}
{[ { label: 'Bold', Icon: BoldIcon, onClick: applyBold }, { label: 'Italic', Icon: ItalicIcon, onClick: applyItalic }, { label: 'Strike', Icon: StrikeIcon, onClick: applyStrike }, { label: 'Code', Icon: Code2Icon, onClick: applyCode }, { label: 'Underline', Icon: UnderlineIcon, onClick: applyUnderline } ].map((mark) => ( ))} applyHighlight(getContentEditorHighlightColorName(color.value)) } onRemoveHighlight={removeHighlight} />
{toolbarEnd ?
{toolbarEnd}
: null}
) }