Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Offer JsonSchemaForm based on rjsf #13951

Open
bollwyvl opened this issue Feb 9, 2023 · 0 comments
Open

Offer JsonSchemaForm based on rjsf #13951

bollwyvl opened this issue Feb 9, 2023 · 0 comments

Comments

@bollwyvl
Copy link
Contributor

bollwyvl commented Feb 9, 2023

References

Problem

As an extension author, given an arbitrarily complex description of some kinda of data, building an accesible, themable, internationalizable form with client-side validation in JupyterLab requires either:

  • hand-jamming a lot of DOM API
  • learning a virtual DOM library (react, lumino, or otherwise)
  • learning a specific library such as react-json-schema-form, final-form or formik

and then:

  • customizing the style to look harmonious in lab (or whatever, throw some material desing at it, bleah)

and then:

  • testing the above machinery
  • handling changes to the underlying schema and UI over time

Proposed Solution

JupyterLab has already invested in react-json-schema-form, an extension author should be able to re-use this investment with minimal disruption.

By exposing a SchemaForm extends Widget (from @lumino/widgets, not @rjsf/utils!) an extension author can compose this with other top-level JupyterLab components. With Promise and Signal APIs, and not worrying too much about the underlying details of rjsf (unless they want to) or even react, the form should "look good" in the host application.

Additional context

Basically do what @deathbeds/jupyterlab-rjsf does.

The initial lift would be limited to the primary form Widget API (wrapping the existing rjsf FormProps), and enough CSS to make something "look like Lab", leaving the existing, highly-bespoke forms (settings, metadata) unchanged.

A downstream example might look like:

import { JsonSchemaForm } from "@jupyterlab/ui-components";

import * as schema from "./my-schema.json";

// all the plugin boilerplate...

function activate(app: JupyterFrontEnd) {
  const form = new JsonSchemaForm({ schema });
  const main = new MainAreaWidget({ content: form });
  form.validated.connect(() => {
    if (content.errors.length) {
      beSadAbout();
    } else {
      doSomethingRadWith(content.instance);
    }
  });
  app.shell.add(main, "main");
}

Some properties of this, when combined along with ajv8:

If the full schema is known at runtime, something like content.validInstance can be fully typed at build time by ajv.JTDDataType. It's possible this could be handled transparently with a generic, but even if it has to be explicit, that is a very small amount of ink for a lot of value over time.

Future work

Some ideas for follow-on:

  • opt into rendering title, description, and ui:help fields as markdown.
    • since that upstream was written, some less-hacky approaches have appeared that might make it easier to bridge the highly-opinionated realms of the JupyterLab markdown rendering machinery, which is both async and needs a very concrete host DOM target, and react which of course knows better. Ugh.
  • exposing the form as a MIME renderer
    • basically if a kernel/whatever emitted an application/json that included schema and/or uiSchema in its metadata, a highly customized, human-readable form could be rendered
@bollwyvl bollwyvl added enhancement status:Needs Triage Applied to new issues that need triage labels Feb 9, 2023
@bollwyvl bollwyvl changed the title Offer SchemaForm based on rjsf Offer JsonSchemaForm based on rjsf Feb 9, 2023
@JasonWeill JasonWeill added status:Work in Progress and removed status:Needs Triage Applied to new issues that need triage labels Feb 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants