1
- import { SchemaForm } from '@deathbeds/jupyterlab-rjsf' ;
2
- import { MessageLoop } from '@lumino/messaging' ;
3
- import { Widget } from '@lumino/widgets' ;
4
1
import { ISubmitEvent } from '@rjsf/core' ;
5
2
import * as React from 'react' ;
6
-
3
+ import { FormComponent } from '@jupyterlab/ui-components' ;
4
+ import validatorAjv8 from '@rjsf/validator-ajv8' ;
7
5
import { IDict } from '../types' ;
6
+ import CustomArrayField from './customarrayfield' ;
8
7
9
8
interface IStates {
10
9
internalData ?: IDict ;
@@ -24,33 +23,18 @@ interface IProps {
24
23
cancel ?: ( ) => void ;
25
24
}
26
25
27
- // Reusing the datalayer/jupyter-react component:
28
- // https://github.com/datalayer/jupyter-react/blob/main/packages/react/src/jupyter/lumino/Lumino.tsx
29
- export const LuminoSchemaForm = (
30
- props : React . PropsWithChildren < any >
31
- ) : JSX . Element => {
32
- const ref = React . useRef < HTMLDivElement > ( null ) ;
33
- const { children } = props ;
34
- React . useEffect ( ( ) => {
35
- const widget = children as SchemaForm ;
36
- try {
37
- MessageLoop . sendMessage ( widget , Widget . Msg . BeforeAttach ) ;
38
- ref . current ! . insertBefore ( widget . node , null ) ;
39
- MessageLoop . sendMessage ( widget , Widget . Msg . AfterAttach ) ;
40
- } catch ( e ) {
41
- console . warn ( 'Exception while attaching Lumino widget.' , e ) ;
42
- }
43
- return ( ) => {
44
- try {
45
- if ( widget . isAttached || widget . node . isConnected ) {
46
- Widget . detach ( widget ) ;
47
- }
48
- } catch ( e ) {
49
- // The widget is destroyed already by React.
50
- }
51
- } ;
52
- } , [ children ] ) ;
53
- return < div ref = { ref } /> ;
26
+ const WrappedFormComponent = ( props : any ) : JSX . Element => {
27
+ const { fields, ...rest } = props ;
28
+ return (
29
+ < FormComponent
30
+ { ...rest }
31
+ validator = { validatorAjv8 }
32
+ fields = { {
33
+ ...fields ,
34
+ ArrayField : CustomArrayField
35
+ } }
36
+ />
37
+ ) ;
54
38
} ;
55
39
56
40
export class ObjectPropertiesForm extends React . Component < IProps , IStates > {
@@ -76,10 +60,14 @@ export class ObjectPropertiesForm extends React.Component<IProps, IStates> {
76
60
) ;
77
61
} ;
78
62
79
- componentDidUpdate ( prevProps : IProps , prevState : IStates ) : void {
63
+ componentDidUpdate ( prevProps : IProps ) : void {
80
64
if ( prevProps . sourceData !== this . props . sourceData ) {
81
65
this . setState ( old => ( { ...old , internalData : this . props . sourceData } ) ) ;
82
66
}
67
+
68
+ if ( prevProps . schema !== this . props . schema ) {
69
+ this . setState ( old => ( { ...old , schema : this . props . schema } ) ) ;
70
+ }
83
71
}
84
72
85
73
buildForm ( ) : JSX . Element [ ] {
@@ -159,33 +147,54 @@ export class ObjectPropertiesForm extends React.Component<IProps, IStates> {
159
147
160
148
const submitRef = React . createRef < HTMLButtonElement > ( ) ;
161
149
162
- const formSchema = new SchemaForm ( schema ?? { } , {
163
- liveValidate : true ,
164
- formData : this . state . internalData ,
165
- onSubmit : this . onFormSubmit ,
166
- onFocus : ( id , value ) => {
167
- this . props . syncSelectedField
168
- ? this . props . syncSelectedField ( id , value , this . props . parentType )
169
- : null ;
170
- } ,
171
- onBlur : ( id , value ) => {
172
- this . props . syncSelectedField
173
- ? this . props . syncSelectedField ( null , value , this . props . parentType )
174
- : null ;
175
- } ,
176
- uiSchema : this . generateUiSchema ( this . props . schema ) ,
177
- children : (
178
- < button ref = { submitRef } type = "submit" style = { { display : 'none' } } />
179
- )
180
- } ) ;
181
150
return (
182
151
< div
183
152
className = "jpcad-property-panel"
184
153
data-path = { this . props . filePath ?? '' }
185
154
>
186
- < div className = "jpcad-property-outer jp-scrollbar-tiny" >
187
- < LuminoSchemaForm > { formSchema } </ LuminoSchemaForm >
155
+ < div
156
+ className = "jpcad-property-outer jp-scrollbar-tiny"
157
+ onKeyUp = { ( e : React . KeyboardEvent ) => {
158
+ if ( e . key === 'Enter' ) {
159
+ e . preventDefault ( ) ;
160
+ submitRef . current ?. click ( ) ;
161
+ }
162
+ } }
163
+ >
164
+ < WrappedFormComponent
165
+ schema = { schema }
166
+ uiSchema = { this . generateUiSchema ( this . props . schema ) }
167
+ formData = { this . state . internalData }
168
+ onSubmit = { this . onFormSubmit }
169
+ liveValidate
170
+ onFocus = { ( id , value ) => {
171
+ this . props . syncSelectedField
172
+ ? this . props . syncSelectedField (
173
+ id ,
174
+ value ,
175
+ this . props . parentType
176
+ )
177
+ : null ;
178
+ } }
179
+ onBlur = { ( id , value ) => {
180
+ this . props . syncSelectedField
181
+ ? this . props . syncSelectedField (
182
+ null ,
183
+ value ,
184
+ this . props . parentType
185
+ )
186
+ : null ;
187
+ } }
188
+ children = {
189
+ < button
190
+ ref = { submitRef }
191
+ type = "submit"
192
+ style = { { display : 'none' } }
193
+ />
194
+ }
195
+ />
188
196
</ div >
197
+
189
198
< div className = "jpcad-property-buttons" >
190
199
{ this . props . cancel ? (
191
200
< button
@@ -198,7 +207,10 @@ export class ObjectPropertiesForm extends React.Component<IProps, IStates> {
198
207
199
208
< button
200
209
className = "jp-Dialog-button jp-mod-accept jp-mod-styled"
201
- onClick = { ( ) => submitRef . current ?. click ( ) }
210
+ type = "button"
211
+ onClick = { ( ) => {
212
+ submitRef . current ?. click ( ) ;
213
+ } }
202
214
>
203
215
< div className = "jp-Dialog-buttonLabel" > Submit</ div >
204
216
</ button >
0 commit comments