tiptap readonly as markdown view

This commit is contained in:
Anton Tranelis 2025-06-17 09:54:35 +02:00
parent 051338246d
commit d8f1405a4f
4 changed files with 16 additions and 26 deletions

View File

@ -37,6 +37,7 @@ interface RichTextEditorProps {
defaultValue: string
placeholder?: string
showMenu?: boolean
readOnly?: boolean
updateFormValue?: (value: string) => void
}
@ -64,12 +65,12 @@ export function RichTextEditor({
defaultValue,
placeholder,
showMenu = true,
readOnly = false,
updateFormValue,
}: RichTextEditorProps) {
const handleChange = () => {
if (updateFormValue) {
if (editor) {
console.log(getStyledMarkdown(editor))
updateFormValue(getStyledMarkdown(editor))
}
}
@ -78,6 +79,7 @@ export function RichTextEditor({
const tags = useTags()
const editor = useEditor({
editable: !readOnly,
extensions: [
Color.configure({ types: ['textStyle', 'listItem'] }),
Youtube.configure({
@ -147,7 +149,7 @@ export function RichTextEditor({
onUpdate: handleChange,
editorProps: {
attributes: {
class: `tw:h-full markdown tw:max-h-full tw:p-2 tw:overflow-y-auto`,
class: `tw:h-full markdown tw:max-h-full ${readOnly ? `` : `tw:p-2`} tw:overflow-y-auto tw:overflow-x-hidden`,
},
},
})
@ -170,12 +172,12 @@ export function RichTextEditor({
</label>
) : null}
<div
className={`editor-wrapper tw:border-base-content/20 tw:rounded-box tw:border tw:flex tw:flex-col tw:flex-1 tw:min-h-0`}
className={`${readOnly ? `` : `editor-wrapper tw:border-base-content/20 tw:rounded-box tw:border`} tw:flex tw:flex-col tw:flex-1 tw:min-h-0`}
>
{editor ? (
<>
{showMenu ? <TextEditorMenu editor={editor} /> : null}
<EditorContent editor={editor} />
{showMenu && !readOnly ? <TextEditorMenu editor={editor} /> : null}
<EditorContent editor={editor}/>
</>
) : null}
</div>

View File

@ -137,7 +137,7 @@ export function HeaderView({
editCallback && (
<li>
<a
className='tw:text-base-content! tw:tooltip tw:tooltip-right tw:cursor-pointer'
className='tw:text-base-content! tw:tooltip tw:tooltip-top tw:cursor-pointer'
data-tip='Edit'
onClick={(e) =>
item.layer?.customEditLink
@ -147,7 +147,7 @@ export function HeaderView({
: editCallback(e)
}
>
<PencilIcon className='tw:h-5 tw:w-5' />
<PencilIcon className='tw:h-5 tw:w-5 tw:!z-0' />
</a>
</li>
)}
@ -156,11 +156,11 @@ export function HeaderView({
setPositionCallback && (
<li>
<a
className='tw:text-base-content! tw:tooltip tw:tooltip-right tw:cursor-pointer'
className='tw:text-base-content! tw:tooltip tw:tooltip-top tw:cursor-pointer'
data-tip='Set position'
onClick={setPositionCallback}
>
<SVG src={TargetDotSVG} className='tw:w-5 tw:h-5' />
<SVG src={TargetDotSVG} className='tw:w-5 tw:h-5 tw:!z-0' />
</a>
</li>
)}
@ -169,14 +169,14 @@ export function HeaderView({
deleteCallback && (
<li>
<a
className='tw:text-error! tw:tooltip tw:tooltip-right tw:cursor-pointer'
className='tw:text-error! tw:tooltip tw:tooltip-top tw:cursor-pointer'
data-tip='Delete'
onClick={openDeleteModal}
>
{loading ? (
<span className='tw:loading tw:loading-spinner tw:loading-sm'></span>
) : (
<TrashIcon className='tw:h-5 tw:w-5' />
<TrashIcon className='tw:h-5 tw:w-5 tw:!z-0' />
)}
</a>
</li>

View File

@ -12,6 +12,7 @@ import remarkBreaks from 'remark-breaks'
import remarkGfm from 'remark-gfm'
import { visit } from 'unist-util-visit'
import { RichTextEditor } from '#components/Input/RichTextEditor/RichTextEditor'
import { useAddFilterTag } from '#components/Map/hooks/useFilter'
import { useTags } from '#components/Map/hooks/useTags'
import { decodeTag } from '#utils/FormatTags'
@ -137,20 +138,7 @@ export const TextView = ({
)
}
return (
<div translate='no'>
<Markdown
className={'markdown tw:text-map tw:leading-map tw:text-sm'}
remarkPlugins={[remarkBreaks, remarkGfm]}
rehypePlugins={[rehypeRaw, [rehypeSanitize, sanitizeSchema]]}
components={{
a: Link,
}}
>
{replacedText}
</Markdown>
</div>
)
return <RichTextEditor defaultValue={replacedText} readOnly={true} />
}
function removeMarkdownKeepParagraphs(text: string): string {

View File

@ -174,7 +174,7 @@ export function ProfileView({ attestationApi }: { attestationApi?: ItemsApi<any>
{item && (
<MapOverlayPage
key={item.id}
className={`tw:p-0! tw:overflow-hidden tw:m-4! tw:md:w-[calc(50%-32px)] tw:w-[calc(100%-32px)] tw:min-w-80 tw:max-w-3xl tw:left-0! tw:sm:left-auto! tw:top-0 tw:bottom-0 tw:transition-opacity tw:duration-500 ${!selectPosition ? 'tw:opacity-100 tw:pointer-events-auto' : 'tw:opacity-0 tw:pointer-events-none'} tw:max-h-[1000px]`}
className={`tw:p-0! tw:overflow-visible tw:m-4! tw:md:w-[calc(50%-32px)] tw:w-[calc(100%-32px)] tw:min-w-80 tw:max-w-3xl tw:left-0! tw:sm:left-auto! tw:top-0 tw:bottom-0 tw:transition-opacity tw:duration-500 ${!selectPosition ? 'tw:opacity-100 tw:pointer-events-auto' : 'tw:opacity-0 tw:pointer-events-none'} tw:max-h-[1000px]`}
>
<>
<div className={'tw:px-6 tw:pt-6'}>