@limetech/lime-elements 40.21.1 → 40.23.0
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/CHANGELOG.md +19 -0
- package/dist/cjs/language-s0bKUCvO.js +58 -0
- package/dist/cjs/lime-elements.cjs.js +1 -1
- package/dist/cjs/limel-action-bar_3.cjs.entry.js +2 -2
- package/dist/cjs/limel-ai-avatar.cjs.entry.js +2 -2
- package/dist/cjs/limel-badge_7.cjs.entry.js +2 -2
- package/dist/cjs/limel-callout.cjs.entry.js +2 -2
- package/dist/cjs/limel-chart.cjs.entry.js +524 -76
- package/dist/cjs/limel-chip-set.cjs.entry.js +2 -2
- package/dist/cjs/limel-chip_2.cjs.entry.js +2 -2
- package/dist/cjs/limel-code-diff.cjs.entry.js +2 -2
- package/dist/cjs/limel-code-editor.cjs.entry.js +2 -2
- package/dist/cjs/limel-collapsible-section.cjs.entry.js +2 -2
- package/dist/cjs/limel-date-picker.cjs.entry.js +1 -1
- package/dist/cjs/limel-dock.cjs.entry.js +2 -2
- package/dist/cjs/limel-drag-handle_2.cjs.entry.js +2 -2
- package/dist/cjs/limel-email-viewer.cjs.entry.js +2 -2
- package/dist/cjs/limel-file-viewer.cjs.entry.js +2 -2
- package/dist/cjs/limel-file.cjs.entry.js +2 -2
- package/dist/cjs/limel-flatpickr-adapter.cjs.entry.js +2 -2
- package/dist/cjs/limel-form.cjs.entry.js +202 -15
- package/dist/cjs/limel-list-item.cjs.entry.js +2 -2
- package/dist/cjs/limel-pagination-jump.cjs.entry.js +2 -2
- package/dist/cjs/limel-pagination.cjs.entry.js +14 -26
- package/dist/cjs/limel-picker.cjs.entry.js +2 -2
- package/dist/cjs/limel-profile-picture.cjs.entry.js +2 -2
- package/dist/cjs/limel-prosemirror-adapter.cjs.entry.js +2 -2
- package/dist/cjs/limel-resize-handle.cjs.entry.js +2 -2
- package/dist/cjs/limel-side-panel.cjs.entry.js +2 -2
- package/dist/cjs/limel-slider.cjs.entry.js +2 -2
- package/dist/cjs/limel-snackbar.cjs.entry.js +2 -2
- package/dist/cjs/limel-table.cjs.entry.js +2 -2
- package/dist/cjs/limel-text-editor-link-menu.cjs.entry.js +2 -2
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/{translations-CqJEWcfw.js → translations-JLP5icQ9.js} +1 -1
- package/dist/collection/components/chart/chart.js +116 -45
- package/dist/collection/components/chart/format.js +302 -0
- package/dist/collection/components/chart/options.js +26 -14
- package/dist/collection/components/chart/scale.js +132 -19
- package/dist/collection/components/form/filled-defaults.js +132 -0
- package/dist/collection/components/form/form.js +93 -15
- package/dist/collection/components/form/form.test-schemas.js +50 -0
- package/dist/collection/components/pagination/pagination.js +13 -25
- package/dist/collection/util/language.js +29 -0
- package/dist/esm/language-VamkUr90.js +55 -0
- package/dist/esm/lime-elements.js +1 -1
- package/dist/esm/limel-action-bar_3.entry.js +2 -2
- package/dist/esm/limel-ai-avatar.entry.js +2 -2
- package/dist/esm/limel-badge_7.entry.js +2 -2
- package/dist/esm/limel-callout.entry.js +2 -2
- package/dist/esm/limel-chart.entry.js +524 -76
- package/dist/esm/limel-chip-set.entry.js +2 -2
- package/dist/esm/limel-chip_2.entry.js +2 -2
- package/dist/esm/limel-code-diff.entry.js +2 -2
- package/dist/esm/limel-code-editor.entry.js +2 -2
- package/dist/esm/limel-collapsible-section.entry.js +2 -2
- package/dist/esm/limel-date-picker.entry.js +1 -1
- package/dist/esm/limel-dock.entry.js +2 -2
- package/dist/esm/limel-drag-handle_2.entry.js +2 -2
- package/dist/esm/limel-email-viewer.entry.js +2 -2
- package/dist/esm/limel-file-viewer.entry.js +2 -2
- package/dist/esm/limel-file.entry.js +2 -2
- package/dist/esm/limel-flatpickr-adapter.entry.js +2 -2
- package/dist/esm/limel-form.entry.js +202 -15
- package/dist/esm/limel-list-item.entry.js +2 -2
- package/dist/esm/limel-pagination-jump.entry.js +2 -2
- package/dist/esm/limel-pagination.entry.js +14 -26
- package/dist/esm/limel-picker.entry.js +2 -2
- package/dist/esm/limel-profile-picture.entry.js +2 -2
- package/dist/esm/limel-prosemirror-adapter.entry.js +2 -2
- package/dist/esm/limel-resize-handle.entry.js +2 -2
- package/dist/esm/limel-side-panel.entry.js +2 -2
- package/dist/esm/limel-slider.entry.js +2 -2
- package/dist/esm/limel-snackbar.entry.js +2 -2
- package/dist/esm/limel-table.entry.js +2 -2
- package/dist/esm/limel-text-editor-link-menu.entry.js +2 -2
- package/dist/esm/loader.js +1 -1
- package/dist/esm/{translations-kct5Kybu.js → translations-D9ZGrMhe.js} +1 -1
- package/dist/lime-elements/lime-elements.esm.js +1 -1
- package/dist/lime-elements/{p-6e9eeb0a.entry.js → p-0a7cbdc3.entry.js} +1 -1
- package/dist/lime-elements/{p-d35d2859.entry.js → p-0f96e94d.entry.js} +1 -1
- package/dist/lime-elements/{p-a7be03e1.entry.js → p-1a0c5e45.entry.js} +1 -1
- package/dist/lime-elements/{p-5e408c27.entry.js → p-401d5c92.entry.js} +1 -1
- package/dist/lime-elements/{p-6d2d25b9.entry.js → p-430db3b9.entry.js} +1 -1
- package/dist/lime-elements/{p-a6c6a31b.entry.js → p-43b62587.entry.js} +1 -1
- package/dist/lime-elements/{p-958396b5.entry.js → p-48dccb83.entry.js} +1 -1
- package/dist/lime-elements/{p-814b4934.entry.js → p-5c918155.entry.js} +1 -1
- package/dist/lime-elements/{p-22e9e327.entry.js → p-66101ed6.entry.js} +1 -1
- package/dist/lime-elements/{p-d8559847.entry.js → p-7ab72b52.entry.js} +1 -1
- package/dist/lime-elements/{p-7af83877.entry.js → p-8d9a2a22.entry.js} +1 -1
- package/dist/lime-elements/{p-55fa19ae.entry.js → p-8de4f0f3.entry.js} +1 -1
- package/dist/lime-elements/p-8e80a884.entry.js +56 -0
- package/dist/lime-elements/{p-bffb5ed2.entry.js → p-99984c66.entry.js} +1 -1
- package/dist/lime-elements/{p-56e2fa48.entry.js → p-9d46f720.entry.js} +1 -1
- package/dist/lime-elements/{p-68bbb8dd.entry.js → p-9e2b426c.entry.js} +1 -1
- package/dist/lime-elements/{p-Dzp8dXTo.js → p-C9dBa_Im.js} +1 -1
- package/dist/lime-elements/p-VamkUr90.js +1 -0
- package/dist/lime-elements/{p-3ac39bd5.entry.js → p-b1c7033b.entry.js} +2 -2
- package/dist/lime-elements/{p-47fe76a8.entry.js → p-b5451350.entry.js} +1 -1
- package/dist/lime-elements/{p-9edd79a8.entry.js → p-c75f3b0d.entry.js} +1 -1
- package/dist/lime-elements/{p-4c080cd9.entry.js → p-ca4247c4.entry.js} +1 -1
- package/dist/lime-elements/{p-1a7d1d2b.entry.js → p-d53421af.entry.js} +1 -1
- package/dist/lime-elements/{p-6d9b89db.entry.js → p-d8901e39.entry.js} +1 -1
- package/dist/lime-elements/{p-933ffaa8.entry.js → p-d89553b3.entry.js} +1 -1
- package/dist/lime-elements/{p-496b2437.entry.js → p-d93b8ce0.entry.js} +1 -1
- package/dist/lime-elements/{p-23067836.entry.js → p-e97340c4.entry.js} +1 -1
- package/dist/lime-elements/{p-7b87e547.entry.js → p-ec0c113d.entry.js} +1 -1
- package/dist/lime-elements/{p-9f0575fd.entry.js → p-f197000b.entry.js} +4 -4
- package/dist/lime-elements/{p-07f3565b.entry.js → p-f6bc6658.entry.js} +1 -1
- package/dist/lime-elements/{p-9b2623fe.entry.js → p-f71fbc9e.entry.js} +1 -1
- package/dist/lime-elements/{p-7fcd48c6.entry.js → p-fa1aa440.entry.js} +1 -1
- package/dist/types/components/chart/chart.d.ts +32 -7
- package/dist/types/components/chart/chart.types.d.ts +15 -1
- package/dist/types/components/chart/format.d.ts +54 -0
- package/dist/types/components/chart/options.d.ts +3 -4
- package/dist/types/components/chart/scale.d.ts +39 -7
- package/dist/types/components/form/filled-defaults.d.ts +12 -0
- package/dist/types/components/form/form.d.ts +17 -0
- package/dist/types/components/form/form.test-schemas.d.ts +2 -0
- package/dist/types/components/pagination/pagination.d.ts +6 -12
- package/dist/types/components.d.ts +51 -8
- package/dist/types/util/language.d.ts +19 -0
- package/package.json +3 -3
- package/dist/cjs/language-v-MMS6ym.js +0 -28
- package/dist/esm/language-ChagAaNf.js +0 -26
- package/dist/lime-elements/p-7d6a12fe.entry.js +0 -56
- package/dist/lime-elements/p-ChagAaNf.js +0 -1
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { isEmpty, isEqual, isPlainObject } from "lodash-es";
|
|
2
|
+
/**
|
|
3
|
+
* The value without the defaults that were filled into the value the form was
|
|
4
|
+
* given, as long as they still hold their default. A default the user changed
|
|
5
|
+
* stays, and so do the defaults of what the user added, such as a list item.
|
|
6
|
+
*
|
|
7
|
+
* @param value - the value the form holds, with the defaults filled in
|
|
8
|
+
* @param filled - the value the form was given, with the defaults filled in
|
|
9
|
+
* @param given - the value the form was given
|
|
10
|
+
* @returns the value without the defaults that were filled in
|
|
11
|
+
*/
|
|
12
|
+
export function withoutFilledDefaults(value, filled, given) {
|
|
13
|
+
// A change can bring in objects that hold nothing, which mean nothing
|
|
14
|
+
if (isPlainObject(value)) {
|
|
15
|
+
return withoutFilledProperties(value, isPlainObject(filled) ? filled : {}, given);
|
|
16
|
+
}
|
|
17
|
+
if (Array.isArray(value)) {
|
|
18
|
+
return withoutFilledItems(value, Array.isArray(filled) ? filled : [], given);
|
|
19
|
+
}
|
|
20
|
+
return given === undefined && isEqual(value, filled) ? undefined : value;
|
|
21
|
+
}
|
|
22
|
+
function withoutFilledProperties(value, filled, given) {
|
|
23
|
+
const givenProperties = isPlainObject(given)
|
|
24
|
+
? given
|
|
25
|
+
: {};
|
|
26
|
+
// In the order they were given, so a saved value keeps its key order
|
|
27
|
+
const keys = new Set([
|
|
28
|
+
...Object.keys(givenProperties),
|
|
29
|
+
...Object.keys(value),
|
|
30
|
+
]);
|
|
31
|
+
const result = {};
|
|
32
|
+
for (const key of keys) {
|
|
33
|
+
if (!Object.hasOwn(value, key)) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
const kept = withoutFilledDefaults(value[key], filled[key], givenProperties[key]);
|
|
37
|
+
if (kept !== undefined) {
|
|
38
|
+
result[key] = kept;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return isEmpty(result) && given == null ? given : result;
|
|
42
|
+
}
|
|
43
|
+
// Items are paired with the ones the form was given by content, so a removed
|
|
44
|
+
// or moved item does not shift the others onto the defaults of their
|
|
45
|
+
// neighbors. An item that no longer equals any of them is paired with the one
|
|
46
|
+
// it has the most in common with, so an edited item still loses its defaults
|
|
47
|
+
function withoutFilledItems(items, filled, given) {
|
|
48
|
+
// A list that was not given is a default as a whole: once the user
|
|
49
|
+
// changes it, it is the user's
|
|
50
|
+
if (!Array.isArray(given)) {
|
|
51
|
+
return isEqual(items, filled) ? given : items;
|
|
52
|
+
}
|
|
53
|
+
const givenItems = given;
|
|
54
|
+
const matches = pairItems(items, filled);
|
|
55
|
+
const result = [];
|
|
56
|
+
for (const [index, item] of items.entries()) {
|
|
57
|
+
const match = matches.get(index);
|
|
58
|
+
if (match === undefined) {
|
|
59
|
+
result.push(item);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const kept = withoutFilledDefaults(item, filled[match], givenItems[match]);
|
|
63
|
+
if (kept !== undefined) {
|
|
64
|
+
result.push(kept);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
function pairItems(items, filled) {
|
|
70
|
+
const matches = new Map();
|
|
71
|
+
const unmatched = new Set(filled.keys());
|
|
72
|
+
const pair = (index, match) => {
|
|
73
|
+
matches.set(index, match);
|
|
74
|
+
unmatched.delete(match);
|
|
75
|
+
};
|
|
76
|
+
for (const [index, item] of items.entries()) {
|
|
77
|
+
if (unmatched.has(index) && isEqual(item, filled[index])) {
|
|
78
|
+
pair(index, index);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
for (const [index, item] of items.entries()) {
|
|
82
|
+
if (matches.has(index)) {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const same = [...unmatched].find((i) => isEqual(item, filled[i]));
|
|
86
|
+
if (same !== undefined) {
|
|
87
|
+
pair(index, same);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
for (const [index, item] of items.entries()) {
|
|
91
|
+
if (matches.has(index)) {
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const closest = findClosest(item, filled, unmatched);
|
|
95
|
+
if (closest !== undefined) {
|
|
96
|
+
pair(index, closest);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return matches;
|
|
100
|
+
}
|
|
101
|
+
// The one item that shares the most equal properties, if it shares any at
|
|
102
|
+
// all. When several share as many there is no telling which the item was, and
|
|
103
|
+
// it is left as it is, since a kept default means the same as a missing one
|
|
104
|
+
// while a lost value does not
|
|
105
|
+
function findClosest(item, filled, candidates) {
|
|
106
|
+
if (!isPlainObject(item)) {
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
let closest;
|
|
110
|
+
let best = 0;
|
|
111
|
+
let isTied = false;
|
|
112
|
+
for (const candidate of candidates) {
|
|
113
|
+
const score = sharedProperties(item, filled[candidate]);
|
|
114
|
+
if (score === best) {
|
|
115
|
+
isTied = true;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (score < best) {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
best = score;
|
|
122
|
+
closest = candidate;
|
|
123
|
+
isTied = false;
|
|
124
|
+
}
|
|
125
|
+
return isTied ? undefined : closest;
|
|
126
|
+
}
|
|
127
|
+
function sharedProperties(item, other) {
|
|
128
|
+
if (!isPlainObject(other)) {
|
|
129
|
+
return 0;
|
|
130
|
+
}
|
|
131
|
+
return Object.entries(item).filter(([key, value]) => isEqual(value, other[key])).length;
|
|
132
|
+
}
|
|
@@ -14,6 +14,7 @@ import { h, } from "@stencil/core";
|
|
|
14
14
|
import React from "react";
|
|
15
15
|
import { createRoot } from "react-dom/client";
|
|
16
16
|
import JSONSchemaForm from "@rjsf/core";
|
|
17
|
+
import { getDefaultFormState, } from "@rjsf/utils";
|
|
17
18
|
import { isHeadingLevel } from "../../util/heading-level";
|
|
18
19
|
import { ArrayFieldTemplate, ArrayFieldItemTemplate, FieldTemplate, ObjectFieldTemplate, } from "./templates";
|
|
19
20
|
import { SchemaField as CustomSchemaField } from "./fields/schema-field";
|
|
@@ -23,7 +24,17 @@ import { widgets } from "./widgets";
|
|
|
23
24
|
import { rjsfValidator } from "./validator";
|
|
24
25
|
import { isEqual, mapValues } from "lodash-es";
|
|
25
26
|
import { showField, stopShowingField } from "./show-field";
|
|
27
|
+
import { withoutFilledDefaults } from "./filled-defaults";
|
|
26
28
|
import { HeadingLevelContext } from "./templates/heading-level";
|
|
29
|
+
// `@rjsf/core` v6 treats a `const` inside `oneOf`/`anyOf` as a default and
|
|
30
|
+
// auto-selects the first option, so an optional enum can never be left empty
|
|
31
|
+
// (clearing it just gets repopulated on the next render). `skipOneOf` keeps this
|
|
32
|
+
// off for enums while still applying genuine `default` values, matching the
|
|
33
|
+
// pre-v6 behavior.
|
|
34
|
+
const FILL_DEFAULTS = {
|
|
35
|
+
constAsDefaults: 'skipOneOf',
|
|
36
|
+
requiredBooleanDefault: 'skip',
|
|
37
|
+
};
|
|
27
38
|
/**
|
|
28
39
|
* @exampleComponent limel-example-form
|
|
29
40
|
* @exampleComponent limel-example-nested-form
|
|
@@ -44,6 +55,7 @@ import { HeadingLevelContext } from "./templates/heading-level";
|
|
|
44
55
|
* @exampleComponent limel-example-code-editor-form
|
|
45
56
|
* @exampleComponent limel-example-form-highlighted-field
|
|
46
57
|
* @exampleComponent limel-example-form-heading-level
|
|
58
|
+
* @exampleComponent limel-example-form-include-defaults
|
|
47
59
|
*/
|
|
48
60
|
export class Form {
|
|
49
61
|
constructor() {
|
|
@@ -73,6 +85,18 @@ export class Form {
|
|
|
73
85
|
* which keeps untouched required-empty fields silent.
|
|
74
86
|
*/
|
|
75
87
|
this.revealErrors = false;
|
|
88
|
+
/**
|
|
89
|
+
* Set to `false` to leave the defaults of the schema out of the value,
|
|
90
|
+
* so that it stays as it was given until the user changes something. The
|
|
91
|
+
* form still shows the defaults. A default the user changes is in the
|
|
92
|
+
* value from then on, and so are the defaults that a change brings in,
|
|
93
|
+
* such as those of a new list item or of fields that depend on the
|
|
94
|
+
* changed one. Pass the value the form emits back in as `value`.
|
|
95
|
+
* The form validates what it shows, defaults included. When the user
|
|
96
|
+
* changes everything back, the value is what the form was given, also
|
|
97
|
+
* when that is `null` or `undefined`.
|
|
98
|
+
*/
|
|
99
|
+
this.includeDefaults = true;
|
|
76
100
|
this.isValid = true;
|
|
77
101
|
this.initialized = false;
|
|
78
102
|
this.handleChange = this.handleChange.bind(this);
|
|
@@ -82,8 +106,17 @@ export class Form {
|
|
|
82
106
|
this.initialize();
|
|
83
107
|
}
|
|
84
108
|
componentWillLoad() {
|
|
109
|
+
this.currentValue = this.value;
|
|
85
110
|
this.warnIfHeadingLevelIsInvalid();
|
|
86
111
|
}
|
|
112
|
+
handleValueChange() {
|
|
113
|
+
// The host usually hands back the value the form emitted, as a new
|
|
114
|
+
// object, which is not a new value to leave the defaults out of
|
|
115
|
+
if (!isEqual(this.value, this.currentValue)) {
|
|
116
|
+
this.givenValue = undefined;
|
|
117
|
+
}
|
|
118
|
+
this.currentValue = this.value;
|
|
119
|
+
}
|
|
87
120
|
componentDidLoad() {
|
|
88
121
|
this.initialize();
|
|
89
122
|
this.showHighlightedField();
|
|
@@ -125,7 +158,7 @@ export class Form {
|
|
|
125
158
|
this.initialized = false;
|
|
126
159
|
}
|
|
127
160
|
render() {
|
|
128
|
-
return h("div", { key: '
|
|
161
|
+
return h("div", { key: 'a50619f8a46a7e3b3ca5ade698141f22cfdd704f', class: "root" });
|
|
129
162
|
}
|
|
130
163
|
reactRender() {
|
|
131
164
|
if (!this.root) {
|
|
@@ -138,21 +171,12 @@ export class Form {
|
|
|
138
171
|
: 1,
|
|
139
172
|
}, React.createElement(JSONSchemaForm, {
|
|
140
173
|
schema: this.prepareSchema(this.schema),
|
|
141
|
-
formData: this.
|
|
174
|
+
formData: this.currentValue,
|
|
142
175
|
onChange: this.handleChange,
|
|
143
176
|
widgets: widgets,
|
|
144
177
|
validator: rjsfValidator,
|
|
145
178
|
liveValidate: 'onChange',
|
|
146
|
-
|
|
147
|
-
// as a default and auto-selects the first option, so an
|
|
148
|
-
// optional enum can never be left empty (clearing it just
|
|
149
|
-
// gets repopulated on the next render). `skipOneOf` keeps
|
|
150
|
-
// this off for enums while still applying genuine
|
|
151
|
-
// `default` values, matching the pre-v6 behavior.
|
|
152
|
-
experimental_defaultFormStateBehavior: {
|
|
153
|
-
constAsDefaults: 'skipOneOf',
|
|
154
|
-
requiredBooleanDefault: 'skip',
|
|
155
|
-
},
|
|
179
|
+
experimental_defaultFormStateBehavior: FILL_DEFAULTS,
|
|
156
180
|
showErrorList: false,
|
|
157
181
|
extraErrors: this.getExtraErrors(this.errors),
|
|
158
182
|
templates: {
|
|
@@ -186,11 +210,42 @@ export class Form {
|
|
|
186
210
|
return this.host.shadowRoot.querySelector('.root');
|
|
187
211
|
}
|
|
188
212
|
handleChange(event) {
|
|
189
|
-
this.
|
|
213
|
+
if (this.includeDefaults) {
|
|
214
|
+
this.currentValue = event.formData;
|
|
215
|
+
this.change.emit(event.formData);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
const { given, filled } = this.getGivenValue();
|
|
219
|
+
this.givenValue.held = event.formData;
|
|
220
|
+
const value = withoutFilledDefaults(event.formData, filled, given);
|
|
221
|
+
if (isEqual(value, this.currentValue)) {
|
|
222
|
+
// What the form holds changed, even though the value did not
|
|
223
|
+
this.emitValidationStatus(event.errors);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
this.currentValue = value;
|
|
227
|
+
this.change.emit(this.currentValue);
|
|
190
228
|
}
|
|
191
|
-
|
|
229
|
+
getGivenValue() {
|
|
192
230
|
var _a;
|
|
193
|
-
const
|
|
231
|
+
const schema = this.prepareSchema(this.schema);
|
|
232
|
+
if (((_a = this.givenValue) === null || _a === void 0 ? void 0 : _a.schemaId) !== schema.$id) {
|
|
233
|
+
const filled = getDefaultFormState(rjsfValidator, schema, this.currentValue, schema, false, FILL_DEFAULTS);
|
|
234
|
+
this.givenValue = {
|
|
235
|
+
schemaId: schema.$id,
|
|
236
|
+
given: this.currentValue,
|
|
237
|
+
filled,
|
|
238
|
+
held: filled,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
return this.givenValue;
|
|
242
|
+
}
|
|
243
|
+
validateFormData() {
|
|
244
|
+
// With the defaults left out of the value, the form holds more than it
|
|
245
|
+
const value = this.includeDefaults
|
|
246
|
+
? this.value
|
|
247
|
+
: this.getGivenValue().held;
|
|
248
|
+
const { errors } = rjsfValidator.validateFormData(value !== null && value !== void 0 ? value : {}, this.prepareSchema(this.schema));
|
|
194
249
|
this.emitValidationStatus(errors);
|
|
195
250
|
}
|
|
196
251
|
/**
|
|
@@ -465,6 +520,26 @@ export class Form {
|
|
|
465
520
|
"attribute": "reveal-errors",
|
|
466
521
|
"defaultValue": "false"
|
|
467
522
|
},
|
|
523
|
+
"includeDefaults": {
|
|
524
|
+
"type": "boolean",
|
|
525
|
+
"mutable": false,
|
|
526
|
+
"complexType": {
|
|
527
|
+
"original": "boolean",
|
|
528
|
+
"resolved": "boolean",
|
|
529
|
+
"references": {}
|
|
530
|
+
},
|
|
531
|
+
"required": false,
|
|
532
|
+
"optional": false,
|
|
533
|
+
"docs": {
|
|
534
|
+
"tags": [],
|
|
535
|
+
"text": "Set to `false` to leave the defaults of the schema out of the value,\nso that it stays as it was given until the user changes something. The\nform still shows the defaults. A default the user changes is in the\nvalue from then on, and so are the defaults that a change brings in,\nsuch as those of a new list item or of fields that depend on the\nchanged one. Pass the value the form emits back in as `value`.\nThe form validates what it shows, defaults included. When the user\nchanges everything back, the value is what the form was given, also\nwhen that is `null` or `undefined`."
|
|
536
|
+
},
|
|
537
|
+
"getter": false,
|
|
538
|
+
"setter": false,
|
|
539
|
+
"reflect": false,
|
|
540
|
+
"attribute": "include-defaults",
|
|
541
|
+
"defaultValue": "true"
|
|
542
|
+
},
|
|
468
543
|
"highlightedField": {
|
|
469
544
|
"type": "unknown",
|
|
470
545
|
"mutable": false,
|
|
@@ -535,6 +610,9 @@ export class Form {
|
|
|
535
610
|
static get elementRef() { return "host"; }
|
|
536
611
|
static get watchers() {
|
|
537
612
|
return [{
|
|
613
|
+
"propName": "value",
|
|
614
|
+
"methodName": "handleValueChange"
|
|
615
|
+
}, {
|
|
538
616
|
"propName": "headingLevel",
|
|
539
617
|
"methodName": "handleHeadingLevelChange"
|
|
540
618
|
}, {
|
|
@@ -896,3 +896,53 @@ export const untitledRowSchema = {
|
|
|
896
896
|
},
|
|
897
897
|
},
|
|
898
898
|
};
|
|
899
|
+
export const dependencyWithDefaultsSchema = {
|
|
900
|
+
type: 'object',
|
|
901
|
+
properties: {
|
|
902
|
+
columns: { type: 'integer', title: 'Columns', default: 5 },
|
|
903
|
+
limetype: { type: 'string', title: 'Limetype' },
|
|
904
|
+
},
|
|
905
|
+
dependencies: {
|
|
906
|
+
limetype: {
|
|
907
|
+
properties: {
|
|
908
|
+
propertyName: {
|
|
909
|
+
type: 'string',
|
|
910
|
+
title: 'Name property',
|
|
911
|
+
default: 'name',
|
|
912
|
+
},
|
|
913
|
+
},
|
|
914
|
+
},
|
|
915
|
+
},
|
|
916
|
+
};
|
|
917
|
+
export const dependencyWithChangingDefaultSchema = {
|
|
918
|
+
type: 'object',
|
|
919
|
+
properties: {
|
|
920
|
+
limetype: { type: 'string', title: 'Limetype' },
|
|
921
|
+
},
|
|
922
|
+
dependencies: {
|
|
923
|
+
limetype: {
|
|
924
|
+
oneOf: [
|
|
925
|
+
{
|
|
926
|
+
properties: {
|
|
927
|
+
limetype: { const: 'person' },
|
|
928
|
+
propertyName: {
|
|
929
|
+
type: 'string',
|
|
930
|
+
title: 'Name property',
|
|
931
|
+
default: 'name',
|
|
932
|
+
},
|
|
933
|
+
},
|
|
934
|
+
},
|
|
935
|
+
{
|
|
936
|
+
properties: {
|
|
937
|
+
limetype: { const: 'company' },
|
|
938
|
+
propertyName: {
|
|
939
|
+
type: 'string',
|
|
940
|
+
title: 'Name property',
|
|
941
|
+
default: 'companyName',
|
|
942
|
+
},
|
|
943
|
+
},
|
|
944
|
+
},
|
|
945
|
+
],
|
|
946
|
+
},
|
|
947
|
+
},
|
|
948
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { h, Host, } from "@stencil/core";
|
|
2
2
|
import translate from "../../global/translations";
|
|
3
3
|
import { createRandomString } from "../../util/random-string";
|
|
4
|
-
import {
|
|
4
|
+
import { getSupportedLocale } from "../../util/language";
|
|
5
5
|
import { getPageSlots } from "./pagination.util";
|
|
6
6
|
const FIRST_PAGE = 1;
|
|
7
7
|
const DEFAULT_PAGE_SIZE = 100;
|
|
@@ -304,7 +304,7 @@ export class Pagination {
|
|
|
304
304
|
}
|
|
305
305
|
render() {
|
|
306
306
|
const { slots } = this.view;
|
|
307
|
-
return (h(Host, { key: '
|
|
307
|
+
return (h(Host, { key: '7c47cdc658859b4cd8199ef92ebd9bc48275a8ae' }, h("nav", { key: '3bba45547a7183a4b1df58294a56788f9b2e078f', "aria-label": this.translate('pagination.label'), "aria-busy": this.loading ? 'true' : null }, this.renderArrow('previous'), slots.map((slot, index) => this.renderSlot(slot, index)), this.renderArrow('next')), h("span", { key: '60fff33d8e135b1605d0a0f68b6c1ede1b571281', class: "live-region", "aria-live": "polite" }, this.liveMessage)));
|
|
308
308
|
}
|
|
309
309
|
/**
|
|
310
310
|
* Without a count we know where the user is but not how far the set goes,
|
|
@@ -620,9 +620,7 @@ export class Pagination {
|
|
|
620
620
|
}
|
|
621
621
|
/**
|
|
622
622
|
* What the jump form is given, so that the one warning about a language
|
|
623
|
-
* this browser cannot write numbers in describes both of us.
|
|
624
|
-
* accepts but does not support, `zz`, resolves to the viewer's own locale
|
|
625
|
-
* rather than throwing, so asking the formatter is the only way to know.
|
|
623
|
+
* this browser cannot write numbers in describes both of us.
|
|
626
624
|
*/
|
|
627
625
|
get languageForNumbers() {
|
|
628
626
|
var _a;
|
|
@@ -630,31 +628,21 @@ export class Pagination {
|
|
|
630
628
|
return this.settledLanguage;
|
|
631
629
|
}
|
|
632
630
|
/**
|
|
633
|
-
* `
|
|
634
|
-
*
|
|
635
|
-
*
|
|
636
|
-
* `src/util/language.ts`
|
|
637
|
-
*
|
|
638
|
-
* A tag it cannot parse throws; a well-formed tag it does not support, like
|
|
639
|
-
* `zz`, does not — it quietly resolves to whatever locale the machine runs
|
|
640
|
-
* in. Both end up formatting numbers in something other than what was
|
|
641
|
-
* asked for, so both are worth saying out loud.
|
|
631
|
+
* This is called from `render`, so a language that `Intl` cannot write
|
|
632
|
+
* numbers in must not throw, or the control would draw nothing at all —
|
|
633
|
+
* the single state a user cannot click their way out of.
|
|
634
|
+
* `getSupportedLocale` in `src/util/language.ts` decides which languages
|
|
635
|
+
* those are.
|
|
642
636
|
*
|
|
643
637
|
* @returns a formatter, in the given language where that is possible
|
|
644
638
|
*/
|
|
645
639
|
createNumberFormat() {
|
|
646
640
|
const { language } = this;
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
this.settledLanguage = language;
|
|
653
|
-
return format;
|
|
654
|
-
}
|
|
655
|
-
}
|
|
656
|
-
catch (_a) {
|
|
657
|
-
// Fall through to the warning below.
|
|
641
|
+
const locale = getSupportedLocale(language);
|
|
642
|
+
if (locale) {
|
|
643
|
+
this.warnedAbout.delete('language');
|
|
644
|
+
this.settledLanguage = language;
|
|
645
|
+
return new Intl.NumberFormat(locale);
|
|
658
646
|
}
|
|
659
647
|
this.warnOnce('language', language, () => `\`language\` must be one this browser can write numbers in, but was ${JSON.stringify(language)}. Using ${FALLBACK_LANGUAGE}.`);
|
|
660
648
|
// Where the translations land for the same unusable value, rather than
|
|
@@ -22,3 +22,32 @@ export function getPrimarySubtag(language) {
|
|
|
22
22
|
}
|
|
23
23
|
return language.toLowerCase().split('-', 1)[0];
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* The locale that `Intl` writes numbers and dates in for `language`, or
|
|
27
|
+
* `undefined` when it cannot write in that language. `Intl` throws on a
|
|
28
|
+
* tag it cannot read, such as `sv_SE`, and quietly uses the viewer's own
|
|
29
|
+
* locale for one it does not know, such as `zz`. A component that writes in
|
|
30
|
+
* its `language` while it renders checks it here, and falls back to English
|
|
31
|
+
* when this gives `undefined`.
|
|
32
|
+
*
|
|
33
|
+
* Examples:
|
|
34
|
+
* - "sv" => "sv"
|
|
35
|
+
* - "SV-se" => "sv-SE"
|
|
36
|
+
* - "sv_SE" => undefined
|
|
37
|
+
* - "zz" => undefined
|
|
38
|
+
* - undefined => undefined
|
|
39
|
+
*
|
|
40
|
+
* @param language - the language to write in
|
|
41
|
+
* @returns the locale, or `undefined`
|
|
42
|
+
*/
|
|
43
|
+
export function getSupportedLocale(language) {
|
|
44
|
+
if (typeof language !== 'string') {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
return Intl.NumberFormat.supportedLocalesOf(language)[0];
|
|
49
|
+
}
|
|
50
|
+
catch (_a) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reduce a language to the primary subtag that our language maps are keyed by.
|
|
3
|
+
*
|
|
4
|
+
* A `language` prop is typed, but a custom element takes whatever string an
|
|
5
|
+
* attribute carries — commonly a full BCP 47 tag such as `nb-NO`, since a host
|
|
6
|
+
* application often derives the language from `document.documentElement.lang`.
|
|
7
|
+
* Anything that is not a string must resolve rather than throw, so that an
|
|
8
|
+
* unexpected value can never break a component's render.
|
|
9
|
+
*
|
|
10
|
+
* Examples:
|
|
11
|
+
* - "nb" => "nb"
|
|
12
|
+
* - "nb-NO" => "nb"
|
|
13
|
+
* - "SV-SE" => "sv"
|
|
14
|
+
* - undefined => ""
|
|
15
|
+
*
|
|
16
|
+
* @param language - the language to reduce
|
|
17
|
+
* @returns the lower-cased primary subtag, or an empty string
|
|
18
|
+
*/
|
|
19
|
+
function getPrimarySubtag(language) {
|
|
20
|
+
if (typeof language !== 'string') {
|
|
21
|
+
return '';
|
|
22
|
+
}
|
|
23
|
+
return language.toLowerCase().split('-', 1)[0];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The locale that `Intl` writes numbers and dates in for `language`, or
|
|
27
|
+
* `undefined` when it cannot write in that language. `Intl` throws on a
|
|
28
|
+
* tag it cannot read, such as `sv_SE`, and quietly uses the viewer's own
|
|
29
|
+
* locale for one it does not know, such as `zz`. A component that writes in
|
|
30
|
+
* its `language` while it renders checks it here, and falls back to English
|
|
31
|
+
* when this gives `undefined`.
|
|
32
|
+
*
|
|
33
|
+
* Examples:
|
|
34
|
+
* - "sv" => "sv"
|
|
35
|
+
* - "SV-se" => "sv-SE"
|
|
36
|
+
* - "sv_SE" => undefined
|
|
37
|
+
* - "zz" => undefined
|
|
38
|
+
* - undefined => undefined
|
|
39
|
+
*
|
|
40
|
+
* @param language - the language to write in
|
|
41
|
+
* @returns the locale, or `undefined`
|
|
42
|
+
*/
|
|
43
|
+
function getSupportedLocale(language) {
|
|
44
|
+
if (typeof language !== 'string') {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
return Intl.NumberFormat.supportedLocalesOf(language)[0];
|
|
49
|
+
}
|
|
50
|
+
catch (_a) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export { getPrimarySubtag as a, getSupportedLocale as g };
|