diff --git a/packages/carbon/README.md b/packages/carbon/README.md
index 69deb9d..88cf6d9 100644
--- a/packages/carbon/README.md
+++ b/packages/carbon/README.md
@@ -1,6 +1,11 @@
# JSON Schema Form Element — ***Carbon*** edition
-See the [documentation](../../README.md).
+```sh
+npm install @jsfe/carbon
+```
+
+Consult the [documentation](../../README.md).
+Open the [playground](https://jsfe.js.org).
---
diff --git a/packages/carbon/package.json b/packages/carbon/package.json
index 0b2c463..97b7e2b 100644
--- a/packages/carbon/package.json
+++ b/packages/carbon/package.json
@@ -29,6 +29,7 @@
"exports": {
".": "./dist/esm/index.js",
"./scss": "./src/styles.scss",
+ "./scss/*": "./src/widgets/*.scss",
"./css": "./dist/esm/styles.css",
"./jss": "./dist/esm/styles.js",
"./min": "./dist/esm-min"
@@ -36,7 +37,7 @@
"files": [
"./dist/esm",
"./dist/esm-min",
- "./src/styles.scss",
+ "./src/**/*.scss",
"./vscode.html-custom-data.json",
"./vscode.css-custom-data.json",
"./custom-elements.json"
diff --git a/packages/form/README.md b/packages/form/README.md
index 654846d..4acc373 100644
--- a/packages/form/README.md
+++ b/packages/form/README.md
@@ -1,6 +1,11 @@
-# JSON Schema Form Element — ***Form*** edition
+# JSON Schema Form Element — ***Barebone*** edition
-See the [documentation](../../README.md).
+```sh
+npm install @jsfe/form
+```
+
+Consult the [documentation](../../README.md).
+Open the [playground](https://jsfe.js.org).
---
diff --git a/packages/form/package.json b/packages/form/package.json
index 2f2a37c..c4af4c3 100644
--- a/packages/form/package.json
+++ b/packages/form/package.json
@@ -27,6 +27,7 @@
"exports": {
".": "./dist/esm/index.js",
"./scss": "./src/styles.scss",
+ "./scss/*": "./src/widgets/*.scss",
"./css": "./dist/esm/styles.css",
"./jss": "./dist/esm/styles.js",
"./min": "./dist/esm-min"
@@ -34,7 +35,7 @@
"files": [
"./dist/esm",
"./dist/esm-min",
- "./src/styles.scss",
+ "./src/**/*.scss",
"./vscode.html-custom-data.json",
"./vscode.css-custom-data.json",
"./custom-elements.json"
diff --git a/packages/form/src/json-schema-form.ts b/packages/form/src/json-schema-form.ts
index bc8bcee..1b516cb 100644
--- a/packages/form/src/json-schema-form.ts
+++ b/packages/form/src/json-schema-form.ts
@@ -60,6 +60,7 @@ export class Jsf extends LitElement {
uiSchema: UiSchema,
schemaPath: Path,
required = false,
+ level = 0,
): TemplateResult<1> => {
let result: TemplateResult<1> | undefined;
const currentNode: JSONSchema7 = node;
@@ -151,6 +152,7 @@ export class Jsf extends LitElement {
this._dig.bind(this),
schemaPathAugmented,
this.widgets,
+ level,
);
}
@@ -178,6 +180,7 @@ export class Jsf extends LitElement {
// this._handleKeydown.bind(this),
schemaPathAugmented,
this.widgets,
+ level,
);
}
@@ -206,6 +209,7 @@ export class Jsf extends LitElement {
this._dig.bind(this),
schemaPathAugmented,
this.widgets,
+ level,
);
/* --- Additionals Array items --- */
@@ -266,6 +270,8 @@ export class Jsf extends LitElement {
this._dig.bind(this),
schemaPathAugmented,
this.widgets,
+ required,
+ level,
);
}
}
diff --git a/packages/form/src/triage/array-primitive.ts b/packages/form/src/triage/array-primitive.ts
index afec44e..4a279b9 100644
--- a/packages/form/src/triage/array-primitive.ts
+++ b/packages/form/src/triage/array-primitive.ts
@@ -14,6 +14,7 @@ export const fieldArrayPrimitive = (
// dig: Jsf['_dig'],
schemaPath: Path,
widgets: Widgets,
+ level = 0,
) => {
// if (!Array.isArray(dataLevel)) return html``;
@@ -62,6 +63,8 @@ export const fieldArrayPrimitive = (
// itemsLabel,
+ level,
+
id,
// required,
valueChangedCallback,
diff --git a/packages/form/src/triage/array.ts b/packages/form/src/triage/array.ts
index e942698..1cbca70 100644
--- a/packages/form/src/triage/array.ts
+++ b/packages/form/src/triage/array.ts
@@ -16,6 +16,8 @@ export const fieldArray = (
dig: Jsf['_dig'],
schemaPath: Path,
widgets: Widgets,
+ required = false,
+ level = 0,
) => {
if (!Array.isArray(dataLevel)) return html``;
@@ -60,6 +62,8 @@ export const fieldArray = (
uiState,
uiSchema,
schemaPathAugmented,
+ required,
+ level + 1,
);
const move = (direction: number) => (_event: Event) => {
@@ -168,6 +172,8 @@ export const fieldArray = (
controls: {
add: { click: addItemClick },
},
+
+ level,
};
return widgets?.array?.(options);
diff --git a/packages/form/src/triage/object.ts b/packages/form/src/triage/object.ts
index da187ec..b998cea 100644
--- a/packages/form/src/triage/object.ts
+++ b/packages/form/src/triage/object.ts
@@ -11,6 +11,7 @@ export const fieldObject = (
dig: Jsf['_dig'],
schemaPath: Path,
widgets: Widgets,
+ level = 0,
) => {
const error = 'Wrong object field';
if (typeof schema.properties !== 'object')
@@ -44,6 +45,7 @@ export const fieldObject = (
uiSchema?.[propName],
schemaPathAugmented,
required,
+ level + 1,
);
},
);
@@ -60,6 +62,7 @@ export const fieldObject = (
label,
helpText: schema.description,
children,
+ level,
};
return (
diff --git a/packages/form/src/triage/primitive.ts b/packages/form/src/triage/primitive.ts
index 1043992..91fbba7 100644
--- a/packages/form/src/triage/primitive.ts
+++ b/packages/form/src/triage/primitive.ts
@@ -134,10 +134,20 @@ export const fieldPrimitive = (
}
if (schema.type === 'string') {
+ let inputType = 'text';
+ if (schema.format === 'password' || schema.format === 'email') {
+ inputType = schema.format;
+ }
+
+ if (uiOptions?.['ui:options']?.inputType === 'tel') {
+ inputType = 'tel';
+ }
const options = {
...baseOptions,
value: baseValue ? String(baseValue) : '',
+ inputType,
+
minLength: schema.minLength,
maxLength: schema.maxLength,
pattern: schema.pattern,
@@ -146,6 +156,10 @@ export const fieldPrimitive = (
if (uiOptions?.['ui:widget'] === 'textarea') {
return widgets?.textarea?.(options) || missing('textarea');
}
+ if (typeof uiOptions?.['ui:widget'] === 'string') {
+ const customWidgetName = uiOptions?.['ui:widget'];
+ return widgets?.[customWidgetName]?.(options) || missing('custom');
+ }
return widgets?.text?.(options) || missing('text');
}
@@ -205,3 +219,36 @@ export const fieldPrimitive = (
return missing(`Wrong input for: ${path.join('/')}`);
};
+
+/*
+
+AJV-Formats
+https://ajv.js.org/packages/ajv-formats.html
+
+date: full-date according to RFC3339 (opens new window).
+time: time (time-zone is mandatory).
+date-time: date-time (time-zone is mandatory).
+iso-time: time with optional time-zone.
+iso-date-time: date-time with optional time-zone.
+duration: duration from RFC3339(opens new window)
+uri: full URI.
+uri-reference: URI reference, including full and relative URIs.
+uri-template: URI template according to RFC6570(opens new window)
+url (deprecated): URL record (opens new window).
+email: email address.
+hostname: host name according to RFC1034 (opens new window).
+ipv4: IP address v4.
+ipv6: IP address v6.
+regex: tests whether a string is a valid regular expression by passing it to RegExp constructor.
+uuid: Universally Unique IDentifier according to RFC4122 (opens new window).
+json-pointer: JSON-pointer according to RFC6901 (opens new window).
+relative-json-pointer: relative JSON-pointer according to this draft (opens new window).
+byte: base64 encoded data according to the openApi 3.0.0 specification(opens new window)
+int32: signed 32 bits integer according to the openApi 3.0.0 specification(opens new window)
+int64: signed 64 bits according to the openApi 3.0.0 specification(opens new window)
+float: float according to the openApi 3.0.0 specification(opens new window)
+double: double according to the openApi 3.0.0 specification(opens new window)
+password: password string according to the openApi 3.0.0 specification(opens new window)
+binary: binary string according to the openApi 3.0.0 specification
+
+*/
diff --git a/packages/material/README.md b/packages/material/README.md
index 427c8b9..ddb6870 100644
--- a/packages/material/README.md
+++ b/packages/material/README.md
@@ -1,6 +1,11 @@
# JSON Schema Form Element — ***Material*** edition
-See the [documentation](../../README.md).
+```sh
+npm install @jsfe/material
+```
+
+Consult the [documentation](../../README.md).
+Open the [playground](https://jsfe.js.org).
---
@@ -24,10 +29,10 @@ See the [documentation](../../README.md).
### Fields
-| Name | Privacy | Type | Default | Description | Inherited From |
-| -------------------- | ------- | ------- | ---------- | ----------- | -------------- |
-| `dataChangeCallback` | public | | `widgets` | | |
-| `styleSheets` | public | `array` | `[styles]` | | |
+| Name | Privacy | Type | Default | Description | Inherited From |
+| ------------- | ------- | ------- | ---------- | ----------- | -------------- |
+| `widgets` | public | | `widgets` | | |
+| `styleSheets` | public | `array` | `[styles]` | | |
diff --git a/packages/material/custom-elements.json b/packages/material/custom-elements.json
index 996fd17..64fa4cb 100644
--- a/packages/material/custom-elements.json
+++ b/packages/material/custom-elements.json
@@ -28,7 +28,7 @@
"members": [
{
"kind": "field",
- "name": "dataChangeCallback",
+ "name": "widgets",
"privacy": "public",
"default": "widgets"
},
diff --git a/packages/material/package.json b/packages/material/package.json
index cf59482..3776bfc 100644
--- a/packages/material/package.json
+++ b/packages/material/package.json
@@ -29,6 +29,7 @@
"exports": {
".": "./dist/esm/index.js",
"./scss": "./src/styles.scss",
+ "./scss/*": "./src/widgets/*.scss",
"./css": "./dist/esm/styles.css",
"./jss": "./dist/esm/styles.js",
"./min": "./dist/esm-min"
@@ -36,7 +37,7 @@
"files": [
"./dist/esm",
"./dist/esm-min",
- "./src/styles.scss",
+ "./src/**/*.scss",
"./vscode.html-custom-data.json",
"./vscode.css-custom-data.json",
"./custom-elements.json"
diff --git a/packages/material/src/form.ts b/packages/material/src/form.ts
index b61aeb8..c53f8b5 100644
--- a/packages/material/src/form.ts
+++ b/packages/material/src/form.ts
@@ -3,7 +3,7 @@ import * as widgets from './widgets/index.js';
import { styles } from './styles.js';
export class JsfMaterial extends Jsf {
- public dataChangeCallback = widgets;
+ public widgets = widgets;
public styleSheets = [styles];
}
diff --git a/packages/material/src/styles.scss b/packages/material/src/styles.scss
index 4e24fed..7a695fe 100644
--- a/packages/material/src/styles.scss
+++ b/packages/material/src/styles.scss
@@ -1,6 +1,8 @@
// keep-sorted start
@import './widgets/_all.scss';
+@import './widgets/_fieldset.scss';
@import './widgets/_toggle.scss';
+@import './widgets/array.scss';
@import './widgets/callout.scss';
@import './widgets/object.scss';
@import './widgets/range.scss';
diff --git a/packages/material/src/widgets/_fieldset.scss b/packages/material/src/widgets/_fieldset.scss
new file mode 100644
index 0000000..cd2b100
--- /dev/null
+++ b/packages/material/src/widgets/_fieldset.scss
@@ -0,0 +1,32 @@
+.theme-material.widget-fieldset {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ gap: 1.5em 0;
+ padding: 2em 1em;
+ margin: 0;
+ font-weight: 300;
+ border: none;
+ // border: 1px solid transparent;
+ border-radius: 1rem;
+ transition-timing-function: ease-in-out;
+ transition-duration: 250ms;
+
+ legend {
+ width: 100%;
+ font-size: 1.5em;
+ border-bottom: 1px solid var(--md-sys-color-inverse-on-surface);
+ }
+
+ .widget-object__description {
+ margin: 0 0 1rem 0;
+ opacity: calc(3 / 4);
+ }
+
+ --md-sys-color-shadow: var(--md-sys-color-inverse-on-surface);
+ --md-elevation-level: 0;
+
+ &:hover {
+ --md-elevation-level: 4;
+ }
+}
diff --git a/packages/material/src/widgets/array.scss b/packages/material/src/widgets/array.scss
new file mode 100644
index 0000000..5bad0b1
--- /dev/null
+++ b/packages/material/src/widgets/array.scss
@@ -0,0 +1,98 @@
+.theme-material.widget-array {
+ --md-sys-color-shadow: var(--md-sys-color-inverse-on-surface);
+ --md-elevation-level: 0;
+
+ &:hover {
+ --md-elevation-level: 4;
+ }
+
+ .widget-array__card {
+ width: 100%;
+ // transition: outline var(--sl-transition-slow);
+
+ transition: box-shadow var(--sl-transition-medium);
+
+ &:hover {
+ // background: var(--sl-color-gray-50);
+ box-shadow: var(--sl-shadow-medium);
+ }
+
+ &[data-dropzone] {
+ border-radius: var(--sl-border-radius-medium);
+ outline: 1px solid var(--sl-color-primary-500);
+ // transition: outline var(--sl-transition-fast);
+
+ // cursor: grab;
+
+ * {
+ pointer-events: none;
+ }
+ }
+ }
+
+ sl-card::part(body) {
+ padding: var(--sl-spacing-medium) var(--sl-spacing-small);
+ }
+
+ .widget-array__header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ width: 100%;
+ font-size: 0.8em;
+ user-select: none;
+ //// sl-icon::pa {
+ //// height: 0.2rem;
+ //// }
+ //// display: none;
+
+ sl-tag::part(base) {
+ background: var(--sl-color-neutral-100);
+ }
+ }
+
+ .widget-array__handle {
+ display: flex;
+ flex-grow: 1;
+ align-items: center;
+ justify-content: space-between;
+ height: 2rem;
+ padding-left: var(--sl-spacing-2x-small);
+ margin: 0 var(--sl-spacing-medium) 0 0;
+ font-size: 1.25em;
+ color: var(--sl-color-neutral-500);
+ // cursor: grab;
+ cursor: move;
+ transition: opacity, var(--sl-transition-fast);
+
+ &:hover {
+ color: var(--sl-color-neutral-600);
+ background: var(--sl-color-neutral-100);
+ border-radius: var(--sl-border-radius-x-large);
+ transition: var(--sl-transition-medium);
+ }
+
+ &:active {
+ // cursor: grabbing;
+ user-select: none;
+ }
+
+ .widget-array__handle-grip {
+ display: flex;
+ flex-grow: 1;
+ justify-content: center;
+ }
+ }
+
+ .widget-array__add-zone {
+ display: flex;
+ padding: var(--sl-spacing-2x-large) var(--sl-spacing-2x-large);
+ border: 2px dashed var(--sl-color-gray-100);
+ border-radius: var(--sl-border-radius-large);
+ box-shadow: var(--sl-shadow-large) inset;
+
+ & > sl-button {
+ width: 100%;
+ }
+ }
+}
diff --git a/packages/material/src/widgets/array.ts b/packages/material/src/widgets/array.ts
new file mode 100644
index 0000000..bfab6e5
--- /dev/null
+++ b/packages/material/src/widgets/array.ts
@@ -0,0 +1,93 @@
+import type { Widgets } from '@jsfe/types';
+import { nothing, html } from 'lit';
+
+import '@material/web/button/outlined-button';
+
+export const array: Widgets['array'] = (options) => {
+ return html`
+
+ `;
+};
diff --git a/packages/material/src/widgets/index.ts b/packages/material/src/widgets/index.ts
index c630a87..8e35ac2 100644
--- a/packages/material/src/widgets/index.ts
+++ b/packages/material/src/widgets/index.ts
@@ -9,6 +9,7 @@ export { object } from './object.js';
export { range } from './range.js';
export { select } from './select.js';
export { submit } from './submit.js';
+// export { array } from './array.js';
export { switchh as switch } from './switch.js';
export { text } from './text.js';
export { textarea } from './textarea.js';
diff --git a/packages/material/src/widgets/object.scss b/packages/material/src/widgets/object.scss
index ed64a72..6415c7d 100644
--- a/packages/material/src/widgets/object.scss
+++ b/packages/material/src/widgets/object.scss
@@ -1,32 +1,2 @@
-.theme-material.object {
- position: relative;
- display: flex;
- flex-direction: column;
- gap: 1.5em 0;
- padding: 2em 1em;
- margin: 0;
- font-weight: 300;
- border: none;
- // border: 1px solid transparent;
- border-radius: 1rem;
- transition-timing-function: ease-in-out;
- transition-duration: 250ms;
-
- legend {
- width: 100%;
- font-size: 1.5em;
- border-bottom: 1px solid var(--md-sys-color-inverse-on-surface);
- }
-
- .object__description {
- margin: 0 0 1rem 0;
- opacity: calc(3 / 4);
- }
-
- --md-sys-color-shadow: var(--md-sys-color-inverse-on-surface);
- --md-elevation-level: 0;
-
- &:hover {
- --md-elevation-level: 4;
- }
+.theme-material.widget-object {
}
diff --git a/packages/material/src/widgets/object.ts b/packages/material/src/widgets/object.ts
index 8de8e9e..0a714d6 100644
--- a/packages/material/src/widgets/object.ts
+++ b/packages/material/src/widgets/object.ts
@@ -5,7 +5,11 @@ import '@material/web/elevation/elevation.js';
export const object: Widgets['object'] = (options) => {
return html`
-