@lrnwebcomponents/eco-json-schema-form
Version:
JSON Schema form data binding magic
134 lines (131 loc) • 4.3 kB
JavaScript
import { html, PolymerElement } from "@polymer/polymer/polymer-element.js";
import { AppLocalizeBehavior } from "@polymer/app-localize-behavior/app-localize-behavior.js";
import { mixinBehaviors } from "@polymer/polymer/lib/legacy/class.js";
import "@lrnwebcomponents/a11y-tabs/a11y-tabs.js";
import "@polymer/polymer/lib/elements/dom-repeat.js";
/**
`eco-json-schema-tabs` takes in a JSON schema of type array and builds a form,
exposing a `value` property that represents an array described by the schema.
Please see the `eco-json-schema-object` documentation for further information.
@group eco Elements
@element eco-json-schema-tabs
* @demo demo/index.html
*/
class EcoJsonSchemaTabs extends mixinBehaviors(
[AppLocalizeBehavior],
PolymerElement
) {
static get tag() {
return "eco-json-schema-tabs";
}
static get template() {
return html`
<custom-style>
<style is="custom-style" include="iron-flex iron-flex-alignment">
:host{
color: var(--eco-json-form-color);
background-color: var(--eco-json-form-bg);
font-family: var(--eco-json-form-font-family);
}
:host ([hidden]) {
display: none;
}
:host a11y-tabs {
--a11y-tabs-color: var(--eco-json-form-faded-color);
--a11y-tabs-focus-color: var(--eco-json-form-color);
--a11y-tabs-border-color: var(--eco-json-form-faded-color);
--a11y-tabs-border-radius: var(--eco-json-form-border-radius);
--a11y-tabs-background: var(--eco-json-form-bg);
--a11y-tabs-faded-background: var(--eco-json-form-faded-bg);
--a11y-tabs-justify-tabs: flex-start;
--ally-tabs-wrap: unset;
--a11y-tabs-content-padding: 4px 8px;
--a11y-tabs-button-padding: 8px;
--a11y-tabs-vertical-button-padding: unset;
--a11y-tabs-horizontal-border-radius: unset;
--a11y-tabs-vertical-border-radius: unset;
--a11y-tabs-horizontal-button-padding: 2px 5px;
}
:host a11y-tabs:focus,
:host a11y-tabs:focus-within {
--a11y-tabs-border-color: : var(--eco-json-form-focus-color);
}
:host .tab-title {
position: absolute;
left: -99999px;
height: 0;
overflow: hidden;
}
</style>
</custom-style>
<a11y-tabs id$="[[schema.property]]" layout-breakpoint="0">
<template
is="dom-repeat"
items="[[schema.properties]]"
as="item"
restamp
>
<a11y-tab
id$="item-[[index]]"
icon$="[[item.icon]]"
disabled$="[[item.disabled]]"
label$="[[item.label]]"
>
<div hidden$="[[!item.description]]">[[item.description]]</div>
<div
id$="[[item.property]]"
class="item-fields"
data-index$="[[index]]"
></div>
</a11y-tab>
</template>
</a11y-tabs>
`;
}
static get properties() {
return {
propertyName: {
type: String,
value: null,
},
schema: {
type: Object,
value: {},
},
};
}
ready() {
super.ready();
this._schemaChanged();
}
/**
* updates the array fields if the schema (which includes values) changes
*/
_schemaChanged() {
//make sure the content is there first
this.shadowRoot.querySelectorAll(".item-fields").forEach((item) => {
let index = item.getAttribute("data-index"),
propertyName = this.propertyName,
tab = this.schema.properties[index],
prop = tab.name,
prefix = `${propertyName}.${prop}`;
this.dispatchEvent(
new CustomEvent("build-fieldset", {
bubbles: false,
cancelable: true,
composed: true,
detail: {
container: item,
path: prefix,
prefix: prefix,
properties: tab.schema.properties,
type: EcoJsonSchemaTabs.tag,
value: tab.value || {},
},
})
);
});
}
}
customElements.define(EcoJsonSchemaTabs.tag, EcoJsonSchemaTabs);
export { EcoJsonSchemaTabs };