Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Need Help: Making Specific Words in a sentence "Uneditable or Readonly" in Vuetify-Pro-Tiptap #254

Open
ravi-cloudworks opened this issue Dec 20, 2023 · 1 comment

Comments

@ravi-cloudworks
Copy link

Hello community, I'm new to Vuetify-Pro-Tiptap and currently exploring the use case of making specific document portions "uneditable or readonly" with Vuetify-Pro-Tiptap. Our goal is to restrict editing in specific words within a sentence while maintaining the overall functionality. Any insights on achieving this or guidance to relevant materials would be highly valuable. Thanks.

@SergkeiM
Copy link
Contributor

SergkeiM commented Apr 19, 2024

Hi @ravi-cloudworks

You can check this guide https://tiptap.dev/docs/editor/guide/node-views/vue

You can create Custon nodes and set wich area should be Editable.

Example:

Section.js (Custom Node)

import { mergeAttributes, Node } from '@tiptap/core'
import { VueNodeViewRenderer } from '@tiptap/vue-3'


import SectionComponent from './components/Section.vue'
import SectionAction from './components/SectionAction.vue'

const Section = Node.create({
    name: 'section',
    group: 'section',
    content: 'block+',
    draggable: true,
    selectable: false,
    inline: false,
    priority: 1000,
    addCommands() {
        return {
            insertSection: () => ({ chain }) => {

                chain()
                .focus('end')
                .insertContent({
                    type: 'section',
                    content: [
                        {
                            type: "paragraph",
                            content: []
                        },
                    ],
                })
                .focus('end')
                .run()
            },
        };
    },
    addOptions() {
        return {
            ...this.parent?.(),
            button: ({ editor }) => ({
                component: SectionAction,
                componentProps: {
                    action: () => editor.commands.insertSection()
                }
            })
        }
    },
    parseHTML() {
        return [
            {
                tag: 'div[data-type="section"]',
            },
        ]
    },
    renderHTML({ HTMLAttributes }) {
        return ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'section' }), 0]
    },
    addNodeView() {
        return VueNodeViewRenderer(SectionComponent)
    },
})

export default Section

SectionComponent

<template>
    <NodeViewWrapper>
        <VCard
            flat
            border="md"
            class="mb-2"
        >
            <VToolbar density="compact" flat height="auto" class="py-1 ps-1">
                <VBtn
                    class="rounded me-1 ms-0"
                    density="comfortable"
                    size="small"
                    icon
                    draggable="true"
                    contenteditable="false"
                    data-drag-handle
                >
                    <VIcon :icon="mdiDrag" />
                    <VTooltip :eager="false" activator="parent" location="top" text="Move section" />
                </VBtn>
                <VBtn
                    class="rounded me-1 ms-0"
                    density="comfortable"
                    size="small"
                    icon
                    @click="deleteNode"
                >
                    <VIcon :icon="mdiDelete" />
                    <VTooltip :eager="false" activator="parent" location="top" text="Delete section" />
                </VBtn>
            </VToolbar>
            <VCardText class="pa-4">
               <!-- Editable part -->
                <NodeViewContent
                    class="section-content"
                />
            </VCardText>
        </VCard>
    </NodeViewWrapper>
</template>
<script setup>
    import { mdiDrag, mdiDelete } from '@mdi/js';
    import { nodeViewProps, NodeViewWrapper, NodeViewContent } from '@tiptap/vue-3'
  
    defineProps(nodeViewProps)
</script>

SectionAction

<template>
    <VBtn
        class="rounded me-1 ms-0"
        density="comfortable"
        size="small"
        icon
        @click="action"
    >
        <VIcon :icon="mdiFormatListGroupPlus" />
        <VTooltip :eager="false" activator="parent" location="top" text="Insert Section" />
    </VBtn>
</template>
<script setup>
    import { mdiFormatListGroupPlus } from '@mdi/js';

    defineProps({
        action: {
            type: Function,
            required: true
        },
    })
</script>

Result

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants