@limetech/lime-elements 37.1.0-next.24 → 37.1.0-next.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/limel-form.cjs.entry.js +6332 -276
- package/dist/cjs/limel-form.cjs.entry.js.map +1 -1
- package/dist/cjs/limel-popover_2.cjs.entry.js +1 -1
- package/dist/cjs/limel-popover_2.cjs.entry.js.map +1 -1
- package/dist/collection/components/form/form.js +20 -8
- package/dist/collection/components/form/form.js.map +1 -1
- package/dist/collection/components/form/validators/format.js +3 -0
- package/dist/collection/components/form/validators/format.js.map +1 -1
- package/dist/collection/components/popover-surface/popover-surface.css +2 -0
- package/dist/esm/limel-form.entry.js +6333 -277
- package/dist/esm/limel-form.entry.js.map +1 -1
- package/dist/esm/limel-popover_2.entry.js +1 -1
- package/dist/esm/limel-popover_2.entry.js.map +1 -1
- package/dist/lime-elements/lime-elements.esm.js +1 -1
- package/dist/lime-elements/{p-8d44ea19.entry.js → p-83b03cd3.entry.js} +2 -2
- package/dist/lime-elements/{p-8d44ea19.entry.js.map → p-83b03cd3.entry.js.map} +1 -1
- package/dist/lime-elements/p-c1a681db.entry.js +27 -0
- package/dist/lime-elements/p-c1a681db.entry.js.map +1 -0
- package/dist/types/components/form/form.d.ts +1 -0
- package/dist/types/components/form/validators/format.d.ts +1 -0
- package/package.json +7 -5
- package/dist/lime-elements/p-d9d4b3bf.entry.js +0 -21
- package/dist/lime-elements/p-d9d4b3bf.entry.js.map +0 -1
|
@@ -112,7 +112,7 @@ const Popover = class {
|
|
|
112
112
|
};
|
|
113
113
|
Popover.style = popoverCss;
|
|
114
114
|
|
|
115
|
-
const popoverSurfaceCss = ":host(limel-popover-surface){isolation:isolate;position:relative;display:flex;width:var(--popover-surface-width, auto);max-height:inherit;max-width:calc(100vw - 2rem);margin:0 0.25rem}.limel-popover-surface{flex:1;border-radius:var(--popover-border-radius, 0.75rem);box-shadow:var(--shadow-depth-16);backdrop-filter:blur(0.3125rem);-webkit-backdrop-filter:blur(0.3125rem)}.limel-popover-surface:after{transition:opacity 0.4s ease;pointer-events:none;content:\"\";position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1;opacity:0.75;border-radius:var(--popover-border-radius, 0.75rem);background-color:var(--popover-body-background-color, var(--lime-elevated-surface-background-color))}.limel-popover-surface:focus{outline:none}.limel-popover-surface:focus-visible{outline:none;box-shadow:var(--shadow-depth-8-focused)}.limel-popover-surface:focus:after,.limel-popover-surface:focus-within:after{opacity:1}.limel-popover-surface>*{box-sizing:border-box}";
|
|
115
|
+
const popoverSurfaceCss = ":host(limel-popover-surface){isolation:isolate;position:relative;display:flex;width:var(--popover-surface-width, auto);max-height:inherit;max-width:calc(100vw - 2rem);margin:0 0.25rem}.limel-popover-surface{flex:1;min-width:0;min-height:0;border-radius:var(--popover-border-radius, 0.75rem);box-shadow:var(--shadow-depth-16);backdrop-filter:blur(0.3125rem);-webkit-backdrop-filter:blur(0.3125rem)}.limel-popover-surface:after{transition:opacity 0.4s ease;pointer-events:none;content:\"\";position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1;opacity:0.75;border-radius:var(--popover-border-radius, 0.75rem);background-color:var(--popover-body-background-color, var(--lime-elevated-surface-background-color))}.limel-popover-surface:focus{outline:none}.limel-popover-surface:focus-visible{outline:none;box-shadow:var(--shadow-depth-8-focused)}.limel-popover-surface:focus:after,.limel-popover-surface:focus-within:after{opacity:1}.limel-popover-surface>*{box-sizing:border-box}";
|
|
116
116
|
|
|
117
117
|
const PopoverSurface = class {
|
|
118
118
|
constructor(hostRef) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"file":"limel-popover.limel-popover-surface.entry.cjs.js","mappings":"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","names":["ESCAPE","createRandomString","h","zipObject"],"sources":["./src/components/portal/contains.ts","./src/components/popover/popover.scss?tag=limel-popover&encapsulation=shadow","./src/components/popover/popover.tsx","./src/components/popover-surface/popover-surface.scss?tag=limel-popover-surface&encapsulation=shadow","./src/components/popover-surface/popover-surface.tsx"],"sourcesContent":["/**\n * Check if an element is a descendant of another\n *\n * If the child element is a descendant of a limel-portal, this function will\n * go back through the portal and check the original tree recursively\n * @param {HTMLElement} element the parent element\n * @param {HTMLElement} child the child element to check\n * @returns {boolean} `true` if child is a descendant of element, taking\n * portals into account\n */\nexport function portalContains(\n element: HTMLElement,\n child: HTMLElement\n): boolean {\n if (element.contains(child) || element.shadowRoot?.contains(child)) {\n return true;\n }\n\n const parent = findParent(child);\n if (!parent) {\n return false;\n }\n\n return portalContains(element, parent);\n}\n\nfunction findParent(element: HTMLElement) {\n const portal: any = element.closest('.limel-portal--container');\n if (portal) {\n return portal.portalSource;\n }\n\n const rootNode = element.getRootNode() as ShadowRoot;\n\n return rootNode.host;\n}\n","/**\n * @prop --popover-surface-width: Width of the popover surface. defaults to `auto`\n * @prop --popover-body-background-color: Background color of popover body, defaults to `--lime-elevated-surface-background-color`.\n * @prop --popover-border-radius: Border radius of popover, defaults to `0.75rem`.\n * @prop --popover-z-index: z-index of the popover.\n */\n\n.trigger-anchor {\n display: inline-block;\n position: relative;\n}\n","import {\n Component,\n h,\n Prop,\n Element,\n Event,\n EventEmitter,\n Watch,\n} from '@stencil/core';\nimport { createRandomString } from '../../util/random-string';\nimport { zipObject } from 'lodash-es';\nimport { portalContains } from '../portal/contains';\nimport { ESCAPE } from '../../util/keycodes';\nimport { OpenDirection } from '../menu/menu.types';\n\n/**\n * A popover is an impermanent layer that is displayed on top of other content\n * when user taps an element that triggers the popover. This element can be\n * practically anything, a button, piece of text, and icon, etc.\n *\n * Popovers are nonmodal, thus they don't have a semi-transparent backdrop layer\n * that darkens the content below them. Also for the same reason, they can be\n * dismissed by tapping or clicking another part of the screen, but not by a\n * clicking a button or link on the popover itself.\n *\n * :::warning\n * The component is emitting a close event when you click outside its container\n * or press the <kbd>Esc</kbd> key. However, it’s up to you as consumer to react\n * properly on this event and hide the component (preferably by setting the\n * property `open` to `false`).\n * :::\n *\n * ## Usage\n * Use a popover to show **options** or **information** related to the trigger\n * onscreen. A typical use case for popovers is a tooltip, in which you show\n * help text or contextual information to users.\n *\n * Popovers are most appropriate on larger screens but can be used on smaller\n * screens too, as long as their content is responsive and takes into account\n * the context they are displayed on.\n *\n * When a popover is displayed, interactions with other controls are blocked,\n * until user dismisses the popover.\n *\n *\n * ## Layout\n * Popovers has only one slot in which you can import a custom web-component.\n *\n * :::note\n * You must make sure that web-components that you import into the slot has\n * a `width: 100%;` style so that it can horizontally stretch across the popover.\n *\n * However, `width` of the popover can be controlled by specifying a CSS variable\n * of `--popover-surface-width`. If you don't specify any width, the popover\n * will grow as wide as its content.\n * :::\n *\n * :::important\n * Do not make a popover too big. They should never take over the entire screen.\n * If your content is that big, you should probably be using a Modal instead.\n * :::\n * @slot - Content to put inside the surface\n * @exampleComponent limel-example-popover\n */\n@Component({\n tag: 'limel-popover',\n shadow: true,\n styleUrl: 'popover.scss',\n})\nexport class Popover {\n /**\n * True if the content within the popover should be visible\n */\n @Prop()\n public open = false;\n\n /**\n * Decides the popover's location in relation to its trigger\n */\n @Prop({ reflect: true })\n public openDirection: OpenDirection;\n\n /**\n * Emits an event when the component is closing\n */\n @Event()\n private close: EventEmitter<void>;\n\n @Element()\n private host: HTMLLimelPopoverElement;\n\n private portalId: string;\n\n constructor() {\n this.portalId = createRandomString();\n this.globalClickListener = this.globalClickListener.bind(this);\n }\n\n @Watch('open')\n protected watchOpen() {\n this.setupGlobalHandlers();\n }\n\n public componentWillLoad() {\n this.setupGlobalHandlers();\n }\n\n private setupGlobalHandlers() {\n if (this.open) {\n document.addEventListener('click', this.globalClickListener, {\n capture: true,\n });\n document.addEventListener('keyup', this.handleGlobalKeyPress);\n } else {\n document.removeEventListener('click', this.globalClickListener);\n document.removeEventListener('keyup', this.handleGlobalKeyPress);\n }\n }\n\n public render() {\n const cssProperties = this.getCssProperties();\n const popoverZIndex = getComputedStyle(this.host).getPropertyValue(\n '--popover-z-index'\n );\n\n return (\n <div class=\"trigger-anchor\">\n <slot name=\"trigger\"></slot>\n <limel-portal\n visible={this.open}\n containerId={this.portalId}\n containerStyle={{ 'z-index': popoverZIndex }}\n openDirection={this.openDirection}\n >\n <limel-popover-surface\n contentCollection={this.host.children}\n style={cssProperties}\n />\n </limel-portal>\n </div>\n );\n }\n\n private globalClickListener(event: MouseEvent) {\n const element: HTMLElement = event.target as HTMLElement;\n const clickedInside = portalContains(this.host, element);\n if (this.open && !clickedInside) {\n event.stopPropagation();\n event.preventDefault();\n this.close.emit();\n }\n }\n\n private getCssProperties() {\n const propertyNames = [\n '--popover-surface-width',\n '--popover-body-background-color',\n '--popover-border-radius',\n ];\n const style = getComputedStyle(this.host);\n const values = propertyNames.map((property) => {\n return style.getPropertyValue(property);\n });\n\n return zipObject(propertyNames, values);\n }\n\n private handleGlobalKeyPress = (event: KeyboardEvent) => {\n if (event.key !== ESCAPE) {\n return;\n }\n\n event.stopPropagation();\n event.preventDefault();\n this.close.emit();\n };\n}\n","@use '../../style/functions';\n@use '../../style/mixins';\n\n:host(limel-popover-surface) {\n isolation: isolate;\n\n position: relative;\n display: flex;\n\n width: var(--popover-surface-width, auto);\n max-height: inherit; // inherits it from the dynamically calculated `max-height` of `limel-portal--container`\n max-width: calc(100vw - 2rem);\n margin: 0 0.25rem;\n}\n\n.limel-popover-surface {\n flex: 1;\n border-radius: var(--popover-border-radius, functions.pxToRem(12));\n box-shadow: var(--shadow-depth-16);\n\n backdrop-filter: blur(functions.pxToRem(5));\n -webkit-backdrop-filter: blur(functions.pxToRem(5));\n\n &:after {\n // allows using `--popover-body-background-color` while\n // getting the blurred backdrop effect\n transition: opacity 0.4s ease;\n pointer-events: none;\n\n content: '';\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: -1;\n\n opacity: 0.75;\n\n border-radius: var(--popover-border-radius, functions.pxToRem(12));\n background-color: var(\n --popover-body-background-color,\n var(--lime-elevated-surface-background-color)\n );\n }\n\n @include mixins.visualize-keyboard-focus;\n\n &:focus,\n &:focus-within {\n &:after {\n opacity: 1;\n }\n }\n\n & > * {\n // this fixes some unwanted layout issues\n // which might be very hard for consumers to realize\n // and fix by themselves. Without this code,\n // if the consumer sets for example paddings in\n // what they send to the popover, their element\n // can grow larger than the popover surface\n box-sizing: border-box;\n }\n}\n","import { Component, h, Prop, Element } from '@stencil/core';\n\n/**\n * @slot - Content to put inside the surface\n * @private\n */\n\n@Component({\n tag: 'limel-popover-surface',\n shadow: true,\n styleUrl: 'popover-surface.scss',\n})\nexport class PopoverSurface {\n /**\n * Content to render\n */\n @Prop()\n public contentCollection: HTMLCollection;\n\n @Element()\n private host: HTMLLimelPopoverSurfaceElement;\n\n public componentDidLoad() {\n this.appendElement();\n }\n\n public render() {\n return <div class=\"limel-popover-surface\" tabindex=\"0\" />;\n }\n\n private appendElement() {\n const portalContainer = this.host.shadowRoot.querySelector(\n '.limel-popover-surface'\n );\n\n Array.from(this.contentCollection).forEach((child) => {\n if (child.slot === 'trigger') {\n return;\n }\n\n portalContainer.appendChild(child);\n });\n }\n}\n"],"version":3}
|
|
1
|
+
{"file":"limel-popover.limel-popover-surface.entry.cjs.js","mappings":"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","names":["ESCAPE","createRandomString","h","zipObject"],"sources":["./src/components/portal/contains.ts","./src/components/popover/popover.scss?tag=limel-popover&encapsulation=shadow","./src/components/popover/popover.tsx","./src/components/popover-surface/popover-surface.scss?tag=limel-popover-surface&encapsulation=shadow","./src/components/popover-surface/popover-surface.tsx"],"sourcesContent":["/**\n * Check if an element is a descendant of another\n *\n * If the child element is a descendant of a limel-portal, this function will\n * go back through the portal and check the original tree recursively\n * @param {HTMLElement} element the parent element\n * @param {HTMLElement} child the child element to check\n * @returns {boolean} `true` if child is a descendant of element, taking\n * portals into account\n */\nexport function portalContains(\n element: HTMLElement,\n child: HTMLElement\n): boolean {\n if (element.contains(child) || element.shadowRoot?.contains(child)) {\n return true;\n }\n\n const parent = findParent(child);\n if (!parent) {\n return false;\n }\n\n return portalContains(element, parent);\n}\n\nfunction findParent(element: HTMLElement) {\n const portal: any = element.closest('.limel-portal--container');\n if (portal) {\n return portal.portalSource;\n }\n\n const rootNode = element.getRootNode() as ShadowRoot;\n\n return rootNode.host;\n}\n","/**\n * @prop --popover-surface-width: Width of the popover surface. defaults to `auto`\n * @prop --popover-body-background-color: Background color of popover body, defaults to `--lime-elevated-surface-background-color`.\n * @prop --popover-border-radius: Border radius of popover, defaults to `0.75rem`.\n * @prop --popover-z-index: z-index of the popover.\n */\n\n.trigger-anchor {\n display: inline-block;\n position: relative;\n}\n","import {\n Component,\n h,\n Prop,\n Element,\n Event,\n EventEmitter,\n Watch,\n} from '@stencil/core';\nimport { createRandomString } from '../../util/random-string';\nimport { zipObject } from 'lodash-es';\nimport { portalContains } from '../portal/contains';\nimport { ESCAPE } from '../../util/keycodes';\nimport { OpenDirection } from '../menu/menu.types';\n\n/**\n * A popover is an impermanent layer that is displayed on top of other content\n * when user taps an element that triggers the popover. This element can be\n * practically anything, a button, piece of text, and icon, etc.\n *\n * Popovers are nonmodal, thus they don't have a semi-transparent backdrop layer\n * that darkens the content below them. Also for the same reason, they can be\n * dismissed by tapping or clicking another part of the screen, but not by a\n * clicking a button or link on the popover itself.\n *\n * :::warning\n * The component is emitting a close event when you click outside its container\n * or press the <kbd>Esc</kbd> key. However, it’s up to you as consumer to react\n * properly on this event and hide the component (preferably by setting the\n * property `open` to `false`).\n * :::\n *\n * ## Usage\n * Use a popover to show **options** or **information** related to the trigger\n * onscreen. A typical use case for popovers is a tooltip, in which you show\n * help text or contextual information to users.\n *\n * Popovers are most appropriate on larger screens but can be used on smaller\n * screens too, as long as their content is responsive and takes into account\n * the context they are displayed on.\n *\n * When a popover is displayed, interactions with other controls are blocked,\n * until user dismisses the popover.\n *\n *\n * ## Layout\n * Popovers has only one slot in which you can import a custom web-component.\n *\n * :::note\n * You must make sure that web-components that you import into the slot has\n * a `width: 100%;` style so that it can horizontally stretch across the popover.\n *\n * However, `width` of the popover can be controlled by specifying a CSS variable\n * of `--popover-surface-width`. If you don't specify any width, the popover\n * will grow as wide as its content.\n * :::\n *\n * :::important\n * Do not make a popover too big. They should never take over the entire screen.\n * If your content is that big, you should probably be using a Modal instead.\n * :::\n * @slot - Content to put inside the surface\n * @exampleComponent limel-example-popover\n */\n@Component({\n tag: 'limel-popover',\n shadow: true,\n styleUrl: 'popover.scss',\n})\nexport class Popover {\n /**\n * True if the content within the popover should be visible\n */\n @Prop()\n public open = false;\n\n /**\n * Decides the popover's location in relation to its trigger\n */\n @Prop({ reflect: true })\n public openDirection: OpenDirection;\n\n /**\n * Emits an event when the component is closing\n */\n @Event()\n private close: EventEmitter<void>;\n\n @Element()\n private host: HTMLLimelPopoverElement;\n\n private portalId: string;\n\n constructor() {\n this.portalId = createRandomString();\n this.globalClickListener = this.globalClickListener.bind(this);\n }\n\n @Watch('open')\n protected watchOpen() {\n this.setupGlobalHandlers();\n }\n\n public componentWillLoad() {\n this.setupGlobalHandlers();\n }\n\n private setupGlobalHandlers() {\n if (this.open) {\n document.addEventListener('click', this.globalClickListener, {\n capture: true,\n });\n document.addEventListener('keyup', this.handleGlobalKeyPress);\n } else {\n document.removeEventListener('click', this.globalClickListener);\n document.removeEventListener('keyup', this.handleGlobalKeyPress);\n }\n }\n\n public render() {\n const cssProperties = this.getCssProperties();\n const popoverZIndex = getComputedStyle(this.host).getPropertyValue(\n '--popover-z-index'\n );\n\n return (\n <div class=\"trigger-anchor\">\n <slot name=\"trigger\"></slot>\n <limel-portal\n visible={this.open}\n containerId={this.portalId}\n containerStyle={{ 'z-index': popoverZIndex }}\n openDirection={this.openDirection}\n >\n <limel-popover-surface\n contentCollection={this.host.children}\n style={cssProperties}\n />\n </limel-portal>\n </div>\n );\n }\n\n private globalClickListener(event: MouseEvent) {\n const element: HTMLElement = event.target as HTMLElement;\n const clickedInside = portalContains(this.host, element);\n if (this.open && !clickedInside) {\n event.stopPropagation();\n event.preventDefault();\n this.close.emit();\n }\n }\n\n private getCssProperties() {\n const propertyNames = [\n '--popover-surface-width',\n '--popover-body-background-color',\n '--popover-border-radius',\n ];\n const style = getComputedStyle(this.host);\n const values = propertyNames.map((property) => {\n return style.getPropertyValue(property);\n });\n\n return zipObject(propertyNames, values);\n }\n\n private handleGlobalKeyPress = (event: KeyboardEvent) => {\n if (event.key !== ESCAPE) {\n return;\n }\n\n event.stopPropagation();\n event.preventDefault();\n this.close.emit();\n };\n}\n","@use '../../style/functions';\n@use '../../style/mixins';\n\n:host(limel-popover-surface) {\n isolation: isolate;\n\n position: relative;\n display: flex;\n\n width: var(--popover-surface-width, auto);\n max-height: inherit; // inherits it from the dynamically calculated `max-height` of `limel-portal--container`\n max-width: calc(100vw - 2rem);\n margin: 0 0.25rem;\n}\n\n.limel-popover-surface {\n flex: 1;\n min-width: 0;\n min-height: 0;\n border-radius: var(--popover-border-radius, functions.pxToRem(12));\n box-shadow: var(--shadow-depth-16);\n\n backdrop-filter: blur(functions.pxToRem(5));\n -webkit-backdrop-filter: blur(functions.pxToRem(5));\n\n &:after {\n // allows using `--popover-body-background-color` while\n // getting the blurred backdrop effect\n transition: opacity 0.4s ease;\n pointer-events: none;\n\n content: '';\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: -1;\n\n opacity: 0.75;\n\n border-radius: var(--popover-border-radius, functions.pxToRem(12));\n background-color: var(\n --popover-body-background-color,\n var(--lime-elevated-surface-background-color)\n );\n }\n\n @include mixins.visualize-keyboard-focus;\n\n &:focus,\n &:focus-within {\n &:after {\n opacity: 1;\n }\n }\n\n & > * {\n // this fixes some unwanted layout issues\n // which might be very hard for consumers to realize\n // and fix by themselves. Without this code,\n // if the consumer sets for example paddings in\n // what they send to the popover, their element\n // can grow larger than the popover surface\n box-sizing: border-box;\n }\n}\n","import { Component, h, Prop, Element } from '@stencil/core';\n\n/**\n * @slot - Content to put inside the surface\n * @private\n */\n\n@Component({\n tag: 'limel-popover-surface',\n shadow: true,\n styleUrl: 'popover-surface.scss',\n})\nexport class PopoverSurface {\n /**\n * Content to render\n */\n @Prop()\n public contentCollection: HTMLCollection;\n\n @Element()\n private host: HTMLLimelPopoverSurfaceElement;\n\n public componentDidLoad() {\n this.appendElement();\n }\n\n public render() {\n return <div class=\"limel-popover-surface\" tabindex=\"0\" />;\n }\n\n private appendElement() {\n const portalContainer = this.host.shadowRoot.querySelector(\n '.limel-popover-surface'\n );\n\n Array.from(this.contentCollection).forEach((child) => {\n if (child.slot === 'trigger') {\n return;\n }\n\n portalContainer.appendChild(child);\n });\n }\n}\n"],"version":3}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { h, } from '@stencil/core';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { unmountComponentAtNode } from 'react-dom';
|
|
4
|
+
import { createRoot } from 'react-dom/client';
|
|
4
5
|
import JSONSchemaForm from '@rjsf/core';
|
|
5
6
|
import retargetEvents from 'react-shadow-dom-retarget-events';
|
|
6
7
|
import { ArrayFieldTemplate, FieldTemplate, ObjectFieldTemplate, } from './templates';
|
|
@@ -10,7 +11,8 @@ import { ObjectField as CustomObjectField } from './fields/object-field';
|
|
|
10
11
|
import { widgets } from './widgets';
|
|
11
12
|
import { createRandomString } from '../../util/random-string';
|
|
12
13
|
import Ajv from 'ajv';
|
|
13
|
-
import
|
|
14
|
+
import addFormats from 'ajv-formats';
|
|
15
|
+
import { isInteger, isNumber } from './validators';
|
|
14
16
|
import { mapValues } from 'lodash-es';
|
|
15
17
|
/**
|
|
16
18
|
* @exampleComponent limel-example-form
|
|
@@ -69,8 +71,11 @@ export class Form {
|
|
|
69
71
|
return h("div", { class: "root" });
|
|
70
72
|
}
|
|
71
73
|
reactRender() {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
+
if (!this.root) {
|
|
75
|
+
const rootElement = this.host.shadowRoot.querySelector('.root');
|
|
76
|
+
this.root = createRoot(rootElement);
|
|
77
|
+
}
|
|
78
|
+
this.root.render(React.createElement(JSONSchemaForm, {
|
|
74
79
|
schema: this.modifiedSchema,
|
|
75
80
|
formData: this.value,
|
|
76
81
|
onChange: this.handleChange,
|
|
@@ -93,7 +98,7 @@ export class Form {
|
|
|
93
98
|
ArrayField: CustomArrayField,
|
|
94
99
|
ObjectField: CustomObjectField,
|
|
95
100
|
},
|
|
96
|
-
}, [])
|
|
101
|
+
}, []));
|
|
97
102
|
}
|
|
98
103
|
handleChange(event) {
|
|
99
104
|
this.change.emit(event.formData);
|
|
@@ -123,16 +128,23 @@ export class Form {
|
|
|
123
128
|
}
|
|
124
129
|
createValidator() {
|
|
125
130
|
const validator = new Ajv({
|
|
126
|
-
unknownFormats: 'ignore',
|
|
127
131
|
allErrors: true,
|
|
128
132
|
multipleOfPrecision: 2,
|
|
129
|
-
|
|
133
|
+
allowUnionTypes: true,
|
|
134
|
+
strict: 'log',
|
|
135
|
+
keywords: ['lime', 'many', 'inline'],
|
|
136
|
+
formats: {
|
|
137
|
+
integer: isInteger,
|
|
138
|
+
decimal: isNumber,
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
addFormats(validator);
|
|
130
142
|
this.validator = validator.compile(this.schema);
|
|
131
143
|
}
|
|
132
144
|
getValidationErrors() {
|
|
133
145
|
const errors = this.validator.errors || [];
|
|
134
146
|
return errors.map((error) => {
|
|
135
|
-
let property = error.
|
|
147
|
+
let property = error.instancePath;
|
|
136
148
|
if (error.keyword === 'required') {
|
|
137
149
|
property = error.params.missingProperty;
|
|
138
150
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form.js","sourceRoot":"","sources":["../../../src/components/form/form.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Element,\n Event,\n EventEmitter,\n h,\n Prop,\n Watch,\n} from '@stencil/core';\nimport React from 'react';\nimport { render, unmountComponentAtNode } from 'react-dom';\nimport JSONSchemaForm, { AjvError } from '@rjsf/core';\nimport retargetEvents from 'react-shadow-dom-retarget-events';\nimport { FormError, ValidationError, ValidationStatus } from './form.types';\nimport {\n ArrayFieldTemplate,\n FieldTemplate,\n ObjectFieldTemplate,\n} from './templates';\nimport { SchemaField as CustomSchemaField } from './fields/schema-field';\nimport { ArrayField as CustomArrayField } from './fields/array-field';\nimport { ObjectField as CustomObjectField } from './fields/object-field';\nimport { widgets } from './widgets';\nimport { createRandomString } from '../../util/random-string';\nimport Ajv, { RequiredParams } from 'ajv';\nimport { isInteger } from './validators';\nimport { mapValues } from 'lodash-es';\n\n/**\n * @exampleComponent limel-example-form\n * @exampleComponent limel-example-nested-form\n * @exampleComponent limel-example-list-form\n * @exampleComponent limel-example-dynamic-form\n * @exampleComponent limel-example-custom-component-form\n * @exampleComponent limel-example-props-factory-form\n * @exampleComponent limel-example-form-layout\n * @exampleComponent limel-example-form-span-fields\n * @exampleComponent limel-example-custom-error-message\n * @exampleComponent limel-example-server-errors\n * @exampleComponent limel-example-form-row-layout\n */\n@Component({\n tag: 'limel-form',\n shadow: true,\n styleUrl: 'form.scss',\n})\nexport class Form {\n /**\n * The schema used to render the form\n */\n @Prop()\n public schema: {\n id?: string;\n [key: string]: any;\n } = {};\n\n /**\n * Value of the form\n */\n @Prop()\n public value: object;\n\n /**\n * Set to `true` to disable the whole form.\n */\n @Prop()\n public disabled = false;\n\n /**\n * Factory for creating properties for custom form components\n *\n * When using custom components in the form some properties might have to be\n * set dynamically. If this factory is set, it will be called with the\n * current schema for the field for each custom component in the form. The\n * factory must return an object where each key is the name of the property\n * that should be set, along with its value.\n */\n @Prop()\n public propsFactory?: (schema: Record<string, any>) => Record<string, any>;\n\n /**\n * Custom function to customize the default error messages\n */\n @Prop()\n public transformErrors?: (errors: FormError[]) => FormError[];\n\n /**\n * Extra errors to display in the form. Typical use case is asynchronous\n * errors generated server side.\n */\n @Prop()\n public errors: ValidationError;\n\n /**\n * Emitted when a change is made within the form\n */\n @Event()\n public change: EventEmitter<object>;\n\n /**\n * Emitted when the validity of the form changes, or when\n * a change is made to an invalid form\n */\n @Event()\n public validate: EventEmitter<ValidationStatus>;\n\n @Element()\n private host: HTMLLimelFormElement;\n\n private isValid = true;\n private modifiedSchema: object;\n private validator: Ajv.ValidateFunction;\n\n public constructor() {\n this.handleChange = this.handleChange.bind(this);\n this.getCustomErrorMessages = this.getCustomErrorMessages.bind(this);\n }\n\n public connectedCallback() {\n this.initialize();\n }\n\n public componentWillLoad() {\n this.setSchemaId();\n this.createValidator();\n }\n\n public componentDidLoad() {\n this.initialize();\n }\n\n private initialize() {\n if (!this.host.shadowRoot.querySelector('.root')) {\n return;\n }\n\n this.reactRender();\n retargetEvents(this.host.shadowRoot);\n this.validateForm(this.value);\n }\n\n public componentDidUpdate() {\n this.reactRender();\n this.validateForm(this.value);\n }\n\n public disconnectedCallback() {\n const rootElement = this.host.shadowRoot.querySelector('.root');\n if (rootElement) {\n unmountComponentAtNode(rootElement);\n }\n }\n\n public render() {\n return <div class=\"root\" />;\n }\n\n private reactRender() {\n const rootElement = this.host.shadowRoot.querySelector('.root');\n\n render(\n React.createElement(\n JSONSchemaForm,\n {\n schema: this.modifiedSchema,\n formData: this.value,\n onChange: this.handleChange,\n widgets: widgets,\n liveValidate: true,\n showErrorList: false,\n extraErrors: this.getExtraErrors(this.errors),\n FieldTemplate: FieldTemplate,\n ArrayFieldTemplate: ArrayFieldTemplate as any,\n ObjectFieldTemplate: ObjectFieldTemplate,\n disabled: this.disabled,\n transformErrors: this.getCustomErrorMessages,\n formContext: {\n schema: this.modifiedSchema,\n rootValue: this.value,\n propsFactory: this.propsFactory,\n },\n fields: {\n SchemaField: CustomSchemaField as any,\n ArrayField: CustomArrayField as any,\n ObjectField: CustomObjectField as any,\n },\n },\n []\n ),\n rootElement\n );\n }\n\n private handleChange(event: any) {\n this.change.emit(event.formData);\n }\n\n private validateForm(value: object) {\n const isValid = this.validator(value) === true;\n const errors: FormError[] = this.getValidationErrors();\n const status: ValidationStatus = {\n valid: isValid,\n errors: errors,\n };\n\n if (this.isValid !== status.valid || !status.valid) {\n this.validate.emit(status);\n }\n\n this.isValid = status.valid;\n }\n\n @Watch('schema')\n public setSchema() {\n this.setSchemaId();\n this.createValidator();\n }\n\n private setSchemaId() {\n // Due to a bug in react-jsonschema-form, validation will stop working if the schema is updated.\n // A workaround at the moment is to always give it a unique ID\n // https://github.com/rjsf-team/react-jsonschema-form/issues/1563\n const id = `${this.schema.$id}-${createRandomString()}`;\n this.modifiedSchema = {\n ...this.schema,\n id: id,\n $id: id,\n };\n }\n\n private createValidator() {\n const validator = new Ajv({\n unknownFormats: 'ignore',\n allErrors: true,\n multipleOfPrecision: 2,\n }).addFormat('integer', isInteger);\n this.validator = validator.compile(this.schema);\n }\n\n private getValidationErrors(): FormError[] {\n const errors = this.validator.errors || [];\n\n return errors.map((error: Ajv.ErrorObject): FormError => {\n let property = error.dataPath;\n if (error.keyword === 'required') {\n property = (error.params as RequiredParams).missingProperty;\n }\n\n return {\n name: error.keyword,\n property: property,\n message: error.message,\n schemaPath: error.schemaPath,\n };\n });\n }\n\n private getExtraErrors(errors: ValidationError): ExtraError | undefined {\n if (!errors) {\n return;\n }\n\n return mapValues(errors, (error) => {\n if (Array.isArray(error)) {\n return { __errors: error };\n }\n\n return this.getExtraErrors(error);\n });\n }\n\n private getCustomErrorMessages(originalErrors: AjvError[]): AjvError[] {\n if (!this.transformErrors) {\n return originalErrors;\n }\n\n const errors: FormError[] = originalErrors.map((error: AjvError) => {\n return {\n name: error.name,\n params: error.params,\n property: error.property,\n message: error.message,\n // For some reason 'schemaPath' is missing from the AjvError type definition:\n // https://github.com/rjsf-team/react-jsonschema-form/issues/2140\n // eslint-disable-next-line @typescript-eslint/dot-notation\n schemaPath: error['schemaPath'],\n };\n });\n\n // Use `.call({}, …)` here to bind `this` to an empty object to prevent\n // the consumer submitted `transformErrors` from getting access to our\n // component's internals. /Ads\n return this.transformErrors\n .call({}, errors)\n .map((transformedError: FormError) => {\n const originalError = originalErrors.find((error: AjvError) => {\n return transformedError.property === error.property;\n });\n\n return {\n ...originalError,\n message: transformedError.message,\n };\n });\n }\n}\n\ninterface ExtraError {\n [key: string]:\n | ExtraError\n | {\n __errors: string[];\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"form.js","sourceRoot":"","sources":["../../../src/components/form/form.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n Element,\n Event,\n EventEmitter,\n h,\n Prop,\n Watch,\n} from '@stencil/core';\nimport React from 'react';\nimport { unmountComponentAtNode } from 'react-dom';\nimport { createRoot, Root } from 'react-dom/client';\nimport JSONSchemaForm, { AjvError } from '@rjsf/core';\nimport retargetEvents from 'react-shadow-dom-retarget-events';\nimport { FormError, ValidationError, ValidationStatus } from './form.types';\nimport {\n ArrayFieldTemplate,\n FieldTemplate,\n ObjectFieldTemplate,\n} from './templates';\nimport { SchemaField as CustomSchemaField } from './fields/schema-field';\nimport { ArrayField as CustomArrayField } from './fields/array-field';\nimport { ObjectField as CustomObjectField } from './fields/object-field';\nimport { widgets } from './widgets';\nimport { createRandomString } from '../../util/random-string';\nimport Ajv, { ErrorObject, ValidateFunction } from 'ajv';\nimport addFormats from 'ajv-formats';\nimport { isInteger, isNumber } from './validators';\nimport { mapValues } from 'lodash-es';\n\n/**\n * @exampleComponent limel-example-form\n * @exampleComponent limel-example-nested-form\n * @exampleComponent limel-example-list-form\n * @exampleComponent limel-example-dynamic-form\n * @exampleComponent limel-example-custom-component-form\n * @exampleComponent limel-example-props-factory-form\n * @exampleComponent limel-example-form-layout\n * @exampleComponent limel-example-form-span-fields\n * @exampleComponent limel-example-custom-error-message\n * @exampleComponent limel-example-server-errors\n * @exampleComponent limel-example-form-row-layout\n */\n@Component({\n tag: 'limel-form',\n shadow: true,\n styleUrl: 'form.scss',\n})\nexport class Form {\n /**\n * The schema used to render the form\n */\n @Prop()\n public schema: {\n id?: string;\n [key: string]: any;\n } = {};\n\n /**\n * Value of the form\n */\n @Prop()\n public value: object;\n\n /**\n * Set to `true` to disable the whole form.\n */\n @Prop()\n public disabled = false;\n\n /**\n * Factory for creating properties for custom form components\n *\n * When using custom components in the form some properties might have to be\n * set dynamically. If this factory is set, it will be called with the\n * current schema for the field for each custom component in the form. The\n * factory must return an object where each key is the name of the property\n * that should be set, along with its value.\n */\n @Prop()\n public propsFactory?: (schema: Record<string, any>) => Record<string, any>;\n\n /**\n * Custom function to customize the default error messages\n */\n @Prop()\n public transformErrors?: (errors: FormError[]) => FormError[];\n\n /**\n * Extra errors to display in the form. Typical use case is asynchronous\n * errors generated server side.\n */\n @Prop()\n public errors: ValidationError;\n\n /**\n * Emitted when a change is made within the form\n */\n @Event()\n public change: EventEmitter<object>;\n\n /**\n * Emitted when the validity of the form changes, or when\n * a change is made to an invalid form\n */\n @Event()\n public validate: EventEmitter<ValidationStatus>;\n\n @Element()\n private host: HTMLLimelFormElement;\n\n private isValid = true;\n private modifiedSchema: object;\n private validator: ValidateFunction;\n private root: Root;\n\n public constructor() {\n this.handleChange = this.handleChange.bind(this);\n this.getCustomErrorMessages = this.getCustomErrorMessages.bind(this);\n }\n\n public connectedCallback() {\n this.initialize();\n }\n\n public componentWillLoad() {\n this.setSchemaId();\n this.createValidator();\n }\n\n public componentDidLoad() {\n this.initialize();\n }\n\n private initialize() {\n if (!this.host.shadowRoot.querySelector('.root')) {\n return;\n }\n\n this.reactRender();\n retargetEvents(this.host.shadowRoot);\n this.validateForm(this.value);\n }\n\n public componentDidUpdate() {\n this.reactRender();\n this.validateForm(this.value);\n }\n\n public disconnectedCallback() {\n const rootElement = this.host.shadowRoot.querySelector('.root');\n if (rootElement) {\n unmountComponentAtNode(rootElement);\n }\n }\n\n public render() {\n return <div class=\"root\" />;\n }\n\n private reactRender() {\n if (!this.root) {\n const rootElement = this.host.shadowRoot.querySelector('.root');\n this.root = createRoot(rootElement);\n }\n\n this.root.render(\n React.createElement(\n JSONSchemaForm,\n {\n schema: this.modifiedSchema,\n formData: this.value,\n onChange: this.handleChange,\n widgets: widgets,\n liveValidate: true,\n showErrorList: false,\n extraErrors: this.getExtraErrors(this.errors),\n FieldTemplate: FieldTemplate,\n ArrayFieldTemplate: ArrayFieldTemplate as any,\n ObjectFieldTemplate: ObjectFieldTemplate,\n disabled: this.disabled,\n transformErrors: this.getCustomErrorMessages,\n formContext: {\n schema: this.modifiedSchema,\n rootValue: this.value,\n propsFactory: this.propsFactory,\n },\n fields: {\n SchemaField: CustomSchemaField as any,\n ArrayField: CustomArrayField as any,\n ObjectField: CustomObjectField as any,\n },\n },\n []\n )\n );\n }\n\n private handleChange(event: any) {\n this.change.emit(event.formData);\n }\n\n private validateForm(value: object) {\n const isValid = this.validator(value) === true;\n const errors: FormError[] = this.getValidationErrors();\n const status: ValidationStatus = {\n valid: isValid,\n errors: errors,\n };\n\n if (this.isValid !== status.valid || !status.valid) {\n this.validate.emit(status);\n }\n\n this.isValid = status.valid;\n }\n\n @Watch('schema')\n public setSchema() {\n this.setSchemaId();\n this.createValidator();\n }\n\n private setSchemaId() {\n // Due to a bug in react-jsonschema-form, validation will stop working if the schema is updated.\n // A workaround at the moment is to always give it a unique ID\n // https://github.com/rjsf-team/react-jsonschema-form/issues/1563\n const id = `${this.schema.$id}-${createRandomString()}`;\n this.modifiedSchema = {\n ...this.schema,\n id: id,\n $id: id,\n };\n }\n\n private createValidator() {\n const validator = new Ajv({\n allErrors: true,\n multipleOfPrecision: 2,\n allowUnionTypes: true,\n strict: 'log',\n keywords: ['lime', 'many', 'inline'],\n formats: {\n integer: isInteger,\n decimal: isNumber,\n },\n });\n addFormats(validator);\n this.validator = validator.compile(this.schema);\n }\n\n private getValidationErrors(): FormError[] {\n const errors = this.validator.errors || [];\n\n return errors.map((error: ErrorObject): FormError => {\n let property = error.instancePath;\n if (error.keyword === 'required') {\n property = error.params.missingProperty;\n }\n\n return {\n name: error.keyword,\n property: property,\n message: error.message,\n schemaPath: error.schemaPath,\n };\n });\n }\n\n private getExtraErrors(errors: ValidationError): ExtraError | undefined {\n if (!errors) {\n return;\n }\n\n return mapValues(errors, (error) => {\n if (Array.isArray(error)) {\n return { __errors: error };\n }\n\n return this.getExtraErrors(error);\n });\n }\n\n private getCustomErrorMessages(originalErrors: AjvError[]): AjvError[] {\n if (!this.transformErrors) {\n return originalErrors;\n }\n\n const errors: FormError[] = originalErrors.map((error: AjvError) => {\n return {\n name: error.name,\n params: error.params,\n property: error.property,\n message: error.message,\n // For some reason 'schemaPath' is missing from the AjvError type definition:\n // https://github.com/rjsf-team/react-jsonschema-form/issues/2140\n // eslint-disable-next-line @typescript-eslint/dot-notation\n schemaPath: error['schemaPath'],\n };\n });\n\n // Use `.call({}, …)` here to bind `this` to an empty object to prevent\n // the consumer submitted `transformErrors` from getting access to our\n // component's internals. /Ads\n return this.transformErrors\n .call({}, errors)\n .map((transformedError: FormError) => {\n const originalError = originalErrors.find((error: AjvError) => {\n return transformedError.property === error.property;\n });\n\n return {\n ...originalError,\n message: transformedError.message,\n };\n });\n }\n}\n\ninterface ExtraError {\n [key: string]:\n | ExtraError\n | {\n __errors: string[];\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../../src/components/form/validators/format.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,SAAS,CAAC,IAAY;EAClC,OAAO,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1C,CAAC","sourcesContent":["export function isInteger(data: string): boolean {\n return Number.isInteger(Number(data));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../../src/components/form/validators/format.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,SAAS,CAAC,IAAY;EAClC,OAAO,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY;EACjC,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AACzC,CAAC","sourcesContent":["export function isInteger(data: string): boolean {\n return Number.isInteger(Number(data));\n}\n\nexport function isNumber(data: string): boolean {\n return Number.isFinite(Number(data));\n}\n"]}
|