@@ -9,7 +9,7 @@ import type { SimplifiedEnum, SimplifiedMcdocType, SimplifiedMcdocTypeNoUnion, S
9
9
import { getValues } from '@spyglassmc/mcdoc/lib/runtime/completer/index.js'
10
10
import { Identifier , ItemStack } from 'deepslate'
11
11
import { marked } from 'marked'
12
- import { useCallback , useMemo , useState } from 'preact/hooks'
12
+ import { useCallback , useEffect , useMemo , useState } from 'preact/hooks'
13
13
import config from '../../Config.js'
14
14
import { useLocale } from '../../contexts/Locale.jsx'
15
15
import { useFocus } from '../../hooks/useFocus.js'
@@ -137,7 +137,12 @@ const SPECIAL_UNSET = '__unset__'
137
137
function StringHead ( { type, optional, excludeStrings, node, ctx } : Props < StringType > ) {
138
138
const { locale } = useLocale ( )
139
139
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 ] )
141
146
142
147
const idAttribute = type . attributes ?. find ( a => a . name === 'id' ) ?. value
143
148
const idRegistry = idAttribute ?. kind === 'literal' && idAttribute . value . kind === 'string'
@@ -152,7 +157,7 @@ function StringHead({ type, optional, excludeStrings, node, ctx }: Props<StringT
152
157
153
158
const onChangeValue = useCallback ( ( newValue : string ) => {
154
159
newValue = newValue . replaceAll ( '\\n' , '\n' )
155
- if ( value === newValue ) {
160
+ if ( nodeValue === newValue ) {
156
161
return
157
162
}
158
163
ctx . makeEdit ( ( range ) => {
@@ -167,7 +172,11 @@ function StringHead({ type, optional, excludeStrings, node, ctx }: Props<StringT
167
172
type : 'json:string' ,
168
173
}
169
174
} )
170
- } , [ optional , node , ctx , isSelect ] )
175
+ } , [ optional , node , ctx , nodeValue , isSelect ] )
176
+
177
+ const onCommitValue = useCallback ( ( ) => {
178
+ onChangeValue ( value ?? '' )
179
+ } , [ value , onChangeValue ] )
171
180
172
181
const completions = useMemo ( ( ) => {
173
182
return getValues ( type , { ...ctx , offset : node ?. range . start ?? 0 } )
@@ -201,7 +210,7 @@ function StringHead({ type, optional, excludeStrings, node, ctx }: Props<StringT
201
210
{ completions . length > 0 && < datalist id = { datalistId } >
202
211
{ completions . map ( c => < option > { c . value } </ option > ) }
203
212
</ 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 } />
205
214
{ 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' ) } >
206
215
{ Octicon . link_external }
207
216
</ a > }
@@ -263,8 +272,12 @@ function EnumHead({ type, optional, excludeStrings, node, ctx }: Props<Simplifie
263
272
function NumericHead ( { type, node, ctx } : Props < NumericType > ) {
264
273
const { locale } = useLocale ( )
265
274
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 ] )
268
281
269
282
const onChangeValue = useCallback ( ( value : string | bigint | number ) => {
270
283
const number = typeof value === 'string'
@@ -277,9 +290,9 @@ function NumericHead({ type, node, ctx }: Props<NumericType>) {
277
290
if ( number === undefined ) {
278
291
return undefined
279
292
}
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 ) }
283
296
const newNode : JsonNumberNode = {
284
297
type : 'json:number' ,
285
298
range,
@@ -289,7 +302,11 @@ function NumericHead({ type, node, ctx }: Props<NumericType>) {
289
302
newValue . parent = newNode
290
303
return newNode
291
304
} )
292
- } , [ isFloat , node , ctx ] )
305
+ } , [ node , ctx ] )
306
+
307
+ const onCommitValue = useCallback ( ( ) => {
308
+ onChangeValue ( value ?? '' )
309
+ } , [ value , onChangeValue ] )
293
310
294
311
const color = type . attributes ?. find ( a => a . name === 'color' ) ?. value
295
312
const colorKind = color ?. kind === 'literal' && color . value . kind === 'string' ? color . value . value : undefined
@@ -309,9 +326,9 @@ function NumericHead({ type, node, ctx }: Props<NumericType>) {
309
326
} , [ type , onChangeValue ] )
310
327
311
328
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 ( ) } } />
313
330
{ 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 ) } />
315
332
< button class = "tooltipped tip-se" aria-label = { locale ( 'generate_new_color' ) } onClick = { onRandomColor } > { Octicon . sync } </ button >
316
333
</ > }
317
334
{ random && < >
0 commit comments