{"id":14962574,"url":"https://github.com/json-schema-form-element/jsfe","last_synced_at":"2025-04-06T12:09:16.266Z","repository":{"id":196812394,"uuid":"694582379","full_name":"json-schema-form-element/jsfe","owner":"json-schema-form-element","description":"A Custom Element that auto-generates forms, declaratively. Works with Lit, Solid, Vue, Svelte, React, Astro, vanilla…","archived":false,"fork":false,"pushed_at":"2024-09-21T15:41:12.000Z","size":459,"stargazers_count":140,"open_issues_count":13,"forks_count":14,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-30T09:09:13.779Z","etag":null,"topics":["form","form-builder","form-generator","form-validator","json-schema","lit","material","react","reactjs","shoelace","solid","sveltejs","vue","web-component"],"latest_commit_sha":null,"homepage":"https://jsfe.js.org","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/json-schema-form-element.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-21T09:34:49.000Z","updated_at":"2025-03-28T21:09:53.000Z","dependencies_parsed_at":null,"dependency_job_id":"5b05a9f3-33dd-4159-b7ce-2a540ff1c9ea","html_url":"https://github.com/json-schema-form-element/jsfe","commit_stats":{"total_commits":47,"total_committers":3,"mean_commits":"15.666666666666666","dds":"0.14893617021276595","last_synced_commit":"1e082e4aa5d67617fd9a982d44ca031560404e16"},"previous_names":["json-schema-form-element/core","json-schema-form-element/jsfe"],"tags_count":46,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/json-schema-form-element%2Fjsfe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/json-schema-form-element%2Fjsfe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/json-schema-form-element%2Fjsfe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/json-schema-form-element%2Fjsfe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/json-schema-form-element","download_url":"https://codeload.github.com/json-schema-form-element/jsfe/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247478152,"owners_count":20945258,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["form","form-builder","form-generator","form-validator","json-schema","lit","material","react","reactjs","shoelace","solid","sveltejs","vue","web-component"],"created_at":"2024-09-24T13:30:02.735Z","updated_at":"2025-04-06T12:09:16.230Z","avatar_url":"https://github.com/json-schema-form-element.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 📝  JSON Schema Form Element\n\n[![Published on webcomponents.org](https://img.shields.io/badge/webcomponents.org-published-blue.svg)](https://www.webcomponents.org/element/@jsfe/form)\n[![ISC License](https://img.shields.io/npm/l/@jsfe/form)](./LICENSE)\n![Downloads](https://img.shields.io/npm/dt/@jsfe/form)\n[![GitHub](https://img.shields.io/badge/Repository-222222?logo=github)](https://github.com/json-schema-form-element/jsfe)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen)](https://makeapullrequest.com)  \n[![TypeScript](https://img.shields.io/badge/TypeScript-333333?logo=typescript)](http://www.typescriptlang.org/)\n[![SCSS](https://img.shields.io/badge/SCSS-333333.svg?logo=sass)](https://sass-lang.com)\n[![Prettier](https://img.shields.io/badge/Prettier-333333?logo=prettier)](https://prettier.io)\n[![EditorConfig](https://img.shields.io/badge/EditorConfig-333333?logo=editorconfig)](https://editorconfig.org)\n[![ESLint](https://img.shields.io/badge/ESLint-3A33D1?logo=eslint)](https://eslint.org)\n[![Stylelint](https://img.shields.io/badge/Stylelint-222222?logo=Stylelint)](https://stylelint.io)\n\n\u003c!-- ![Downloads](https://img.shields.io/npm/dt/@jsfe/form) --\u003e\n\nEffortless forms, with standards.\n\n**Features**:\n\n- Instant **form generation** based on your JSON schemas.\n- Integrates within your **OpenAPI** / **JSON schema** / MongoDB (BSON) stack.\n- Comes with **sensible defaults**, while aiming for **extensibility** (themes, widgets…).\n- ⚡️ Fast, and light 🪶.\n\n**Use cases**:\n\n- Quick CRUDs for you backends (JS, Python, PHP, Ruby…).\n- Lightly interactive websites contact forms.\n- Building block for custom CMSes.\n- Building block for Markdown YAML frontmatter editors.\n- Form builders… builder (🪆)\n- _You name it_…\n\nDue to their **declarative** and **serializable** nature, JSON schemas are highly **interoperable** and **portable**.  \nMoreover, **UI schemas** can be declared alongside to customize the view layer.  \nYou can also **override totally** one ore more widgets, or just **sprinkle some styles** on top of the included ones.\n\n**Why?**\n\nWhile there is a handful of project for major frontend frameworks, there wasn't any **Web Component** packing all the features above.  \nAlso if your are evaluating **Web Component design systems** or if you are building your own, this library is providing you a handy testbed.\n\nSee also the [inspirations](#acknowledgements) for this project.\n\n\u003c!-- **Theming**\n\nComes with Shoelace 2 and Google Material 3 web components libraries or barebone, with Bootstrap 5 semantics. --\u003e\n\n\u003c!-- **Customization**\n\nSwap built-in components with your own, or add custom widget thanks to [UI schema](#schema) definitions. --\u003e\n\n\u003e [!CAUTION]  \n\u003e Not for production.  \n\u003e Expect the doc. to be not in sync. with the actual released code.\n\n![](https://ik.imagekit.io/jc0/jsfe/design/header_json-schema-form-element_2RpVU_W-y-.png?updatedAt=1695289194993)\n\n\u003cdiv align=\"center\"\u003e\n\u003ch4\u003e\u003ca href=\"https://jsfe.js.org\" \u003e🕹️ Open the playground (jsfe.js.org)\u003c/a\u003e\u003c/h4\u003e\n\n---\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/json-schema-form-element/examples)\n\n\u003c/div\u003e\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\nJump to **implementations**:  \n— [Pure HTML (CDN)](#pure-html-with-cdn)\n— [TypeScript only (DOM)](#typescript-no-framework)\n— [Astro (SSR)](#astro-ssr) —  \n— [Lit](#lit)\n— [Solid](#solid)\n— [Vue](#vue)\n— [Svelte](#svelte)\n— [(P)React](#react)\n—\n\n\u003c/div\u003e\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\nJump to [**UI libraries**](#component-libraries):  \n— [Shoelace](#ui-libraries)\n— [Material](#ui-libraries)\n— [Carbon](#ui-libraries)\n— [Wired](#ui-libraries)\n— [System](#ui-libraries)\n—\n\n\u003c/div\u003e\n\n---\n\n\u003cdetails\u003e\n\u003csummary  align=\"center\"\u003e\u003cstrong\u003e🗂️ Table of Contents\u003c/strong\u003e\u003c/summary\u003e\n\n\u003c!-- prettier-ignore --\u003e\n- [Field types](#field-types)\n\t- [Primitives](#primitives)\n\t\t- [String](#string)\n\t\t- [Number](#number)\n\t\t- [Boolean](#boolean)\n\t\t- [Enumeration](#enumeration)\n\t\t- [Date](#date)\n\t- [Object](#object)\n\t\t- [Additional properties](#additional-properties)\n\t- [Arrays](#arrays)\n\t\t- [Basic](#basic)\n\t\t- [Fixed](#fixed)\n\t\t- [Nested](#nested)\n\t\t- [Multiple choices (enums.)](#multiple-choices-enums)\n\t\t- [Additional items](#additional-items)\n- [Subschemas](#subschemas)\n\t- [allOf](#allof)\n\t- [oneOf](#oneof)\n\t- [anyOf](#anyof)\n- [Conditionals](#conditionals)\n\t- [Dependencies](#dependencies)\n\t- [If, then, else](#if-then-else)\n- [Miscellaneous](#miscellaneous)\n\t- [References](#references)\n\t- [Recursivity](#recursivity)\n\t- [Nullable values](#nullable-values)\n- [User Interface](#user-interface)\n\t- [Schema](#schema)\n- [Usage](#usage)\n\t- [Installation](#installation)\n\t\t- [UI Libraries](#ui-libraries)\n\t- [Implementations](#implementations)\n\t\t- [All examples](#all-examples)\n\t\t- [Pure HTML with CDN](#pure-html-with-cdn)\n\t\t- [TypeScript (no framework)](#typescript-no-framework)\n\t\t- [Astro (SSR)](#astro-ssr)\n\t\t- [Lit](#lit)\n\t\t- [Solid](#solid)\n\t\t- [Vue](#vue)\n\t\t- [Svelte](#svelte)\n\t\t- [React](#react)\n\t- [CSS](#css)\n\t- [TypeScript](#typescript)\n\t\t- [Support for each implementation](#support-for-each-implementation)\n- [Component libraries](#component-libraries)\n\t- [Shoelace](#shoelace)\n\t- [Custom widgets](#custom-widgets)\n\t\t- [Design choices](#design-choices)\n- [Validation](#validation)\n- [Schema massaging](#schema-massaging)\n- [Custom Elements Manifests](#custom-elements-manifests)\n- [Packages informations](#packages-informations)\n\t- [_Next_ versions](#next-versions)\n- [Experimental features](#experimental-features)\n- [Improvements](#improvements)\n- [Acknowledgements](#acknowledgements)\n\n\u003c/details\u003e\n\n---\n\n## Field types\n\n### Primitives\n\n#### String\n\n![](https://ik.imagekit.io/jc0/jsfe/design/screenshots/fields/string_kWHRZlCmX.png?updatedAt=1695289199793)\n\n```yaml\ntitle: String\nrequired:\n  - stringConstrained\n\nproperties:\n  simpleString:\n    title: Simple inline string\n    type: string\n    default: With default value from schema\n\n  stringConstrained:\n    title: String with constraints\n    type: string\n    pattern: '^[A-Z \\d\\W]+$'\n    minLength: 2\n    maxLength: 10\n    description: Only UPPERCASE with 2 to 10 characters is allowed.\n\n  textArea:\n    title: Text area\n    description: Using UI schema options.\n    type: string\n\n  color:\n    title: Color picker\n    type: string\n    default: '#4a90e2'\n```\n\n```yaml\n# UI schema\ntextArea:\n  'ui:widget': textarea\n  'ui:placeholder': This is a placeholder\ncolor:\n  'ui:widget': color\n```\n\n#### Number\n\n![](https://ik.imagekit.io/jc0/jsfe/design/screenshots/fields/number_yX9YKqWfo.png?updatedAt=1695289197011)\n\n```yaml\ntitle: Number\n\nproperties:\n  float:\n    title: Number (float)\n    type: number\n\n  integer:\n    default: 5\n    title: Number (integer)\n    type: integer\n\n  numberConstrained:\n    title: Number with constraints\n    description: min + max + multiple of\n    type: integer\n    minimum: 50\n    maximum: 100\n    multipleOf: 10\n\n  range:\n    title: Range with default\n    default: 28\n    type: integer\n\n  rangeConstrained:\n    title: Range  with constraints\n    type: integer\n    minimum: -50\n    maximum: 50\n    multipleOf: 25\n```\n\n```yaml\n# UI schema\nrange:\n  'ui:widget': range\nrangeConstrained:\n  'ui:widget': range\n```\n\n#### Boolean\n\n![](https://ik.imagekit.io/jc0/jsfe/design/screenshots/fields/boolean_yjmdyRBwN.png?updatedAt=1695289196457)\n\n```yaml\ntitle: Boolean\n\nproperties:\n  checkbox:\n    title: Checkbox (default)\n    type: boolean\n\n  switch:\n    title: 'Switch, enabled by default'\n    type: boolean\n    default: true\n\n  radio:\n    title: Radio\n    type: boolean\n\n  radioWithDefault:\n    title: 'Radio, with default'\n    type: boolean\n    default: false\n\n  buttonGroup:\n    title: Button group\n    type: boolean\n```\n\n```yaml\n# UI schema\nswitch:\n  'ui:widget': switch\nradio:\n  'ui:widget': radio\nradioWithDefault:\n  'ui:widget': radio\nbuttonGroup:\n  'ui:widget': button-group\n```\n\n#### Enumeration\n\n![](https://ik.imagekit.io/jc0/jsfe/design/screenshots/fields/enumeration_O9QtaJKDW.png?updatedAt=1695289198058)\n\n```yaml\ntitle: Enumeration\n\nproperties:\n  select:\n    title: Select menu (default)\n    properties:\n      string:\n        title: String\n        type: string\n        enum: [Ola, Hello, Bonjour, Buongiorno, Guten Tag]\n      number:\n        title: Number\n        type: number\n        enum: [10, 100, 1000, 10000]\n        description: With default value set\n        default: 1000\n\n  radio:\n    title: Radio group\n    properties:\n      string:\n        title: String\n        type: string\n        enum: [Ola, Hello, Bonjour, Buongiorno, Guten Tag]\n      number:\n        title: Number\n        type: number\n        enum: [10, 100, 1000, 10000]\n        description: With default value set\n        default: 1000\n\n  buttonGroup:\n    title: Button group\n    properties:\n      string:\n        title: String\n        type: string\n        enum: [Ola, Hello, Bonjour, Buongiorno, Guten Tag]\n        default: Ola\n        description: With default value set\n      number:\n        title: Number\n        type: number\n        enum: [10, 100, 1000, 10000]\n```\n\n```yaml\n# UI schema\nradio:\n  string:\n    'ui:widget': radio\n  number:\n    'ui:widget': radio\n\nbuttonGroup:\n  string:\n    'ui:widget': button-group\n  number:\n    'ui:widget': button-group\n```\n\n#### Date\n\n![](https://ik.imagekit.io/jc0/jsfe/design/screenshots/fields/date_0OQk6xh5o.png?updatedAt=1695289196256)\n\n```yaml\ntitle: Date and time\n\nproperties:\n  datetime:\n    title: Date and time\n    description: Hurry up!\n    type: string\n    format: date-time\n\n  date:\n    title: Date\n    type: string\n    format: date\n\n  time:\n    title: Time\n    type: string\n    format: time\n```\n\n### Object\n\n![](https://ik.imagekit.io/jc0/jsfe/design/screenshots/fields/object_d5h6WASTP.png?updatedAt=1695289194664)\n\n```yaml\ntitle: Object type\ndescription: Nests each property to a field in a fieldset.\nrequired:\n  - textBar\n\nproperties:\n  textFoo:\n    title: Some text input\n    type: string\n    description: The help text is from \"description\".\n\n  textBar:\n    title: Some other -required- text input\n    type: string\n```\n\n#### Additional properties\n\n🚧……🚧\n\n### Arrays\n\n#### Basic\n\n![](https://ik.imagekit.io/jc0/jsfe/design/screenshots/fields/array-basic_FWWfDhpwQ.png?updatedAt=1695289197520)\n\n```yaml\ntitle: Basic array\ntype: array\n\nitems:\n  properties:\n    textA:\n      title: Some field A\n      type: string\n    textB:\n      title: Some field B\n      type: string\n```\n\n#### Fixed\n\n![](https://ik.imagekit.io/jc0/jsfe/design/screenshots/fields/array-fixed_5rVKt1A_h_.png?updatedAt=1695289195885)\n\n```yaml\ntitle: Fixed array\ntype: array\n\nitems:\n  - title: A number\n    type: number\n    default: 42\n  - title: A boolean\n    type: boolean\n    default: false\n  - title: An object\n    properties:\n      when:\n        title: A date\n        type: string\n        format: date\n```\n\n#### Nested\n\n![](https://ik.imagekit.io/jc0/jsfe/design/screenshots/fields/array-nested_doIhIi99j.png?updatedAt=1695289200095)\n\n```yaml\ntitle: Prepopulated and nested arrays\ntype: array\n\nitems:\n  title: Group\n  type: array\n\n  items:\n    title: Some sub-field\n    type: string\n```\n\n```yaml\n# Data\nprepopulatedNested:\n  - - Hello\n    - Ola\n```\n\n#### Multiple choices (enums.)\n\n![](https://ik.imagekit.io/jc0/jsfe/design/screenshots/fields/array-multichoices_hjCAewQR9.png?updatedAt=1695289199921)\n\n```yaml\ntitle: A multiple choices list with checkboxes\ndescription: Please choose yum yum.\ntype: array\nuniqueItems: true\n\nitems:\n  type: string\n  enum:\n    - Apple\n    - Banana\n    - Mango\n    - Tomato\n    - Baguette\n    - Beaufort\n    - Comté\n    - Avocado\n```\n\n#### Additional items\n\n🚧……🚧\n\n\u003c!-- ## Installation --\u003e\n\n\u003c!-- TODO --\u003e\n\n## Subschemas\n\n### allOf\n\n🚧……🚧\n\n### oneOf\n\n🚧……🚧\n\n### anyOf\n\n🚧……🚧\n\n## Conditionals\n\n### Dependencies\n\n🚧……🚧\n\n### If, then, else\n\n🚧……🚧\n\n## Miscellaneous\n\n### References\n\n🚧……🚧\n\n### Recursivity\n\n🚧……🚧\n\n### Nullable values\n\n🚧……🚧\n\n## User Interface\n\n### Schema\n\n🚧……🚧\n\n## Usage\n\n### Installation\n\n**This is for the bare package**. You'll have to bring all the widgets yourself.\n\n```sh\nnpm i @jsfe/form\n# or\npnpm i @jsfe/form\n# or\nyarn add @jsfe/form\n```\n\n#### UI Libraries\n\nSee [examples/src/pages/flavored.astro](https://github.com/json-schema-form-element/examples/blob/main/src/pages/flavored.astro)\n\n_Alternatively_:\n\n```\nnpm install @jsfe/shoelace\nnpm install @jsfe/material\nnpm install @jsfe/carbon\nnpm install @jsfe/wired\nnpm install @jsfe/system\n```\n\n```html\n\u003cjsf-shoelace schema=\"...\" uiSchema=\"...\" data=\"...\"\u003e\u003c/jsf-shoelace\u003e\n\u003cjsf-material schema=\"...\" uiSchema=\"...\" data=\"...\"\u003e\u003c/jsf-material\u003e\n\u003cjsf-carbon schema=\"...\" uiSchema=\"...\" data=\"...\"\u003e\u003c/jsf-carbon\u003e\n\u003cjsf-wired schema=\"...\" uiSchema=\"...\" data=\"...\"\u003e\u003c/jsf-wired\u003e\n\u003cjsf-system schema=\"...\" uiSchema=\"...\" data=\"...\"\u003e\u003c/jsf-system\u003e\n```\n\n\u003c!-- ```ts\nimport '@jsfe/form';\n``` --\u003e\n\n\u003c!-- ```ts\nimport '@shoelace-style/shoelace/dist/themes/light.css';\nimport '@shoelace-style/shoelace/dist/themes/dark.css';\n``` --\u003e\n\nSee also the [CSS section](#CSS).\n\n### Implementations\n\n\u003e [!CAUTION]  \n\u003e This project is new, API is subject to changes\n\n#### All examples\n\nYou can try the [multi-frameworks examples](https://github.com/json-schema-form-element/examples) like this:\n\n```\nnpx degit https://github.com/json-schema-form-element/examples jsfe-examples\n\ncd jsfe-examples\n\nnpm i\nnpm run dev\n```\n\n---\n\n\u003c!-- TODO: for WebComponents.org --\u003e\n\u003c!--\n```\n\u003ccustom-element-demo\u003e\n  \u003ctemplate\u003e\n    \u003clink rel=\"import\" href=\"my-element.html\"\u003e\n    \u003clink rel=\"import\" href=\"../other-element/other-element.html\"\u003e\n    \u003cnext-code-block\u003e\u003c/next-code-block\u003e\n  \u003c/template\u003e\n\u003c/custom-element-demo\u003e\n```\n--\u003e\n\u003c!-- ```html\n\u003cother-element\u003e\u003c/other-element\u003e\n\u003cmy-element\u003e\u003c/my-element\u003e\n``` --\u003e\n\n\u003ctable\u003e\n\u003cthead\u003e\n\u003ctr\u003e\n\u003cth valign=\"center\"\u003e\n\nImplementation\n\n\u003c/th\u003e\n\u003cth valign=\"center\"\u003e\n\nWorking sources\n\n\u003c/th\u003e\n\u003cth valign=\"center\"\u003e\n\nCode sandbox\n\n\u003c/th\u003e\n\u003c/tr\u003e\n\u003c/thead\u003e\n\u003ctbody\u003e\n\u003ctr\u003e\n\u003ctd valign=\"center\"\u003e\n\n#### Pure HTML with CDN\n\n\u003cbr /\u003e\n\u003c/td\u003e\n\u003ctd valign=\"center\"\u003e\n\n[🗂️ examples/src/pages/pure-html.html](https://github.com/json-schema-form-element/examples/blob/main/src/pages/pure-html.html)\n\n\u003c/td\u003e\n\u003ctd valign=\"center\" align=\"center\"\u003e\n\n[Open in **CodePen.io**](https://codepen.io/JulianCataldo/pen/KKbBepN?editors=1001)\n\n---\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/json-schema-form-element/examples?file=src%2Fpages%2Fpure-html.html)\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd valign=\"center\"\u003e\n\n#### TypeScript (no framework)\n\n\u003cbr /\u003e\n\u003c/td\u003e\n\u003ctd valign=\"center\"\u003e\n\n[🗂️ examples/src/components/TypeScriptOnly.ts](https://github.com/json-schema-form-element/examples/blob/main/src/components/TypeScriptOnly.ts)\n\n\u003c/td\u003e\n\u003ctd valign=\"center\" align=\"center\"\u003e\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/json-schema-form-element/examples?file=src%2Fcomponents%2FTypeScriptOnly.ts)\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd valign=\"center\"\u003e\n\n#### Astro (SSR)\n\n\u003cbr /\u003e\n\u003c/td\u003e\n\u003ctd valign=\"center\"\u003e\n\n[🗂️ examples/src/components/AstroJs.astro](https://github.com/json-schema-form-element/examples/blob/main/src/components/AstroJs.astro)\n\n\u003c/td\u003e\n\u003ctd valign=\"center\" align=\"center\"\u003e\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/json-schema-form-element/examples?file=src%2Fcomponents%2FAstroJs.astro)\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd valign=\"center\"\u003e\n\n#### Lit\n\n\u003cbr /\u003e\n\u003c/td\u003e\n\u003ctd valign=\"center\"\u003e\n\n[🗂️ examples/src/components/LitJs.ts](https://github.com/json-schema-form-element/examples/blob/main/src/components/LitJs.ts)\n\n\u003c/td\u003e\n\u003ctd valign=\"center\" align=\"center\"\u003e\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/json-schema-form-element/examples?file=src%2Fcomponents%2FLitJs.ts)\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd valign=\"center\"\u003e\n\n#### Solid\n\n\u003cbr /\u003e\n\u003c/td\u003e\n\u003ctd valign=\"center\"\u003e\n\n[🗂️ examples/src/components/SolidJs.solid.tsx](https://github.com/json-schema-form-element/examples/blob/main/src/components/SolidJs.solid.tsx)\n\n\u003c/td\u003e\n\u003ctd valign=\"center\" align=\"center\"\u003e\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/json-schema-form-element/examples?file=src%2Fcomponents%2FSolidJs.solid.tsx)\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd valign=\"center\"\u003e\n\n#### Vue\n\n\u003cbr /\u003e\n\u003c/td\u003e\n\u003ctd valign=\"center\"\u003e\n\n[🗂️ examples/src/components/VueJs.vue](https://github.com/json-schema-form-element/examples/blob/main/src/components/VueJs.vue)\n\n\u003c/td\u003e\n\u003ctd valign=\"center\" align=\"center\"\u003e\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/json-schema-form-element/examples?file=src%2Fcomponents%2FVueJs.vue)\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd valign=\"center\"\u003e\n\n#### Svelte\n\n\u003cbr /\u003e\n\u003c/td\u003e\n\u003ctd valign=\"center\"\u003e\n\n[🗂️ examples/src/components/VueJs.vue](https://github.com/json-schema-form-element/examples/blob/main/src/components/VueJs.vue)\n\n\u003c/td\u003e\n\u003ctd valign=\"center\" align=\"center\"\u003e\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/json-schema-form-element/examples?file=src%2Fcomponents%2FVueJs.vue)\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd valign=\"center\"\u003e\n\n#### React\n\n\u003cbr /\u003e\n\u003c/td\u003e\n\u003ctd valign=\"center\"\u003e\n\n[🗂️ examples/src/components/ReactJs18.react.tsx](https://github.com/json-schema-form-element/examples/blob/main/src/components/ReactJs18.react.tsx)\n\n\u003c/td\u003e\n\u003ctd valign=\"center\" align=\"center\"\u003e\n\n[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/json-schema-form-element/examples?file=src%2Fcomponents%2FReactJs18.react.tsx)\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/tbody\u003e\n\n\u003c/table\u003e\n\n### CSS\n\nNowadays, there are many different strategies for CSS loading / bundling.\n_JSFE_ is embedding its own style in its shadow, but for components libraries (here Shoelace) you should act depending on your current workflow.\n\n**References**:\n\n- \u003chttps://lit.dev/docs/components/styles\u003e\n- \u003chttps://vitejs.dev/guide/features.html#css\u003e\n- \u003chttps://shoelace.style/getting-started/installation#light-and-dark-theme\u003e\n\nShoelace is embedding styles chunks accross components, however CSS custom properties\nare injected globally.\n\n\u003c!-- TODO --\u003e\n\n### TypeScript\n\n#### Support for each implementation\n\n| API                       | No framework      | Astro (SSR)       | Lit               | Solid          | Vue          | React / Preact | Svelte            |\n| ------------------------- | ----------------- | ----------------- | ----------------- | -------------- | ------------ | -------------- | ----------------- |\n| Declarative control       | ✅                | ✅                | ✅                | ✅ via `prop:` | ✅           | ❌             | ❌ \u003csup\u003e(4)\u003c/sup\u003e |\n| Declarative inference     | ❌ \u003csup\u003e(1)\u003c/sup\u003e | ❌ \u003csup\u003e(2)\u003c/sup\u003e | ❌ \u003csup\u003e(3)\u003c/sup\u003e | ✅ via `prop:` | ❌           | ❌             | ❌                |\n| Declarative type-checking | ❌ \u003csup\u003e(1)\u003c/sup\u003e | ❌ \u003csup\u003e(2)\u003c/sup\u003e | ✅                | ✅ via `prop:` | ❌           | ❌             | ❌                |\n| Imperative control        | ✅ via DOM        | -                 | ✅ via `ref`      | ✅ via `ref`   | ✅ via `ref` | ✅ via `ref`   | ✅ via `use:`     |\n| Imperative inference      | ✅ via DOM        | -                 | ✅ via `ref`      | ✅ via `ref`   | ✅ via `ref` | ✅ via `ref`   | ✅ via `use:`     |\n| Imperative type-checking  | ✅ via DOM        | -                 | ✅ via `ref`      | ✅ via `ref`   | ✅ via `ref` | ✅ via `ref`   | ✅ via `use:`     |\n\n---\n\n1. \u003csmall\u003eHTML language servers can't support TypeScript obviously. But IDE can leverage Custom Element metadata.\u003c/small\u003e\n2. \u003csmall\u003eAstro JSX namespace / LSP are not handling `HTMLElementTagNameMap` or Custom Element metadata, yet.\u003c/small\u003e\n3. \u003csmall\u003eTemplate literals are preventing automatic properties inference, but at least, you can't assign wrong argument types without knowing it.\u003c/small\u003e\n4. \u003csmall\u003eSvelte heuristics are not clear regarding _attributes_ versus _properties_ handling. Better be safe than sorry. Also the `use:` directive is neat.\u003c/small\u003e\n\n---\n\nThere might be changes regarding support for Web Components accross various the various UI frameworks above.\nPlease file an issue if an info is wrong or missing.\n\nEach implementation examples are trying to show off the most type-safe way to use JSFE, with the least trade-offs.\n\nUsing it more **declaratively** or **imperatively** is up to you, your framework ability and you coding style.  \nBoth usages are valid and can be mixed. Typically when you want to use the schema elsewhere in your app., or\nwhen your callbacks are getting too beefy, you'll better extract them from templates.\n\nGenerally, imperative usage get perfect TypeScript support (you just handle the class), whereas declaratively, you'll have\nto deal with various template languages limitations (this is an universal problem).\n\n## Component libraries\n\n\u003e [!IMPORTANT]  \n\u003e Before you dive in, here is some context about Web Components libraries support with JSFE.\n\nWhereas you are starting from scratch or you want to integrate declarative forms in\nan existing project, you'll want to **choose** an UI library or **build** your own from scratch (or a mix of both).  \nIn either case, JSFE got you covered up, as an agnostic platform for consuming\nstandardized form inputs widgets (see [types](./packages/types/src/widgets.ts)).  \nWeb Components technologies has a lot of traction in 2022-23, with big names\nlaunching their own collections. As any flourishing eco-system, there are _opinions_.  \nFortunately, _most_ divergences happens on the _CSS side_. Specifically on styles consuming mechanisms.\n\nAs the initial maintainer, I decided to focus on _Shoelace_, while experimenting with other **great** options out there.  \nWhy so?\n\n- Keep an eye on converging practices across vendors.\n- Ensure that _JSFE_ remains not to tied with _Shoelace_ way of things (which is already quite thin, relatively).\n- Be able to swap out built-ins for custom widgets on a pinch, when needed.\n- Borrow valuable ideas from others libraries and re-implement them with Shoelace bits when lacking.\n\n\u003e [!WARNING]  \n\u003e I will not maintain the **full spectrum** of _JSFE_ widgets, accross all libraries!\n\nBut I will do my best to provide all the hooks you need, thanks to an _agnostic_ and _type-safe_ API,\nsmoothening some peculiarities.\n\nAlso, expect varying support for CSS implementations as for now, in 2023, it's just a bit too wild to keep up.\n\nNon-exhaustive notes about what you might deal with WC components libraries' CSS:\n\n- Carbon use pure SCSS import, with mixins. Only root element seems to be allowed for CSS vars injection (no `:host` or `\u003cbody\u003e`…).\n- Material UI uses a JS color utility to inject CSS vars on `style` attributes, with a sophisticated color generator.\n- 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).\n- Spectrum use licensed fonts it seems?\n- Spectrum has a tricky dependencies injection system, it took me the longest to achieve, and it's not perfect yet.\n\nI'll not expand up furthermore on that, but if you're curious, it's you're lucky day. You can [see and compare all styles implementations across UI libs in examples](https://github.com/json-schema-form-element/examples/blob/main/src/themes).  \nAlso, I recommend that you take a peek at the [playground source-code](https://github.com/json-schema-form-element/playground) for themes wizardry.\n\nI find little gems in all of these frameworks, for example:\n\n- Carbon has neat rocker switchs for numbers\n- Adobe kills it with colours\n- Wired is fun\n- Material has an innovative color themes generator\n- …you'll find some others too!\n\nI'm not an expert on each of this libs., and please note many of them are quite new / rapidly evolving.  \nThat's why it's interesting to keep a bird-eye view from time to time.\n\nOverall, Shoelace seems to be the most equilibrated in my eyes.  \nIf you require top-notch support for you favourite UI lib. which is not Shoelace,\nI encourage you to contribute,\nlike people did for the [React JSON Schema Form](https://github.com/rjsf-team/react-jsonschema-form) project.  \nCore maintainers are working on the reference implementation, and community can add things of their interest.\n\nIf you want to enhance the lib. by bringing support for more fields, it's quite easy!  \nJust take a peek on the [Shoelace package](./packages/shoelace),\nwhich is the canonical implementation (meaning it's the most complete, API-wise).  \nThen, you are welcome to make a pull request with new features, or bug fixes.\n\n### Shoelace\n\n[Shoelace](https://shoelace.style/) is the UI component library of choice for rendering fields, and as a\ngeneral design system backbone for _JSFE_.  \nIt's beautiful, aims for simplicity, is not too opinionated, while still having character.  \nThat's why it's the very first library implemented in _JSFE_.\n\n\u003c!-- ### Material Design --\u003e\n\n\u003c!-- 🚧……🚧 --\u003e\n\n\u003c!-- Support for [Google Material 3 Web Components](https://material-web.dev) is planned. --\u003e\n\n### Custom widgets\n\n#### Design choices\n\nYou might have noticed that _JSFE_ is not using Custom Elements as a medium for injecting widgets.  \nFirst prototypes were using them, but I've had troubles regarding the parent form element awareness about its children.  \nE.g. with Shoelace, inputs weren't responding well with form validation, the \u003ckbd\u003eENTER\u003c/kbd\u003e key for submit, etc.  \nI'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.\n\nMoreover, Web Components users are eager to see [Custom Registries](https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry) becoming maintream.\nThat will make the process of overriding widgets much more flexible.\n\nFor now, using Lit's `TemplateResult` (from a function returning a `html` literal) is straight-forward, however there are some trade-offs; it's a state-less function, no CSS scoping, lit-tied, etc.\n\nUltimately, goal is to make JSFE fully modular and agnostic, by using well-defined Custom Elements, for each individual form control.\n\n🚧……🚧\n\n\u003c!-- OLD --\u003e\n\u003c!-- It's totally doable to swap some or all components for another\nsystem, thanks to the very Custom Element flexible nature.\nFirst step would be to create a generic interface\nfor communicating with individual fields, starting with the raw system browser ones as a reference. That might add a fair amount of complexity and some (negligible?) performance impact though.\nMain benefit could be to add some “missing” components in Shoelace, like\ncombobox, complex date-time ranges, or whatever fancy widget your dreaming of.\n\nFor example, _React JSON Schema Form_ does support a handful of different UI libraries maintained by the community,\nbut AFAIK, in the Web Component space only Shoelace is on par, thanks its Lit backbone, all while beeing totally FLOSS.\nThings are changing fast though, thanks to a growing WC ecosystem, with big names backing it up (Adobe, MS, Google, IBM, SpaceX… basically everyone).\n\nFor now, the _JSFE_ component is one Lit Element monolith. All sub-parts are “partials“,\nnot individual Web Components. Those snippets are wrapping the Shoelace\ncomponents and make them aware and alive.\nThe validation logic / UI options are mostly happening there.\nChoice has been made to tie the logic closely with the component.\nWhile this practice should be avoided generally, here we have a fully declarative / programmatic UI, so no need to create more levels of indirection than needed.\nMapping between schema and “real” fields happens at the `HTMLElement` level, same as all validation stuff, though you got hooks / bypasses for custom behaviors (see below). --\u003e\n\n## Validation\n\nYou're responsible to hook-up additional / more advanced validation with, e.g, AJV.  \nHTML native validation is already quite powerful, but you might want to do\nyour own wizardry.\nNote that client-validation is more for user experience,\nwhile server validation is here to ensure data integrity, provide context aware round-trips…  \nJSON schemas are easing up the constraints enforcement for moving data around, but you'll still have to manage traditional chores.  \nGood news is that they give you more time to take care of business related operations, UX…\n\n## Schema massaging\n\nSame as advanced validation handling above,\nJSFE doesn't bundle, dereference, nor it is fetching remote\nschemas.  \nDoing so would add a huge payload to the library, and you might certainly have already those tools at hand somewhere in your stack.  \nOnly thing it does is resolving [JSON references](https://datatracker.ietf.org/doc/html/draft-pbryan-zyp-json-ref-03), pointing to **local definitions** only.\nThis is because implementation is relatively trivial, without much code, and that's a much needed feature for DRY-ness, recursivity…  \nHopefully it's easy to bring in an full-featured parser / resolver along, like the [`json-schema-ref-parser`](https://github.com/APIDevTools/json-schema-ref-parser).\n\n## Custom Elements Manifests\n\nSee [./custom-elements.json](./custom-elements.json) \u0026 [./custom-elements.md](./custom-elements.md)\n\n## Packages informations\n\nWith internal dependencies included, minus peer dependencies (UI libs.):\n\n\u003cdiv align=\"center\"\u003e\n\n| Package        | Size                                                                                    | Version                                                                                             |\n| -------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |\n| @jsfe/form     | ![form bundle size](https://deno.bundlejs.com/badge?q=@jsfe/form\u0026treeshake=[*])         | [![NPM](https://img.shields.io/npm/v/@jsfe/form)](https://www.npmjs.com/package/@jsfe/form)         |\n| @jsfe/shoelace | ![shoelace bundle size](https://deno.bundlejs.com/badge?q=@jsfe/shoelace\u0026treeshake=[*]) | [![NPM](https://img.shields.io/npm/v/@jsfe/shoelace)](https://www.npmjs.com/package/@jsfe/shoelace) |\n| @jsfe/material | ![material bundle size](https://deno.bundlejs.com/badge?q=@jsfe/material\u0026treeshake=[*]) | [![NPM](https://img.shields.io/npm/v/@jsfe/material)](https://www.npmjs.com/package/@jsfe/material) |\n| @jsfe/carbon   | ![carbon bundle size](https://deno.bundlejs.com/badge?q=@jsfe/carbon\u0026treeshake=[*])     | [![NPM](https://img.shields.io/npm/v/@jsfe/carbon)](https://www.npmjs.com/package/@jsfe/carbon)     |\n| @jsfe/wired    | ![wired bundle size](https://deno.bundlejs.com/badge?q=@jsfe/wired\u0026treeshake=[*])       | [![NPM](https://img.shields.io/npm/v/@jsfe/wired)](https://www.npmjs.com/package/@jsfe/wired)       |\n| @jsfe/system   | ![system bundle size](https://deno.bundlejs.com/badge?q=@jsfe/system\u0026treeshake=[*])     | [![NPM](https://img.shields.io/npm/v/@jsfe/system)](https://www.npmjs.com/package/@jsfe/system)     |\n| @jsfe/types    |                                                                                         | [![NPM](https://img.shields.io/npm/v/@jsfe/types)](https://www.npmjs.com/package/@jsfe/types)       |\n\n\u003c/div\u003e\n\n`@jsfe/form` contains the base class from which all other packages extends themselves from.  \n**You don't need to install it**, unless you want to provide widgets and styles from scratch.  \nIf you just want to override _some_ of the flavored components, `@jsfe/\u003ctheme\u003e` packages are handy starters.\n\n`@jsfe/types` contains everything for assisting your own widgets authoring.  \nIt's re-exported from every package so you don't need to install it on your own.\n\n### _Next_ versions\n\n\u003e [!TIP]  \n\u003e You can try the upcoming release from the [`next` branch](https://github.com/json-schema-form-element/jsfe/tree/next) like this:  \n\u003e `npm i @jsfe/\u003cpackage\u003e@next`.\n\n## Experimental features\n\nTo activate experimental features preview flags, just pass the `experimental` property.\n\nE.g. with Lit:\n\n```ts\nhtml`\u003cjson-schema-form\n\totherProps=\"...\"\n\t.experimental=${{\n\t\t'\u003cflag\u003e': true,\n\t\t// ...\n\t}}\n\u003e\u003c/json-schema-form\u003e`;\n```\n\nActual **features flags** list:\n\n- None\n\n\u003c!-- - `allOf`\n- `oneOf` --\u003e\n\n## Improvements\n\n- BYOC (bring your own components).\n- Extensive and modern JSON Schema support (identify Draft 4 / 7 / 2020 subtleties).\n- Nice file uploaders for the `data-url` format.\n- Layout customizations\n- Tests, browser based (due to the WC nature).\n- Tests, tests, even more tests in the field to reveal shortcomings.\n- Drag and drop: improve the initial implementation (E.g. cross-nested arrays).\n- Autofocuses (for added array item, etc.)\n- …\n- Have an idea? [Discussions are open](https://github.com/json-schema-form-element/form/discussions)!\n\n## Acknowledgements\n\nThe Web Component and [JSON Schema](https://json-schema.org) communities, the [Lit](https://lit.dev) team, the [Shoelace](https://shoelace.style) maintainers,…\n\nAs a workhorse for many projects of mine for a long time, I'm grateful for all\nthe ideas RSJF creators brought.\n\n**Similar projects**:\n\n- [react-jsonschema-form](https://github.com/remoteoss/json-schema-form)\n- [vuetify-jsonschema-form](https://koumoul-dev.github.io/vuetify-jsonschema-form/latest)\n- [jsonforms](https://jsonforms.io)\n- [remoteoss/json-schema-form](https://github.com/rjsf-team/react-jsonschema-form)\n\n**See also**:\n\n- [remark-lint-frontmatter-schema](https://github.com/JulianCataldo/remark-lint-frontmatter-schema): Validate your Markdown **frontmatter** data against a **JSON schema**.\n- [retext-case-police](https://github.com/JulianCataldo/retext-case-police): Check popular names casing. Example: ⚠️ `github` → ✅ `GitHub`.\n- [astro-openapi](https://github.com/JulianCataldo/astro-openapi): An Astro toolset for building full-stack operations easily, with type-safety and documentation as first-class citizens.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjson-schema-form-element%2Fjsfe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjson-schema-form-element%2Fjsfe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjson-schema-form-element%2Fjsfe/lists"}