diff --git a/src/app/components/generator/McdocRenderer.tsx b/src/app/components/generator/McdocRenderer.tsx index 344c815e..249d9646 100644 --- a/src/app/components/generator/McdocRenderer.tsx +++ b/src/app/components/generator/McdocRenderer.tsx @@ -9,7 +9,7 @@ import type { SimplifiedEnum, SimplifiedMcdocType, SimplifiedMcdocTypeNoUnion, S 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 { useCallback, useEffect, useMemo, useState } from 'preact/hooks' import config from '../../Config.js' import { useLocale } from '../../contexts/Locale.jsx' import { useFocus } from '../../hooks/useFocus.js' @@ -137,7 +137,12 @@ const SPECIAL_UNSET = '__unset__' function StringHead({ type, optional, excludeStrings, node, ctx }: Props) { const { locale } = useLocale() - const value = (JsonStringNode.is(node) ? node.value : undefined)?.replaceAll('\n', '\\n') + const nodeValue = (JsonStringNode.is(node) ? node.value : undefined)?.replaceAll('\n', '\\n') + const [value, setValue] = useState(nodeValue) + + useEffect(() => { + setValue(nodeValue) + }, [nodeValue]) const idAttribute = type.attributes?.find(a => a.name === 'id')?.value const idRegistry = idAttribute?.kind === 'literal' && idAttribute.value.kind === 'string' @@ -152,7 +157,7 @@ function StringHead({ type, optional, excludeStrings, node, ctx }: Props { newValue = newValue.replaceAll('\\n', '\n') - if (value === newValue) { + if (nodeValue === newValue) { return } ctx.makeEdit((range) => { @@ -167,7 +172,11 @@ function StringHead({ type, optional, excludeStrings, node, ctx }: Props { + onChangeValue(value ?? '') + }, [value, onChangeValue]) const completions = useMemo(() => { return getValues(type, { ...ctx, offset: node?.range.start ?? 0 }) @@ -201,7 +210,7 @@ function StringHead({ type, optional, excludeStrings, node, ctx }: Props 0 && {completions.map(c => )} } - onChangeValue((e.target as HTMLInputElement).value)} list={completions.length > 0 ? datalistId : undefined} /> + setValue((e.target as HTMLInputElement).value)} onBlur={onCommitValue} onSubmit={onCommitValue} onKeyDown={(e) => {if (e.key === 'Enter') onCommitValue()}} list={completions.length > 0 ? datalistId : undefined} /> {value && gen && {Octicon.link_external} } @@ -263,8 +272,12 @@ function EnumHead({ type, optional, excludeStrings, node, ctx }: Props) { const { locale } = useLocale() - const value = node && JsonNumberNode.is(node) ? Number(node.value.value) : undefined - const isFloat = type.kind === 'float' || type.kind === 'double' + const nodeValue = node && JsonNumberNode.is(node) ? Number(node.value.value) : undefined + const [value, setValue] = useState(nodeValue?.toString()) + + useEffect(() => { + setValue(nodeValue?.toString()) + }, [nodeValue]) const onChangeValue = useCallback((value: string | bigint | number) => { const number = typeof value === 'string' @@ -277,9 +290,9 @@ function NumericHead({ type, node, ctx }: Props) { if (number === undefined) { return undefined } - const newValue: core.FloatNode | core.LongNode = isFloat - ? { type: 'float', range, value: Number(number) } - : { type: 'long', range, value: BigInt(number) } + const newValue: core.FloatNode | core.LongNode = typeof number === 'bigint' || Number.isInteger(number) + ? { type: 'long', range, value: BigInt(number) } + : { type: 'float', range, value: Number(number) } const newNode: JsonNumberNode = { type: 'json:number', range, @@ -289,7 +302,11 @@ function NumericHead({ type, node, ctx }: Props) { newValue.parent = newNode return newNode }) - }, [isFloat, node, ctx]) + }, [node, ctx]) + + const onCommitValue = useCallback(() => { + onChangeValue(value ?? '') + }, [value, onChangeValue]) const color = type.attributes?.find(a => a.name === 'color')?.value const colorKind = color?.kind === 'literal' && color.value.kind === 'string' ? color.value.value : undefined @@ -309,9 +326,9 @@ function NumericHead({ type, node, ctx }: Props) { }, [type, onChangeValue]) return <> - onChangeValue((e.target as HTMLInputElement).value)} /> + setValue((e.target as HTMLInputElement).value)} onBlur={onCommitValue} onSubmit={onCommitValue} onKeyDown={(e) => {if (e.key === 'Enter') onCommitValue()}} /> {colorKind && <> - onChangeColor((e.target as HTMLInputElement).value)} /> + onChangeColor((e.target as HTMLInputElement).value)} /> } {random && <>