編輯器

Editor YouTube

參考
嵌入 YouTube 影片;以程式插入。

安裝

Terminal
pnpm dlx shadcn-vue add @admin/editor-youtubepnpm add @tiptap/extension-youtube
import { Youtube } from '@tiptap/extension-youtube'import { createYoutubeHandler } from '@/registry/admin/ui/editor-youtube'

含 createYoutubeHandler;嵌入能力來自 tiptap Youtube,需自行注入。把 Youtube.configure({}) 傳入 :extensions、createYoutubeHandler 經 :handlers 注入後,toolbar 可放 { kind: 'youtube' } 按鈕(見下方用法)。

用法

<script setup lang="ts">import type { JSONContent } from '@tiptap/core'import type { EditorToolbarItem } from '@/components/admin/editor-toolbar'import { IconBrandYoutube } from '@tabler/icons-vue'import { Youtube } from '@tiptap/extension-youtube'import { ref } from 'vue'import { cn } from '@/lib/utils'import { baseProseClass } from '@/components/admin/editor'import { AdminEditorToolbar, defaultEditorItems } from '@/components/admin/editor-toolbar'import { createYoutubeHandler, editorYoutubeClass } from '@/components/admin/editor-youtube'import { AdminRichEditor, starterKitProseClass } from '@/components/admin/rich-editor'​const value = ref<JSONContent | string>(  '<p>下方為 YouTube 影片,toolbar 的插入 YouTube 按鈕會以 prompt 取網址後 setYoutubeVideo。</p><div data-youtube-video><iframe src="https://www.youtube.com/embed/dQw4w9WgXcQ"></iframe></div>')​// opt-in:注入官方 Youtube extension 與 youtube handlerconst extensions = [Youtube.configure({ nocookie: true, width: 640, height: 360 })]const handlers = { youtube: createYoutubeHandler() }​// 預設 toolbar(純 StarterKit)後面 append youtube 按鈕const items: EditorToolbarItem[][] = [  ...defaultEditorItems,  [    {      kind: 'youtube',      icon: IconBrandYoutube,      label: '插入 YouTube',      tooltip: { text: '插入 YouTube' }    }  ]]</script>​<template>  <admin-rich-editor    v-slot="{ editor, handlers: mergedHandlers }"    v-model="value"    :extensions="extensions"    :handlers="handlers"    :ui="{ base: cn(baseProseClass, starterKitProseClass, editorYoutubeClass) }"  >    <admin-editor-toolbar :editor :handlers="mergedHandlers" :items="items" />  </admin-rich-editor></template>
<script setup lang="ts">import type { EditorToolbarItem } from '@/registry/admin/ui/editor-toolbar'import { IconBrandYoutube } from '@tabler/icons-vue'import { Youtube } from '@tiptap/extension-youtube'import { ref } from 'vue'import { AdminEditorToolbar, defaultEditorItems } from '@/registry/admin/ui/editor-toolbar'import { createYoutubeHandler } from '@/registry/admin/ui/editor-youtube'import { AdminRichEditor } from '@/registry/admin/ui/rich-editor'​const value = ref('<p>影片:</p><div data-youtube-video><iframe src="https://www.youtube.com/embed/dQw4w9WgXcQ"></iframe></div>')​const extensions = [Youtube.configure({ nocookie: true, width: 640, height: 360 })]const handlers = { youtube: createYoutubeHandler() }const items: EditorToolbarItem[][] = [  ...defaultEditorItems,  [{ kind: 'youtube', icon: IconBrandYoutube, label: '插入 YouTube', tooltip: { text: '插入 YouTube' } }]]</script>​<template>  <admin-rich-editor v-model="value" :extensions="extensions" :handlers="handlers">    <admin-editor-toolbar :items="items" />  </admin-rich-editor></template>

啟用後:

  • YouTube iframe 顯示不會被 tiptap parser 丟掉
  • editor.commands.setYoutubeVideo({ src }) 可程式式嵌入影片(src 需為合法 YouTube 網址,否則官方 command 回 false 不插入)
  • 序列化輸出為 <div data-youtube-video><iframe ...></iframe></div>
選取外框與節點拖曳

data-youtube-video wrapper 是 block 元素,預設佔滿整行,選取時的 .ProseMirror-selectednode 外框會比 iframe 寬。要讓外框貼齊 iframe,給 wrapper 套 width: fit-content(如 [&_[data-youtube-video]]:w-fit)。

不過 YouTube iframe 會攔截滑鼠事件(點擊會進到 YouTube 而不是選取節點),縮成 w-fit 後 iframe 旁已無可點區域,無法用點擊選取或拖曳。要選取、拖曳影片節點,請一併啟用 Drag Handle,以把手拖曳(tiptap 官方對互動式 node 的建議做法)。

進階 configure

寬高、隱私模式(nocookie)等由 consumer 自行 Youtube.configure({...}):

<script setup lang="ts">import { Youtube } from '@tiptap/extension-youtube'​const customYoutube = Youtube.configure({ nocookie: true, width: 640, height: 360, controls: true })</script>​<template>  <admin-rich-editor v-model="value" :extensions="[customYoutube]" /></template>

src 來源

createYoutubeHandler 只處理網址:缺 src 時以 window.prompt 要一個 URL。進階選片 UI 請自行以 :handlers 覆寫 youtube handler。

API 參考

匯出說明
createYoutubeHandler()回傳 EditorHandler,傳入 <AdminRichEditor :handlers> 的 youtube key

@tiptap/extension-youtube 套件 API 詳見 tiptap youtube 官方文件。