Skip to content
This repository has been archived by the owner on Feb 7, 2024. It is now read-only.

Commit

Permalink
feat(vitepress-twoslash): support floating-vue for completions
Browse files Browse the repository at this point in the history
  • Loading branch information
antfu committed Jan 15, 2024
1 parent 311ca69 commit 42ab0f2
Show file tree
Hide file tree
Showing 4 changed files with 173 additions and 16 deletions.
6 changes: 4 additions & 2 deletions packages/shikiji-twoslash/src/renderer-rich.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,12 +195,14 @@ export function rendererRich(options: RendererRichOptions = {}): TwoSlashRendere
type: 'element',
tagName: 'span',
properties: {
class: ['twoslash-completions-list', classExtra].filter(Boolean).join(' '),
class: ['twoslash-completion-cursor', classExtra].filter(Boolean).join(' '),
},
children: [{
type: 'element',
tagName: 'ul',
properties: {},
properties: {
class: ['twoslash-completion-list', classExtra].filter(Boolean).join(' '),
},
children: query.completions!
.filter(i => i.name.startsWith(query.completionsPrefix || '____'))
.map(i => ({
Expand Down
29 changes: 16 additions & 13 deletions packages/shikiji-twoslash/style-rich.css
Original file line number Diff line number Diff line change
Expand Up @@ -107,33 +107,36 @@
}

/* ===== Completeions ===== */
.twoslash .twoslash-completions-list {
.twoslash .twoslash-completion-cursor {
position: relative;
}

.twoslash .twoslash-completions-list ul {
.twoslash .twoslash-completion-cursor .twoslash-completion-list {
user-select: none;
position: absolute;
top: 0;
left: 0;
transform: translate(0, 1.2em);
margin: 3px 0 0 -1px;
display: inline-block;
width: 240px;
z-index: 8;
box-shadow: var(--twoslash-popup-shadow);
background: var(--twoslash-popup-bg);
border: 1px solid var(--twoslash-border-color);
}

.twoslash-completion-list {
width: 240px;
font-size: 0.8rem;
margin: 3px 0 0 -1px;
padding: 4px;
z-index: 8;
display: flex;
flex-direction: column;
gap: 4px;
box-shadow: var(--twoslash-popup-shadow);
}
.twoslash .twoslash-completions-list ul:hover {
.twoslash-completion-list:hover {
user-select: auto;
}
.twoslash .twoslash-completions-list ul::before {
.twoslash-completion-list::before {
background-color: var(--twoslash-cursor-color);
width: 2px;
position: absolute;
Expand All @@ -142,25 +145,25 @@
left: -1px;
content: ' ';
}
.twoslash .twoslash-completions-list ul li {
.twoslash-completion-list li {
overflow: hidden;
display: flex;
align-items: center;
gap: 0.25em;
line-height: 1em;
}
.twoslash .twoslash-completions-list ul li span.twoslash-completions-unmatched {
.twoslash-completion-list li span.twoslash-completions-unmatched {
color: var(--twoslash-unmatched-color);
}
.twoslash .twoslash-completions-list ul .deprecated {
.twoslash-completion-list .deprecated {
text-decoration: line-through;
opacity: 0.5;
}
.twoslash .twoslash-completions-list ul li span.twoslash-completions-matched {
.twoslash-completion-list li span.twoslash-completions-matched {
color: var(--twoslash-matched-color);
}
/* Icons */
.twoslash .twoslash-completions-list .twoslash-completions-icon {
.twoslash-completion-list .twoslash-completions-icon {
color: var(--twoslash-unmatched-color);
width: 1em;
flex: none;
Expand Down
123 changes: 122 additions & 1 deletion packages/vitepress-plugin-twoslash/src/renderer-floating-vue.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { defaultHoverInfoProcessor, rendererRich } from 'shikiji-twoslash'
import { defaultCompletionIcons, defaultHoverInfoProcessor, rendererRich } from 'shikiji-twoslash'
import type { RendererRichOptions, TwoSlashRenderer } from 'shikiji-twoslash'
import type { Element, Text } from 'hast'
import type { ShikijiTransformerContext } from 'shikiji'
Expand Down Expand Up @@ -122,6 +122,10 @@ export function rendererFloatingVue(options: VitePressPluginTwoSlashOptions & Re
}
}

const {
completionIcons = defaultCompletionIcons,
} = options

return {
...rich,
nodeStaticInfo(info, node) {
Expand All @@ -132,5 +136,122 @@ export function rendererFloatingVue(options: VitePressPluginTwoSlashOptions & Re
return {}
return createFloatingVueWarpper.call(this, query.text, query.docs, node, true) || {}
},
nodeCompletion(query, node) {
if (node.type !== 'text')
throw new Error(`[shikiji-twoslash] nodeCompletion only works on text nodes, got ${node.type}`)

const leftPart = query.completionsPrefix || ''
const rightPart = node.value.slice(leftPart.length || 0)

return <Element>{
type: 'element',
tagName: 'span',
properties: {},
children: [
{
type: 'text',
value: leftPart,
},
{
type: 'element',
tagName: 'v-menu',
properties: {
'popper-class': 'vp-code shiki floating-vue-twoslash-compeltion vp-copy-ignore',
'placement': 'bottom-start',
'theme': 'twoslash',
':distance': '0',
':arrow-overflow': 'true',
':auto-boundary-max-size': 'true',
':shown': 'true',
':triggers': '["click"]',
':popper-triggers': '["click"]',
':auto-hide': 'false',
},
children: [
{
type: 'element',
tagName: 'span',
properties: {
class: 'twoslash-completion-cursor',
},
},
{
type: 'element',
tagName: 'template',
properties: {
'v-slot:popper': '{}',
},
content: {
type: 'root',
children: [{
type: 'element',
tagName: 'ul',
properties: {
class: 'twoslash-completion-list',
},
children: query.completions
.map((i): Element => ({
type: 'element',
tagName: 'li',
properties: {},
children: [
...completionIcons
? [<Element>{
type: 'element',
tagName: 'span',
properties: { class: `twoslash-completions-icon completions-${i.kind.replace(/\s/g, '-')}` },
children: [
completionIcons[i.kind] || completionIcons.property,
].filter(Boolean),
}]
: [],
{
type: 'element',
tagName: 'span',
properties: {
class: i.kindModifiers?.split(',').includes('deprecated')
? 'deprecated'
: undefined,
},
children: [
{
type: 'element',
tagName: 'span',
properties: { class: 'twoslash-completions-matched' },
children: [
{
type: 'text',
value: query.completionsPrefix || '',
},
],
},
{
type: 'element',
tagName: 'span',
properties: { class: 'twoslash-completions-unmatched' },
children: [
{
type: 'text',
value: i.name.slice(query.completionsPrefix?.length || 0),
},
],
},
],
},
],
})),
}],
},
children: [],
},
],
},
{
type: 'text',
value: rightPart,
},
],
}
},
}
}
31 changes: 31 additions & 0 deletions packages/vitepress-plugin-twoslash/src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
display: inline-block;
}

.twoslash-completion-list .twoslash-completions-icon {
color: var(--twoslash-unmatched-color) !important;
}

.floating-vue-twoslash .twoslash-popup-type {
max-width: 600px;
display: block;
Expand Down Expand Up @@ -73,3 +77,30 @@
margin: 6px -2px;
overflow-x: auto;
}

.twoslash-completion-cursor {
height: 1.2em;
width: 2px;
margin-bottom: -0.2em;
background: var(--vp-c-brand);
display: inline-block;
user-select: none;
}

.floating-vue-twoslash-compeltion {
--twoslash-matched-color: var(--vp-c-brand);
}

.floating-vue-twoslash-compeltion .v-popper__arrow-container {
display: none;
}

.floating-vue-twoslash-compeltion .twoslash-completion-list {
padding: 6px;
font-family: var(--vp-font-family-mono);
font-size: var(--vp-code-font-size) !important;
}

.floating-vue-twoslash-compeltion .twoslash-completion-list li {
padding: 3px 0;
}

0 comments on commit 42ab0f2

Please sign in to comment.