@@ -9,7 +9,7 @@ import type { SimplifiedEnum, SimplifiedMcdocType, SimplifiedMcdocTypeNoUnion, S
99import { getValues } from '@spyglassmc/mcdoc/lib/runtime/completer/index.js'
1010import { Identifier , ItemStack } from 'deepslate'
1111import { marked } from 'marked'
12- import { useCallback , useMemo , useState } from 'preact/hooks'
12+ import { useCallback , useEffect , useMemo , useState } from 'preact/hooks'
1313import config from '../../Config.js'
1414import { useLocale } from '../../contexts/Locale.jsx'
1515import { useFocus } from '../../hooks/useFocus.js'
@@ -137,7 +137,12 @@ const SPECIAL_UNSET = '__unset__'
137137function StringHead ( { type, optional, excludeStrings, node, ctx } : Props < StringType > ) {
138138 const { locale } = useLocale ( )
139139
140- const value = ( JsonStringNode . is ( node ) ? node . value : undefined ) ?. replaceAll ( '\n' , '\\n' )
140+ const nodeValue = ( JsonStringNode . is ( node ) ? node . value : undefined ) ?. replaceAll ( '\n' , '\\n' )
141+ const [ value , setValue ] = useState ( nodeValue )
142+
143+ useEffect ( ( ) => {
144+ setValue ( nodeValue )
145+ } , [ nodeValue ] )
141146
142147 const idAttribute = type . attributes ?. find ( a => a . name === 'id' ) ?. value
143148 const idRegistry = idAttribute ?. kind === 'literal' && idAttribute . value . kind === 'string'
@@ -152,7 +157,7 @@ function StringHead({ type, optional, excludeStrings, node, ctx }: Props<StringT
152157
153158 const onChangeValue = useCallback ( ( newValue : string ) => {
154159 newValue = newValue . replaceAll ( '\\n' , '\n' )
155- if ( value === newValue ) {
160+ if ( nodeValue === newValue ) {
156161 return
157162 }
158163 ctx . makeEdit ( ( range ) => {
@@ -167,7 +172,11 @@ function StringHead({ type, optional, excludeStrings, node, ctx }: Props<StringT
167172 type : 'json:string' ,
168173 }
169174 } )
170- } , [ optional , node , ctx , isSelect ] )
175+ } , [ optional , node , ctx , nodeValue , isSelect ] )
176+
177+ const onCommitValue = useCallback ( ( ) => {
178+ onChangeValue ( value ?? '' )
179+ } , [ value , onChangeValue ] )
171180
172181 const completions = useMemo ( ( ) => {
173182 return getValues ( type , { ...ctx , offset : node ?. range . start ?? 0 } )
@@ -201,7 +210,7 @@ function StringHead({ type, optional, excludeStrings, node, ctx }: Props<StringT
201210 { completions . length > 0 && < datalist id = { datalistId } >
202211 { completions . map ( c => < option > { c . value } </ option > ) }
203212 </ datalist > }
204- < input class = { colorKind === 'hex_rgb' ? 'short-input' : idRegistry ? 'long-input' : '' } value = { value ?? '' } onInput = { ( e ) => onChangeValue ( ( e . target as HTMLInputElement ) . value ) } list = { completions . length > 0 ? datalistId : undefined } />
213+ < input class = { colorKind === 'hex_rgb' ? 'short-input' : idRegistry ? 'long-input' : '' } value = { value ?? '' } onInput = { ( e ) => setValue ( ( e . target as HTMLInputElement ) . value ) } onBlur = { onCommitValue } onSubmit = { onCommitValue } onKeyDown = { ( e ) => { if ( e . key === 'Enter' ) onCommitValue ( ) } } list = { completions . length > 0 ? datalistId : undefined } />
205214 { value && gen && < a href = { `/${ gen . url } /?preset=${ value ?. replace ( / ^ m i n e c r a f t : / , '' ) } ` } class = "tooltipped tip-se" aria-label = { locale ( 'follow_reference' ) } >
206215 { Octicon . link_external }
207216 </ a > }
@@ -263,8 +272,12 @@ function EnumHead({ type, optional, excludeStrings, node, ctx }: Props<Simplifie
263272function NumericHead ( { type, node, ctx } : Props < NumericType > ) {
264273 const { locale } = useLocale ( )
265274
266- const value = node && JsonNumberNode . is ( node ) ? Number ( node . value . value ) : undefined
267- const isFloat = type . kind === 'float' || type . kind === 'double'
275+ const nodeValue = node && JsonNumberNode . is ( node ) ? Number ( node . value . value ) : undefined
276+ const [ value , setValue ] = useState ( nodeValue ?. toString ( ) )
277+
278+ useEffect ( ( ) => {
279+ setValue ( nodeValue ?. toString ( ) )
280+ } , [ nodeValue ] )
268281
269282 const onChangeValue = useCallback ( ( value : string | bigint | number ) => {
270283 const number = typeof value === 'string'
@@ -277,9 +290,9 @@ function NumericHead({ type, node, ctx }: Props<NumericType>) {
277290 if ( number === undefined ) {
278291 return undefined
279292 }
280- const newValue : core . FloatNode | core . LongNode = isFloat
281- ? { type : 'float ' , range, value : Number ( number ) }
282- : { type : 'long ' , range, value : BigInt ( number ) }
293+ const newValue : core . FloatNode | core . LongNode = typeof number === 'bigint' || Number . isInteger ( number )
294+ ? { type : 'long ' , range, value : BigInt ( number ) }
295+ : { type : 'float ' , range, value : Number ( number ) }
283296 const newNode : JsonNumberNode = {
284297 type : 'json:number' ,
285298 range,
@@ -289,7 +302,11 @@ function NumericHead({ type, node, ctx }: Props<NumericType>) {
289302 newValue . parent = newNode
290303 return newNode
291304 } )
292- } , [ isFloat , node , ctx ] )
305+ } , [ node , ctx ] )
306+
307+ const onCommitValue = useCallback ( ( ) => {
308+ onChangeValue ( value ?? '' )
309+ } , [ value , onChangeValue ] )
293310
294311 const color = type . attributes ?. find ( a => a . name === 'color' ) ?. value
295312 const colorKind = color ?. kind === 'literal' && color . value . kind === 'string' ? color . value . value : undefined
@@ -309,9 +326,9 @@ function NumericHead({ type, node, ctx }: Props<NumericType>) {
309326 } , [ type , onChangeValue ] )
310327
311328 return < >
312- < input class = "short-input" type = "number" value = { value } onInput = { ( e ) => onChangeValue ( ( e . target as HTMLInputElement ) . value ) } />
329+ < input class = "short-input" type = "number" value = { value } onInput = { ( e ) => setValue ( ( e . target as HTMLInputElement ) . value ) } onBlur = { onCommitValue } onSubmit = { onCommitValue } onKeyDown = { ( e ) => { if ( e . key === 'Enter' ) onCommitValue ( ) } } />
313330 { colorKind && < >
314- < input class = "short-input" type = "color" value = { '#' + ( value ?. toString ( 16 ) . padStart ( 6 , '0' ) ?? '000000' ) } onChange = { ( e ) => onChangeColor ( ( e . target as HTMLInputElement ) . value ) } />
331+ < input class = "short-input" type = "color" value = { '#' + ( nodeValue ?. toString ( 16 ) . padStart ( 6 , '0' ) ?? '000000' ) } onChange = { ( e ) => onChangeColor ( ( e . target as HTMLInputElement ) . value ) } />
315332 < button class = "tooltipped tip-se" aria-label = { locale ( 'generate_new_color' ) } onClick = { onRandomColor } > { Octicon . sync } </ button >
316333 </ > }
317334 { random && < >
0 commit comments