Py.Cafe

maartenbreddels/

solara-react-json-schema

Demos react-jsonschema using solara and ipyreact

DocsPricing
  • app.py
  • react-jsonschema.jsx
  • requirements.txt
  • style.css
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# check out https://solara.dev/ for documentation
# or https://github.com/widgetti/solara/
# And check out https://py.cafe/maartenbreddels for more examples
import asyncio

import solara
import solara.lab

import ipyreact
import ipywidgets
from pathlib import Path
from traitlets import Unicode


class RJSFSchema(ipyreact.ValueWidget):
    _esm = Path("react-jsonschema.jsx")


schema = {
  "title": 'Todo',
  "type": 'object',
  "required": ['title'],
  "properties": {
    "title": { "type": 'string', "title": 'Title', "default": 'A new task' },
    "done": { "type": 'boolean', "title": 'Done?', "default": False },
  },    
}

form_data = solara.reactive(None)


@solara.lab.task
async def do_stuff():
    print("calculating...")
    await asyncio.sleep(3)
    print("Done")


@solara.component
def Page():
    solara.Style(Path("style.css"))
    RJSFSchema.element(value=form_data.value, on_value=form_data.set,
        events={"onSubmit": do_stuff},
        props={
            "schema": schema,
        })
    solara.ProgressLinear(do_stuff.pending)
    if form_data.value:
        solara.Markdown(f"""
```
# Form data
{form_data.value}
```
""")
        def reset():
            form_data.value = {'title': 'A new task', 'done': False}
        solara.Button("Reset", on_click=reset)
react-jsonschema.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import * as React from "react";

import Form from 'https://esm.sh/@rjsf/core?external=react,react-dom';
import { RJSFSchema } from 'https://esm.sh/@rjsf/utils?external=react,react-dom';
import validator from 'https://esm.sh/@rjsf/validator-ajv8?external=react,react-dom';


const schema: RJSFSchema = {
  title: 'Todo',
  type: 'object',
  required: ['title'],
  properties: {
    title: { type: 'string', title: 'Title', default: 'A new task' },
    done: { type: 'boolean', title: 'Done?', default: false },
  },
};

const log = (type) => console.log.bind(console, type);

export default function Test({value, setValue, onSubmit, schema}) {
    const onChange = (data) => {
        console.log("onChange", data)
        setValue(data.formData)
    }
    return <Form
        formData={value}
        schema={schema}
        validator={validator}
        onChange={onChange}
        onSubmit={() => onSubmit()} // remove the argument (does not serialize)
        onError={log('errors')}
    />
}
style.css
1
2
3
4

.rjsf {
    background-color: red;
}