Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork19
A Custom Element that auto-generates forms, declaratively. Works with Lit, Solid, Vue, Svelte, React, Astro, vanilla…
License
json-schema-form-element/jsfe
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Effortless forms, with standards.
Features:
- Instantform generation based on your JSON schemas.
- Integrates within yourOpenAPI /JSON schema / MongoDB (BSON) stack.
- Comes withsensible defaults, while aiming forextensibility (themes, widgets…).
- ⚡️ Fast, and light 🪶.
Use cases:
- Quick CRUDs for you backends (JS, Python, PHP, Ruby…).
- Lightly interactive websites contact forms.
- Building block for custom CMSes.
- Building block for Markdown YAML frontmatter editors.
- Form builders… builder (🪆)
- You name it…
Due to theirdeclarative andserializable nature, JSON schemas are highlyinteroperable andportable.
Moreover,UI schemas can be declared alongside to customize the view layer.
You can alsooverride totally one ore more widgets, or justsprinkle some styles on top of the included ones.
Why?
While there is a handful of project for major frontend frameworks, there wasn't anyWeb Component packing all the features above.
Also if your are evaluatingWeb Component design systems or if you are building your own, this library is providing you a handy testbed.
See also theinspirations for this project.
Caution
Not for production.
Expect the doc. to be not in sync. with the actual released code.
Jump toimplementations:
—Pure HTML (CDN)—TypeScript only (DOM)—Astro (SSR) —
—Lit—Solid—Vue—Svelte—(P)React—
🗂️ Table of Contents
title:Stringrequired: -stringConstrainedproperties:simpleString:title:Simple inline stringtype:stringdefault:With default value from schemastringConstrained:title:String with constraintstype:stringpattern:'^[A-Z \d\W]+$'minLength:2maxLength:10description:Only UPPERCASE with 2 to 10 characters is allowed.textArea:title:Text areadescription:Using UI schema options.type:stringcolor:title:Color pickertype:stringdefault:'#4a90e2'
# UI schematextArea:'ui:widget':textarea'ui:placeholder':This is a placeholdercolor:'ui:widget':color
title:Numberproperties:float:title:Number (float)type:numberinteger:default:5title:Number (integer)type:integernumberConstrained:title:Number with constraintsdescription:min + max + multiple oftype:integerminimum:50maximum:100multipleOf:10range:title:Range with defaultdefault:28type:integerrangeConstrained:title:Range with constraintstype:integerminimum:-50maximum:50multipleOf:25
# UI schemarange:'ui:widget':rangerangeConstrained:'ui:widget':range
title:Booleanproperties:checkbox:title:Checkbox (default)type:booleanswitch:title:'Switch, enabled by default'type:booleandefault:trueradio:title:Radiotype:booleanradioWithDefault:title:'Radio, with default'type:booleandefault:falsebuttonGroup:title:Button grouptype:boolean
# UI schemaswitch:'ui:widget':switchradio:'ui:widget':radioradioWithDefault:'ui:widget':radiobuttonGroup:'ui:widget':button-group
title:Enumerationproperties:select:title:Select menu (default)properties:string:title:Stringtype:stringenum:[Ola, Hello, Bonjour, Buongiorno, Guten Tag]number:title:Numbertype:numberenum:[10, 100, 1000, 10000]description:With default value setdefault:1000radio:title:Radio groupproperties:string:title:Stringtype:stringenum:[Ola, Hello, Bonjour, Buongiorno, Guten Tag]number:title:Numbertype:numberenum:[10, 100, 1000, 10000]description:With default value setdefault:1000buttonGroup:title:Button groupproperties:string:title:Stringtype:stringenum:[Ola, Hello, Bonjour, Buongiorno, Guten Tag]default:Oladescription:With default value setnumber:title:Numbertype:numberenum:[10, 100, 1000, 10000]
# UI schemaradio:string:'ui:widget':radionumber:'ui:widget':radiobuttonGroup:string:'ui:widget':button-groupnumber:'ui:widget':button-group
title:Date and timeproperties:datetime:title:Date and timedescription:Hurry up!type:stringformat:date-timedate:title:Datetype:stringformat:datetime:title:Timetype:stringformat:time
title:Object typedescription:Nests each property to a field in a fieldset.required: -textBarproperties:textFoo:title:Some text inputtype:stringdescription:The help text is from "description".textBar:title:Some other -required- text inputtype:string
🚧……🚧
title:Basic arraytype:arrayitems:properties:textA:title:Some field Atype:stringtextB:title:Some field Btype:string
title:Fixed arraytype:arrayitems: -title:A numbertype:numberdefault:42 -title:A booleantype:booleandefault:false -title:An objectproperties:when:title:A datetype:stringformat:date
title:Prepopulated and nested arraystype:arrayitems:title:Grouptype:arrayitems:title:Some sub-fieldtype:string
# DataprepopulatedNested: -- Hello -Ola
title:A multiple choices list with checkboxesdescription:Please choose yum yum.type:arrayuniqueItems:trueitems:type:stringenum: -Apple -Banana -Mango -Tomato -Baguette -Beaufort -Comté -Avocado
🚧……🚧
🚧……🚧
🚧……🚧
🚧……🚧
🚧……🚧
🚧……🚧
🚧……🚧
🚧……🚧
🚧……🚧
🚧……🚧
This is for the bare package. You'll have to bring all the widgets yourself.
npm i @jsfe/form# orpnpm i @jsfe/form# oryarn add @jsfe/form
Seeexamples/src/pages/flavored.astro
Alternatively:
npm install @jsfe/shoelacenpm install @jsfe/materialnpm install @jsfe/carbonnpm install @jsfe/wirednpm install @jsfe/system<jsf-shoelaceschema="..."uiSchema="..."data="..."></jsf-shoelace><jsf-materialschema="..."uiSchema="..."data="..."></jsf-material><jsf-carbonschema="..."uiSchema="..."data="..."></jsf-carbon><jsf-wiredschema="..."uiSchema="..."data="..."></jsf-wired><jsf-systemschema="..."uiSchema="..."data="..."></jsf-system>
See also theCSS section.
Caution
This project is new, API is subject to changes
You can try themulti-frameworks examples like this:
npx degit https://github.com/json-schema-form-element/examples jsfe-examplescd jsfe-examplesnpm inpm run devImplementation | Working sources | Code sandbox |
|---|---|---|
Nowadays, there are many different strategies for CSS loading / bundling.JSFE is embedding its own style in its shadow, but for components libraries (here Shoelace) you should act depending on your current workflow.
References:
- https://lit.dev/docs/components/styles
- https://vitejs.dev/guide/features.html#css
- https://shoelace.style/getting-started/installation#light-and-dark-theme
Shoelace is embedding styles chunks accross components, however CSS custom propertiesare injected globally.
| API | No framework | Astro (SSR) | Lit | Solid | Vue | React / Preact | Svelte |
|---|---|---|---|---|---|---|---|
| Declarative control | ✅ | ✅ | ✅ | ✅ viaprop: | ✅ | ❌ | ❌(4) |
| Declarative inference | ❌(1) | ❌(2) | ❌(3) | ✅ viaprop: | ❌ | ❌ | ❌ |
| Declarative type-checking | ❌(1) | ❌(2) | ✅ | ✅ viaprop: | ❌ | ❌ | ❌ |
| Imperative control | ✅ via DOM | - | ✅ viaref | ✅ viaref | ✅ viaref | ✅ viaref | ✅ viause: |
| Imperative inference | ✅ via DOM | - | ✅ viaref | ✅ viaref | ✅ viaref | ✅ viaref | ✅ viause: |
| Imperative type-checking | ✅ via DOM | - | ✅ viaref | ✅ viaref | ✅ viaref | ✅ viaref | ✅ viause: |
- HTML language servers can't support TypeScript obviously. But IDE can leverage Custom Element metadata.
- Astro JSX namespace / LSP are not handling
HTMLElementTagNameMapor Custom Element metadata, yet. - Template literals are preventing automatic properties inference, but at least, you can't assign wrong argument types without knowing it.
- Svelte heuristics are not clear regardingattributes versusproperties handling. Better be safe than sorry. Also the
use:directive is neat.
There might be changes regarding support for Web Components accross various the various UI frameworks above.Please file an issue if an info is wrong or missing.
Each implementation examples are trying to show off the most type-safe way to use JSFE, with the least trade-offs.
Using it moredeclaratively orimperatively is up to you, your framework ability and you coding style.
Both usages are valid and can be mixed. Typically when you want to use the schema elsewhere in your app., orwhen your callbacks are getting too beefy, you'll better extract them from templates.
Generally, imperative usage get perfect TypeScript support (you just handle the class), whereas declaratively, you'll haveto deal with various template languages limitations (this is an universal problem).
Important
Before you dive in, here is some context about Web Components libraries support with JSFE.
Whereas you are starting from scratch or you want to integrate declarative forms inan existing project, you'll want tochoose an UI library orbuild your own from scratch (or a mix of both).
In either case, JSFE got you covered up, as an agnostic platform for consumingstandardized form inputs widgets (seetypes).
Web Components technologies has a lot of traction in 2022-23, with big nameslaunching their own collections. As any flourishing eco-system, there areopinions.
Fortunately,most divergences happens on theCSS side. Specifically on styles consuming mechanisms.
As the initial maintainer, I decided to focus onShoelace, while experimenting with othergreat options out there.
Why so?
- Keep an eye on converging practices across vendors.
- Ensure thatJSFE remains not to tied withShoelace way of things (which is already quite thin, relatively).
- Be able to swap out built-ins for custom widgets on a pinch, when needed.
- Borrow valuable ideas from others libraries and re-implement them with Shoelace bits when lacking.
Warning
I will not maintain thefull spectrum ofJSFE widgets, accross all libraries!
But I will do my best to provide all the hooks you need, thanks to anagnostic andtype-safe API,smoothening some peculiarities.
Also, expect varying support for CSS implementations as for now, in 2023, it's just a bit too wild to keep up.
Non-exhaustive notes about what you might deal with WC components libraries' CSS:
- Carbon use pure SCSS import, with mixins. Only root element seems to be allowed for CSS vars injection (no
:hostor<body>…). - Material UI uses a JS color utility to inject CSS vars on
styleattributes, with a sophisticated color generator. - Shoelace is straightforward by giving us regular CSS files with vars I can apply on a boring class. But that also means you have to build your own color palette if you want to match your brand (it's easy).
- Spectrum use licensed fonts it seems?
- Spectrum has a tricky dependencies injection system, it took me the longest to achieve, and it's not perfect yet.
I'll not expand up furthermore on that, but if you're curious, it's you're lucky day. You cansee and compare all styles implementations across UI libs in examples.
Also, I recommend that you take a peek at theplayground source-code for themes wizardry.
I find little gems in all of these frameworks, for example:
- Carbon has neat rocker switchs for numbers
- Adobe kills it with colours
- Wired is fun
- Material has an innovative color themes generator
- …you'll find some others too!
I'm not an expert on each of this libs., and please note many of them are quite new / rapidly evolving.
That's why it's interesting to keep a bird-eye view from time to time.
Overall, Shoelace seems to be the most equilibrated in my eyes.
If you require top-notch support for you favourite UI lib. which is not Shoelace,I encourage you to contribute,like people did for theReact JSON Schema Form project.
Core maintainers are working on the reference implementation, and community can add things of their interest.
If you want to enhance the lib. by bringing support for more fields, it's quite easy!
Just take a peek on theShoelace package,which is the canonical implementation (meaning it's the most complete, API-wise).
Then, you are welcome to make a pull request with new features, or bug fixes.
Shoelace is the UI component library of choice for rendering fields, and as ageneral design system backbone forJSFE.
It's beautiful, aims for simplicity, is not too opinionated, while still having character.
That's why it's the very first library implemented inJSFE.
You might have noticed thatJSFE is not using Custom Elements as a medium for injecting widgets.
First prototypes were using them, but I've had troubles regarding the parent form element awareness about its children.
E.g. with Shoelace, inputs weren't responding well with form validation, theENTER key for submit, etc.
I'm sure there are ways to circumvent those hassles (forwarding events…). I tried, but for now it's not a priority, as that might affect various UI libs in different ways.
Moreover, Web Components users are eager to seeCustom Registries becoming maintream.That will make the process of overriding widgets much more flexible.
For now, using Lit'sTemplateResult (from a function returning ahtml literal) is straight-forward, however there are some trade-offs; it's a state-less function, no CSS scoping, lit-tied, etc.
Ultimately, goal is to make JSFE fully modular and agnostic, by using well-defined Custom Elements, for each individual form control.
🚧……🚧
You're responsible to hook-up additional / more advanced validation with, e.g, AJV.
HTML native validation is already quite powerful, but you might want to doyour own wizardry.Note that client-validation is more for user experience,while server validation is here to ensure data integrity, provide context aware round-trips…
JSON schemas are easing up the constraints enforcement for moving data around, but you'll still have to manage traditional chores.
Good news is that they give you more time to take care of business related operations, UX…
Same as advanced validation handling above,JSFE doesn't bundle, dereference, nor it is fetching remoteschemas.
Doing so would add a huge payload to the library, and you might certainly have already those tools at hand somewhere in your stack.
Only thing it does is resolvingJSON references, pointing tolocal definitions only.This is because implementation is relatively trivial, without much code, and that's a much needed feature for DRY-ness, recursivity…
Hopefully it's easy to bring in an full-featured parser / resolver along, like thejson-schema-ref-parser.
See./custom-elements.json &./custom-elements.md
With internal dependencies included, minus peer dependencies (UI libs.):
| Package | Size | Version |
|---|---|---|
| @jsfe/form | ||
| @jsfe/shoelace | ||
| @jsfe/material | ||
| @jsfe/carbon | ||
| @jsfe/wired | ||
| @jsfe/system | ||
| @jsfe/types |
@jsfe/form contains the base class from which all other packages extends themselves from.
You don't need to install it, unless you want to provide widgets and styles from scratch.
If you just want to overridesome of the flavored components,@jsfe/<theme> packages are handy starters.
@jsfe/types contains everything for assisting your own widgets authoring.
It's re-exported from every package so you don't need to install it on your own.
Tip
You can try the upcoming release from thenext branch like this:npm i @jsfe/<package>@next.
To activate experimental features preview flags, just pass theexperimental property.
E.g. with Lit:
html`<json-schema-formotherProps="...".experimental=${{'<flag>':true,// ...}}></json-schema-form>`;
Actualfeatures flags list:
- None
- BYOC (bring your own components).
- Extensive and modern JSON Schema support (identify Draft 4 / 7 / 2020 subtleties).
- Nice file uploaders for the
data-urlformat. - Layout customizations
- Tests, browser based (due to the WC nature).
- Tests, tests, even more tests in the field to reveal shortcomings.
- Drag and drop: improve the initial implementation (E.g. cross-nested arrays).
- Autofocuses (for added array item, etc.)
- …
- Have an idea?Discussions are open!
The Web Component andJSON Schema communities, theLit team, theShoelace maintainers,…
As a workhorse for many projects of mine for a long time, I'm grateful for allthe ideas RSJF creators brought.
Similar projects:
See also:
- remark-lint-frontmatter-schema: Validate your Markdownfrontmatter data against aJSON schema.
- retext-case-police: Check popular names casing. Example:
⚠️ github→ ✅GitHub. - astro-openapi: An Astro toolset for building full-stack operations easily, with type-safety and documentation as first-class citizens.
About
A Custom Element that auto-generates forms, declaratively. Works with Lit, Solid, Vue, Svelte, React, Astro, vanilla…
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Sponsor this project
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.










