Skip to content

New API for reactpy.html #1279

Description

@Archmonger

Current Situation

Currently, the reactpy.html API feels a bit too wordy/verbose. When code formatters hit ReactPy code, it results in a lot of lines wasted to nothing but brackets or parenthesis.

To demonstrate, just look at how many lines of code the following example is:

html.div(
    {
        "className": "modal fade",
        "id": "exampleModal",
        "tabIndex": "-1",
        "aria-labeledby": "exampleModalLabel",
        "aria-hidden": "true",
    },
    html.div(
        {"className": "modal-dialog"},
        html.div(
            {"className": "modal-content"},
            modal_header(title="Modal Title"),
            modal_body(),
            html.div(
                {"className": "modal-footer"},
                html.hr(),
                [
                    html.button(
                        {
                            "type": "button",
                            "className": "btn btn-secondary",
                            "data-bs-dismiss": "modal",
                            "aria-label": "Close",
                        },
                        "Close",
                    ),
                    html.button(
                        {
                            "type": "button",
                            "className": "btn btn-primary",
                            "data-bs-dismiss": "modal",
                        },
                        "Save Changes",
                    ),
                ],
            ),
        ),
    ),
)

Proposed Actions

Here are some interfaces that have potential to be more compact.

Note that with both of the interfaces below, aince underscores are an invalid symbol in ReactJS properties, they would be automatically translated into hyphens. Single trailing underscores (ex _my_prop) would be automatically stripped to allow for for reserved keywords like for and while. Perhaps double underscore could work as an escape hatch denotation if underscores are truly wanted for that key value?

Context Manager API

with html.div(
    className="modal fade",
    _id="exampleModal",
    tabIndex="-1",
    aria_labeledby="exampleModalLabel",
    aria_hidden="true",
):
    with html.div(className="modal-dialog"):
        with html.div(className="modal-content"):
            modal_header(title="Modal Title")
            modal_body()
            with html.div(className="modal-footer"):
                html.hr()
                html.button(
                    "Close",
                    _type="button",
                    className="btn btn-secondary",
                    data_bs_dismiss="modal",
                    aria_label="Close",
                )
                html.button(
                    "Save Changes",
                    _type="button",
                    className="btn btn-primary",
                    data_bs_dismiss="modal",
                )

This has the added benefit of removing a lot of parenthesis, but comes at the cost of potentially feeling unnatural to users converting from ReactJS to ReactPy. As a note, what would traditionally be a list of elements with the old API would be done via for loops with this context manager API.

This interface design could be inspired by NiceGUI or Textual.

Props within kwargs and children within call args.

html.div(
    className="modal fade",
    _id="exampleModal",
    tabIndex="-1",
    aria_labeledby="exampleModalLabel",
    aria_hidden="true",
)(
    html.div(className="modal-dialog")(
        html.div(className="modal-content")(
            modal_header(title="Modal Title"),
            modal_body(),
            html.div(className="modal-footer")(
                html.hr(),
                [
                    html.button(
                        _type="button",
                        className="btn btn-secondary",
                        data_bs_dismiss="modal",
                        aria_label="Close",
                    )("Close"),
                    html.button(
                        _type="button",
                        className="btn btn-primary",
                        data_bs_dismiss="modal",
                    )("Save Changes"),
                ],
            ),
        )
    )
)

The biggest change is that ReactJS props would now be kwargs, and children would exist within a separate set of parenthesis call.


Previous discussions:

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority-2-moderateShould be resolved on a reasonable timeline.release-majorWarrents a major release

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions