99} from '../../common/cell.ts' ;
1010import { jsonParse , jsonString } from '../../common/json.ts' ;
1111import { isObject , objToArray } from '../../common/obj.ts' ;
12- import { isArray , isFalse , isUndefined } from '../../common/other.ts' ;
12+ import { isArray , isFalse , isUndefined , tryReturn } from '../../common/other.ts' ;
1313import { getProps , useCallback , useState } from '../../common/react.ts' ;
1414import {
1515 _VALUE ,
@@ -131,36 +131,37 @@ export const HtmlTable = ({
131131 </ table >
132132) ;
133133
134- export const EditableThing = < Thing extends Cell | Value > ( {
134+ export const EditableThing = ( {
135135 thing,
136136 onThingChange,
137137 className,
138138 hasSchema,
139139 showType = true ,
140140} : {
141- readonly thing : Thing | undefined ;
142- readonly onThingChange : ( thing : Thing ) => void ;
141+ readonly thing : Cell | Value | undefined ;
142+ readonly onThingChange : ( thing : Cell | Value ) => void ;
143143 readonly className : string ;
144144 readonly hasSchema : ( ( ) => boolean ) | undefined ;
145145 readonly showType ?: boolean ;
146146} ) => {
147147 const [ thingType , setThingType ] = useState < CellOrValueType > ( ) ;
148- const [ currentThing , setCurrentThing ] = useState <
149- string | number | boolean | null
150- > ( ) ;
148+ const [ currentThing , setCurrentThing ] = useState < Cell | Value > ( ) ;
151149 const [ stringThing , setStringThing ] = useState < string > ( ) ;
152150 const [ numberThing , setNumberThing ] = useState < number > ( ) ;
153151 const [ booleanThing , setBooleanThing ] = useState < boolean > ( ) ;
154- const [ objectThingJson , setObjectThingJson ] = useState < string > ( EMPTY_STRING ) ;
155- const [ arrayThingJson , setArrayThingJson ] = useState < string > ( EMPTY_STRING ) ;
152+ const [ objectThing , setObjectThing ] = useState < string > ( '{}' ) ;
153+ const [ arrayThing , setArrayThing ] = useState < string > ( '[]' ) ;
154+
155+ const [ objectClassName , setObjectClassName ] = useState < string > ( '' ) ;
156+ const [ arrayClassName , setArrayClassName ] = useState < string > ( '' ) ;
156157
157158 if ( currentThing !== thing ) {
158159 setThingType ( getCellOrValueType ( thing ) ) ;
159- setCurrentThing ( thing as string | number | boolean | null ) ;
160+ setCurrentThing ( thing ) ;
160161 if ( isObject ( thing ) ) {
161- setObjectThingJson ( jsonString ( thing ) ) ;
162+ setObjectThing ( jsonString ( thing ) ) ;
162163 } else if ( isArray ( thing ) ) {
163- setArrayThingJson ( jsonString ( thing ) ) ;
164+ setArrayThing ( jsonString ( thing ) ) ;
164165 } else {
165166 setStringThing ( String ( thing ) ) ;
166167 setNumberThing ( Number ( thing ) || 0 ) ;
@@ -169,10 +170,32 @@ export const EditableThing = <Thing extends Cell | Value>({
169170 }
170171
171172 const handleThingChange = useCallback (
172- ( thing : string | number | boolean , setTypedThing : ( thing : any ) => void ) => {
173+ < T extends Cell | Value > ( thing : T , setTypedThing : ( thing : T ) => void ) => {
173174 setTypedThing ( thing ) ;
174175 setCurrentThing ( thing ) ;
175- onThingChange ( thing as Thing ) ;
176+ onThingChange ( thing ) ;
177+ } ,
178+ [ onThingChange ] ,
179+ ) ;
180+
181+ const handleJsonThingChange = useCallback (
182+ (
183+ value : string ,
184+ setTypedThing : ( value : string ) => void ,
185+ isThing : ( thing : any ) => boolean ,
186+ setTypedClassName : ( className : string ) => void ,
187+ ) => {
188+ setTypedThing ( value ) ;
189+ try {
190+ const object = jsonParse ( value ) ;
191+ if ( isThing ( object ) ) {
192+ setCurrentThing ( object ) ;
193+ onThingChange ( object ) ;
194+ setTypedClassName ( '' ) ;
195+ }
196+ } catch {
197+ setTypedClassName ( 'invalid' ) ;
198+ }
176199 } ,
177200 [ onThingChange ] ,
178201 ) ;
@@ -192,21 +215,21 @@ export const EditableThing = <Thing extends Cell | Value>({
192215 stringThing ,
193216 numberThing ,
194217 booleanThing ,
195- ( objectThingJson ? jsonParse ( objectThingJson ) : { } ) as any ,
196- ( arrayThingJson ? jsonParse ( arrayThingJson ) : [ ] ) as any ,
218+ tryReturn ( ( ) => jsonParse ( objectThing ) , { } ) ,
219+ tryReturn ( ( ) => jsonParse ( arrayThing ) , [ ] ) ,
197220 ) ;
198221 setThingType ( nextType ) ;
199222 setCurrentThing ( thing ) ;
200- onThingChange ( thing as Thing ) ;
223+ onThingChange ( thing ) ;
201224 }
202225 } , [
203226 hasSchema ,
204227 onThingChange ,
205228 stringThing ,
206229 numberThing ,
207230 booleanThing ,
208- objectThingJson ,
209- arrayThingJson ,
231+ objectThing ,
232+ arrayThing ,
210233 thingType ,
211234 ] ) ;
212235
@@ -250,38 +273,34 @@ export const EditableThing = <Thing extends Cell | Value>({
250273 [ handleThingChange ] ,
251274 ) }
252275 /> ,
253- < textarea
276+ < input
254277 key = { thingType }
255- value = { objectThingJson }
278+ value = { objectThing }
279+ className = { objectClassName }
256280 onChange = { useCallback (
257- ( event : FormEvent < HTMLTextAreaElement > ) => {
258- const str = event [ CURRENT_TARGET ] [ _VALUE ] ;
259- setObjectThingJson ( str ) ;
260- try {
261- const parsed = jsonParse ( str ) ;
262- if ( isObject ( parsed ) ) {
263- onThingChange ( parsed as Thing ) ;
264- }
265- } catch { }
266- } ,
267- [ onThingChange ] ,
281+ ( event : FormEvent < HTMLInputElement > ) =>
282+ handleJsonThingChange (
283+ event [ CURRENT_TARGET ] [ _VALUE ] ,
284+ setObjectThing ,
285+ isObject ,
286+ setObjectClassName ,
287+ ) ,
288+ [ handleJsonThingChange ] ,
268289 ) }
269290 /> ,
270- < textarea
291+ < input
271292 key = { thingType }
272- value = { arrayThingJson }
293+ value = { arrayThing }
294+ className = { arrayClassName }
273295 onChange = { useCallback (
274- ( event : FormEvent < HTMLTextAreaElement > ) => {
275- const str = event [ CURRENT_TARGET ] [ _VALUE ] ;
276- setArrayThingJson ( str ) ;
277- try {
278- const parsed = jsonParse ( str ) ;
279- if ( isArray ( parsed ) ) {
280- onThingChange ( parsed as Thing ) ;
281- }
282- } catch { }
283- } ,
284- [ onThingChange ] ,
296+ ( event : FormEvent < HTMLInputElement > ) =>
297+ handleJsonThingChange (
298+ event [ CURRENT_TARGET ] [ _VALUE ] ,
299+ setArrayThing ,
300+ isArray ,
301+ setArrayClassName ,
302+ ) ,
303+ [ handleJsonThingChange ] ,
285304 ) }
286305 /> ,
287306 ) ;
0 commit comments