mirror of
https://github.com/misode/misode.github.io.git
synced 2026-04-23 07:10:41 +00:00
Improve doc comment rendering in markdown
This commit is contained in:
@@ -8,6 +8,7 @@ import { handleAttributes } from '@spyglassmc/mcdoc/lib/runtime/attribute/index.
|
||||
import type { SimplifiedEnum, SimplifiedMcdocType, SimplifiedMcdocTypeNoUnion, SimplifiedStructType, SimplifiedStructTypePairField } from '@spyglassmc/mcdoc/lib/runtime/checker/index.js'
|
||||
import { getValues } from '@spyglassmc/mcdoc/lib/runtime/completer/index.js'
|
||||
import { Identifier, ItemStack } from 'deepslate'
|
||||
import { marked } from 'marked'
|
||||
import { useCallback, useMemo, useState } from 'preact/hooks'
|
||||
import config from '../../Config.js'
|
||||
import { useLocale } from '../../contexts/Locale.jsx'
|
||||
@@ -490,7 +491,6 @@ function StructBody({ type: outerType, node, ctx }: Props<SimplifiedStructType>)
|
||||
const keyType = simplifyType(field.key, ctx)
|
||||
return <div key={`__dynamic_${index}__`} class="node">
|
||||
<div class="node-header">
|
||||
<Docs desc={field.desc} />
|
||||
<DynamicKey keyType={keyType} valueType={field.type} parent={node} ctx={ctx} />
|
||||
</div>
|
||||
</div>
|
||||
@@ -578,12 +578,11 @@ function StaticField({ pair, index, field, fieldKey, isToggled, expand, collapse
|
||||
<div class="node-header">
|
||||
{!field.optional && child === undefined && <ErrorIndicator error={{ message: locale('missing_key', localeQuote(fieldKey)), range: node.range, severity: 3 }} />}
|
||||
<Errors type={childType} node={child} ctx={ctx} />
|
||||
<Docs desc={field.desc} />
|
||||
{canToggle && (isCollapsed
|
||||
? <button class="toggle tooltipped tip-se" aria-label={`${locale('expand')}\n${locale('expand_all', 'Ctrl')}`} onClick={expand}>{Octicon.chevron_right}</button>
|
||||
: <button class="toggle tooltipped tip-se" aria-label={`${locale('collapse')}\n${locale('collapse_all', 'Ctrl')}`} onClick={collapse}>{Octicon.chevron_down}</button>
|
||||
)}
|
||||
<Key label={fieldKey} />
|
||||
<Key label={fieldKey} doc={field.desc} />
|
||||
{!isCollapsed && <Head type={childType} node={child} optional={field.optional} ctx={fieldCtx} />}
|
||||
</div>
|
||||
{!isCollapsed && <Body type={childType} node={child} optional={field.optional} ctx={fieldCtx} />}
|
||||
@@ -598,9 +597,10 @@ interface DynamicKeyProps {
|
||||
}
|
||||
function DynamicKey({ keyType, valueType, parent, ctx }: DynamicKeyProps) {
|
||||
const { locale } = useLocale()
|
||||
const [key, setKey] = useState<string>('')
|
||||
const [key, setKey] = useState<string>()
|
||||
|
||||
const keyNode = useMemo(() => {
|
||||
if (key === undefined) return undefined
|
||||
const node = JsonStringNode.mock(core.Range.create(0))
|
||||
node.value = key
|
||||
return node
|
||||
@@ -618,7 +618,10 @@ function DynamicKey({ keyType, valueType, parent, ctx }: DynamicKeyProps) {
|
||||
}, [ctx, makeKeyEdit])
|
||||
|
||||
const addKey = useCallback(() => {
|
||||
setKey('')
|
||||
if (!keyNode) {
|
||||
return
|
||||
}
|
||||
setKey(undefined)
|
||||
ctx.makeEdit((range) => {
|
||||
const valueNode = getDefault(simplifyType(valueType, ctx, { key: keyNode, parent }), range, ctx)
|
||||
const newPair: core.PairNode<JsonStringNode, JsonNode> = {
|
||||
@@ -636,7 +639,7 @@ function DynamicKey({ keyType, valueType, parent, ctx }: DynamicKeyProps) {
|
||||
|
||||
return <>
|
||||
<Head type={keyType} optional={true} node={keyNode} ctx={keyCtx} />
|
||||
<button class="add tooltipped tip-se" aria-label={locale('add_key')} onClick={addKey} disabled={key.length === 0}>{Octicon.plus_circle}</button>
|
||||
<button class="add tooltipped tip-se" aria-label={locale('add_key')} onClick={addKey} disabled={!key || key.length === 0}>{Octicon.plus_circle}</button>
|
||||
</>
|
||||
}
|
||||
|
||||
@@ -1124,10 +1127,16 @@ function selectAnyType(node: JsonNode | undefined) {
|
||||
|
||||
interface KeyProps {
|
||||
label: string | number | boolean
|
||||
doc?: string
|
||||
raw?: boolean
|
||||
}
|
||||
function Key({ label, raw }: KeyProps) {
|
||||
return <label>{raw ? label.toString() : formatIdentifier(label.toString())}</label>
|
||||
function Key({ label, doc, raw }: KeyProps) {
|
||||
const [shown, setShown] = useFocus()
|
||||
|
||||
return <label onClick={() => setShown(true)}>
|
||||
<span class={doc ? `underline ${shown ? '' : 'decoration-dotted hover:decoration-solid'}` : ''}>{raw ? label.toString() : formatIdentifier(label.toString())}</span>
|
||||
{doc && <div class={`node-doc ${shown ? '' : 'hidden'}`} onClick={e => e.stopPropagation()} dangerouslySetInnerHTML={{ __html: marked(doc) }}></div>}
|
||||
</label>
|
||||
}
|
||||
|
||||
interface ErrorsProps {
|
||||
@@ -1170,22 +1179,6 @@ function ErrorIndicator({ error }: ErrorIndicatorProps) {
|
||||
</div>
|
||||
}
|
||||
|
||||
interface DocsProps {
|
||||
desc: string | undefined
|
||||
}
|
||||
function Docs({ desc }: DocsProps) {
|
||||
if (!desc || desc.length === 0) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
const [active, setActive] = useFocus()
|
||||
|
||||
return <div class={`node-icon node-help ${active ? 'show' : ''}`} onClick={() => setActive()}>
|
||||
{Octicon.info}
|
||||
<span class="icon-popup">{desc}</span>
|
||||
</div>
|
||||
}
|
||||
|
||||
function useToggles() {
|
||||
const [toggleState, setToggleState] = useState(new Map<string, boolean>())
|
||||
const [toggleAll, setToggleAll] = useState<boolean | undefined>(undefined)
|
||||
|
||||
@@ -304,7 +304,7 @@ export class SpyglassService {
|
||||
idOmitDefaultNamespace: false,
|
||||
undeclaredSymbol: [
|
||||
{
|
||||
if: { category: ['bossbar', 'objective', 'team'] },
|
||||
if: { category: ['bossbar', 'objective', 'team', 'shader'] },
|
||||
then: { declare: 'block' },
|
||||
},
|
||||
...core.VanillaConfig.lint.undeclaredSymbol as any[],
|
||||
|
||||
@@ -74,11 +74,15 @@
|
||||
|
||||
.node-header > label {
|
||||
align-self: flex-start;
|
||||
padding: 0 9px;
|
||||
line-height: 1.94rem;
|
||||
background-color: var(--node-background-label);
|
||||
}
|
||||
|
||||
.node-header > label > span {
|
||||
padding: 0 9px;
|
||||
white-space: nowrap;
|
||||
user-select: none;
|
||||
background-color: var(--node-background-label);
|
||||
text-decoration-color: var(--node-text-dimmed);
|
||||
}
|
||||
|
||||
.node-header > label > .item-display {
|
||||
@@ -86,6 +90,35 @@
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.node-doc {
|
||||
position: absolute;
|
||||
font-size: 16px;
|
||||
line-height: 1.3;
|
||||
z-index: 10;
|
||||
margin-top: -1px;
|
||||
margin-left: 3px;
|
||||
padding: 4px 9px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid;
|
||||
color: var(--node-text-dimmed);
|
||||
border-color: var(--node-border);
|
||||
background-color: var(--node-background-label);
|
||||
box-shadow: 0 1px 7px -2px #000;
|
||||
}
|
||||
|
||||
.node-header > label > span:hover + .node-doc {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.node-doc code {
|
||||
color: var(--accent-primary);
|
||||
}
|
||||
|
||||
.node-doc ul {
|
||||
padding-left: 16px;
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
.node-header > input {
|
||||
font-size: 18px;
|
||||
padding-left: 9px;
|
||||
@@ -126,7 +159,7 @@
|
||||
background-color: var(--node-background-hover);
|
||||
}
|
||||
|
||||
.node-header a {
|
||||
.node-header > a {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 18px;
|
||||
|
||||
Reference in New Issue
Block a user