@limetech/lime-elements 39.20.0 → 39.22.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 +14 -0
- package/dist/cjs/limel-chip_2.cjs.entry.js +2 -2
- package/dist/cjs/limel-form.cjs.entry.js +1111 -263
- package/dist/collection/components/chip-set/chip-set.js +3 -2
- package/dist/esm/{_baseEach-CL_-rBMy.js → _baseEach-C4UJIc96.js} +1 -1
- package/dist/esm/{_baseIsEqual-BfXMsuGh.js → _baseIsEqual-DCZXUzsZ.js} +1 -1
- package/dist/esm/{_baseIteratee-kS1-0_xD.js → _baseIteratee-CI-QZdpx.js} +1 -1
- package/dist/esm/{_getAllKeysIn-BKpeslPJ.js → _getAllKeysIn-v-KlW5r_.js} +1 -1
- package/dist/esm/{cloneDeep-BXAw5H-1.js → cloneDeep-V4fB8wfG.js} +2 -2
- package/dist/esm/{difference-DMAjHh-t.js → difference-CWrdq-hd.js} +1 -1
- package/dist/esm/{isEmpty-DrFXbHWO.js → isEmpty-BFxMjh_H.js} +1 -1
- package/dist/esm/{isEqual-CpaoJ_AF.js → isEqual-CsrptmTU.js} +1 -1
- package/dist/esm/limel-chip_2.entry.js +5 -5
- package/dist/esm/limel-dialog.entry.js +2 -2
- package/dist/esm/limel-file-dropzone_2.entry.js +3 -3
- package/dist/esm/limel-form.entry.js +1127 -279
- package/dist/esm/limel-prosemirror-adapter.entry.js +4 -4
- package/dist/esm/limel-tab-bar.entry.js +3 -3
- package/dist/esm/limel-table.entry.js +5 -5
- package/dist/esm/{pickBy-BEA90LIZ.js → pickBy-D8CUtxE4.js} +2 -2
- package/dist/lime-elements/lime-elements.esm.js +1 -1
- package/dist/lime-elements/p-29a59535.entry.js +13 -0
- package/dist/lime-elements/p-34d1d00a.entry.js +1 -0
- package/dist/lime-elements/{p-4ca67b17.entry.js → p-48db87d3.entry.js} +1 -1
- package/dist/lime-elements/{p-757896f5.entry.js → p-4e9baf08.entry.js} +1 -1
- package/dist/lime-elements/{p-BbU4FGNT.js → p-7uuv3HUP.js} +1 -1
- package/dist/lime-elements/{p-4ce682cf.entry.js → p-8139d26a.entry.js} +1 -1
- package/dist/lime-elements/{p-CMjGNANG.js → p-BTHqaZIi.js} +1 -1
- package/dist/lime-elements/p-Bj622DVt.js +1 -0
- package/dist/lime-elements/p-C3Myy3mA.js +1 -0
- package/dist/lime-elements/{p-xQsJdKrq.js → p-CXgJVvTe.js} +1 -1
- package/dist/lime-elements/p-CxfAgSVd.js +1 -0
- package/dist/lime-elements/{p-DFWcgJ_i.js → p-DNIqLXTL.js} +1 -1
- package/dist/lime-elements/p-DbC-smVQ.js +1 -0
- package/dist/lime-elements/p-SvuA3Boo.js +1 -0
- package/dist/lime-elements/{p-cffc137e.entry.js → p-e720f65c.entry.js} +3 -3
- package/dist/lime-elements/{p-8065425a.entry.js → p-fd4a4f87.entry.js} +1 -1
- package/dist/types/components/chip-set/chip-set.d.ts +1 -0
- package/dist/types/components/chip-set/chip.types.d.ts +4 -0
- package/dist/types/components.d.ts +4 -0
- package/package.json +4 -4
- package/dist/lime-elements/p-B3zCFNAw.js +0 -1
- package/dist/lime-elements/p-B6bNnxRu.js +0 -1
- package/dist/lime-elements/p-BCMRfUKp.js +0 -1
- package/dist/lime-elements/p-DTXIk0fN.js +0 -1
- package/dist/lime-elements/p-UGKt6Ywx.js +0 -1
- package/dist/lime-elements/p-cae35eb0.entry.js +0 -1
- package/dist/lime-elements/p-e60ffc0a.entry.js +0 -13
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import { r as registerInstance, c as createEvent, h as h$1, a as getElement } from './index-DBTJNfo7.js';
|
|
2
2
|
import { g as getDefaultExportFromCjs } from './_commonjsHelpers-B85MJLTf.js';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { i as isEqual } from './isEqual-CpaoJ_AF.js';
|
|
3
|
+
import { t as toString$1, a as arrayMap, b as baseGet, c as baseIteratee, d as castPath, e as toKey, h as hasIn, s as stringToPath, g as get } from './_baseIteratee-CI-QZdpx.js';
|
|
4
|
+
import { b as basePickBy, a as baseSet, h as has, p as pickBy, n as negate } from './pickBy-D8CUtxE4.js';
|
|
5
|
+
import { i as isBuffer, a as isTypedArray, b as isArguments, S as Stack, k as keys$1, c as SetCache, d as cacheHas, e as baseTimes, f as Set$1, s as setToArray } from './_baseIsEqual-DCZXUzsZ.js';
|
|
7
6
|
import { i as identity$1 } from './identity-CK4jS9_E.js';
|
|
8
7
|
import { t as toFinite, i as isIterateeCall } from './_isIterateeCall-CTcCv8Mb.js';
|
|
9
|
-
import { c as copyObject, a as copyArray, b as cloneBuffer, d as cloneTypedArray, i as initCloneObject, e as arrayEach, f as baseClone, g as baseCreate, h as cloneDeep } from './cloneDeep-
|
|
10
|
-
import { b as baseFor, a as baseEach, c as baseForOwn } from './_baseEach-
|
|
11
|
-
import { g as getPrototype, k as keysIn, a as getAllKeysIn } from './_getAllKeysIn-
|
|
8
|
+
import { c as copyObject, a as copyArray, b as cloneBuffer, d as cloneTypedArray, i as initCloneObject, e as arrayEach, f as baseClone, g as baseCreate, h as cloneDeep } from './cloneDeep-V4fB8wfG.js';
|
|
9
|
+
import { b as baseFor, a as baseEach, c as baseForOwn } from './_baseEach-C4UJIc96.js';
|
|
10
|
+
import { g as getPrototype, k as keysIn, a as getAllKeysIn } from './_getAllKeysIn-v-KlW5r_.js';
|
|
12
11
|
import { i as isArray } from './isArray-B8VKuhvH.js';
|
|
13
12
|
import { e as eq, i as isFunction } from './eq-D7VMHFyO.js';
|
|
14
13
|
import { b as baseGetTag, i as isObject$1 } from './isObject-BJQylLSL.js';
|
|
15
14
|
import { b as baseAssignValue } from './_assignValue-DOEO9byf.js';
|
|
16
|
-
import { b as baseRest, a as baseFlatten, s as setToString, o as overRest, i as isArrayLikeObject, c as baseIndexOf, d as arrayIncludes, e as difference } from './difference-
|
|
15
|
+
import { b as baseRest, a as baseFlatten, s as setToString, o as overRest, i as isArrayLikeObject, c as baseIndexOf, d as arrayIncludes, e as difference } from './difference-CWrdq-hd.js';
|
|
17
16
|
import { i as isObjectLike } from './isObjectLike-oiMYqRQ0.js';
|
|
18
|
-
import { i as isEmpty } from './isEmpty-
|
|
17
|
+
import { i as isEmpty } from './isEmpty-BFxMjh_H.js';
|
|
19
18
|
import { i as isSymbol } from './isSymbol-ClAke5ga.js';
|
|
20
19
|
import { i as isArrayLike } from './isArrayLike-D1QkaJU2.js';
|
|
20
|
+
import { i as isEqual } from './isEqual-CsrptmTU.js';
|
|
21
21
|
import { m as moment } from './moment-DQRNe8qq.js';
|
|
22
22
|
import { i as isMultiple } from './multiple-BylwpiM6.js';
|
|
23
23
|
import './_getNative-aN4R8EiP.js';
|
|
@@ -147,7 +147,7 @@ var funcProto = Function.prototype,
|
|
|
147
147
|
var funcToString = funcProto.toString;
|
|
148
148
|
|
|
149
149
|
/** Used to check objects for own properties. */
|
|
150
|
-
var hasOwnProperty$
|
|
150
|
+
var hasOwnProperty$2 = objectProto$1.hasOwnProperty;
|
|
151
151
|
|
|
152
152
|
/** Used to infer the `Object` constructor. */
|
|
153
153
|
var objectCtorString = funcToString.call(Object);
|
|
@@ -188,7 +188,7 @@ function isPlainObject(value) {
|
|
|
188
188
|
if (proto === null) {
|
|
189
189
|
return true;
|
|
190
190
|
}
|
|
191
|
-
var Ctor = hasOwnProperty$
|
|
191
|
+
var Ctor = hasOwnProperty$2.call(proto, 'constructor') && proto.constructor;
|
|
192
192
|
return typeof Ctor == 'function' && Ctor instanceof Ctor &&
|
|
193
193
|
funcToString.call(Ctor) == objectCtorString;
|
|
194
194
|
}
|
|
@@ -335,7 +335,7 @@ function stringToArray(string) {
|
|
|
335
335
|
*/
|
|
336
336
|
function createCaseFirst(methodName) {
|
|
337
337
|
return function(string) {
|
|
338
|
-
string = toString(string);
|
|
338
|
+
string = toString$1(string);
|
|
339
339
|
|
|
340
340
|
var strSymbols = hasUnicode(string)
|
|
341
341
|
? stringToArray(string)
|
|
@@ -388,7 +388,7 @@ var upperFirst = createCaseFirst('toUpperCase');
|
|
|
388
388
|
* // => 'Fred'
|
|
389
389
|
*/
|
|
390
390
|
function capitalize(string) {
|
|
391
|
-
return upperFirst(toString(string).toLowerCase());
|
|
391
|
+
return upperFirst(toString$1(string).toLowerCase());
|
|
392
392
|
}
|
|
393
393
|
|
|
394
394
|
/**
|
|
@@ -745,7 +745,7 @@ function baseValues(object, props) {
|
|
|
745
745
|
* // => ['h', 'i']
|
|
746
746
|
*/
|
|
747
747
|
function values(object) {
|
|
748
|
-
return object == null ? [] : baseValues(object, keys(object));
|
|
748
|
+
return object == null ? [] : baseValues(object, keys$1(object));
|
|
749
749
|
}
|
|
750
750
|
|
|
751
751
|
/* Built-in method references for those with the same name as other `lodash` methods. */
|
|
@@ -904,44 +904,6 @@ function parent(object, path) {
|
|
|
904
904
|
return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
|
|
905
905
|
}
|
|
906
906
|
|
|
907
|
-
/**
|
|
908
|
-
* This method is like `_.isEqual` except that it accepts `customizer` which
|
|
909
|
-
* is invoked to compare values. If `customizer` returns `undefined`, comparisons
|
|
910
|
-
* are handled by the method instead. The `customizer` is invoked with up to
|
|
911
|
-
* six arguments: (objValue, othValue [, index|key, object, other, stack]).
|
|
912
|
-
*
|
|
913
|
-
* @static
|
|
914
|
-
* @memberOf _
|
|
915
|
-
* @since 4.0.0
|
|
916
|
-
* @category Lang
|
|
917
|
-
* @param {*} value The value to compare.
|
|
918
|
-
* @param {*} other The other value to compare.
|
|
919
|
-
* @param {Function} [customizer] The function to customize comparisons.
|
|
920
|
-
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
|
|
921
|
-
* @example
|
|
922
|
-
*
|
|
923
|
-
* function isGreeting(value) {
|
|
924
|
-
* return /^h(?:i|ello)$/.test(value);
|
|
925
|
-
* }
|
|
926
|
-
*
|
|
927
|
-
* function customizer(objValue, othValue) {
|
|
928
|
-
* if (isGreeting(objValue) && isGreeting(othValue)) {
|
|
929
|
-
* return true;
|
|
930
|
-
* }
|
|
931
|
-
* }
|
|
932
|
-
*
|
|
933
|
-
* var array = ['hello', 'goodbye'];
|
|
934
|
-
* var other = ['hi', 'goodbye'];
|
|
935
|
-
*
|
|
936
|
-
* _.isEqualWith(array, other, customizer);
|
|
937
|
-
* // => true
|
|
938
|
-
*/
|
|
939
|
-
function isEqualWith(value, other, customizer) {
|
|
940
|
-
customizer = typeof customizer == 'function' ? customizer : undefined;
|
|
941
|
-
var result = customizer ? customizer(value, other) : undefined;
|
|
942
|
-
return result === undefined ? baseIsEqual(value, other, undefined, customizer) : !!result;
|
|
943
|
-
}
|
|
944
|
-
|
|
945
907
|
/** `Object#toString` result references. */
|
|
946
908
|
var numberTag = '[object Number]';
|
|
947
909
|
|
|
@@ -1098,7 +1060,7 @@ var merge = createAssigner(function(object, source, srcIndex) {
|
|
|
1098
1060
|
var objectProto = Object.prototype;
|
|
1099
1061
|
|
|
1100
1062
|
/** Used to check objects for own properties. */
|
|
1101
|
-
var hasOwnProperty = objectProto.hasOwnProperty;
|
|
1063
|
+
var hasOwnProperty$1 = objectProto.hasOwnProperty;
|
|
1102
1064
|
|
|
1103
1065
|
/**
|
|
1104
1066
|
* The base implementation of `_.unset`.
|
|
@@ -1125,7 +1087,7 @@ function baseUnset(object, path) {
|
|
|
1125
1087
|
var key = toKey(path[index]);
|
|
1126
1088
|
|
|
1127
1089
|
// Always block "__proto__" anywhere in the path if it's not expected
|
|
1128
|
-
if (key === '__proto__' && !hasOwnProperty.call(object, '__proto__')) {
|
|
1090
|
+
if (key === '__proto__' && !hasOwnProperty$1.call(object, '__proto__')) {
|
|
1129
1091
|
return false;
|
|
1130
1092
|
}
|
|
1131
1093
|
|
|
@@ -1430,7 +1392,7 @@ function toPath(value) {
|
|
|
1430
1392
|
if (isArray(value)) {
|
|
1431
1393
|
return arrayMap(value, toKey);
|
|
1432
1394
|
}
|
|
1433
|
-
return isSymbol(value) ? [value] : copyArray(stringToPath(toString(value)));
|
|
1395
|
+
return isSymbol(value) ? [value] : copyArray(stringToPath(toString$1(value)));
|
|
1434
1396
|
}
|
|
1435
1397
|
|
|
1436
1398
|
/**
|
|
@@ -1621,7 +1583,7 @@ var idCounter = 0;
|
|
|
1621
1583
|
*/
|
|
1622
1584
|
function uniqueId(prefix) {
|
|
1623
1585
|
var id = ++idCounter;
|
|
1624
|
-
return toString(prefix) + id;
|
|
1586
|
+
return toString$1(prefix) + id;
|
|
1625
1587
|
}
|
|
1626
1588
|
|
|
1627
1589
|
/**
|
|
@@ -18533,23 +18495,633 @@ function createErrorHandler(formData) {
|
|
|
18533
18495
|
return handler;
|
|
18534
18496
|
}
|
|
18535
18497
|
|
|
18536
|
-
|
|
18537
|
-
|
|
18498
|
+
const { getOwnPropertyNames, getOwnPropertySymbols } = Object;
|
|
18499
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
18500
|
+
const { hasOwnProperty } = Object.prototype;
|
|
18501
|
+
/**
|
|
18502
|
+
* Combine two comparators into a single comparators.
|
|
18503
|
+
*/
|
|
18504
|
+
function combineComparators(comparatorA, comparatorB) {
|
|
18505
|
+
return function isEqual(a, b, state) {
|
|
18506
|
+
return comparatorA(a, b, state) && comparatorB(a, b, state);
|
|
18507
|
+
};
|
|
18508
|
+
}
|
|
18509
|
+
/**
|
|
18510
|
+
* Wrap the provided `areItemsEqual` method to manage the circular state, allowing
|
|
18511
|
+
* for circular references to be safely included in the comparison without creating
|
|
18512
|
+
* stack overflows.
|
|
18513
|
+
*/
|
|
18514
|
+
function createIsCircular(areItemsEqual) {
|
|
18515
|
+
return function isCircular(a, b, state) {
|
|
18516
|
+
if (!a || !b || typeof a !== 'object' || typeof b !== 'object') {
|
|
18517
|
+
return areItemsEqual(a, b, state);
|
|
18518
|
+
}
|
|
18519
|
+
const { cache } = state;
|
|
18520
|
+
const cachedA = cache.get(a);
|
|
18521
|
+
const cachedB = cache.get(b);
|
|
18522
|
+
if (cachedA && cachedB) {
|
|
18523
|
+
return cachedA === b && cachedB === a;
|
|
18524
|
+
}
|
|
18525
|
+
cache.set(a, b);
|
|
18526
|
+
cache.set(b, a);
|
|
18527
|
+
const result = areItemsEqual(a, b, state);
|
|
18528
|
+
cache.delete(a);
|
|
18529
|
+
cache.delete(b);
|
|
18530
|
+
return result;
|
|
18531
|
+
};
|
|
18532
|
+
}
|
|
18533
|
+
/**
|
|
18534
|
+
* Get the properties to strictly examine, which include both own properties that are
|
|
18535
|
+
* not enumerable and symbol properties.
|
|
18536
|
+
*/
|
|
18537
|
+
function getStrictProperties(object) {
|
|
18538
|
+
return getOwnPropertyNames(object).concat(getOwnPropertySymbols(object));
|
|
18539
|
+
}
|
|
18540
|
+
/**
|
|
18541
|
+
* Whether the object contains the property passed as an own property.
|
|
18542
|
+
*/
|
|
18543
|
+
const hasOwn =
|
|
18544
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
18545
|
+
Object.hasOwn || ((object, property) => hasOwnProperty.call(object, property));
|
|
18546
|
+
|
|
18547
|
+
const PREACT_VNODE = '__v';
|
|
18548
|
+
const PREACT_OWNER = '__o';
|
|
18549
|
+
const REACT_OWNER = '_owner';
|
|
18550
|
+
const { getOwnPropertyDescriptor, keys } = Object;
|
|
18551
|
+
/**
|
|
18552
|
+
* Whether the values passed are equal based on a [SameValue](https://262.ecma-international.org/7.0/#sec-samevalue) basis.
|
|
18553
|
+
* Simplified, this maps to if the two values are referentially equal to one another (`a === b`) or both are `NaN`.
|
|
18554
|
+
*
|
|
18555
|
+
* @note
|
|
18556
|
+
* When available in the environment, this is just a re-export of the global
|
|
18557
|
+
* [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) method.
|
|
18558
|
+
*/
|
|
18559
|
+
const sameValueEqual =
|
|
18560
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
18561
|
+
Object.is
|
|
18562
|
+
|| function sameValueEqual(a, b) {
|
|
18563
|
+
return a === b ? a !== 0 || 1 / a === 1 / b : a !== a && b !== b;
|
|
18564
|
+
};
|
|
18565
|
+
/**
|
|
18566
|
+
* Whether the values passed are equal based on a
|
|
18567
|
+
* [Strict Equality Comparison](https://262.ecma-international.org/7.0/#sec-strict-equality-comparison) basis.
|
|
18568
|
+
* Simplified, this maps to if the two values are referentially equal to one another (`a === b`).
|
|
18538
18569
|
*
|
|
18539
|
-
* @
|
|
18540
|
-
*
|
|
18541
|
-
*
|
|
18570
|
+
* @note
|
|
18571
|
+
* This is mainly available as a convenience function, such as being a default when a function to determine equality between
|
|
18572
|
+
* two objects is used.
|
|
18573
|
+
*/
|
|
18574
|
+
function strictEqual(a, b) {
|
|
18575
|
+
return a === b;
|
|
18576
|
+
}
|
|
18577
|
+
/**
|
|
18578
|
+
* Whether the array buffers are equal in value.
|
|
18579
|
+
*/
|
|
18580
|
+
function areArrayBuffersEqual(a, b) {
|
|
18581
|
+
return a.byteLength === b.byteLength && areTypedArraysEqual(new Uint8Array(a), new Uint8Array(b));
|
|
18582
|
+
}
|
|
18583
|
+
/**
|
|
18584
|
+
* Whether the arrays are equal in value.
|
|
18585
|
+
*/
|
|
18586
|
+
function areArraysEqual(a, b, state) {
|
|
18587
|
+
let index = a.length;
|
|
18588
|
+
if (b.length !== index) {
|
|
18589
|
+
return false;
|
|
18590
|
+
}
|
|
18591
|
+
while (index-- > 0) {
|
|
18592
|
+
if (!state.equals(a[index], b[index], index, index, a, b, state)) {
|
|
18593
|
+
return false;
|
|
18594
|
+
}
|
|
18595
|
+
}
|
|
18596
|
+
return true;
|
|
18597
|
+
}
|
|
18598
|
+
/**
|
|
18599
|
+
* Whether the dataviews are equal in value.
|
|
18600
|
+
*/
|
|
18601
|
+
function areDataViewsEqual(a, b) {
|
|
18602
|
+
return (a.byteLength === b.byteLength
|
|
18603
|
+
&& areTypedArraysEqual(new Uint8Array(a.buffer, a.byteOffset, a.byteLength), new Uint8Array(b.buffer, b.byteOffset, b.byteLength)));
|
|
18604
|
+
}
|
|
18605
|
+
/**
|
|
18606
|
+
* Whether the dates passed are equal in value.
|
|
18607
|
+
*/
|
|
18608
|
+
function areDatesEqual(a, b) {
|
|
18609
|
+
return sameValueEqual(a.getTime(), b.getTime());
|
|
18610
|
+
}
|
|
18611
|
+
/**
|
|
18612
|
+
* Whether the errors passed are equal in value.
|
|
18613
|
+
*/
|
|
18614
|
+
function areErrorsEqual(a, b) {
|
|
18615
|
+
return a.name === b.name && a.message === b.message && a.cause === b.cause && a.stack === b.stack;
|
|
18616
|
+
}
|
|
18617
|
+
/**
|
|
18618
|
+
* Whether the `Map`s are equal in value.
|
|
18542
18619
|
*/
|
|
18543
|
-
function
|
|
18544
|
-
|
|
18545
|
-
|
|
18546
|
-
|
|
18547
|
-
|
|
18620
|
+
function areMapsEqual(a, b, state) {
|
|
18621
|
+
const size = a.size;
|
|
18622
|
+
if (size !== b.size) {
|
|
18623
|
+
return false;
|
|
18624
|
+
}
|
|
18625
|
+
if (!size) {
|
|
18626
|
+
return true;
|
|
18627
|
+
}
|
|
18628
|
+
const matchedIndices = new Array(size);
|
|
18629
|
+
const aIterable = a.entries();
|
|
18630
|
+
let aResult;
|
|
18631
|
+
let bResult;
|
|
18632
|
+
let index = 0;
|
|
18633
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
18634
|
+
while ((aResult = aIterable.next())) {
|
|
18635
|
+
if (aResult.done) {
|
|
18636
|
+
break;
|
|
18637
|
+
}
|
|
18638
|
+
const bIterable = b.entries();
|
|
18639
|
+
let hasMatch = false;
|
|
18640
|
+
let matchIndex = 0;
|
|
18641
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
18642
|
+
while ((bResult = bIterable.next())) {
|
|
18643
|
+
if (bResult.done) {
|
|
18644
|
+
break;
|
|
18645
|
+
}
|
|
18646
|
+
if (matchedIndices[matchIndex]) {
|
|
18647
|
+
matchIndex++;
|
|
18648
|
+
continue;
|
|
18649
|
+
}
|
|
18650
|
+
const aEntry = aResult.value;
|
|
18651
|
+
const bEntry = bResult.value;
|
|
18652
|
+
if (state.equals(aEntry[0], bEntry[0], index, matchIndex, a, b, state)
|
|
18653
|
+
&& state.equals(aEntry[1], bEntry[1], aEntry[0], bEntry[0], a, b, state)) {
|
|
18654
|
+
hasMatch = matchedIndices[matchIndex] = true;
|
|
18655
|
+
break;
|
|
18656
|
+
}
|
|
18657
|
+
matchIndex++;
|
|
18658
|
+
}
|
|
18659
|
+
if (!hasMatch) {
|
|
18660
|
+
return false;
|
|
18661
|
+
}
|
|
18662
|
+
index++;
|
|
18663
|
+
}
|
|
18664
|
+
return true;
|
|
18665
|
+
}
|
|
18666
|
+
/**
|
|
18667
|
+
* Whether the objects are equal in value.
|
|
18668
|
+
*/
|
|
18669
|
+
function areObjectsEqual(a, b, state) {
|
|
18670
|
+
const properties = keys(a);
|
|
18671
|
+
let index = properties.length;
|
|
18672
|
+
if (keys(b).length !== index) {
|
|
18673
|
+
return false;
|
|
18674
|
+
}
|
|
18675
|
+
// Decrementing `while` showed faster results than either incrementing or
|
|
18676
|
+
// decrementing `for` loop and than an incrementing `while` loop. Declarative
|
|
18677
|
+
// methods like `some` / `every` were not used to avoid incurring the garbage
|
|
18678
|
+
// cost of anonymous callbacks.
|
|
18679
|
+
while (index-- > 0) {
|
|
18680
|
+
if (!isPropertyEqual(a, b, state, properties[index])) {
|
|
18681
|
+
return false;
|
|
18682
|
+
}
|
|
18683
|
+
}
|
|
18684
|
+
return true;
|
|
18685
|
+
}
|
|
18686
|
+
/**
|
|
18687
|
+
* Whether the objects are equal in value with strict property checking.
|
|
18688
|
+
*/
|
|
18689
|
+
function areObjectsEqualStrict(a, b, state) {
|
|
18690
|
+
const properties = getStrictProperties(a);
|
|
18691
|
+
let index = properties.length;
|
|
18692
|
+
if (getStrictProperties(b).length !== index) {
|
|
18693
|
+
return false;
|
|
18694
|
+
}
|
|
18695
|
+
let property;
|
|
18696
|
+
let descriptorA;
|
|
18697
|
+
let descriptorB;
|
|
18698
|
+
// Decrementing `while` showed faster results than either incrementing or
|
|
18699
|
+
// decrementing `for` loop and than an incrementing `while` loop. Declarative
|
|
18700
|
+
// methods like `some` / `every` were not used to avoid incurring the garbage
|
|
18701
|
+
// cost of anonymous callbacks.
|
|
18702
|
+
while (index-- > 0) {
|
|
18703
|
+
property = properties[index];
|
|
18704
|
+
if (!isPropertyEqual(a, b, state, property)) {
|
|
18705
|
+
return false;
|
|
18706
|
+
}
|
|
18707
|
+
descriptorA = getOwnPropertyDescriptor(a, property);
|
|
18708
|
+
descriptorB = getOwnPropertyDescriptor(b, property);
|
|
18709
|
+
if ((descriptorA || descriptorB)
|
|
18710
|
+
&& (!descriptorA
|
|
18711
|
+
|| !descriptorB
|
|
18712
|
+
|| descriptorA.configurable !== descriptorB.configurable
|
|
18713
|
+
|| descriptorA.enumerable !== descriptorB.enumerable
|
|
18714
|
+
|| descriptorA.writable !== descriptorB.writable)) {
|
|
18715
|
+
return false;
|
|
18716
|
+
}
|
|
18717
|
+
}
|
|
18718
|
+
return true;
|
|
18719
|
+
}
|
|
18720
|
+
/**
|
|
18721
|
+
* Whether the primitive wrappers passed are equal in value.
|
|
18722
|
+
*/
|
|
18723
|
+
function arePrimitiveWrappersEqual(a, b) {
|
|
18724
|
+
return sameValueEqual(a.valueOf(), b.valueOf());
|
|
18725
|
+
}
|
|
18726
|
+
/**
|
|
18727
|
+
* Whether the regexps passed are equal in value.
|
|
18728
|
+
*/
|
|
18729
|
+
function areRegExpsEqual(a, b) {
|
|
18730
|
+
return a.source === b.source && a.flags === b.flags;
|
|
18731
|
+
}
|
|
18732
|
+
/**
|
|
18733
|
+
* Whether the `Set`s are equal in value.
|
|
18734
|
+
*/
|
|
18735
|
+
function areSetsEqual(a, b, state) {
|
|
18736
|
+
const size = a.size;
|
|
18737
|
+
if (size !== b.size) {
|
|
18738
|
+
return false;
|
|
18739
|
+
}
|
|
18740
|
+
if (!size) {
|
|
18741
|
+
return true;
|
|
18742
|
+
}
|
|
18743
|
+
const matchedIndices = new Array(size);
|
|
18744
|
+
const aIterable = a.values();
|
|
18745
|
+
let aResult;
|
|
18746
|
+
let bResult;
|
|
18747
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
18748
|
+
while ((aResult = aIterable.next())) {
|
|
18749
|
+
if (aResult.done) {
|
|
18750
|
+
break;
|
|
18751
|
+
}
|
|
18752
|
+
const bIterable = b.values();
|
|
18753
|
+
let hasMatch = false;
|
|
18754
|
+
let matchIndex = 0;
|
|
18755
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
18756
|
+
while ((bResult = bIterable.next())) {
|
|
18757
|
+
if (bResult.done) {
|
|
18758
|
+
break;
|
|
18759
|
+
}
|
|
18760
|
+
if (!matchedIndices[matchIndex]
|
|
18761
|
+
&& state.equals(aResult.value, bResult.value, aResult.value, bResult.value, a, b, state)) {
|
|
18762
|
+
hasMatch = matchedIndices[matchIndex] = true;
|
|
18763
|
+
break;
|
|
18764
|
+
}
|
|
18765
|
+
matchIndex++;
|
|
18766
|
+
}
|
|
18767
|
+
if (!hasMatch) {
|
|
18768
|
+
return false;
|
|
18769
|
+
}
|
|
18770
|
+
}
|
|
18771
|
+
return true;
|
|
18772
|
+
}
|
|
18773
|
+
/**
|
|
18774
|
+
* Whether the TypedArray instances are equal in value.
|
|
18775
|
+
*/
|
|
18776
|
+
function areTypedArraysEqual(a, b) {
|
|
18777
|
+
let index = a.byteLength;
|
|
18778
|
+
if (b.byteLength !== index || a.byteOffset !== b.byteOffset) {
|
|
18779
|
+
return false;
|
|
18780
|
+
}
|
|
18781
|
+
while (index-- > 0) {
|
|
18782
|
+
if (a[index] !== b[index]) {
|
|
18783
|
+
return false;
|
|
18784
|
+
}
|
|
18785
|
+
}
|
|
18786
|
+
return true;
|
|
18787
|
+
}
|
|
18788
|
+
/**
|
|
18789
|
+
* Whether the URL instances are equal in value.
|
|
18790
|
+
*/
|
|
18791
|
+
function areUrlsEqual(a, b) {
|
|
18792
|
+
return (a.hostname === b.hostname
|
|
18793
|
+
&& a.pathname === b.pathname
|
|
18794
|
+
&& a.protocol === b.protocol
|
|
18795
|
+
&& a.port === b.port
|
|
18796
|
+
&& a.hash === b.hash
|
|
18797
|
+
&& a.username === b.username
|
|
18798
|
+
&& a.password === b.password);
|
|
18799
|
+
}
|
|
18800
|
+
function isPropertyEqual(a, b, state, property) {
|
|
18801
|
+
if ((property === REACT_OWNER || property === PREACT_OWNER || property === PREACT_VNODE)
|
|
18802
|
+
&& (a.$$typeof || b.$$typeof)) {
|
|
18803
|
+
return true;
|
|
18804
|
+
}
|
|
18805
|
+
return hasOwn(b, property) && state.equals(a[property], b[property], property, property, a, b, state);
|
|
18806
|
+
}
|
|
18807
|
+
|
|
18808
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
18809
|
+
const toString = Object.prototype.toString;
|
|
18810
|
+
/**
|
|
18811
|
+
* Create a comparator method based on the type-specific equality comparators passed.
|
|
18812
|
+
*/
|
|
18813
|
+
function createEqualityComparator(config) {
|
|
18814
|
+
const supportedComparatorMap = createSupportedComparatorMap(config);
|
|
18815
|
+
const { areArraysEqual, areDatesEqual, areFunctionsEqual, areMapsEqual, areNumbersEqual, areObjectsEqual, areRegExpsEqual, areSetsEqual, getUnsupportedCustomComparator, } = config;
|
|
18816
|
+
/**
|
|
18817
|
+
* compare the value of the two objects and return true if they are equivalent in values
|
|
18818
|
+
*/
|
|
18819
|
+
return function comparator(a, b, state) {
|
|
18820
|
+
// If the items are strictly equal, no need to do a value comparison.
|
|
18821
|
+
if (a === b) {
|
|
18548
18822
|
return true;
|
|
18549
18823
|
}
|
|
18550
|
-
|
|
18551
|
-
|
|
18824
|
+
// If either of the items are nullish and fail the strictly equal check
|
|
18825
|
+
// above, then they must be unequal.
|
|
18826
|
+
if (a == null || b == null) {
|
|
18827
|
+
return false;
|
|
18828
|
+
}
|
|
18829
|
+
const type = typeof a;
|
|
18830
|
+
if (type !== typeof b) {
|
|
18831
|
+
return false;
|
|
18832
|
+
}
|
|
18833
|
+
if (type !== 'object') {
|
|
18834
|
+
if (type === 'number' || type === 'bigint') {
|
|
18835
|
+
return areNumbersEqual(a, b, state);
|
|
18836
|
+
}
|
|
18837
|
+
if (type === 'function') {
|
|
18838
|
+
return areFunctionsEqual(a, b, state);
|
|
18839
|
+
}
|
|
18840
|
+
// If a primitive value that is not strictly equal, it must be unequal.
|
|
18841
|
+
return false;
|
|
18842
|
+
}
|
|
18843
|
+
const constructor = a.constructor;
|
|
18844
|
+
// Checks are listed in order of commonality of use-case:
|
|
18845
|
+
// 1. Common complex object types (plain object, array)
|
|
18846
|
+
// 2. Common data values (date, regexp)
|
|
18847
|
+
// 3. Less-common complex object types (map, set)
|
|
18848
|
+
// 4. Less-common data values (promise, primitive wrappers)
|
|
18849
|
+
// Inherently this is both subjective and assumptive, however
|
|
18850
|
+
// when reviewing comparable libraries in the wild this order
|
|
18851
|
+
// appears to be generally consistent.
|
|
18852
|
+
// Constructors should match, otherwise there is potential for false positives
|
|
18853
|
+
// between class and subclass or custom object and POJO.
|
|
18854
|
+
if (constructor !== b.constructor) {
|
|
18855
|
+
return false;
|
|
18856
|
+
}
|
|
18857
|
+
// Try to fast-path equality checks for other complex object types in the
|
|
18858
|
+
// same realm to avoid capturing the string tag. Strict equality is used
|
|
18859
|
+
// instead of `instanceof` because it is more performant for the common
|
|
18860
|
+
// use-case. If someone is creating a subclass from a native class, it will be
|
|
18861
|
+
// handled with the string tag comparison.
|
|
18862
|
+
if (constructor === Object) {
|
|
18863
|
+
return areObjectsEqual(a, b, state);
|
|
18864
|
+
}
|
|
18865
|
+
if (constructor === Array) {
|
|
18866
|
+
return areArraysEqual(a, b, state);
|
|
18867
|
+
}
|
|
18868
|
+
if (constructor === Date) {
|
|
18869
|
+
return areDatesEqual(a, b, state);
|
|
18870
|
+
}
|
|
18871
|
+
if (constructor === RegExp) {
|
|
18872
|
+
return areRegExpsEqual(a, b, state);
|
|
18873
|
+
}
|
|
18874
|
+
if (constructor === Map) {
|
|
18875
|
+
return areMapsEqual(a, b, state);
|
|
18876
|
+
}
|
|
18877
|
+
if (constructor === Set) {
|
|
18878
|
+
return areSetsEqual(a, b, state);
|
|
18879
|
+
}
|
|
18880
|
+
if (constructor === Promise) {
|
|
18881
|
+
// Avoid tag checks for promise values, since we know if they are not referentially equal
|
|
18882
|
+
// then they are not equal.
|
|
18883
|
+
return false;
|
|
18884
|
+
}
|
|
18885
|
+
// `isArray()` works on subclasses and is cross-realm, so we can avoid capturing
|
|
18886
|
+
// the string tag or doing an `instanceof` in edge cases.
|
|
18887
|
+
if (Array.isArray(a)) {
|
|
18888
|
+
return areArraysEqual(a, b, state);
|
|
18889
|
+
}
|
|
18890
|
+
// Since this is a custom object, capture the string tag to determining its type.
|
|
18891
|
+
// This is reasonably performant in modern environments like v8 and SpiderMonkey.
|
|
18892
|
+
const tag = toString.call(a);
|
|
18893
|
+
const supportedComparator = supportedComparatorMap[tag];
|
|
18894
|
+
if (supportedComparator) {
|
|
18895
|
+
return supportedComparator(a, b, state);
|
|
18896
|
+
}
|
|
18897
|
+
const unsupportedCustomComparator = getUnsupportedCustomComparator && getUnsupportedCustomComparator(a, b, state, tag);
|
|
18898
|
+
if (unsupportedCustomComparator) {
|
|
18899
|
+
return unsupportedCustomComparator(a, b, state);
|
|
18900
|
+
}
|
|
18901
|
+
// If not matching any tags that require a specific type of comparison, then we hard-code false because
|
|
18902
|
+
// the only thing remaining is strict equality, which has already been compared. This is for a few reasons:
|
|
18903
|
+
// - Certain types that cannot be introspected (e.g., `WeakMap`). For these types, this is the only
|
|
18904
|
+
// comparison that can be made.
|
|
18905
|
+
// - For types that can be introspected but do not have an objective definition of what
|
|
18906
|
+
// equality is (`Error`, etc.), the subjective decision is to be conservative and strictly compare.
|
|
18907
|
+
// In all cases, these decisions should be reevaluated based on changes to the language and
|
|
18908
|
+
// common development practices.
|
|
18909
|
+
return false;
|
|
18910
|
+
};
|
|
18911
|
+
}
|
|
18912
|
+
/**
|
|
18913
|
+
* Create the configuration object used for building comparators.
|
|
18914
|
+
*/
|
|
18915
|
+
function createEqualityComparatorConfig({ circular, createCustomConfig, strict, }) {
|
|
18916
|
+
let config = {
|
|
18917
|
+
areArrayBuffersEqual,
|
|
18918
|
+
areArraysEqual: strict ? areObjectsEqualStrict : areArraysEqual,
|
|
18919
|
+
areDataViewsEqual,
|
|
18920
|
+
areDatesEqual: areDatesEqual,
|
|
18921
|
+
areErrorsEqual: areErrorsEqual,
|
|
18922
|
+
areFunctionsEqual: strictEqual,
|
|
18923
|
+
areMapsEqual: strict ? combineComparators(areMapsEqual, areObjectsEqualStrict) : areMapsEqual,
|
|
18924
|
+
areNumbersEqual: sameValueEqual,
|
|
18925
|
+
areObjectsEqual: strict ? areObjectsEqualStrict : areObjectsEqual,
|
|
18926
|
+
arePrimitiveWrappersEqual: arePrimitiveWrappersEqual,
|
|
18927
|
+
areRegExpsEqual: areRegExpsEqual,
|
|
18928
|
+
areSetsEqual: strict ? combineComparators(areSetsEqual, areObjectsEqualStrict) : areSetsEqual,
|
|
18929
|
+
areTypedArraysEqual: strict
|
|
18930
|
+
? combineComparators(areTypedArraysEqual, areObjectsEqualStrict)
|
|
18931
|
+
: areTypedArraysEqual,
|
|
18932
|
+
areUrlsEqual: areUrlsEqual,
|
|
18933
|
+
getUnsupportedCustomComparator: undefined,
|
|
18934
|
+
};
|
|
18935
|
+
if (createCustomConfig) {
|
|
18936
|
+
config = Object.assign({}, config, createCustomConfig(config));
|
|
18937
|
+
}
|
|
18938
|
+
if (circular) {
|
|
18939
|
+
const areArraysEqual = createIsCircular(config.areArraysEqual);
|
|
18940
|
+
const areMapsEqual = createIsCircular(config.areMapsEqual);
|
|
18941
|
+
const areObjectsEqual = createIsCircular(config.areObjectsEqual);
|
|
18942
|
+
const areSetsEqual = createIsCircular(config.areSetsEqual);
|
|
18943
|
+
config = Object.assign({}, config, {
|
|
18944
|
+
areArraysEqual,
|
|
18945
|
+
areMapsEqual,
|
|
18946
|
+
areObjectsEqual,
|
|
18947
|
+
areSetsEqual,
|
|
18948
|
+
});
|
|
18949
|
+
}
|
|
18950
|
+
return config;
|
|
18951
|
+
}
|
|
18952
|
+
/**
|
|
18953
|
+
* Default equality comparator pass-through, used as the standard `isEqual` creator for
|
|
18954
|
+
* use inside the built comparator.
|
|
18955
|
+
*/
|
|
18956
|
+
function createInternalEqualityComparator(compare) {
|
|
18957
|
+
return function (a, b, _indexOrKeyA, _indexOrKeyB, _parentA, _parentB, state) {
|
|
18958
|
+
return compare(a, b, state);
|
|
18959
|
+
};
|
|
18552
18960
|
}
|
|
18961
|
+
/**
|
|
18962
|
+
* Create the `isEqual` function used by the consuming application.
|
|
18963
|
+
*/
|
|
18964
|
+
function createIsEqual({ circular, comparator, createState, equals, strict }) {
|
|
18965
|
+
if (createState) {
|
|
18966
|
+
return function isEqual(a, b) {
|
|
18967
|
+
const { cache = circular ? new WeakMap() : undefined, meta } = createState();
|
|
18968
|
+
return comparator(a, b, {
|
|
18969
|
+
cache,
|
|
18970
|
+
equals,
|
|
18971
|
+
meta,
|
|
18972
|
+
strict,
|
|
18973
|
+
});
|
|
18974
|
+
};
|
|
18975
|
+
}
|
|
18976
|
+
if (circular) {
|
|
18977
|
+
return function isEqual(a, b) {
|
|
18978
|
+
return comparator(a, b, {
|
|
18979
|
+
cache: new WeakMap(),
|
|
18980
|
+
equals,
|
|
18981
|
+
meta: undefined,
|
|
18982
|
+
strict,
|
|
18983
|
+
});
|
|
18984
|
+
};
|
|
18985
|
+
}
|
|
18986
|
+
const state = {
|
|
18987
|
+
cache: undefined,
|
|
18988
|
+
equals,
|
|
18989
|
+
meta: undefined,
|
|
18990
|
+
strict,
|
|
18991
|
+
};
|
|
18992
|
+
return function isEqual(a, b) {
|
|
18993
|
+
return comparator(a, b, state);
|
|
18994
|
+
};
|
|
18995
|
+
}
|
|
18996
|
+
/**
|
|
18997
|
+
* Create a map of `toString()` values to their respective handlers for `tag`-based lookups.
|
|
18998
|
+
*/
|
|
18999
|
+
function createSupportedComparatorMap({ areArrayBuffersEqual, areArraysEqual, areDataViewsEqual, areDatesEqual, areErrorsEqual, areFunctionsEqual, areMapsEqual, areNumbersEqual, areObjectsEqual, arePrimitiveWrappersEqual, areRegExpsEqual, areSetsEqual, areTypedArraysEqual, areUrlsEqual, }) {
|
|
19000
|
+
return {
|
|
19001
|
+
'[object Arguments]': areObjectsEqual,
|
|
19002
|
+
'[object Array]': areArraysEqual,
|
|
19003
|
+
'[object ArrayBuffer]': areArrayBuffersEqual,
|
|
19004
|
+
'[object AsyncGeneratorFunction]': areFunctionsEqual,
|
|
19005
|
+
'[object BigInt]': areNumbersEqual,
|
|
19006
|
+
'[object BigInt64Array]': areTypedArraysEqual,
|
|
19007
|
+
'[object BigUint64Array]': areTypedArraysEqual,
|
|
19008
|
+
'[object Boolean]': arePrimitiveWrappersEqual,
|
|
19009
|
+
'[object DataView]': areDataViewsEqual,
|
|
19010
|
+
'[object Date]': areDatesEqual,
|
|
19011
|
+
// If an error tag, it should be tested explicitly. Like RegExp, the properties are not
|
|
19012
|
+
// enumerable, and therefore will give false positives if tested like a standard object.
|
|
19013
|
+
'[object Error]': areErrorsEqual,
|
|
19014
|
+
'[object Float16Array]': areTypedArraysEqual,
|
|
19015
|
+
'[object Float32Array]': areTypedArraysEqual,
|
|
19016
|
+
'[object Float64Array]': areTypedArraysEqual,
|
|
19017
|
+
'[object Function]': areFunctionsEqual,
|
|
19018
|
+
'[object GeneratorFunction]': areFunctionsEqual,
|
|
19019
|
+
'[object Int8Array]': areTypedArraysEqual,
|
|
19020
|
+
'[object Int16Array]': areTypedArraysEqual,
|
|
19021
|
+
'[object Int32Array]': areTypedArraysEqual,
|
|
19022
|
+
'[object Map]': areMapsEqual,
|
|
19023
|
+
'[object Number]': arePrimitiveWrappersEqual,
|
|
19024
|
+
'[object Object]': (a, b, state) =>
|
|
19025
|
+
// The exception for value comparison is custom `Promise`-like class instances. These should
|
|
19026
|
+
// be treated the same as standard `Promise` objects, which means strict equality, and if
|
|
19027
|
+
// it reaches this point then that strict equality comparison has already failed.
|
|
19028
|
+
typeof a.then !== 'function' && typeof b.then !== 'function' && areObjectsEqual(a, b, state),
|
|
19029
|
+
// For RegExp, the properties are not enumerable, and therefore will give false positives if
|
|
19030
|
+
// tested like a standard object.
|
|
19031
|
+
'[object RegExp]': areRegExpsEqual,
|
|
19032
|
+
'[object Set]': areSetsEqual,
|
|
19033
|
+
'[object String]': arePrimitiveWrappersEqual,
|
|
19034
|
+
'[object URL]': areUrlsEqual,
|
|
19035
|
+
'[object Uint8Array]': areTypedArraysEqual,
|
|
19036
|
+
'[object Uint8ClampedArray]': areTypedArraysEqual,
|
|
19037
|
+
'[object Uint16Array]': areTypedArraysEqual,
|
|
19038
|
+
'[object Uint32Array]': areTypedArraysEqual,
|
|
19039
|
+
};
|
|
19040
|
+
}
|
|
19041
|
+
|
|
19042
|
+
/**
|
|
19043
|
+
* Whether the items passed are deeply-equal in value.
|
|
19044
|
+
*/
|
|
19045
|
+
createCustomEqual();
|
|
19046
|
+
/**
|
|
19047
|
+
* Whether the items passed are deeply-equal in value based on strict comparison.
|
|
19048
|
+
*/
|
|
19049
|
+
createCustomEqual({ strict: true });
|
|
19050
|
+
/**
|
|
19051
|
+
* Whether the items passed are deeply-equal in value, including circular references.
|
|
19052
|
+
*/
|
|
19053
|
+
createCustomEqual({ circular: true });
|
|
19054
|
+
/**
|
|
19055
|
+
* Whether the items passed are deeply-equal in value, including circular references,
|
|
19056
|
+
* based on strict comparison.
|
|
19057
|
+
*/
|
|
19058
|
+
createCustomEqual({
|
|
19059
|
+
circular: true,
|
|
19060
|
+
strict: true,
|
|
19061
|
+
});
|
|
19062
|
+
/**
|
|
19063
|
+
* Whether the items passed are shallowly-equal in value.
|
|
19064
|
+
*/
|
|
19065
|
+
createCustomEqual({
|
|
19066
|
+
createInternalComparator: () => sameValueEqual,
|
|
19067
|
+
});
|
|
19068
|
+
/**
|
|
19069
|
+
* Whether the items passed are shallowly-equal in value based on strict comparison
|
|
19070
|
+
*/
|
|
19071
|
+
createCustomEqual({
|
|
19072
|
+
strict: true,
|
|
19073
|
+
createInternalComparator: () => sameValueEqual,
|
|
19074
|
+
});
|
|
19075
|
+
/**
|
|
19076
|
+
* Whether the items passed are shallowly-equal in value, including circular references.
|
|
19077
|
+
*/
|
|
19078
|
+
createCustomEqual({
|
|
19079
|
+
circular: true,
|
|
19080
|
+
createInternalComparator: () => sameValueEqual,
|
|
19081
|
+
});
|
|
19082
|
+
/**
|
|
19083
|
+
* Whether the items passed are shallowly-equal in value, including circular references,
|
|
19084
|
+
* based on strict comparison.
|
|
19085
|
+
*/
|
|
19086
|
+
createCustomEqual({
|
|
19087
|
+
circular: true,
|
|
19088
|
+
createInternalComparator: () => sameValueEqual,
|
|
19089
|
+
strict: true,
|
|
19090
|
+
});
|
|
19091
|
+
/**
|
|
19092
|
+
* Create a custom equality comparison method.
|
|
19093
|
+
*
|
|
19094
|
+
* This can be done to create very targeted comparisons in extreme hot-path scenarios
|
|
19095
|
+
* where the standard methods are not performant enough, but can also be used to provide
|
|
19096
|
+
* support for legacy environments that do not support expected features like
|
|
19097
|
+
* `RegExp.prototype.flags` out of the box.
|
|
19098
|
+
*/
|
|
19099
|
+
function createCustomEqual(options = {}) {
|
|
19100
|
+
const { circular = false, createInternalComparator: createCustomInternalComparator, createState, strict = false, } = options;
|
|
19101
|
+
const config = createEqualityComparatorConfig(options);
|
|
19102
|
+
const comparator = createEqualityComparator(config);
|
|
19103
|
+
const equals = createCustomInternalComparator
|
|
19104
|
+
? createCustomInternalComparator(comparator)
|
|
19105
|
+
: createInternalEqualityComparator(comparator);
|
|
19106
|
+
return createIsEqual({ circular, comparator, createState, equals, strict });
|
|
19107
|
+
}
|
|
19108
|
+
|
|
19109
|
+
/** Implements a deep equals using `fast-equals.createCustomEqual`. Functions
|
|
19110
|
+
* are always considered equal, and circular references are tracked to avoid
|
|
19111
|
+
* infinite recursion on self-referential inputs.
|
|
19112
|
+
*
|
|
19113
|
+
* @param a - The first element to compare
|
|
19114
|
+
* @param b - The second element to compare
|
|
19115
|
+
* @returns - True if the `a` and `b` are deeply equal, false otherwise
|
|
19116
|
+
*/
|
|
19117
|
+
const deepEquals = createCustomEqual({
|
|
19118
|
+
circular: true,
|
|
19119
|
+
createCustomConfig: () => ({
|
|
19120
|
+
areFunctionsEqual(_a, b) {
|
|
19121
|
+
return typeof b === 'function';
|
|
19122
|
+
},
|
|
19123
|
+
}),
|
|
19124
|
+
});
|
|
18553
19125
|
|
|
18554
19126
|
const objProto = Object.prototype;
|
|
18555
19127
|
function isRecordEmpty(rec) {
|
|
@@ -21612,7 +22184,7 @@ function findSelectedOptionInXxxOf(validator, rootSchema, schema, fallbackField,
|
|
|
21612
22184
|
const data = get(formData, selectorField);
|
|
21613
22185
|
if (data !== undefined) {
|
|
21614
22186
|
return xxxOfs.find((xxx) => {
|
|
21615
|
-
return
|
|
22187
|
+
return deepEquals(get(xxx, [PROPERTIES_KEY, selectorField, DEFAULT_KEY], get(xxx, [PROPERTIES_KEY, selectorField, CONST_KEY])), data);
|
|
21616
22188
|
});
|
|
21617
22189
|
}
|
|
21618
22190
|
}
|
|
@@ -22496,11 +23068,6 @@ function getObjectDefaults(validator, rawSchema, { rawFormData, rootSchema = {},
|
|
|
22496
23068
|
? retrievedSchema.additionalProperties
|
|
22497
23069
|
: {};
|
|
22498
23070
|
const keys = new Set();
|
|
22499
|
-
if (isObject(defaults)) {
|
|
22500
|
-
Object.keys(defaults)
|
|
22501
|
-
.filter((key) => !retrievedSchema.properties || !retrievedSchema.properties[key])
|
|
22502
|
-
.forEach((key) => keys.add(key));
|
|
22503
|
-
}
|
|
22504
23071
|
const formDataRequired = [];
|
|
22505
23072
|
Object.keys(formData)
|
|
22506
23073
|
.filter((key) => !retrievedSchema.properties || !retrievedSchema.properties[key])
|
|
@@ -22508,6 +23075,14 @@ function getObjectDefaults(validator, rawSchema, { rawFormData, rootSchema = {},
|
|
|
22508
23075
|
keys.add(key);
|
|
22509
23076
|
formDataRequired.push(key);
|
|
22510
23077
|
});
|
|
23078
|
+
// Only seed keys from schema defaults when formData has no additionalProperties of its own.
|
|
23079
|
+
// If the user already has data (e.g. after a key rename), injecting default keys would
|
|
23080
|
+
// re-add stale entries that no longer exist in formData.
|
|
23081
|
+
if (isObject(defaults) && formDataRequired.length === 0) {
|
|
23082
|
+
Object.keys(defaults)
|
|
23083
|
+
.filter((key) => !retrievedSchema.properties || !retrievedSchema.properties[key])
|
|
23084
|
+
.forEach((key) => keys.add(key));
|
|
23085
|
+
}
|
|
22511
23086
|
keys.forEach((key) => {
|
|
22512
23087
|
var _a;
|
|
22513
23088
|
const computedDefault = computeDefaults(validator, additionalPropertiesSchema, {
|
|
@@ -23496,6 +24071,67 @@ function englishStringTranslator(stringToTranslate, params) {
|
|
|
23496
24071
|
return replaceStringParameters(stringToTranslate, params);
|
|
23497
24072
|
}
|
|
23498
24073
|
|
|
24074
|
+
/** Determines whether the given `value` is (one of) the `selected` value(s).
|
|
24075
|
+
*
|
|
24076
|
+
* @param value - The value being checked to see if it is selected
|
|
24077
|
+
* @param selected - The current selected value or list of values
|
|
24078
|
+
* @returns - true if the `value` is one of the `selected` ones, false otherwise
|
|
24079
|
+
*/
|
|
24080
|
+
function enumOptionsIsSelected(value, selected) {
|
|
24081
|
+
if (Array.isArray(selected)) {
|
|
24082
|
+
return selected.some((sel) => deepEquals(sel, value));
|
|
24083
|
+
}
|
|
24084
|
+
return deepEquals(selected, value);
|
|
24085
|
+
}
|
|
24086
|
+
|
|
24087
|
+
/** Returns the index(es) of the options in `allEnumOptions` whose value(s) match the ones in `value`. All the
|
|
24088
|
+
* `enumOptions` are filtered based on whether they are a "selected" `value` and the index of each selected one is then
|
|
24089
|
+
* stored in an array. If `multiple` is true, that array is returned, otherwise the first element in the array is
|
|
24090
|
+
* returned.
|
|
24091
|
+
*
|
|
24092
|
+
* @param value - The single value or list of values for which indexes are desired
|
|
24093
|
+
* @param [allEnumOptions=[]] - The list of all the known enumOptions
|
|
24094
|
+
* @param [multiple=false] - Optional flag, if true will return a list of index, otherwise a single one
|
|
24095
|
+
* @returns - A single string index for the first `value` in `allEnumOptions`, if not `multiple`. Otherwise, the list
|
|
24096
|
+
* of indexes for (each of) the value(s) in `value`.
|
|
24097
|
+
*/
|
|
24098
|
+
function enumOptionsIndexForValue(value, allEnumOptions = [], multiple = false) {
|
|
24099
|
+
const selectedIndexes = allEnumOptions
|
|
24100
|
+
.map((opt, index) => (enumOptionsIsSelected(opt.value, value) ? String(index) : undefined))
|
|
24101
|
+
.filter((opt) => typeof opt !== 'undefined');
|
|
24102
|
+
if (!multiple) {
|
|
24103
|
+
return selectedIndexes[0];
|
|
24104
|
+
}
|
|
24105
|
+
return selectedIndexes;
|
|
24106
|
+
}
|
|
24107
|
+
|
|
24108
|
+
/** Computes the value to pass to a select element's `value` attribute.
|
|
24109
|
+
*
|
|
24110
|
+
* When `format` is `'realValue'`, converts form data values to strings.
|
|
24111
|
+
* When `format` is `'indexed'` (the default), resolves to index-based values via
|
|
24112
|
+
* `enumOptionsIndexForValue`. Returns `emptyValue` when the current value is empty.
|
|
24113
|
+
*
|
|
24114
|
+
* @param value - The current form data value
|
|
24115
|
+
* @param enumOptions - The available enum options
|
|
24116
|
+
* @param multiple - Whether the select allows multiple selections
|
|
24117
|
+
* @param [format='indexed'] - How option values are encoded on the DOM
|
|
24118
|
+
* @param emptyValue - The value to return when the selection is empty
|
|
24119
|
+
* @returns The value to use for the select element's `value` attribute
|
|
24120
|
+
*/
|
|
24121
|
+
function enumOptionSelectedValue(value, enumOptions, multiple, format = 'indexed', emptyValue) {
|
|
24122
|
+
const isEmpty = typeof value === 'undefined' ||
|
|
24123
|
+
(multiple && Array.isArray(value) && value.length < 1) ||
|
|
24124
|
+
(!multiple && value === emptyValue);
|
|
24125
|
+
if (isEmpty) {
|
|
24126
|
+
return emptyValue;
|
|
24127
|
+
}
|
|
24128
|
+
if (format === 'realValue') {
|
|
24129
|
+
return multiple ? value.map(String) : String(value);
|
|
24130
|
+
}
|
|
24131
|
+
const indexes = enumOptionsIndexForValue(value, enumOptions, multiple);
|
|
24132
|
+
return typeof indexes === 'undefined' ? emptyValue : indexes;
|
|
24133
|
+
}
|
|
24134
|
+
|
|
23499
24135
|
/** Returns the value(s) from `allEnumOptions` at the index(es) provided by `valueIndex`. If `valueIndex` is not an
|
|
23500
24136
|
* array AND the index is not valid for `allEnumOptions`, `emptyValue` is returned. If `valueIndex` is an array, AND it
|
|
23501
24137
|
* contains an invalid index, the returned array will have the resulting undefined values filtered out, leaving only
|
|
@@ -23520,6 +24156,84 @@ function enumOptionsValueForIndex(valueIndex, allEnumOptions = [], emptyValue) {
|
|
|
23520
24156
|
return option ? option.value : emptyValue;
|
|
23521
24157
|
}
|
|
23522
24158
|
|
|
24159
|
+
/** Resolves a single DOM value string back to its typed enum value in `'realValue'` mode.
|
|
24160
|
+
*
|
|
24161
|
+
* First attempts a reverse lookup by matching `String(opt.value)` against the input.
|
|
24162
|
+
* If no option matches and the input parses as a valid index, falls back to the
|
|
24163
|
+
* option at that index — this is how object/array enum values round-trip, since
|
|
24164
|
+
* they are encoded as indices by the encoder.
|
|
24165
|
+
*
|
|
24166
|
+
* @param value - A single string value from a DOM attribute
|
|
24167
|
+
* @param enumOptions - The available enum options
|
|
24168
|
+
* @param emptyValue - The value to return when the input is empty, options are missing, or no match is found
|
|
24169
|
+
* @returns The original typed enum value, or `emptyValue`
|
|
24170
|
+
*/
|
|
24171
|
+
function decodeSingle(value, enumOptions, emptyValue) {
|
|
24172
|
+
if (value === '' || !Array.isArray(enumOptions)) {
|
|
24173
|
+
return emptyValue;
|
|
24174
|
+
}
|
|
24175
|
+
const match = enumOptions.find((opt) => String(opt.value) === value);
|
|
24176
|
+
if (match) {
|
|
24177
|
+
return match.value;
|
|
24178
|
+
}
|
|
24179
|
+
// Fallback: value might be an index (for object/array enum values)
|
|
24180
|
+
const index = Number(value);
|
|
24181
|
+
if (!isNaN(index) && index >= 0 && index < enumOptions.length) {
|
|
24182
|
+
return enumOptions[index].value;
|
|
24183
|
+
}
|
|
24184
|
+
return emptyValue;
|
|
24185
|
+
}
|
|
24186
|
+
/** Decodes a string from a DOM value attribute back to a typed enum value.
|
|
24187
|
+
*
|
|
24188
|
+
* When `format` is `'realValue'`, does a reverse lookup: finds the enum option
|
|
24189
|
+
* whose `String(value)` matches the input string and returns the original typed value.
|
|
24190
|
+
* For object/array values that were encoded as indices, falls back to index resolution.
|
|
24191
|
+
*
|
|
24192
|
+
* When `format` is `'indexed'` (the default), uses index-based resolution via
|
|
24193
|
+
* `enumOptionsValueForIndex`.
|
|
24194
|
+
*
|
|
24195
|
+
* @param value - The string value(s) from the DOM
|
|
24196
|
+
* @param enumOptions - The available enum options
|
|
24197
|
+
* @param [format='indexed'] - How the values were encoded on the DOM
|
|
24198
|
+
* @param emptyValue - The value to return for empty/missing selections
|
|
24199
|
+
* @returns The original typed enum value(s)
|
|
24200
|
+
*/
|
|
24201
|
+
function enumOptionValueDecoder(value, enumOptions, format = 'indexed', emptyValue) {
|
|
24202
|
+
if (format !== 'realValue') {
|
|
24203
|
+
return enumOptionsValueForIndex(value, enumOptions, emptyValue);
|
|
24204
|
+
}
|
|
24205
|
+
if (Array.isArray(value)) {
|
|
24206
|
+
return value.map((v) => decodeSingle(v, enumOptions, emptyValue));
|
|
24207
|
+
}
|
|
24208
|
+
return decodeSingle(value, enumOptions, emptyValue);
|
|
24209
|
+
}
|
|
24210
|
+
|
|
24211
|
+
/** Encodes an enum option value into a string for a DOM value attribute.
|
|
24212
|
+
*
|
|
24213
|
+
* When `format` is `'realValue'`, primitive values are converted via `String()`.
|
|
24214
|
+
* Non-primitive values (objects, arrays) fall back to the index since
|
|
24215
|
+
* `String()` would produce `"[object Object]"`.
|
|
24216
|
+
*
|
|
24217
|
+
* When `format` is `'indexed'` (the default), returns the index as a string.
|
|
24218
|
+
*
|
|
24219
|
+
* @param value - The typed enum value
|
|
24220
|
+
* @param index - The option's position in the enumOptions array
|
|
24221
|
+
* @param [format='indexed'] - How to encode the value for the DOM attribute
|
|
24222
|
+
* @returns The string to use as the DOM value attribute
|
|
24223
|
+
*/
|
|
24224
|
+
function enumOptionValueEncoder(value, index, format = 'indexed') {
|
|
24225
|
+
if (format !== 'realValue') {
|
|
24226
|
+
return String(index);
|
|
24227
|
+
}
|
|
24228
|
+
if (isNil(value)) {
|
|
24229
|
+
return '';
|
|
24230
|
+
}
|
|
24231
|
+
if (typeof value === 'object') {
|
|
24232
|
+
return String(index);
|
|
24233
|
+
}
|
|
24234
|
+
return String(value);
|
|
24235
|
+
}
|
|
24236
|
+
|
|
23523
24237
|
/** Removes the enum option value at the `valueIndex` from the currently `selected` (list of) value(s). If `selected` is
|
|
23524
24238
|
* a list, then that list is updated to remove the enum option value with the `valueIndex` in `allEnumOptions`. If it is
|
|
23525
24239
|
* a single value, then if the enum option value with the `valueIndex` in `allEnumOptions` matches `selected`, undefined
|
|
@@ -23540,40 +24254,6 @@ function enumOptionsDeselectValue(valueIndex, selected, allEnumOptions = []) {
|
|
|
23540
24254
|
return deepEquals(value, selected) ? undefined : selected;
|
|
23541
24255
|
}
|
|
23542
24256
|
|
|
23543
|
-
/** Determines whether the given `value` is (one of) the `selected` value(s).
|
|
23544
|
-
*
|
|
23545
|
-
* @param value - The value being checked to see if it is selected
|
|
23546
|
-
* @param selected - The current selected value or list of values
|
|
23547
|
-
* @returns - true if the `value` is one of the `selected` ones, false otherwise
|
|
23548
|
-
*/
|
|
23549
|
-
function enumOptionsIsSelected(value, selected) {
|
|
23550
|
-
if (Array.isArray(selected)) {
|
|
23551
|
-
return selected.some((sel) => deepEquals(sel, value));
|
|
23552
|
-
}
|
|
23553
|
-
return deepEquals(selected, value);
|
|
23554
|
-
}
|
|
23555
|
-
|
|
23556
|
-
/** Returns the index(es) of the options in `allEnumOptions` whose value(s) match the ones in `value`. All the
|
|
23557
|
-
* `enumOptions` are filtered based on whether they are a "selected" `value` and the index of each selected one is then
|
|
23558
|
-
* stored in an array. If `multiple` is true, that array is returned, otherwise the first element in the array is
|
|
23559
|
-
* returned.
|
|
23560
|
-
*
|
|
23561
|
-
* @param value - The single value or list of values for which indexes are desired
|
|
23562
|
-
* @param [allEnumOptions=[]] - The list of all the known enumOptions
|
|
23563
|
-
* @param [multiple=false] - Optional flag, if true will return a list of index, otherwise a single one
|
|
23564
|
-
* @returns - A single string index for the first `value` in `allEnumOptions`, if not `multiple`. Otherwise, the list
|
|
23565
|
-
* of indexes for (each of) the value(s) in `value`.
|
|
23566
|
-
*/
|
|
23567
|
-
function enumOptionsIndexForValue(value, allEnumOptions = [], multiple = false) {
|
|
23568
|
-
const selectedIndexes = allEnumOptions
|
|
23569
|
-
.map((opt, index) => (enumOptionsIsSelected(opt.value, value) ? String(index) : undefined))
|
|
23570
|
-
.filter((opt) => typeof opt !== 'undefined');
|
|
23571
|
-
if (!multiple) {
|
|
23572
|
-
return selectedIndexes[0];
|
|
23573
|
-
}
|
|
23574
|
-
return selectedIndexes;
|
|
23575
|
-
}
|
|
23576
|
-
|
|
23577
24257
|
/** Add the enum option value at the `valueIndex` to the list of `selected` values in the proper order as defined by
|
|
23578
24258
|
* `allEnumOptions`
|
|
23579
24259
|
*
|
|
@@ -23719,14 +24399,14 @@ function getChangedFields(a, b) {
|
|
|
23719
24399
|
return [];
|
|
23720
24400
|
}
|
|
23721
24401
|
if (aIsPlainObject && !bIsPlainObject) {
|
|
23722
|
-
return keys(a);
|
|
24402
|
+
return keys$1(a);
|
|
23723
24403
|
}
|
|
23724
24404
|
else if (!aIsPlainObject && bIsPlainObject) {
|
|
23725
|
-
return keys(b);
|
|
24405
|
+
return keys$1(b);
|
|
23726
24406
|
}
|
|
23727
24407
|
else {
|
|
23728
|
-
const unequalFields = keys(pickBy(a, (value, key) => !deepEquals(value, get(b, key))));
|
|
23729
|
-
const diffFields = difference(keys(b), keys(a));
|
|
24408
|
+
const unequalFields = keys$1(pickBy(a, (value, key) => !deepEquals(value, get(b, key))));
|
|
24409
|
+
const diffFields = difference(keys$1(b), keys$1(a));
|
|
23730
24410
|
return [...unequalFields, ...diffFields];
|
|
23731
24411
|
}
|
|
23732
24412
|
}
|
|
@@ -23819,6 +24499,15 @@ function getInputProps(schema, defaultType, options = {}, autoDefaultStepAny = t
|
|
|
23819
24499
|
}
|
|
23820
24500
|
}
|
|
23821
24501
|
}
|
|
24502
|
+
// For date/time input types, propagate formatMinimum/formatMaximum to min/max
|
|
24503
|
+
if (['date', 'datetime-local', 'time', 'week', 'month'].includes(inputProps.type)) {
|
|
24504
|
+
if (schema.formatMinimum !== undefined) {
|
|
24505
|
+
inputProps.min = schema.formatMinimum;
|
|
24506
|
+
}
|
|
24507
|
+
if (schema.formatMaximum !== undefined) {
|
|
24508
|
+
inputProps.max = schema.formatMaximum;
|
|
24509
|
+
}
|
|
24510
|
+
}
|
|
23822
24511
|
if (options.autocomplete) {
|
|
23823
24512
|
inputProps.autoComplete = options.autocomplete;
|
|
23824
24513
|
}
|
|
@@ -23828,6 +24517,23 @@ function getInputProps(schema, defaultType, options = {}, autoDefaultStepAny = t
|
|
|
23828
24517
|
return inputProps;
|
|
23829
24518
|
}
|
|
23830
24519
|
|
|
24520
|
+
/** Resolves the effective `optionValueFormat` for enum-backed widgets.
|
|
24521
|
+
*
|
|
24522
|
+
* Provides a single source of truth for the default DOM encoding format
|
|
24523
|
+
* (`'indexed'`) used by `SelectWidget`, `RadioWidget`, and `CheckboxesWidget`.
|
|
24524
|
+
* Widgets should call this helper once and pass the result to
|
|
24525
|
+
* `enumOptionValueEncoder`, `enumOptionValueDecoder`, and `enumOptionSelectedValue`
|
|
24526
|
+
* rather than reading `options.optionValueFormat` directly.
|
|
24527
|
+
*
|
|
24528
|
+
* @param options - The widget options (typically from the `options` prop, already
|
|
24529
|
+
* resolved from `ui:options` and `ui:globalOptions`)
|
|
24530
|
+
* @returns The resolved `OptionValueFormat`, defaulting to `'indexed'` when not set
|
|
24531
|
+
*/
|
|
24532
|
+
function getOptionValueFormat(options) {
|
|
24533
|
+
var _a;
|
|
24534
|
+
return (_a = options === null || options === void 0 ? void 0 : options.optionValueFormat) !== null && _a !== void 0 ? _a : 'indexed';
|
|
24535
|
+
}
|
|
24536
|
+
|
|
23831
24537
|
/** The default submit button options, exported for testing purposes
|
|
23832
24538
|
*/
|
|
23833
24539
|
const DEFAULT_OPTIONS = {
|
|
@@ -24244,12 +24950,12 @@ function isFormDataAvailable(formData) {
|
|
|
24244
24950
|
*/
|
|
24245
24951
|
function isRootSchema(registry, schemaToCompare) {
|
|
24246
24952
|
const { rootSchema, schemaUtils } = registry;
|
|
24247
|
-
if (
|
|
24953
|
+
if (deepEquals(schemaToCompare, rootSchema)) {
|
|
24248
24954
|
return true;
|
|
24249
24955
|
}
|
|
24250
24956
|
if (REF_KEY in rootSchema) {
|
|
24251
24957
|
const resolvedSchema = schemaUtils.retrieveSchema(rootSchema);
|
|
24252
|
-
return
|
|
24958
|
+
return deepEquals(schemaToCompare, omit(resolvedSchema, RJSF_REF_KEY));
|
|
24253
24959
|
}
|
|
24254
24960
|
return false;
|
|
24255
24961
|
}
|
|
@@ -24284,6 +24990,111 @@ function lookupFromFormContext(regOrFc, toLookup, fallback) {
|
|
|
24284
24990
|
return get(regOrFc, [...lookupPath, toLookup], fallback);
|
|
24285
24991
|
}
|
|
24286
24992
|
|
|
24993
|
+
/** Determines whether a value is considered "empty" for the purposes of optional object pruning.
|
|
24994
|
+
* A value is empty if it is `undefined`, `null`, an empty string, or an object where all own
|
|
24995
|
+
* properties are themselves empty.
|
|
24996
|
+
*
|
|
24997
|
+
* @param value - The value to check
|
|
24998
|
+
* @returns True if the value is considered empty
|
|
24999
|
+
*/
|
|
25000
|
+
function isValueEmpty(value) {
|
|
25001
|
+
if (isNil(value) || value === '') {
|
|
25002
|
+
return true;
|
|
25003
|
+
}
|
|
25004
|
+
if (Array.isArray(value)) {
|
|
25005
|
+
// An empty array is considered empty; a non-empty array is not
|
|
25006
|
+
return value.length === 0;
|
|
25007
|
+
}
|
|
25008
|
+
if (isObject(value)) {
|
|
25009
|
+
const obj = value;
|
|
25010
|
+
const keys = Object.keys(obj);
|
|
25011
|
+
return keys.every((key) => isValueEmpty(obj[key]));
|
|
25012
|
+
}
|
|
25013
|
+
return false;
|
|
25014
|
+
}
|
|
25015
|
+
/** Recursively removes optional objects from the `formData` that are empty (i.e., all their fields
|
|
25016
|
+
* are undefined, null, empty strings, or themselves empty optional objects). This solves the problem
|
|
25017
|
+
* where interacting with fields inside an optional object "activates" it permanently, making the
|
|
25018
|
+
* form unsubmittable when the optional object has required inner fields.
|
|
25019
|
+
*
|
|
25020
|
+
* An object property is considered "optional" when it is NOT listed in its parent schema's `required`
|
|
25021
|
+
* array.
|
|
25022
|
+
*
|
|
25023
|
+
* @param validator - An implementation of the `ValidatorType` interface that will be used when necessary
|
|
25024
|
+
* @param schema - The JSON schema describing the `formData`
|
|
25025
|
+
* @param [rootSchema] - The root schema, used primarily to look up `$ref`s
|
|
25026
|
+
* @param [formData] - The current form data to prune
|
|
25027
|
+
* @returns - A new copy of `formData` with empty optional objects removed, or `undefined` if the
|
|
25028
|
+
* entire formData was pruned
|
|
25029
|
+
*/
|
|
25030
|
+
function removeOptionalEmptyObjects(validator, schema, rootSchema, formData) {
|
|
25031
|
+
if (!isObject(schema)) {
|
|
25032
|
+
return formData;
|
|
25033
|
+
}
|
|
25034
|
+
const resolvedSchema = retrieveSchema(validator, schema, rootSchema, formData);
|
|
25035
|
+
if (Array.isArray(formData)) {
|
|
25036
|
+
const itemsSchema = resolvedSchema.items;
|
|
25037
|
+
if (!itemsSchema) {
|
|
25038
|
+
return formData;
|
|
25039
|
+
}
|
|
25040
|
+
let hasChanges = false;
|
|
25041
|
+
const mapped = formData.map((item, index) => {
|
|
25042
|
+
let itemSchema = itemsSchema;
|
|
25043
|
+
if (Array.isArray(itemsSchema)) {
|
|
25044
|
+
itemSchema = itemsSchema[index] || resolvedSchema.additionalItems || {};
|
|
25045
|
+
}
|
|
25046
|
+
const cleaned = removeOptionalEmptyObjects(validator, itemSchema, rootSchema, item);
|
|
25047
|
+
if (cleaned !== item) {
|
|
25048
|
+
hasChanges = true;
|
|
25049
|
+
}
|
|
25050
|
+
return cleaned === undefined ? {} : cleaned;
|
|
25051
|
+
});
|
|
25052
|
+
// Although T is an array type here, we still need to cast it back to T since TS
|
|
25053
|
+
// doesn't narrow the generic T automatically
|
|
25054
|
+
return hasChanges ? mapped : formData;
|
|
25055
|
+
}
|
|
25056
|
+
const { properties, required: requiredFields = [] } = resolvedSchema;
|
|
25057
|
+
if (!isObject(formData) || !properties) {
|
|
25058
|
+
return formData;
|
|
25059
|
+
}
|
|
25060
|
+
const result = {};
|
|
25061
|
+
const data = formData;
|
|
25062
|
+
let hasAnyValue = false;
|
|
25063
|
+
for (const key of Object.keys(data)) {
|
|
25064
|
+
const value = data[key];
|
|
25065
|
+
const propertySchema = (properties[key] || {});
|
|
25066
|
+
const isRequired = requiredFields.includes(key);
|
|
25067
|
+
const isObj = isObject(value);
|
|
25068
|
+
const isArr = Array.isArray(value);
|
|
25069
|
+
if ((isObj || isArr) && properties[key]) {
|
|
25070
|
+
// Recursively process nested objects and arrays
|
|
25071
|
+
const cleaned = removeOptionalEmptyObjects(validator, propertySchema, rootSchema, value);
|
|
25072
|
+
if (!isRequired && isValueEmpty(cleaned)) {
|
|
25073
|
+
// This is an optional property and the cleaned result is empty — omit it
|
|
25074
|
+
continue;
|
|
25075
|
+
}
|
|
25076
|
+
result[key] = cleaned;
|
|
25077
|
+
hasAnyValue = true;
|
|
25078
|
+
}
|
|
25079
|
+
else if (!isRequired && isValueEmpty(value) && properties[key]) {
|
|
25080
|
+
// Optional scalar property that is empty — omit it
|
|
25081
|
+
continue;
|
|
25082
|
+
}
|
|
25083
|
+
else {
|
|
25084
|
+
result[key] = value;
|
|
25085
|
+
if (!isValueEmpty(value)) {
|
|
25086
|
+
hasAnyValue = true;
|
|
25087
|
+
}
|
|
25088
|
+
}
|
|
25089
|
+
}
|
|
25090
|
+
// If the entire object ended up empty after pruning, return undefined so that the
|
|
25091
|
+
// caller (which may itself be a recursive call) can decide whether to keep or drop it
|
|
25092
|
+
if (!hasAnyValue && Object.keys(result).length === 0) {
|
|
25093
|
+
return undefined;
|
|
25094
|
+
}
|
|
25095
|
+
return result;
|
|
25096
|
+
}
|
|
25097
|
+
|
|
24287
25098
|
/** Given a list of `properties` and an `order` list, returns a list that contains the `properties` ordered correctly.
|
|
24288
25099
|
* If `order` is not an array, then the untouched `properties` list is returned. Otherwise `properties` is ordered per
|
|
24289
25100
|
* the `order` list. If `order` contains a '*' then any `properties` that are not mentioned explicity in `order` will be
|
|
@@ -24354,104 +25165,18 @@ function parseDateString(dateString, includeTime = true) {
|
|
|
24354
25165
|
};
|
|
24355
25166
|
}
|
|
24356
25167
|
|
|
24357
|
-
// Keywords where child schemas map to uiSchema at the SAME key
|
|
24358
|
-
const SAME_KEY_KEYWORDS = [ITEMS_KEY, ADDITIONAL_PROPERTIES_KEY];
|
|
24359
|
-
// Keywords where child schemas are in an array, each mapping to uiSchema[keyword][i]
|
|
24360
|
-
const ARRAY_KEYWORDS = [ONE_OF_KEY, ANY_OF_KEY, ALL_OF_KEY];
|
|
24361
|
-
/** Expands `ui:definitions` into the uiSchema by walking the schema tree and finding all `$ref`s.
|
|
24362
|
-
* Called once at form initialization to pre-expand definitions into the uiSchema structure.
|
|
24363
|
-
*
|
|
24364
|
-
* For recursive schemas, expansion stops at recursion points to avoid infinite loops.
|
|
24365
|
-
* Runtime resolution via `resolveUiSchema` handles these cases using registry definitions.
|
|
24366
|
-
*
|
|
24367
|
-
* @param currentSchema - The current schema node being processed
|
|
24368
|
-
* @param uiSchema - The uiSchema at the current path
|
|
24369
|
-
* @param registry - The registry containing rootSchema and uiSchemaDefinitions
|
|
24370
|
-
* @param visited - Set of $refs already visited (to detect recursion)
|
|
24371
|
-
* @returns - The expanded uiSchema with definitions merged in
|
|
24372
|
-
*/
|
|
24373
|
-
function expandUiSchemaDefinitions(currentSchema, uiSchema, registry, visited = new Set()) {
|
|
24374
|
-
const { rootSchema, uiSchemaDefinitions: definitions } = registry;
|
|
24375
|
-
let result = { ...uiSchema };
|
|
24376
|
-
let resolvedSchema = currentSchema;
|
|
24377
|
-
const ref = currentSchema[REF_KEY];
|
|
24378
|
-
const isRecursive = ref && visited.has(ref);
|
|
24379
|
-
if (ref) {
|
|
24380
|
-
visited.add(ref);
|
|
24381
|
-
if (definitions && ref in definitions) {
|
|
24382
|
-
result = mergeObjects(definitions[ref], result);
|
|
24383
|
-
}
|
|
24384
|
-
if (isRecursive) {
|
|
24385
|
-
return result;
|
|
24386
|
-
}
|
|
24387
|
-
try {
|
|
24388
|
-
resolvedSchema = findSchemaDefinition(ref, rootSchema);
|
|
24389
|
-
}
|
|
24390
|
-
catch (_a) {
|
|
24391
|
-
resolvedSchema = currentSchema;
|
|
24392
|
-
}
|
|
24393
|
-
}
|
|
24394
|
-
// Process properties (each property maps to uiSchema[propName] - flattened)
|
|
24395
|
-
const properties = resolvedSchema[PROPERTIES_KEY];
|
|
24396
|
-
if (properties && isObject(properties)) {
|
|
24397
|
-
for (const [propName, propSchema] of Object.entries(properties)) {
|
|
24398
|
-
const propUiSchema = (result[propName] || {});
|
|
24399
|
-
const expanded = expandUiSchemaDefinitions(propSchema, propUiSchema, registry, new Set(visited));
|
|
24400
|
-
if (Object.keys(expanded).length > 0) {
|
|
24401
|
-
result[propName] = expanded;
|
|
24402
|
-
}
|
|
24403
|
-
}
|
|
24404
|
-
}
|
|
24405
|
-
// Process keywords where child maps to same key in uiSchema (items, additionalProperties)
|
|
24406
|
-
for (const keyword of SAME_KEY_KEYWORDS) {
|
|
24407
|
-
const subSchema = resolvedSchema[keyword];
|
|
24408
|
-
if (subSchema && isObject(subSchema) && !Array.isArray(subSchema)) {
|
|
24409
|
-
const currentUiSchema = result[keyword];
|
|
24410
|
-
if (typeof currentUiSchema !== 'function') {
|
|
24411
|
-
const subUiSchema = (currentUiSchema || {});
|
|
24412
|
-
const expanded = expandUiSchemaDefinitions(subSchema, subUiSchema, registry, new Set(visited));
|
|
24413
|
-
if (Object.keys(expanded).length > 0) {
|
|
24414
|
-
result[keyword] = expanded;
|
|
24415
|
-
}
|
|
24416
|
-
}
|
|
24417
|
-
}
|
|
24418
|
-
}
|
|
24419
|
-
// Process array keywords (oneOf, anyOf, allOf) - each option maps to uiSchema[keyword][i]
|
|
24420
|
-
for (const keyword of ARRAY_KEYWORDS) {
|
|
24421
|
-
const schemaOptions = resolvedSchema[keyword];
|
|
24422
|
-
if (Array.isArray(schemaOptions) && schemaOptions.length > 0) {
|
|
24423
|
-
const currentUiSchemaArray = result[keyword];
|
|
24424
|
-
const uiSchemaArray = Array.isArray(currentUiSchemaArray) ? [...currentUiSchemaArray] : [];
|
|
24425
|
-
let hasExpanded = false;
|
|
24426
|
-
for (let i = 0; i < schemaOptions.length; i++) {
|
|
24427
|
-
const optionSchema = schemaOptions[i];
|
|
24428
|
-
const optionUiSchema = (uiSchemaArray[i] || {});
|
|
24429
|
-
const expanded = expandUiSchemaDefinitions(optionSchema, optionUiSchema, registry, new Set(visited));
|
|
24430
|
-
if (Object.keys(expanded).length > 0) {
|
|
24431
|
-
uiSchemaArray[i] = expanded;
|
|
24432
|
-
hasExpanded = true;
|
|
24433
|
-
}
|
|
24434
|
-
}
|
|
24435
|
-
if (hasExpanded) {
|
|
24436
|
-
result[keyword] = uiSchemaArray;
|
|
24437
|
-
}
|
|
24438
|
-
}
|
|
24439
|
-
}
|
|
24440
|
-
return result;
|
|
24441
|
-
}
|
|
24442
25168
|
/** Resolves the uiSchema for a given schema, considering `ui:definitions` stored in the registry.
|
|
24443
25169
|
*
|
|
24444
|
-
*
|
|
24445
|
-
*
|
|
24446
|
-
*
|
|
24447
|
-
*
|
|
24448
|
-
* from `registry.uiSchemaDefinitions` and merges it with any local uiSchema overrides.
|
|
25170
|
+
* Called at runtime for each field. When the schema contains a `$ref`, looks up the corresponding
|
|
25171
|
+
* uiSchema definition from `registry.uiSchemaDefinitions` and merges it with local overrides.
|
|
25172
|
+
* For schemas with `oneOf`/`anyOf` branches, also populates `uiSchema[keyword][i]` for branches
|
|
25173
|
+
* whose `$ref` matches a definition, so `MultiSchemaField` can read dropdown option titles.
|
|
24449
25174
|
*
|
|
24450
25175
|
* Resolution order (later sources override earlier):
|
|
24451
25176
|
* 1. `ui:definitions[$ref]` - base definition from registry
|
|
24452
25177
|
* 2. `localUiSchema` - local overrides at current path
|
|
24453
25178
|
*
|
|
24454
|
-
* @param schema - The JSON schema (may
|
|
25179
|
+
* @param schema - The JSON schema (may contain `$ref` or `RJSF_REF_KEY`)
|
|
24455
25180
|
* @param localUiSchema - The uiSchema at the current path (local overrides)
|
|
24456
25181
|
* @param registry - The registry containing `uiSchemaDefinitions`
|
|
24457
25182
|
* @returns - The resolved uiSchema with definitions merged in
|
|
@@ -24459,14 +25184,54 @@ function expandUiSchemaDefinitions(currentSchema, uiSchema, registry, visited =
|
|
|
24459
25184
|
function resolveUiSchema(schema, localUiSchema, registry) {
|
|
24460
25185
|
var _a, _b;
|
|
24461
25186
|
const ref = ((_a = schema[RJSF_REF_KEY]) !== null && _a !== void 0 ? _a : schema[REF_KEY]);
|
|
24462
|
-
const
|
|
25187
|
+
const definitions = registry.uiSchemaDefinitions;
|
|
25188
|
+
const definitionUiSchema = ref && definitions ? definitions[ref] : undefined;
|
|
25189
|
+
let result;
|
|
24463
25190
|
if (!definitionUiSchema) {
|
|
24464
|
-
|
|
25191
|
+
result = localUiSchema || {};
|
|
25192
|
+
}
|
|
25193
|
+
else if (!localUiSchema || isEmpty(localUiSchema)) {
|
|
25194
|
+
result = { ...definitionUiSchema };
|
|
24465
25195
|
}
|
|
24466
|
-
|
|
24467
|
-
|
|
25196
|
+
else {
|
|
25197
|
+
result = mergeObjects(definitionUiSchema, localUiSchema);
|
|
24468
25198
|
}
|
|
24469
|
-
|
|
25199
|
+
// Walk oneOf/anyOf branches to populate uiSchema[keyword][i] so MultiSchemaField
|
|
25200
|
+
// can read dropdown option titles at the parent level.
|
|
25201
|
+
if (definitions) {
|
|
25202
|
+
let resolvedSchema = schema;
|
|
25203
|
+
if (ref && schema[REF_KEY] && !schema[RJSF_REF_KEY]) {
|
|
25204
|
+
try {
|
|
25205
|
+
resolvedSchema = findSchemaDefinition(ref, registry.rootSchema);
|
|
25206
|
+
}
|
|
25207
|
+
catch (e) {
|
|
25208
|
+
console.warn('could not resolve $ref in resolveUiSchema:\n', e);
|
|
25209
|
+
return result;
|
|
25210
|
+
}
|
|
25211
|
+
}
|
|
25212
|
+
for (const keyword of [ONE_OF_KEY, ANY_OF_KEY]) {
|
|
25213
|
+
const schemaOptions = resolvedSchema[keyword];
|
|
25214
|
+
if (!Array.isArray(schemaOptions) || schemaOptions.length === 0) {
|
|
25215
|
+
continue;
|
|
25216
|
+
}
|
|
25217
|
+
const currentUiSchemaArray = result[keyword];
|
|
25218
|
+
const uiSchemaArray = Array.isArray(currentUiSchemaArray) ? [...currentUiSchemaArray] : [];
|
|
25219
|
+
let hasExpanded = false;
|
|
25220
|
+
for (let i = 0; i < schemaOptions.length; i++) {
|
|
25221
|
+
const option = schemaOptions[i];
|
|
25222
|
+
const optionRef = ((_b = option === null || option === void 0 ? void 0 : option[RJSF_REF_KEY]) !== null && _b !== void 0 ? _b : option === null || option === void 0 ? void 0 : option[REF_KEY]);
|
|
25223
|
+
if (optionRef && optionRef in definitions) {
|
|
25224
|
+
const optionUiSchema = (uiSchemaArray[i] || {});
|
|
25225
|
+
uiSchemaArray[i] = mergeObjects(definitions[optionRef], optionUiSchema);
|
|
25226
|
+
hasExpanded = true;
|
|
25227
|
+
}
|
|
25228
|
+
}
|
|
25229
|
+
if (hasExpanded) {
|
|
25230
|
+
result[keyword] = uiSchemaArray;
|
|
25231
|
+
}
|
|
25232
|
+
}
|
|
25233
|
+
}
|
|
25234
|
+
return result;
|
|
24470
25235
|
}
|
|
24471
25236
|
|
|
24472
25237
|
/** Check to see if a `schema` specifies that a value must be true. This happens when:
|
|
@@ -24777,7 +25542,7 @@ function useAltDateWidgetProps(props) {
|
|
|
24777
25542
|
*/
|
|
24778
25543
|
function useDeepCompareMemo(newValue) {
|
|
24779
25544
|
const valueRef = reactExports.useRef(newValue);
|
|
24780
|
-
if (!
|
|
25545
|
+
if (!deepEquals(newValue, valueRef.current)) {
|
|
24781
25546
|
valueRef.current = newValue;
|
|
24782
25547
|
}
|
|
24783
25548
|
return valueRef.current;
|
|
@@ -25702,10 +26467,12 @@ function ArrayField$1(props) {
|
|
|
25702
26467
|
* @param index - The index of the item being changed
|
|
25703
26468
|
*/
|
|
25704
26469
|
const handleChange = reactExports.useCallback((value, path, newErrorSchema, id) => {
|
|
26470
|
+
const lastPathIsItemIndex = typeof path.at(-1) === 'number';
|
|
25705
26471
|
onChange(
|
|
25706
26472
|
// We need to treat undefined items as nulls to have validation.
|
|
25707
26473
|
// See https://github.com/tdegrunt/jsonschema/issues/206
|
|
25708
|
-
|
|
26474
|
+
// Only set to null for array items, and not for object properties within array items
|
|
26475
|
+
lastPathIsItemIndex && value === undefined ? null : value, path, newErrorSchema, id);
|
|
25709
26476
|
}, [onChange]);
|
|
25710
26477
|
/** Callback handler used to change the value for a checkbox */
|
|
25711
26478
|
const onSelectChange = reactExports.useCallback((value) => {
|
|
@@ -27021,11 +27788,14 @@ function ObjectField$1(props) {
|
|
|
27021
27788
|
const { schema: rawSchema, uiSchema = {}, formData, errorSchema, fieldPathId, name, required = false, disabled, readonly, hideError, onBlur, onFocus, onChange, registry, title, } = props;
|
|
27022
27789
|
const { fields, schemaUtils, translateString, globalUiOptions } = registry;
|
|
27023
27790
|
const { OptionalDataControlsField } = fields;
|
|
27791
|
+
const formDataRef = reactExports.useRef(formData);
|
|
27792
|
+
formDataRef.current = formData;
|
|
27024
27793
|
const schema = schemaUtils.retrieveSchema(rawSchema, formData, true);
|
|
27025
27794
|
const uiOptions = getUiOptions(uiSchema, globalUiOptions);
|
|
27026
27795
|
const { properties: schemaProperties = {} } = schema;
|
|
27027
27796
|
// All the children will use childFieldPathId if present in the props, falling back to the fieldPathId
|
|
27028
27797
|
const childFieldPathId = props.childFieldPathId ?? fieldPathId;
|
|
27798
|
+
const lastRenamedProperty = reactExports.useRef({ previousKey: '', currentKey: undefined });
|
|
27029
27799
|
const templateTitle = uiOptions.title ?? schema.title ?? title ?? name;
|
|
27030
27800
|
const description = uiOptions.description ?? schema.description;
|
|
27031
27801
|
const renderOptionalField = shouldRenderOptionalField(registry, schema, required, uiSchema);
|
|
@@ -27085,6 +27855,10 @@ function ObjectField$1(props) {
|
|
|
27085
27855
|
// Cast this to make the `set` work properly
|
|
27086
27856
|
set(newFormData, newKey, newValue);
|
|
27087
27857
|
}
|
|
27858
|
+
if (lastRenamedProperty.current.previousKey === newKey) {
|
|
27859
|
+
lastRenamedProperty.current.currentKey = newKey;
|
|
27860
|
+
lastRenamedProperty.current.previousKey = getAvailableKey(newKey, newFormData);
|
|
27861
|
+
}
|
|
27088
27862
|
onChange(newFormData, childFieldPathId.path);
|
|
27089
27863
|
}, [formData, onChange, registry, childFieldPathId, getAvailableKey, schema]);
|
|
27090
27864
|
/** Returns a callback function that deals with the rename of a key for an additional property for a schema. That
|
|
@@ -27096,9 +27870,10 @@ function ObjectField$1(props) {
|
|
|
27096
27870
|
*/
|
|
27097
27871
|
const handleKeyRename = reactExports.useCallback((oldKey, newKey) => {
|
|
27098
27872
|
if (oldKey !== newKey) {
|
|
27099
|
-
const
|
|
27873
|
+
const currentFormData = formDataRef.current;
|
|
27874
|
+
const actualNewKey = getAvailableKey(newKey, currentFormData);
|
|
27100
27875
|
const newFormData = {
|
|
27101
|
-
...
|
|
27876
|
+
...currentFormData,
|
|
27102
27877
|
};
|
|
27103
27878
|
const newKeys = { [oldKey]: actualNewKey };
|
|
27104
27879
|
const keyValues = Object.keys(newFormData).map((key) => {
|
|
@@ -27106,15 +27881,31 @@ function ObjectField$1(props) {
|
|
|
27106
27881
|
return { [newKey]: newFormData[key] };
|
|
27107
27882
|
});
|
|
27108
27883
|
const renamedObj = Object.assign({}, ...keyValues);
|
|
27884
|
+
formDataRef.current = renamedObj;
|
|
27885
|
+
if (oldKey !== lastRenamedProperty.current.currentKey) {
|
|
27886
|
+
lastRenamedProperty.current.previousKey = oldKey;
|
|
27887
|
+
}
|
|
27888
|
+
lastRenamedProperty.current.currentKey = actualNewKey;
|
|
27109
27889
|
onChange(renamedObj, childFieldPathId.path);
|
|
27110
27890
|
}
|
|
27111
|
-
}, [
|
|
27891
|
+
}, [onChange, childFieldPathId, getAvailableKey]);
|
|
27112
27892
|
/** Handles the remove click which calls the `onChange` callback with the special ADDITIONAL_PROPERTY_FIELD_REMOVE
|
|
27113
27893
|
* value for the path plus the key to be removed
|
|
27114
27894
|
*/
|
|
27115
27895
|
const handleRemoveProperty = reactExports.useCallback((key) => {
|
|
27116
27896
|
onChange(ADDITIONAL_PROPERTY_KEY_REMOVE, [...childFieldPathId.path, key]);
|
|
27117
27897
|
}, [onChange, childFieldPathId]);
|
|
27898
|
+
/** Returns the stable React key for a property. For the most recently renamed
|
|
27899
|
+
* additional property, returns the previous key so that React reuses the
|
|
27900
|
+
* existing component instance instead of unmounting/remounting it. This
|
|
27901
|
+
* preserves DOM focus naturally without manual focus management.
|
|
27902
|
+
*/
|
|
27903
|
+
const getStableKey = reactExports.useCallback((property) => {
|
|
27904
|
+
if (lastRenamedProperty.current.currentKey === property) {
|
|
27905
|
+
return lastRenamedProperty.current.previousKey;
|
|
27906
|
+
}
|
|
27907
|
+
return property;
|
|
27908
|
+
}, []);
|
|
27118
27909
|
if (!renderOptionalField || hasFormData) {
|
|
27119
27910
|
try {
|
|
27120
27911
|
const properties = Object.keys(schemaProperties);
|
|
@@ -27134,7 +27925,7 @@ function ObjectField$1(props) {
|
|
|
27134
27925
|
const addedByAdditionalProperties = has(schema, [PROPERTIES_KEY, name, ADDITIONAL_PROPERTY_FLAG]);
|
|
27135
27926
|
const fieldUiSchema = addedByAdditionalProperties ? uiSchema.additionalProperties : uiSchema[name];
|
|
27136
27927
|
const hidden = getUiOptions(fieldUiSchema).widget === 'hidden';
|
|
27137
|
-
const content = (jsxRuntimeExports.jsx(ObjectFieldProperty, { propertyName: name, required: isRequired(schema, name), schema: get(schema, [PROPERTIES_KEY, name], {}), uiSchema: fieldUiSchema, errorSchema: get(errorSchema, [name]), fieldPathId: childFieldPathId, formData: get(formData, [name]), handleKeyRename: handleKeyRename, handleRemoveProperty: handleRemoveProperty, addedByAdditionalProperties: addedByAdditionalProperties, onChange: onChange, onBlur: onBlur, onFocus: onFocus, registry: registry, disabled: disabled, readonly: readonly, hideError: hideError }, name));
|
|
27928
|
+
const content = (jsxRuntimeExports.jsx(ObjectFieldProperty, { propertyName: name, required: isRequired(schema, name), schema: get(schema, [PROPERTIES_KEY, name], {}), uiSchema: fieldUiSchema, errorSchema: get(errorSchema, [name]), fieldPathId: childFieldPathId, formData: get(formData, [name]), handleKeyRename: handleKeyRename, handleRemoveProperty: handleRemoveProperty, addedByAdditionalProperties: addedByAdditionalProperties, onChange: onChange, onBlur: onBlur, onFocus: onFocus, registry: registry, disabled: disabled, readonly: readonly, hideError: hideError }, getStableKey(name)));
|
|
27138
27929
|
return {
|
|
27139
27930
|
content,
|
|
27140
27931
|
name,
|
|
@@ -27879,7 +28670,7 @@ function WrapIfAdditionalTemplate(props) {
|
|
|
27879
28670
|
return (jsxRuntimeExports.jsx("div", { className: uiClassNames, style: style, children: children }));
|
|
27880
28671
|
}
|
|
27881
28672
|
const margin = hasDescription ? 46 : 26;
|
|
27882
|
-
return (jsxRuntimeExports.jsx("div", { className: uiClassNames, style: style, children: jsxRuntimeExports.jsxs("div", { className: 'row', children: [jsxRuntimeExports.jsx("div", { className: 'col-xs-5 form-additional', children: jsxRuntimeExports.jsxs("div", { className: 'form-group', children: [displayLabel && jsxRuntimeExports.jsx(Label, { label: keyLabel, required: required, id: `${id}-key` }), displayLabel && rawDescription && jsxRuntimeExports.jsx("div", { children: "\u00A0" }), jsxRuntimeExports.jsx("input", { className: 'form-control', type: 'text', id: `${id}-key`, onBlur: onKeyRenameBlur, defaultValue: label })] }) }), jsxRuntimeExports.jsx("div", { className: 'form-additional form-group col-xs-5', children: children }), jsxRuntimeExports.jsx("div", { className: 'col-xs-2', style: { marginTop: displayLabel ? `${margin}px` : undefined }, children: jsxRuntimeExports.jsx(RemoveButton, { id: buttonId(id, 'remove'), className: 'rjsf-object-property-remove btn-block', style: { border: '0' }, disabled: disabled || readonly, onClick: onRemoveProperty, uiSchema: uiSchema, registry: registry }) })] }) }));
|
|
28673
|
+
return (jsxRuntimeExports.jsx("div", { className: uiClassNames, style: style, children: jsxRuntimeExports.jsxs("div", { className: 'row', children: [jsxRuntimeExports.jsx("div", { className: 'col-xs-5 form-additional', children: jsxRuntimeExports.jsxs("div", { className: 'form-group', children: [displayLabel && jsxRuntimeExports.jsx(Label, { label: keyLabel, required: required, id: `${id}-key` }), displayLabel && rawDescription && jsxRuntimeExports.jsx("div", { children: "\u00A0" }), jsxRuntimeExports.jsx("input", { className: 'form-control', type: 'text', id: `${id}-key`, onBlur: onKeyRenameBlur, defaultValue: label }, label)] }) }), jsxRuntimeExports.jsx("div", { className: 'form-additional form-group col-xs-5', children: children }), jsxRuntimeExports.jsx("div", { className: 'col-xs-2', style: { marginTop: displayLabel ? `${margin}px` : undefined }, children: jsxRuntimeExports.jsx(RemoveButton, { id: buttonId(id, 'remove'), className: 'rjsf-object-property-remove btn-block', style: { border: '0' }, disabled: disabled || readonly, onClick: onRemoveProperty, uiSchema: uiSchema, registry: registry }) })] }) }));
|
|
27883
28674
|
}
|
|
27884
28675
|
|
|
27885
28676
|
function templates() {
|
|
@@ -27952,10 +28743,12 @@ function CheckboxWidget({ schema, uiSchema, options, id, value, disabled, readon
|
|
|
27952
28743
|
*
|
|
27953
28744
|
* @param props - The `WidgetProps` for this component
|
|
27954
28745
|
*/
|
|
27955
|
-
function CheckboxesWidget({ id, disabled, options
|
|
28746
|
+
function CheckboxesWidget({ id, disabled, options, value, autofocus = false, readonly, onChange, onBlur, onFocus, htmlName, }) {
|
|
28747
|
+
const { inline = false, enumOptions, enumDisabled, emptyValue } = options;
|
|
28748
|
+
const optionValueFormat = getOptionValueFormat(options);
|
|
27956
28749
|
const checkboxesValues = Array.isArray(value) ? value : [value];
|
|
27957
|
-
const handleBlur = reactExports.useCallback(({ target }) => onBlur(id,
|
|
27958
|
-
const handleFocus = reactExports.useCallback(({ target }) => onFocus(id,
|
|
28750
|
+
const handleBlur = reactExports.useCallback(({ target }) => onBlur(id, enumOptionValueDecoder(target && target.value, enumOptions, optionValueFormat, emptyValue)), [onBlur, id, enumOptions, emptyValue, optionValueFormat]);
|
|
28751
|
+
const handleFocus = reactExports.useCallback(({ target }) => onFocus(id, enumOptionValueDecoder(target && target.value, enumOptions, optionValueFormat, emptyValue)), [onFocus, id, enumOptions, emptyValue, optionValueFormat]);
|
|
27959
28752
|
return (jsxRuntimeExports.jsx("div", { className: 'checkboxes', id: id, children: Array.isArray(enumOptions) &&
|
|
27960
28753
|
enumOptions.map((option, index) => {
|
|
27961
28754
|
const checked = enumOptionsIsSelected(option.value, checkboxesValues);
|
|
@@ -27969,7 +28762,7 @@ function CheckboxesWidget({ id, disabled, options: { inline = false, enumOptions
|
|
|
27969
28762
|
onChange(enumOptionsDeselectValue(index, checkboxesValues, enumOptions));
|
|
27970
28763
|
}
|
|
27971
28764
|
};
|
|
27972
|
-
const checkbox = (jsxRuntimeExports.jsxs("span", { children: [jsxRuntimeExports.jsx("input", { type: 'checkbox', id: optionId(id, index), name: htmlName || id, checked: checked, value:
|
|
28765
|
+
const checkbox = (jsxRuntimeExports.jsxs("span", { children: [jsxRuntimeExports.jsx("input", { type: 'checkbox', id: optionId(id, index), name: htmlName || id, checked: checked, value: enumOptionValueEncoder(option.value, index, optionValueFormat), disabled: disabled || itemDisabled || readonly, autoFocus: autofocus && index === 0, onChange: handleChange, onBlur: handleBlur, onFocus: handleFocus, "aria-describedby": ariaDescribedByIds(id) }), jsxRuntimeExports.jsx("span", { children: option.label })] }));
|
|
27973
28766
|
return inline ? (jsxRuntimeExports.jsx("label", { className: `checkbox-inline ${disabledCls}`, children: checkbox }, index)) : (jsxRuntimeExports.jsx("div", { className: `checkbox ${disabledCls}`, children: jsxRuntimeExports.jsx("label", { children: checkbox }) }, index));
|
|
27974
28767
|
}) }));
|
|
27975
28768
|
}
|
|
@@ -28087,15 +28880,16 @@ function PasswordWidget(props) {
|
|
|
28087
28880
|
*/
|
|
28088
28881
|
function RadioWidget({ options, value, required, disabled, readonly, autofocus = false, onBlur, onFocus, onChange, id, htmlName, }) {
|
|
28089
28882
|
const { enumOptions, enumDisabled, inline, emptyValue } = options;
|
|
28090
|
-
const
|
|
28091
|
-
const
|
|
28883
|
+
const optionValueFormat = getOptionValueFormat(options);
|
|
28884
|
+
const handleBlur = reactExports.useCallback(({ target }) => onBlur(id, enumOptionValueDecoder(target && target.value, enumOptions, optionValueFormat, emptyValue)), [onBlur, enumOptions, emptyValue, id, optionValueFormat]);
|
|
28885
|
+
const handleFocus = reactExports.useCallback(({ target }) => onFocus(id, enumOptionValueDecoder(target && target.value, enumOptions, optionValueFormat, emptyValue)), [onFocus, enumOptions, emptyValue, id, optionValueFormat]);
|
|
28092
28886
|
return (jsxRuntimeExports.jsx("div", { className: 'field-radio-group', id: id, role: 'radiogroup', children: Array.isArray(enumOptions) &&
|
|
28093
28887
|
enumOptions.map((option, i) => {
|
|
28094
28888
|
const checked = enumOptionsIsSelected(option.value, value);
|
|
28095
28889
|
const itemDisabled = Array.isArray(enumDisabled) && enumDisabled.indexOf(option.value) !== -1;
|
|
28096
28890
|
const disabledCls = disabled || itemDisabled || readonly ? 'disabled' : '';
|
|
28097
28891
|
const handleChange = () => onChange(option.value);
|
|
28098
|
-
const radio = (jsxRuntimeExports.jsxs("span", { children: [jsxRuntimeExports.jsx("input", { type: 'radio', id: optionId(id, i), checked: checked, name: htmlName || id, required: required, value:
|
|
28892
|
+
const radio = (jsxRuntimeExports.jsxs("span", { children: [jsxRuntimeExports.jsx("input", { type: 'radio', id: optionId(id, i), checked: checked, name: htmlName || id, required: required, value: enumOptionValueEncoder(option.value, i, optionValueFormat), disabled: disabled || itemDisabled || readonly, autoFocus: autofocus && i === 0, onChange: handleChange, onBlur: handleBlur, onFocus: handleFocus, "aria-describedby": ariaDescribedByIds(id) }), jsxRuntimeExports.jsx("span", { children: option.label })] }));
|
|
28099
28893
|
return inline ? (jsxRuntimeExports.jsx("label", { className: `radio-inline ${disabledCls}`, children: radio }, i)) : (jsxRuntimeExports.jsx("div", { className: `radio ${disabledCls}`, children: jsxRuntimeExports.jsx("label", { children: radio }) }, i));
|
|
28100
28894
|
}) }));
|
|
28101
28895
|
}
|
|
@@ -28189,24 +28983,25 @@ function getValue(event, multiple) {
|
|
|
28189
28983
|
function SelectWidget({ schema, id, options, value, required, disabled, readonly, multiple = false, autofocus = false, onChange, onBlur, onFocus, placeholder, htmlName, }) {
|
|
28190
28984
|
const { enumOptions, enumDisabled, emptyValue: optEmptyVal } = options;
|
|
28191
28985
|
const emptyValue = multiple ? [] : '';
|
|
28986
|
+
const optionValueFormat = getOptionValueFormat(options);
|
|
28192
28987
|
const handleFocus = reactExports.useCallback((event) => {
|
|
28193
28988
|
const newValue = getValue(event, multiple);
|
|
28194
|
-
return onFocus(id,
|
|
28195
|
-
}, [onFocus, id, multiple, enumOptions, optEmptyVal]);
|
|
28989
|
+
return onFocus(id, enumOptionValueDecoder(newValue, enumOptions, optionValueFormat, optEmptyVal));
|
|
28990
|
+
}, [onFocus, id, multiple, enumOptions, optEmptyVal, optionValueFormat]);
|
|
28196
28991
|
const handleBlur = reactExports.useCallback((event) => {
|
|
28197
28992
|
const newValue = getValue(event, multiple);
|
|
28198
|
-
return onBlur(id,
|
|
28199
|
-
}, [onBlur, id, multiple, enumOptions, optEmptyVal]);
|
|
28993
|
+
return onBlur(id, enumOptionValueDecoder(newValue, enumOptions, optionValueFormat, optEmptyVal));
|
|
28994
|
+
}, [onBlur, id, multiple, enumOptions, optEmptyVal, optionValueFormat]);
|
|
28200
28995
|
const handleChange = reactExports.useCallback((event) => {
|
|
28201
28996
|
const newValue = getValue(event, multiple);
|
|
28202
|
-
return onChange(
|
|
28203
|
-
}, [onChange, multiple, enumOptions, optEmptyVal]);
|
|
28204
|
-
const
|
|
28997
|
+
return onChange(enumOptionValueDecoder(newValue, enumOptions, optionValueFormat, optEmptyVal));
|
|
28998
|
+
}, [onChange, multiple, enumOptions, optEmptyVal, optionValueFormat]);
|
|
28999
|
+
const selectValue = enumOptionSelectedValue(value, enumOptions, multiple, optionValueFormat, emptyValue);
|
|
28205
29000
|
const showPlaceholderOption = !multiple && schema.default === undefined;
|
|
28206
|
-
return (jsxRuntimeExports.jsxs("select", { id: id, name: htmlName || id, multiple: multiple, role: 'combobox', className: 'form-control', value:
|
|
29001
|
+
return (jsxRuntimeExports.jsxs("select", { id: id, name: htmlName || id, multiple: multiple, role: 'combobox', className: 'form-control', value: selectValue, required: required, disabled: disabled || readonly, autoFocus: autofocus, onBlur: handleBlur, onFocus: handleFocus, onChange: handleChange, "aria-describedby": ariaDescribedByIds(id), children: [showPlaceholderOption && jsxRuntimeExports.jsx("option", { value: '', children: placeholder }), Array.isArray(enumOptions) &&
|
|
28207
29002
|
enumOptions.map(({ value, label }, i) => {
|
|
28208
29003
|
const disabled = enumDisabled && enumDisabled.indexOf(value) !== -1;
|
|
28209
|
-
return (jsxRuntimeExports.jsx("option", { value:
|
|
29004
|
+
return (jsxRuntimeExports.jsx("option", { value: enumOptionValueEncoder(value, i, optionValueFormat), disabled: disabled, children: label }, i));
|
|
28210
29005
|
})] }));
|
|
28211
29006
|
}
|
|
28212
29007
|
|
|
@@ -28544,10 +29339,6 @@ let Form$1 = class Form extends reactExports.Component {
|
|
|
28544
29339
|
// Only store a new registry when the props cause a different one to be created
|
|
28545
29340
|
const newRegistry = this.getRegistry(props, rootSchema, schemaUtils);
|
|
28546
29341
|
const registry = deepEquals(state.registry, newRegistry) ? state.registry : newRegistry;
|
|
28547
|
-
// Pre-expand ui:definitions into the uiSchema structure (must happen after registry is created)
|
|
28548
|
-
const expandedUiSchema = registry.uiSchemaDefinitions
|
|
28549
|
-
? expandUiSchemaDefinitions(rootSchema, uiSchema, registry)
|
|
28550
|
-
: uiSchema;
|
|
28551
29342
|
// Only compute a new `fieldPathId` when the `idPrefix` is different than the existing fieldPathId's ID_KEY
|
|
28552
29343
|
const fieldPathId = state.fieldPathId && state.fieldPathId?.[ID_KEY] === registry.globalFormOptions.idPrefix
|
|
28553
29344
|
? state.fieldPathId
|
|
@@ -28555,7 +29346,7 @@ let Form$1 = class Form extends reactExports.Component {
|
|
|
28555
29346
|
const nextState = {
|
|
28556
29347
|
schemaUtils,
|
|
28557
29348
|
schema: rootSchema,
|
|
28558
|
-
uiSchema
|
|
29349
|
+
uiSchema,
|
|
28559
29350
|
fieldPathId,
|
|
28560
29351
|
formData,
|
|
28561
29352
|
edit,
|
|
@@ -28729,9 +29520,13 @@ let Form$1 = class Form extends reactExports.Component {
|
|
|
28729
29520
|
this._isProcessingUserChange = true;
|
|
28730
29521
|
const { newValue, path, id } = this.pendingChanges[0];
|
|
28731
29522
|
const { newErrorSchema } = this.pendingChanges[0];
|
|
28732
|
-
const { extraErrors, omitExtraData, liveOmit, noValidate, liveValidate, onChange } = this.props;
|
|
29523
|
+
const { extraErrors, omitExtraData, liveOmit, noValidate, liveValidate, onChange, removeEmptyOptionalObjects } = this.props;
|
|
28733
29524
|
const { formData: oldFormData, schemaUtils, schema, fieldPathId, schemaValidationErrorSchema, errors } = this.state;
|
|
28734
|
-
let { customErrors
|
|
29525
|
+
let { customErrors } = this.state;
|
|
29526
|
+
// Use the un-merged AJV-only schema as the base for re-merging extraErrors. Mirrors the
|
|
29527
|
+
// pattern in getStateFromProps/getDerivedStateFromProps and avoids the duplication that
|
|
29528
|
+
// happened when state.errorSchema (already containing merged extraErrors) was passed in.
|
|
29529
|
+
let mergeBaseErrorSchema = schemaValidationErrorSchema;
|
|
28735
29530
|
const rootPathId = fieldPathId.path[0] || '';
|
|
28736
29531
|
const isRootPath = !path || path.length === 0 || (path.length === 1 && path[0] === rootPathId);
|
|
28737
29532
|
let retrievedSchema = this.state.retrievedSchema;
|
|
@@ -28768,18 +29563,27 @@ let Form$1 = class Form extends reactExports.Component {
|
|
|
28768
29563
|
formData: newFormData,
|
|
28769
29564
|
};
|
|
28770
29565
|
}
|
|
29566
|
+
if (removeEmptyOptionalObjects) {
|
|
29567
|
+
newFormData = removeOptionalEmptyObjects(schemaUtils.getValidator(), schema, schemaUtils.getRootSchema(), newFormData);
|
|
29568
|
+
state = {
|
|
29569
|
+
...state,
|
|
29570
|
+
formData: newFormData,
|
|
29571
|
+
};
|
|
29572
|
+
}
|
|
28771
29573
|
if (newErrorSchema) {
|
|
28772
29574
|
// First check to see if there is an existing validation error on this path...
|
|
28773
29575
|
// @ts-expect-error TS2590, because getting from the error schema is confusing TS
|
|
28774
29576
|
const oldValidationError = !isRootPath ? get(schemaValidationErrorSchema, path) : schemaValidationErrorSchema;
|
|
28775
29577
|
// If there is an old validation error for this path, assume we are updating it directly
|
|
28776
29578
|
if (!isEmpty(oldValidationError)) {
|
|
28777
|
-
//
|
|
29579
|
+
// Apply the user-supplied newErrorSchema onto a clone of the AJV-only base, so that
|
|
29580
|
+
// mergeErrors below sees the user's error at this path without mutating shared state.
|
|
28778
29581
|
if (!isRootPath) {
|
|
28779
|
-
|
|
29582
|
+
mergeBaseErrorSchema = cloneDeep(schemaValidationErrorSchema);
|
|
29583
|
+
set(mergeBaseErrorSchema, path, newErrorSchema);
|
|
28780
29584
|
}
|
|
28781
29585
|
else {
|
|
28782
|
-
|
|
29586
|
+
mergeBaseErrorSchema = newErrorSchema;
|
|
28783
29587
|
}
|
|
28784
29588
|
}
|
|
28785
29589
|
else {
|
|
@@ -28804,12 +29608,12 @@ let Form$1 = class Form extends reactExports.Component {
|
|
|
28804
29608
|
}
|
|
28805
29609
|
// If there are pending changes in the queue, skip live validation since it will happen with the last change
|
|
28806
29610
|
if (mustValidate && this.pendingChanges.length === 1) {
|
|
28807
|
-
const liveValidation = this.liveValidate(schema, schemaUtils,
|
|
29611
|
+
const liveValidation = this.liveValidate(schema, schemaUtils, mergeBaseErrorSchema, newFormData, extraErrors, customErrors, retrievedSchema);
|
|
28808
29612
|
state = { formData: newFormData, ...liveValidation, customErrors };
|
|
28809
29613
|
}
|
|
28810
29614
|
else if (!noValidate && newErrorSchema) {
|
|
28811
29615
|
// Merging 'newErrorSchema' into 'errorSchema' to display the custom raised errors.
|
|
28812
|
-
const mergedErrors = this.mergeErrors({ errorSchema:
|
|
29616
|
+
const mergedErrors = this.mergeErrors({ errorSchema: mergeBaseErrorSchema, errors }, extraErrors, customErrors);
|
|
28813
29617
|
state = {
|
|
28814
29618
|
formData: newFormData,
|
|
28815
29619
|
...mergedErrors,
|
|
@@ -28868,19 +29672,23 @@ let Form$1 = class Form extends reactExports.Component {
|
|
|
28868
29672
|
* @param data - The data associated with the field that was blurred
|
|
28869
29673
|
*/
|
|
28870
29674
|
onBlur = (id, data) => {
|
|
28871
|
-
const { onBlur, omitExtraData, liveOmit, liveValidate } = this.props;
|
|
29675
|
+
const { onBlur, omitExtraData, liveOmit, liveValidate, removeEmptyOptionalObjects } = this.props;
|
|
28872
29676
|
if (onBlur) {
|
|
28873
29677
|
onBlur(id, data);
|
|
28874
29678
|
}
|
|
28875
29679
|
if ((omitExtraData === true && liveOmit === 'onBlur') || liveValidate === 'onBlur') {
|
|
28876
29680
|
const { onChange, extraErrors } = this.props;
|
|
28877
|
-
const { formData } = this.state;
|
|
29681
|
+
const { formData, schemaUtils, schema } = this.state;
|
|
28878
29682
|
let newFormData = formData;
|
|
28879
29683
|
let state = { formData: newFormData };
|
|
28880
29684
|
if (omitExtraData === true && liveOmit === 'onBlur') {
|
|
28881
29685
|
newFormData = this.omitExtraData(formData);
|
|
28882
29686
|
state = { formData: newFormData };
|
|
28883
29687
|
}
|
|
29688
|
+
if (removeEmptyOptionalObjects) {
|
|
29689
|
+
newFormData = removeOptionalEmptyObjects(schemaUtils.getValidator(), schema, schemaUtils.getRootSchema(), newFormData);
|
|
29690
|
+
state = { ...state, formData: newFormData };
|
|
29691
|
+
}
|
|
28884
29692
|
if (liveValidate === 'onBlur') {
|
|
28885
29693
|
const { schema, schemaUtils, errorSchema, customErrors, retrievedSchema } = this.state;
|
|
28886
29694
|
const liveValidation = this.liveValidate(schema, schemaUtils, errorSchema, newFormData, extraErrors, customErrors, retrievedSchema);
|
|
@@ -28927,11 +29735,15 @@ let Form$1 = class Form extends reactExports.Component {
|
|
|
28927
29735
|
return;
|
|
28928
29736
|
}
|
|
28929
29737
|
event.persist();
|
|
28930
|
-
const { omitExtraData, extraErrors, noValidate, onSubmit } = this.props;
|
|
29738
|
+
const { omitExtraData, extraErrors, noValidate, onSubmit, removeEmptyOptionalObjects } = this.props;
|
|
28931
29739
|
let { formData: newFormData } = this.state;
|
|
28932
29740
|
if (omitExtraData === true) {
|
|
28933
29741
|
newFormData = this.omitExtraData(newFormData);
|
|
28934
29742
|
}
|
|
29743
|
+
if (removeEmptyOptionalObjects) {
|
|
29744
|
+
const { schemaUtils, schema } = this.state;
|
|
29745
|
+
newFormData = removeOptionalEmptyObjects(schemaUtils.getValidator(), schema, schemaUtils.getRootSchema(), newFormData);
|
|
29746
|
+
}
|
|
28935
29747
|
if (noValidate || this.validateFormWithFormData(newFormData)) {
|
|
28936
29748
|
// There are no errors generated through schema validation.
|
|
28937
29749
|
// Check for user provided errors and update state accordingly.
|
|
@@ -29024,8 +29836,9 @@ let Form$1 = class Form extends reactExports.Component {
|
|
|
29024
29836
|
const elementId = path.join(idSeparator);
|
|
29025
29837
|
let field = this.formElement.current.elements[elementId];
|
|
29026
29838
|
if (!field) {
|
|
29027
|
-
// if not an exact match, try finding
|
|
29028
|
-
|
|
29839
|
+
// if not an exact match, try finding a focusable element starting with the element id (like radio buttons or checkboxes)
|
|
29840
|
+
// some themes (e.g. shadcn) use button elements instead of native inputs for radio groups
|
|
29841
|
+
field = this.formElement.current.querySelector(`input[id^="${elementId}"], button[id^="${elementId}"]`);
|
|
29029
29842
|
}
|
|
29030
29843
|
if (field && field.length) {
|
|
29031
29844
|
// If we got a list with length > 0
|
|
@@ -29099,11 +29912,15 @@ let Form$1 = class Form extends reactExports.Component {
|
|
|
29099
29912
|
* @returns - True if the form is valid, false otherwise.
|
|
29100
29913
|
*/
|
|
29101
29914
|
validateForm() {
|
|
29102
|
-
const { omitExtraData } = this.props;
|
|
29915
|
+
const { omitExtraData, removeEmptyOptionalObjects } = this.props;
|
|
29103
29916
|
let { formData: newFormData } = this.state;
|
|
29104
29917
|
if (omitExtraData === true) {
|
|
29105
29918
|
newFormData = this.omitExtraData(newFormData);
|
|
29106
29919
|
}
|
|
29920
|
+
if (removeEmptyOptionalObjects) {
|
|
29921
|
+
const { schemaUtils, schema } = this.state;
|
|
29922
|
+
newFormData = removeOptionalEmptyObjects(schemaUtils.getValidator(), schema, schemaUtils.getRootSchema(), newFormData);
|
|
29923
|
+
}
|
|
29107
29924
|
return this.validateFormWithFormData(newFormData);
|
|
29108
29925
|
}
|
|
29109
29926
|
/** Renders the `Form` fields inside the <form> | `tagName` or `_internalFormWrapper`, rendering any errors if
|
|
@@ -35782,13 +36599,50 @@ function createAjvInstance(additionalMetaSchemas, customFormats, ajvOptionsOverr
|
|
|
35782
36599
|
return ajv;
|
|
35783
36600
|
}
|
|
35784
36601
|
|
|
36602
|
+
/** Filters duplicate errors from `anyOf`/`oneOf` schema paths according to the `suppressDuplicateFiltering` flag.
|
|
36603
|
+
*
|
|
36604
|
+
* @param errorList - The list of `RJSFValidationError`s to filter
|
|
36605
|
+
* @param [suppressDuplicateFiltering='none'] - Controls which duplicate filtering is suppressed:
|
|
36606
|
+
* - `'none'` (default): filters duplicates for both `anyOf` and `oneOf`
|
|
36607
|
+
* - `'all'`: returns `errorList` unmodified
|
|
36608
|
+
* - `'anyOf'`: suppresses filtering for `anyOf` errors; `oneOf` duplicates are still filtered
|
|
36609
|
+
* - `'oneOf'`: suppresses filtering for `oneOf` errors; `anyOf` duplicates are still filtered
|
|
36610
|
+
*/
|
|
36611
|
+
function filterDuplicateErrors(errorList, suppressDuplicateFiltering = 'none') {
|
|
36612
|
+
if (suppressDuplicateFiltering === 'all') {
|
|
36613
|
+
return errorList;
|
|
36614
|
+
}
|
|
36615
|
+
return errorList.reduce((acc, err) => {
|
|
36616
|
+
const { message, schemaPath } = err;
|
|
36617
|
+
// Compute the index only when filtering for that keyword is not suppressed.
|
|
36618
|
+
// 'all' is already handled above; within the reduce, only 'none', 'anyOf', and 'oneOf' are possible.
|
|
36619
|
+
const anyOfIndex = suppressDuplicateFiltering !== 'anyOf' ? schemaPath === null || schemaPath === void 0 ? void 0 : schemaPath.indexOf(`/${ANY_OF_KEY}/`) : undefined;
|
|
36620
|
+
const oneOfIndex = suppressDuplicateFiltering !== 'oneOf' ? schemaPath === null || schemaPath === void 0 ? void 0 : schemaPath.indexOf(`/${ONE_OF_KEY}/`) : undefined;
|
|
36621
|
+
let schemaPrefix;
|
|
36622
|
+
if (anyOfIndex && anyOfIndex >= 0) {
|
|
36623
|
+
schemaPrefix = schemaPath === null || schemaPath === void 0 ? void 0 : schemaPath.substring(0, anyOfIndex);
|
|
36624
|
+
}
|
|
36625
|
+
else if (oneOfIndex && oneOfIndex >= 0) {
|
|
36626
|
+
schemaPrefix = schemaPath === null || schemaPath === void 0 ? void 0 : schemaPath.substring(0, oneOfIndex);
|
|
36627
|
+
}
|
|
36628
|
+
// If there is a schemaPrefix, then search for a duplicate message with the same prefix, otherwise undefined
|
|
36629
|
+
const dup = schemaPrefix
|
|
36630
|
+
? acc.find((e) => { var _a; return e.message === message && ((_a = e.schemaPath) === null || _a === void 0 ? void 0 : _a.startsWith(schemaPrefix)); })
|
|
36631
|
+
: undefined;
|
|
36632
|
+
if (!dup) {
|
|
36633
|
+
acc.push(err);
|
|
36634
|
+
}
|
|
36635
|
+
return acc;
|
|
36636
|
+
}, []);
|
|
36637
|
+
}
|
|
35785
36638
|
/** Transforming the error output from ajv to format used by @rjsf/utils.
|
|
35786
36639
|
* At some point, components should be updated to support ajv.
|
|
35787
36640
|
*
|
|
35788
36641
|
* @param errors - The list of AJV errors to convert to `RJSFValidationErrors`
|
|
35789
36642
|
* @param [uiSchema] - An optional uiSchema that is passed to `transformErrors` and `customValidate`
|
|
36643
|
+
* @param [suppressDuplicateFiltering] - Controls which duplicate filtering is suppressed; see `filterDuplicateErrors`
|
|
35790
36644
|
*/
|
|
35791
|
-
function transformRJSFValidationErrors(errors = [], uiSchema) {
|
|
36645
|
+
function transformRJSFValidationErrors(errors = [], uiSchema, suppressDuplicateFiltering) {
|
|
35792
36646
|
const errorList = errors.map((e) => {
|
|
35793
36647
|
var _a;
|
|
35794
36648
|
const { instancePath, keyword, params, schemaPath, parentSchema, ...rest } = e;
|
|
@@ -35858,29 +36712,7 @@ function transformRJSFValidationErrors(errors = [], uiSchema) {
|
|
|
35858
36712
|
title: uiTitle,
|
|
35859
36713
|
};
|
|
35860
36714
|
});
|
|
35861
|
-
|
|
35862
|
-
return errorList.reduce((acc, err) => {
|
|
35863
|
-
const { message, schemaPath } = err;
|
|
35864
|
-
const anyOfIndex = schemaPath === null || schemaPath === void 0 ? void 0 : schemaPath.indexOf(`/${ANY_OF_KEY}/`);
|
|
35865
|
-
const oneOfIndex = schemaPath === null || schemaPath === void 0 ? void 0 : schemaPath.indexOf(`/${ONE_OF_KEY}/`);
|
|
35866
|
-
let schemaPrefix;
|
|
35867
|
-
// Look specifically for `/anyOr/` or `/oneOf/` within the schemaPath information
|
|
35868
|
-
if (anyOfIndex && anyOfIndex >= 0) {
|
|
35869
|
-
schemaPrefix = schemaPath === null || schemaPath === void 0 ? void 0 : schemaPath.substring(0, anyOfIndex);
|
|
35870
|
-
}
|
|
35871
|
-
else if (oneOfIndex && oneOfIndex >= 0) {
|
|
35872
|
-
schemaPrefix = schemaPath === null || schemaPath === void 0 ? void 0 : schemaPath.substring(0, oneOfIndex);
|
|
35873
|
-
}
|
|
35874
|
-
// If there is a schemaPrefix, then search for a duplicate message with the same prefix, otherwise undefined
|
|
35875
|
-
const dup = schemaPrefix
|
|
35876
|
-
? acc.find((e) => { var _a; return e.message === message && ((_a = e.schemaPath) === null || _a === void 0 ? void 0 : _a.startsWith(schemaPrefix)); })
|
|
35877
|
-
: undefined;
|
|
35878
|
-
if (!dup) {
|
|
35879
|
-
// Only push an error that is not a duplicate
|
|
35880
|
-
acc.push(err);
|
|
35881
|
-
}
|
|
35882
|
-
return acc;
|
|
35883
|
-
}, []);
|
|
36715
|
+
return filterDuplicateErrors(errorList, suppressDuplicateFiltering);
|
|
35884
36716
|
}
|
|
35885
36717
|
/** This function processes the `formData` with an optional user contributed `customValidate` function, which receives
|
|
35886
36718
|
* the form data and a `errorHandler` function that will be used to add custom validation errors for each field. Also
|
|
@@ -35894,10 +36726,11 @@ function transformRJSFValidationErrors(errors = [], uiSchema) {
|
|
|
35894
36726
|
* @param [customValidate] - An optional function that is used to perform custom validation
|
|
35895
36727
|
* @param [transformErrors] - An optional function that is used to transform errors after AJV validation
|
|
35896
36728
|
* @param [uiSchema] - An optional uiSchema that is passed to `transformErrors` and `customValidate`
|
|
36729
|
+
* @param [suppressDuplicateFiltering] - Controls which duplicate filtering is suppressed; see `filterDuplicateErrors`
|
|
35897
36730
|
*/
|
|
35898
|
-
function processRawValidationErrors(validator, rawErrors, formData, schema, customValidate, transformErrors, uiSchema) {
|
|
36731
|
+
function processRawValidationErrors(validator, rawErrors, formData, schema, customValidate, transformErrors, uiSchema, suppressDuplicateFiltering) {
|
|
35899
36732
|
const { validationError: invalidSchemaError } = rawErrors;
|
|
35900
|
-
let errors = transformRJSFValidationErrors(rawErrors.errors, uiSchema);
|
|
36733
|
+
let errors = transformRJSFValidationErrors(rawErrors.errors, uiSchema, suppressDuplicateFiltering);
|
|
35901
36734
|
if (invalidSchemaError) {
|
|
35902
36735
|
errors = [...errors, { stack: invalidSchemaError.message }];
|
|
35903
36736
|
}
|
|
@@ -35932,14 +36765,22 @@ class AJV8Validator {
|
|
|
35932
36765
|
* @param [localizer] - If provided, is used to localize a list of Ajv `ErrorObject`s
|
|
35933
36766
|
*/
|
|
35934
36767
|
constructor(options, localizer) {
|
|
35935
|
-
|
|
36768
|
+
/** True once a `rootSchema` has been registered with Ajv in this lifecycle.
|
|
36769
|
+
*
|
|
36770
|
+
* @private
|
|
36771
|
+
*/
|
|
36772
|
+
this.hasRegisteredRootSchema = false;
|
|
36773
|
+
const { additionalMetaSchemas, customFormats, ajvOptionsOverrides, ajvFormatOptions, AjvClass, extenderFn, suppressDuplicateFiltering, } = options;
|
|
35936
36774
|
this.ajv = createAjvInstance(additionalMetaSchemas, customFormats, ajvOptionsOverrides, ajvFormatOptions, AjvClass, extenderFn);
|
|
35937
36775
|
this.localizer = localizer;
|
|
36776
|
+
this.suppressDuplicateFiltering = suppressDuplicateFiltering;
|
|
35938
36777
|
}
|
|
35939
36778
|
/** Resets the internal AJV validator to clear schemas from it. Can be helpful for resetting the validator for tests.
|
|
35940
36779
|
*/
|
|
35941
36780
|
reset() {
|
|
35942
36781
|
this.ajv.removeSchema();
|
|
36782
|
+
this.lastSeenRootSchema = undefined;
|
|
36783
|
+
this.hasRegisteredRootSchema = false;
|
|
35943
36784
|
}
|
|
35944
36785
|
/** Runs the pure validation of the `schema` and `formData` without any of the RJSF functionality. Provided for use
|
|
35945
36786
|
* by the playground. Returns the `errors` from the validation
|
|
@@ -36027,14 +36868,19 @@ class AJV8Validator {
|
|
|
36027
36868
|
*/
|
|
36028
36869
|
validateFormData(formData, schema, customValidate, transformErrors, uiSchema) {
|
|
36029
36870
|
const rawErrors = this.rawValidation(schema, formData);
|
|
36030
|
-
return processRawValidationErrors(this, rawErrors, formData, schema, customValidate, transformErrors, uiSchema);
|
|
36871
|
+
return processRawValidationErrors(this, rawErrors, formData, schema, customValidate, transformErrors, uiSchema, this.suppressDuplicateFiltering);
|
|
36031
36872
|
}
|
|
36032
36873
|
/**
|
|
36033
36874
|
* This function checks if a schema needs to be added and if the root schemas don't match it removes the old root schema from the ajv instance and adds the new one.
|
|
36875
|
+
* When called repeatedly with the same `rootSchema` reference the deep-equality check is skipped.
|
|
36876
|
+
*
|
|
36034
36877
|
* @param rootSchema - The root schema used to provide $ref resolutions
|
|
36035
36878
|
*/
|
|
36036
36879
|
handleSchemaUpdate(rootSchema) {
|
|
36037
36880
|
var _a, _b;
|
|
36881
|
+
if (this.lastSeenRootSchema === rootSchema && this.hasRegisteredRootSchema) {
|
|
36882
|
+
return;
|
|
36883
|
+
}
|
|
36038
36884
|
const rootSchemaId = (_a = rootSchema[ID_KEY]) !== null && _a !== void 0 ? _a : ROOT_SCHEMA_PREFIX;
|
|
36039
36885
|
// add the rootSchema ROOT_SCHEMA_PREFIX as id.
|
|
36040
36886
|
// if schema validator instance doesn't exist, add it.
|
|
@@ -36046,6 +36892,8 @@ class AJV8Validator {
|
|
|
36046
36892
|
this.ajv.removeSchema(rootSchemaId);
|
|
36047
36893
|
this.ajv.addSchema(rootSchema, rootSchemaId);
|
|
36048
36894
|
}
|
|
36895
|
+
this.lastSeenRootSchema = rootSchema;
|
|
36896
|
+
this.hasRegisteredRootSchema = true;
|
|
36049
36897
|
}
|
|
36050
36898
|
/** Validates data against a schema, returning true if the data is valid, or
|
|
36051
36899
|
* false otherwise. If the schema is invalid, then this function will return
|