Skip to content

Commit 9e60091

Browse files
committed
feat(code-block-shiki): support display and toggle lang
1 parent 9086c2a commit 9e60091

2 files changed

Lines changed: 74 additions & 0 deletions

File tree

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,24 @@
11
.node-editor__code-block-shiki {
2+
position: relative;
23
border-radius: 8px;
34
padding: 4px 8px;
45
}
6+
7+
.note-editor__code-block-shiki__lang-tag {
8+
position: absolute;
9+
top: 4px;
10+
right: 4px;
11+
font-size: 12px;
12+
line-height: 16px;
13+
padding: 2px 4px;
14+
border-radius: 4px;
15+
}
16+
17+
.note-editor__code-block-shiki__select-lang {
18+
position: absolute;
19+
top: 4px;
20+
right: 4px;
21+
font-size: 12px;
22+
line-height: 16px;
23+
cursor: pointer;
24+
}

packages/tiptap-extension-code-block-shiki/src/codeBlockShiki.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,60 @@ export const codeBlockShiki = CodeBlock.extend<CodeBlockShikiOptions, CodeBlockS
7474
}),
7575
]
7676
},
77+
addNodeView() {
78+
return ({ editor, node, getPos, HTMLAttributes }) => {
79+
const dom = window.document.createElement('pre')
80+
dom.classList.add('note-editor__code-block-shiki')
81+
Object.keys(HTMLAttributes).forEach((key) => {
82+
dom.setAttribute(key, HTMLAttributes[key])
83+
})
84+
85+
const content = window.document.createElement('code')
86+
// @ts-expect-error language
87+
const langClass = this.options.languageClassPrefix + node.attrs.language
88+
content.classList.add(langClass)
89+
dom.append(content)
90+
91+
if (this.editor.isEditable) {
92+
const selectLang = window.document.createElement('select')
93+
selectLang.classList.add('note-editor__code-block-shiki__select-lang')
94+
selectLang.addEventListener('change', (event) => {
95+
// @ts-expect-error value
96+
const lang = event.target.value
97+
editor.commands.command(({ tr }) => {
98+
const pos = (getPos as () => number)()
99+
tr.setNodeAttribute(pos, 'language', lang)
100+
101+
return true
102+
})
103+
})
104+
const options = bundledLanguagesInfo.map((item) => {
105+
const option = document.createElement('option')
106+
option.setAttribute('value', item.id)
107+
// @ts-expect-error language
108+
if (node.attrs.language === item.id || node.attrs.language === item.name || item.aliases?.includes(node.attrs.language))
109+
option.setAttribute('selected', '')
110+
111+
option.textContent = item.id
112+
return option
113+
})
114+
selectLang.append(...options)
115+
dom.append(selectLang)
116+
}
117+
else {
118+
const langTag = window.document.createElement('div')
119+
langTag.classList.add('note-editor__code-block-shiki__lang-tag')
120+
// @ts-expect-error language
121+
langTag.textContent = node.attrs.language ?? 'text'
122+
dom.append(langTag)
123+
}
124+
125+
return {
126+
dom,
127+
contentDOM: content,
128+
}
129+
}
130+
},
77131
})
78132

79133
function getDecorations({

0 commit comments

Comments
 (0)