@abgov/jsonforms-components 2.70.3 → 2.71.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/index.esm.js CHANGED
@@ -6,7 +6,8 @@ import axios from 'axios';
6
6
  import get$1 from 'lodash/get';
7
7
  import { toDataPath, INIT, UPDATE_CORE, isVisible, isEnabled, deriveLabelForUISchemaElement, rankWith, isStringControl, and, optionIs, isDateControl, isNumberControl, isIntegerControl, isDateTimeControl, isTimeControl, uiTypeIs, isControl as isControl$1, isEnumControl, or, isOneOfEnumControl, isBooleanControl, createDefaultValue, Paths, Resolve, schemaTypeIs, formatIs, getAjv, schemaMatches, isObjectArrayControl, isPrimitiveArrayControl, composePaths, hasType, isCategorization, isLayout } from '@jsonforms/core';
8
8
  import * as _$c from 'lodash';
9
- import ___default, { isEmpty, isObject as isObject$i } from 'lodash';
9
+ import ___default, { isEqual as isEqual$1, isEmpty, isObject as isObject$i } from 'lodash';
10
+ import isEqual from 'lodash/isEqual';
10
11
  import { useJsonForms, withJsonFormsControlProps, withJsonFormsEnumProps, withTranslateProps, JsonFormsDispatch, withJsonFormsAllOfProps, withJsonFormsArrayLayoutProps, withJsonFormsLayoutProps, withJsonFormsCellProps } from '@jsonforms/react';
11
12
  import dompurify from 'dompurify';
12
13
  import * as xss from 'xss';
@@ -6811,20 +6812,192 @@ $$f({ target: 'Array', proto: true, forced: FORCED$3 }, {
6811
6812
  }
6812
6813
  });
6813
6814
 
6815
+ var tryToString = tryToString$5;
6816
+
6817
+ var $TypeError$1 = TypeError;
6818
+
6819
+ var deletePropertyOrThrow$2 = function (O, P) {
6820
+ if (!delete O[P]) throw new $TypeError$1('Cannot delete property ' + tryToString(P) + ' of ' + tryToString(O));
6821
+ };
6822
+
6823
+ var arraySlice$1 = arraySlice$4;
6824
+
6825
+ var floor$2 = Math.floor;
6826
+
6827
+ var sort = function (array, comparefn) {
6828
+ var length = array.length;
6829
+
6830
+ if (length < 8) {
6831
+ // insertion sort
6832
+ var i = 1;
6833
+ var element, j;
6834
+
6835
+ while (i < length) {
6836
+ j = i;
6837
+ element = array[i];
6838
+ while (j && comparefn(array[j - 1], element) > 0) {
6839
+ array[j] = array[--j];
6840
+ }
6841
+ if (j !== i++) array[j] = element;
6842
+ }
6843
+ } else {
6844
+ // merge sort
6845
+ var middle = floor$2(length / 2);
6846
+ var left = sort(arraySlice$1(array, 0, middle), comparefn);
6847
+ var right = sort(arraySlice$1(array, middle), comparefn);
6848
+ var llength = left.length;
6849
+ var rlength = right.length;
6850
+ var lindex = 0;
6851
+ var rindex = 0;
6852
+
6853
+ while (lindex < llength || rindex < rlength) {
6854
+ array[lindex + rindex] = (lindex < llength && rindex < rlength)
6855
+ ? comparefn(left[lindex], right[rindex]) <= 0 ? left[lindex++] : right[rindex++]
6856
+ : lindex < llength ? left[lindex++] : right[rindex++];
6857
+ }
6858
+ }
6859
+
6860
+ return array;
6861
+ };
6862
+
6863
+ var arraySort$1 = sort;
6864
+
6865
+ var userAgent$2 = engineUserAgent;
6866
+
6867
+ var firefox = userAgent$2.match(/firefox\/(\d+)/i);
6868
+
6869
+ var engineFfVersion = !!firefox && +firefox[1];
6870
+
6871
+ var UA = engineUserAgent;
6872
+
6873
+ var engineIsIeOrEdge = /MSIE|Trident/.test(UA);
6874
+
6875
+ var userAgent$1 = engineUserAgent;
6876
+
6877
+ var webkit = userAgent$1.match(/AppleWebKit\/(\d+)\./);
6878
+
6879
+ var engineWebkitVersion = !!webkit && +webkit[1];
6880
+
6814
6881
  var $$e = _export;
6815
- var iterate$1 = iterate$a;
6882
+ var uncurryThis$d = functionUncurryThis;
6816
6883
  var aCallable$3 = aCallable$k;
6884
+ var toObject$4 = toObject$c;
6885
+ var lengthOfArrayLike$6 = lengthOfArrayLike$c;
6886
+ var deletePropertyOrThrow$1 = deletePropertyOrThrow$2;
6887
+ var toString$b = toString$n;
6888
+ var fails$4 = fails$y;
6889
+ var internalSort = arraySort$1;
6890
+ var arrayMethodIsStrict = arrayMethodIsStrict$2;
6891
+ var FF = engineFfVersion;
6892
+ var IE_OR_EDGE = engineIsIeOrEdge;
6893
+ var V8 = engineV8Version;
6894
+ var WEBKIT = engineWebkitVersion;
6895
+
6896
+ var test = [];
6897
+ var nativeSort = uncurryThis$d(test.sort);
6898
+ var push$6 = uncurryThis$d(test.push);
6899
+
6900
+ // IE8-
6901
+ var FAILS_ON_UNDEFINED = fails$4(function () {
6902
+ test.sort(undefined);
6903
+ });
6904
+ // V8 bug
6905
+ var FAILS_ON_NULL = fails$4(function () {
6906
+ test.sort(null);
6907
+ });
6908
+ // Old WebKit
6909
+ var STRICT_METHOD = arrayMethodIsStrict('sort');
6910
+
6911
+ var STABLE_SORT = !fails$4(function () {
6912
+ // feature detection can be too slow, so check engines versions
6913
+ if (V8) return V8 < 70;
6914
+ if (FF && FF > 3) return;
6915
+ if (IE_OR_EDGE) return true;
6916
+ if (WEBKIT) return WEBKIT < 603;
6917
+
6918
+ var result = '';
6919
+ var code, chr, value, index;
6920
+
6921
+ // generate an array with more 512 elements (Chakra and old V8 fails only in this case)
6922
+ for (code = 65; code < 76; code++) {
6923
+ chr = String.fromCharCode(code);
6924
+
6925
+ switch (code) {
6926
+ case 66: case 69: case 70: case 72: value = 3; break;
6927
+ case 68: case 71: value = 4; break;
6928
+ default: value = 2;
6929
+ }
6930
+
6931
+ for (index = 0; index < 47; index++) {
6932
+ test.push({ k: chr + index, v: value });
6933
+ }
6934
+ }
6935
+
6936
+ test.sort(function (a, b) { return b.v - a.v; });
6937
+
6938
+ for (index = 0; index < test.length; index++) {
6939
+ chr = test[index].k.charAt(0);
6940
+ if (result.charAt(result.length - 1) !== chr) result += chr;
6941
+ }
6942
+
6943
+ return result !== 'DGBEFHACIJK';
6944
+ });
6945
+
6946
+ var FORCED$2 = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || !STRICT_METHOD || !STABLE_SORT;
6947
+
6948
+ var getSortCompare = function (comparefn) {
6949
+ return function (x, y) {
6950
+ if (y === undefined) return -1;
6951
+ if (x === undefined) return 1;
6952
+ if (comparefn !== undefined) return +comparefn(x, y) || 0;
6953
+ return toString$b(x) > toString$b(y) ? 1 : -1;
6954
+ };
6955
+ };
6956
+
6957
+ // `Array.prototype.sort` method
6958
+ // https://tc39.es/ecma262/#sec-array.prototype.sort
6959
+ $$e({ target: 'Array', proto: true, forced: FORCED$2 }, {
6960
+ sort: function sort(comparefn) {
6961
+ if (comparefn !== undefined) aCallable$3(comparefn);
6962
+
6963
+ var array = toObject$4(this);
6964
+
6965
+ if (STABLE_SORT) return comparefn === undefined ? nativeSort(array) : nativeSort(array, comparefn);
6966
+
6967
+ var items = [];
6968
+ var arrayLength = lengthOfArrayLike$6(array);
6969
+ var itemsLength, index;
6970
+
6971
+ for (index = 0; index < arrayLength; index++) {
6972
+ if (index in array) push$6(items, array[index]);
6973
+ }
6974
+
6975
+ internalSort(items, getSortCompare(comparefn));
6976
+
6977
+ itemsLength = lengthOfArrayLike$6(items);
6978
+ index = 0;
6979
+
6980
+ while (index < itemsLength) array[index] = items[index++];
6981
+ while (index < arrayLength) deletePropertyOrThrow$1(array, index++);
6982
+
6983
+ return array;
6984
+ }
6985
+ });
6986
+
6987
+ var $$d = _export;
6988
+ var iterate$1 = iterate$a;
6989
+ var aCallable$2 = aCallable$k;
6817
6990
  var anObject$5 = anObject$t;
6818
6991
  var getIteratorDirect$2 = getIteratorDirect$a;
6819
6992
 
6820
- var $TypeError$1 = TypeError;
6993
+ var $TypeError = TypeError;
6821
6994
 
6822
6995
  // `Iterator.prototype.reduce` method
6823
6996
  // https://github.com/tc39/proposal-iterator-helpers
6824
- $$e({ target: 'Iterator', proto: true, real: true }, {
6997
+ $$d({ target: 'Iterator', proto: true, real: true }, {
6825
6998
  reduce: function reduce(reducer /* , initialValue */) {
6826
6999
  anObject$5(this);
6827
- aCallable$3(reducer);
7000
+ aCallable$2(reducer);
6828
7001
  var record = getIteratorDirect$2(this);
6829
7002
  var noInitial = arguments.length < 2;
6830
7003
  var accumulator = noInitial ? undefined : arguments[1];
@@ -6838,7 +7011,7 @@ $$e({ target: 'Iterator', proto: true, real: true }, {
6838
7011
  }
6839
7012
  counter++;
6840
7013
  }, { IS_RECORD: true });
6841
- if (noInitial) throw new $TypeError$1('Reduce of empty iterator with no initial value');
7014
+ if (noInitial) throw new $TypeError('Reduce of empty iterator with no initial value');
6842
7015
  return accumulator;
6843
7016
  }
6844
7017
  });
@@ -6869,15 +7042,15 @@ const pickPropertyValues = (obj, property, endWithType) => {
6869
7042
  return values;
6870
7043
  };
6871
7044
 
6872
- var uncurryThis$d = functionUncurryThis;
7045
+ var uncurryThis$c = functionUncurryThis;
6873
7046
  var hasOwn$4 = hasOwnProperty_1;
6874
7047
 
6875
7048
  var $SyntaxError = SyntaxError;
6876
7049
  var $parseInt$2 = parseInt;
6877
7050
  var fromCharCode$1 = String.fromCharCode;
6878
- var at$1 = uncurryThis$d(''.charAt);
6879
- var slice$2 = uncurryThis$d(''.slice);
6880
- var exec$4 = uncurryThis$d(/./.exec);
7051
+ var at$1 = uncurryThis$c(''.charAt);
7052
+ var slice$2 = uncurryThis$c(''.slice);
7053
+ var exec$4 = uncurryThis$c(/./.exec);
6881
7054
 
6882
7055
  var codePoints = {
6883
7056
  '\\"': '"',
@@ -6925,20 +7098,20 @@ var parseJsonString = function (source, i) {
6925
7098
  return { value: value, end: i };
6926
7099
  };
6927
7100
 
6928
- var $$d = _export;
7101
+ var $$c = _export;
6929
7102
  var DESCRIPTORS$5 = descriptors;
6930
7103
  var global$5 = global$t;
6931
7104
  var getBuiltIn = getBuiltIn$b;
6932
- var uncurryThis$c = functionUncurryThis;
7105
+ var uncurryThis$b = functionUncurryThis;
6933
7106
  var call$7 = functionCall;
6934
7107
  var isCallable$2 = isCallable$t;
6935
7108
  var isObject$2 = isObject$h;
6936
7109
  var isArray$2 = isArray$5;
6937
7110
  var hasOwn$3 = hasOwnProperty_1;
6938
- var toString$b = toString$n;
6939
- var lengthOfArrayLike$6 = lengthOfArrayLike$c;
7111
+ var toString$a = toString$n;
7112
+ var lengthOfArrayLike$5 = lengthOfArrayLike$c;
6940
7113
  var createProperty$2 = createProperty$4;
6941
- var fails$4 = fails$y;
7114
+ var fails$3 = fails$y;
6942
7115
  var parseJSONString = parseJsonString;
6943
7116
  var NATIVE_SYMBOL$1 = symbolConstructorDetection;
6944
7117
 
@@ -6949,10 +7122,10 @@ var nativeParse = JSON$1 && JSON$1.parse;
6949
7122
  var enumerableOwnProperties = getBuiltIn('Object', 'keys');
6950
7123
  // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
6951
7124
  var getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor;
6952
- var at = uncurryThis$c(''.charAt);
6953
- var slice$1 = uncurryThis$c(''.slice);
6954
- var exec$3 = uncurryThis$c(/./.exec);
6955
- var push$6 = uncurryThis$c([].push);
7125
+ var at = uncurryThis$b(''.charAt);
7126
+ var slice$1 = uncurryThis$b(''.slice);
7127
+ var exec$3 = uncurryThis$b(/./.exec);
7128
+ var push$5 = uncurryThis$b([].push);
6956
7129
 
6957
7130
  var IS_DIGIT = /^\d$/;
6958
7131
  var IS_NON_ZERO_DIGIT = /^[1-9]$/;
@@ -6963,7 +7136,7 @@ var PRIMITIVE = 0;
6963
7136
  var OBJECT = 1;
6964
7137
 
6965
7138
  var $parse = function (source, reviver) {
6966
- source = toString$b(source);
7139
+ source = toString$a(source);
6967
7140
  var context = new Context(source, 0);
6968
7141
  var root = context.parse();
6969
7142
  var value = root.value;
@@ -6984,13 +7157,13 @@ var internalize = function (holder, name, reviver, node) {
6984
7157
  var nodes = unmodified ? node.nodes : nodeIsArray ? [] : {};
6985
7158
  if (nodeIsArray) {
6986
7159
  elementRecordsLen = nodes.length;
6987
- len = lengthOfArrayLike$6(val);
7160
+ len = lengthOfArrayLike$5(val);
6988
7161
  for (i = 0; i < len; i++) {
6989
7162
  internalizeProperty(val, i, internalize(val, '' + i, reviver, i < elementRecordsLen ? nodes[i] : undefined));
6990
7163
  }
6991
7164
  } else {
6992
7165
  keys = enumerableOwnProperties(val);
6993
- len = lengthOfArrayLike$6(keys);
7166
+ len = lengthOfArrayLike$5(keys);
6994
7167
  for (i = 0; i < len; i++) {
6995
7168
  P = keys[i];
6996
7169
  internalizeProperty(val, P, internalize(val, P, reviver, hasOwn$3(nodes, P) ? nodes[P] : undefined));
@@ -7097,8 +7270,8 @@ Context.prototype = {
7097
7270
  break;
7098
7271
  }
7099
7272
  var result = this.fork(i).parse();
7100
- push$6(nodes, result);
7101
- push$6(array, result.value);
7273
+ push$5(nodes, result);
7274
+ push$5(array, result.value);
7102
7275
  i = this.until([',', ']'], result.end);
7103
7276
  if (at(source, i) === ',') {
7104
7277
  expectElement = true;
@@ -7153,7 +7326,7 @@ Context.prototype = {
7153
7326
  }
7154
7327
  };
7155
7328
 
7156
- var NO_SOURCE_SUPPORT = fails$4(function () {
7329
+ var NO_SOURCE_SUPPORT = fails$3(function () {
7157
7330
  var unsafeInt = '9007199254740993';
7158
7331
  var source;
7159
7332
  nativeParse(unsafeInt, function (key, value, context) {
@@ -7162,7 +7335,7 @@ var NO_SOURCE_SUPPORT = fails$4(function () {
7162
7335
  return source !== unsafeInt;
7163
7336
  });
7164
7337
 
7165
- var PROPER_BASE_PARSE = NATIVE_SYMBOL$1 && !fails$4(function () {
7338
+ var PROPER_BASE_PARSE = NATIVE_SYMBOL$1 && !fails$3(function () {
7166
7339
  // Safari 9 bug
7167
7340
  return 1 / nativeParse('-0 \t') !== -Infinity;
7168
7341
  });
@@ -7170,7 +7343,7 @@ var PROPER_BASE_PARSE = NATIVE_SYMBOL$1 && !fails$4(function () {
7170
7343
  // `JSON.parse` method
7171
7344
  // https://tc39.es/ecma262/#sec-json.parse
7172
7345
  // https://github.com/tc39/proposal-json-parse-with-source
7173
- $$d({ target: 'JSON', stat: true, forced: NO_SOURCE_SUPPORT }, {
7346
+ $$c({ target: 'JSON', stat: true, forced: NO_SOURCE_SUPPORT }, {
7174
7347
  parse: function parse(text, reviver) {
7175
7348
  return PROPER_BASE_PARSE && !isCallable$2(reviver) ? nativeParse(text) : $parse(text, reviver);
7176
7349
  }
@@ -7343,6 +7516,9 @@ function anyRequiredFieldEmpty(scopes, data, required, schema) {
7343
7516
  }
7344
7517
  return false;
7345
7518
  }
7519
+ // Auto-populate targets reach us either as schema scopes (#/properties/firstName) or as the data
7520
+ // paths toDataPath produces (firstName). Normalize both to the dot form used for value lookups.
7521
+ const toNormalizedPath = pathOrScope => pathOrScope != null && pathOrScope.startsWith('#/') ? normalizeSchemaPath(pathOrScope) : pathOrScope || '';
7346
7522
  function getStepStatus(opts) {
7347
7523
  const {
7348
7524
  scopes,
@@ -7350,7 +7526,8 @@ function getStepStatus(opts) {
7350
7526
  schema,
7351
7527
  data,
7352
7528
  visited,
7353
- autoPopulatedScopes = []
7529
+ autoPopulatedScopes = [],
7530
+ autoPopulatedValues = []
7354
7531
  } = opts;
7355
7532
  const normalizedScopes = scopes.map(normalizeSchemaPath).filter(Boolean);
7356
7533
  const requiredForScopes = getRequiredForScopes(scopes, schema);
@@ -7359,9 +7536,32 @@ function getStepStatus(opts) {
7359
7536
  // Auto-populated values (system-filled from the user profile) are excluded, so:
7360
7537
  // - a page the user has never opened is NotStarted even when auto-populated, and
7361
7538
  // - a saved form the user actually filled still shows its status when resumed.
7362
- const autoPopulatedSet = new Set(autoPopulatedScopes.map(normalizeSchemaPath).filter(Boolean));
7539
+ const autoPopulatedSet = new Set(autoPopulatedScopes.map(toNormalizedPath).filter(Boolean));
7540
+ const autoPopulatedValueByPath = new Map();
7541
+ autoPopulatedValues.forEach(({
7542
+ path,
7543
+ value
7544
+ }) => {
7545
+ const normalized = toNormalizedPath(path);
7546
+ if (normalized) {
7547
+ autoPopulatedSet.add(normalized);
7548
+ autoPopulatedValueByPath.set(normalized, value);
7549
+ }
7550
+ });
7551
+ // Still system-filled only while the value matches what auto-populate would write. Without a
7552
+ // known value we can't tell an edit from the original, so assume it is untouched.
7553
+ const isStillAutoPopulated = path => {
7554
+ if (!autoPopulatedValueByPath.has(path)) {
7555
+ return true;
7556
+ }
7557
+ return isEqual(get$1(data || {}, path), autoPopulatedValueByPath.get(path));
7558
+ };
7559
+ // Editing or clearing an auto-populated field is user activity in its own right, even when what
7560
+ // is left behind is empty — otherwise clearing a pre-filled field would send the step back to
7561
+ // NotStarted.
7562
+ const userEditedAutoPopulated = normalizedScopes.some(path => autoPopulatedSet.has(path) && !isStillAutoPopulated(path));
7363
7563
  const userDataScopes = normalizedScopes.filter(path => !autoPopulatedSet.has(path));
7364
- const stepHasUserData = userDataScopes.length > 0 ? userDataScopes.some(path => hasMeaningfulValue(get$1(data || {}, path))) : false;
7564
+ const stepHasUserData = userDataScopes.some(path => hasMeaningfulValue(get$1(data || {}, path))) || userEditedAutoPopulated;
7365
7565
  const started = (visited != null ? visited : false) || stepHasUserData;
7366
7566
  if (!started) {
7367
7567
  return {
@@ -7499,6 +7699,37 @@ function getIncompletePaths(errors, scopePaths) {
7499
7699
  const getLocalStorageKeyPrefix = () => {
7500
7700
  return window.location.href + '_' + new Date().toISOString().slice(0, 10);
7501
7701
  };
7702
+ // Steps the user has opened, persisted per form so the status survives a resume.
7703
+ //
7704
+ // Whether a step was opened cannot be recovered from the form data: a user who edits an
7705
+ // auto-populated field and then puts the original value back leaves data identical to the
7706
+ // untouched case. The visit has to be recorded when it happens, or it is lost.
7707
+ //
7708
+ // Deliberately keyed on the form id rather than the URL+date used by the cacheStatus cache above,
7709
+ // so resuming a draft tomorrow — or from a different route to the same form — still restores it.
7710
+ const getVisitedStepsKey = formId => `adsp.form.${formId}.visitedSteps`;
7711
+ const saveVisitedSteps = (formId, ids) => {
7712
+ if (!formId) return;
7713
+ try {
7714
+ localStorage.setItem(getVisitedStepsKey(formId), JSON.stringify(ids));
7715
+ } catch (err) {
7716
+ // Private browsing and full quotas both throw here. Losing the cache only costs the user the
7717
+ // restored status on resume, so it must never take the form down with it.
7718
+ console.warn(`Could not persist visited steps: ${err}`);
7719
+ }
7720
+ };
7721
+ const getVisitedSteps = formId => {
7722
+ if (!formId) return undefined;
7723
+ try {
7724
+ const value = localStorage.getItem(getVisitedStepsKey(formId));
7725
+ if (!value || !isJson(value)) return undefined;
7726
+ const parsed = JSON.parse(value);
7727
+ return Array.isArray(parsed) ? parsed.filter(id => typeof id === 'number') : undefined;
7728
+ } catch (err) {
7729
+ console.warn(`Could not read visited steps: ${err}`);
7730
+ return undefined;
7731
+ }
7732
+ };
7502
7733
  function isJson(str) {
7503
7734
  try {
7504
7735
  JSON.parse(str);
@@ -7670,7 +7901,7 @@ const stepperReducer = (state, action) => {
7670
7901
  };
7671
7902
 
7672
7903
  var isArray$1 = isArray$5;
7673
- var lengthOfArrayLike$5 = lengthOfArrayLike$c;
7904
+ var lengthOfArrayLike$4 = lengthOfArrayLike$c;
7674
7905
  var doesNotExceedSafeInteger$1 = doesNotExceedSafeInteger$3;
7675
7906
  var bind$3 = functionBindContext;
7676
7907
 
@@ -7687,7 +7918,7 @@ var flattenIntoArray$2 = function (target, original, source, sourceLen, start, d
7687
7918
  element = mapFn ? mapFn(source[sourceIndex], sourceIndex, original) : source[sourceIndex];
7688
7919
 
7689
7920
  if (depth > 0 && isArray$1(element)) {
7690
- elementLen = lengthOfArrayLike$5(element);
7921
+ elementLen = lengthOfArrayLike$4(element);
7691
7922
  targetIndex = flattenIntoArray$2(target, original, element, elementLen, targetIndex, depth - 1) - 1;
7692
7923
  } else {
7693
7924
  doesNotExceedSafeInteger$1(targetIndex + 1);
@@ -7734,21 +7965,21 @@ var arraySpeciesCreate$2 = function (originalArray, length) {
7734
7965
  return new (arraySpeciesConstructor(originalArray))(length === 0 ? 0 : length);
7735
7966
  };
7736
7967
 
7737
- var $$c = _export;
7968
+ var $$b = _export;
7738
7969
  var flattenIntoArray$1 = flattenIntoArray_1;
7739
- var aCallable$2 = aCallable$k;
7740
- var toObject$4 = toObject$c;
7741
- var lengthOfArrayLike$4 = lengthOfArrayLike$c;
7970
+ var aCallable$1 = aCallable$k;
7971
+ var toObject$3 = toObject$c;
7972
+ var lengthOfArrayLike$3 = lengthOfArrayLike$c;
7742
7973
  var arraySpeciesCreate$1 = arraySpeciesCreate$2;
7743
7974
 
7744
7975
  // `Array.prototype.flatMap` method
7745
7976
  // https://tc39.es/ecma262/#sec-array.prototype.flatmap
7746
- $$c({ target: 'Array', proto: true }, {
7977
+ $$b({ target: 'Array', proto: true }, {
7747
7978
  flatMap: function flatMap(callbackfn /* , thisArg */) {
7748
- var O = toObject$4(this);
7749
- var sourceLen = lengthOfArrayLike$4(O);
7979
+ var O = toObject$3(this);
7980
+ var sourceLen = lengthOfArrayLike$3(O);
7750
7981
  var A;
7751
- aCallable$2(callbackfn);
7982
+ aCallable$1(callbackfn);
7752
7983
  A = arraySpeciesCreate$1(O, 0);
7753
7984
  A.length = flattenIntoArray$1(A, O, O, sourceLen, 0, 1, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
7754
7985
  return A;
@@ -7763,7 +7994,7 @@ var addToUnscopables$1 = addToUnscopables$5;
7763
7994
  addToUnscopables$1('flatMap');
7764
7995
 
7765
7996
  var call$6 = functionCall;
7766
- var uncurryThis$b = functionUncurryThis;
7997
+ var uncurryThis$a = functionUncurryThis;
7767
7998
  var fixRegExpWellKnownSymbolLogic$1 = fixRegexpWellKnownSymbolLogic;
7768
7999
  var anObject$4 = anObject$t;
7769
8000
  var isNullOrUndefined$1 = isNullOrUndefined$7;
@@ -7771,21 +8002,21 @@ var requireObjectCoercible$4 = requireObjectCoercible$e;
7771
8002
  var speciesConstructor = speciesConstructor$2;
7772
8003
  var advanceStringIndex$1 = advanceStringIndex$3;
7773
8004
  var toLength$3 = toLength$7;
7774
- var toString$a = toString$n;
8005
+ var toString$9 = toString$n;
7775
8006
  var getMethod$1 = getMethod$7;
7776
8007
  var regExpExec$1 = regexpExecAbstract;
7777
8008
  var stickyHelpers = regexpStickyHelpers;
7778
- var fails$3 = fails$y;
8009
+ var fails$2 = fails$y;
7779
8010
 
7780
8011
  var UNSUPPORTED_Y = stickyHelpers.UNSUPPORTED_Y;
7781
8012
  var MAX_UINT32 = 0xFFFFFFFF;
7782
8013
  var min$1 = Math.min;
7783
- var push$5 = uncurryThis$b([].push);
7784
- var stringSlice$4 = uncurryThis$b(''.slice);
8014
+ var push$4 = uncurryThis$a([].push);
8015
+ var stringSlice$4 = uncurryThis$a(''.slice);
7785
8016
 
7786
8017
  // Chrome 51 has a buggy "split" implementation when RegExp#exec !== nativeExec
7787
8018
  // Weex JS has frozen built-in prototypes, so use try / catch wrapper
7788
- var SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = !fails$3(function () {
8019
+ var SPLIT_WORKS_WITH_OVERWRITTEN_EXEC = !fails$2(function () {
7789
8020
  // eslint-disable-next-line regexp/no-empty-group -- required for testing
7790
8021
  var re = /(?:)/;
7791
8022
  var originalExec = re.exec;
@@ -7817,7 +8048,7 @@ fixRegExpWellKnownSymbolLogic$1('split', function (SPLIT, nativeSplit, maybeCall
7817
8048
  var splitter = isNullOrUndefined$1(separator) ? undefined : getMethod$1(separator, SPLIT);
7818
8049
  return splitter
7819
8050
  ? call$6(splitter, separator, O, limit)
7820
- : call$6(internalSplit, toString$a(O), separator, limit);
8051
+ : call$6(internalSplit, toString$9(O), separator, limit);
7821
8052
  },
7822
8053
  // `RegExp.prototype[@@split]` method
7823
8054
  // https://tc39.es/ecma262/#sec-regexp.prototype-@@split
@@ -7826,7 +8057,7 @@ fixRegExpWellKnownSymbolLogic$1('split', function (SPLIT, nativeSplit, maybeCall
7826
8057
  // the 'y' flag.
7827
8058
  function (string, limit) {
7828
8059
  var rx = anObject$4(this);
7829
- var S = toString$a(string);
8060
+ var S = toString$9(string);
7830
8061
 
7831
8062
  if (!BUGGY) {
7832
8063
  var res = maybeCallNative(internalSplit, rx, S, limit, internalSplit !== nativeSplit);
@@ -7858,16 +8089,16 @@ fixRegExpWellKnownSymbolLogic$1('split', function (SPLIT, nativeSplit, maybeCall
7858
8089
  ) {
7859
8090
  q = advanceStringIndex$1(S, q, unicodeMatching);
7860
8091
  } else {
7861
- push$5(A, stringSlice$4(S, p, q));
8092
+ push$4(A, stringSlice$4(S, p, q));
7862
8093
  if (A.length === lim) return A;
7863
8094
  for (var i = 1; i <= z.length - 1; i++) {
7864
- push$5(A, z[i]);
8095
+ push$4(A, z[i]);
7865
8096
  if (A.length === lim) return A;
7866
8097
  }
7867
8098
  q = p = e;
7868
8099
  }
7869
8100
  }
7870
- push$5(A, stringSlice$4(S, p));
8101
+ push$4(A, stringSlice$4(S, p));
7871
8102
  return A;
7872
8103
  }
7873
8104
  ];
@@ -7884,9 +8115,9 @@ var getIteratorFlattenable$1 = function (obj, stringHandling) {
7884
8115
  return getIteratorDirect$1(anObject$3(method !== undefined ? call$5(method, obj) : obj));
7885
8116
  };
7886
8117
 
7887
- var $$b = _export;
8118
+ var $$a = _export;
7888
8119
  var call$4 = functionCall;
7889
- var aCallable$1 = aCallable$k;
8120
+ var aCallable = aCallable$k;
7890
8121
  var anObject$2 = anObject$t;
7891
8122
  var getIteratorDirect = getIteratorDirect$a;
7892
8123
  var getIteratorFlattenable = getIteratorFlattenable$1;
@@ -7918,10 +8149,10 @@ var IteratorProxy = createIteratorProxy(function () {
7918
8149
 
7919
8150
  // `Iterator.prototype.flatMap` method
7920
8151
  // https://github.com/tc39/proposal-iterator-helpers
7921
- $$b({ target: 'Iterator', proto: true, real: true, forced: IS_PURE$1 }, {
8152
+ $$a({ target: 'Iterator', proto: true, real: true, forced: IS_PURE$1 }, {
7922
8153
  flatMap: function flatMap(mapper) {
7923
8154
  anObject$2(this);
7924
- aCallable$1(mapper);
8155
+ aCallable(mapper);
7925
8156
  return new IteratorProxy(getIteratorDirect(this), {
7926
8157
  mapper: mapper,
7927
8158
  inner: null
@@ -8087,7 +8318,182 @@ const createAutoPopulateMiddleware = (uischema, user) => (state, action, default
8087
8318
  */
8088
8319
  const autoPopulatePropertiesMonaco = [];
8089
8320
 
8090
- const createStepperContextInitData = props => {
8321
+ class ContextProviderClass {
8322
+ async addDataByUrl(key, url, processDataFunction, token) {
8323
+ let header = {};
8324
+ const [requestId, axiosWithConfig] = this.getAxiosInterceptorConfig(axios);
8325
+ if (token) {
8326
+ header = Object.assign({}, header, {
8327
+ Authorization: `Bearer ${token}`
8328
+ });
8329
+ }
8330
+ await axiosWithConfig.get(url, header).then(response => {
8331
+ const processedData = processDataFunction(response.data);
8332
+ this.enumValues.set(key, () => processedData);
8333
+ }).catch(err => {
8334
+ if (err.message.includes('CORS')) {
8335
+ console.warn(err.message);
8336
+ } else {
8337
+ console.warn(`addDataByUrl: ${err.message}`);
8338
+ }
8339
+ });
8340
+ axiosWithConfig.interceptors.request.eject(requestId);
8341
+ }
8342
+ constructor() {
8343
+ this.selfProps = void 0;
8344
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8345
+ this.enumValues = new Map();
8346
+ this.enumFunctions = new Map();
8347
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8348
+ this.enumSubmitFunctions = new Map();
8349
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8350
+ this.enumSaveFunctions = new Map();
8351
+ this.baseEnumerator = void 0;
8352
+ this.addFormContextData = (key, data) => {
8353
+ this.enumValues.set(key, () => data);
8354
+ };
8355
+ this.setup = props => {
8356
+ var _props$isFormSubmitte, _props$autoPopulatedD, _this$selfProps;
8357
+ this.selfProps = props;
8358
+ if (props.fileManagement) {
8359
+ const {
8360
+ fileList,
8361
+ uploadFile,
8362
+ downloadFile,
8363
+ deleteFile
8364
+ } = props.fileManagement;
8365
+ this.enumValues.set('file-list', () => fileList);
8366
+ this.enumFunctions.set('upload-file', () => uploadFile);
8367
+ this.enumFunctions.set('download-file', () => downloadFile);
8368
+ this.enumFunctions.set('delete-file', () => deleteFile);
8369
+ }
8370
+ if (props.submit) {
8371
+ const {
8372
+ submitForm,
8373
+ saveForm
8374
+ } = props.submit;
8375
+ const submitFunction = submitForm;
8376
+ const saveFormFunction = saveForm;
8377
+ this.enumSubmitFunctions.set('submit-form', () => submitFunction);
8378
+ this.enumSaveFunctions.set('save-form', () => saveFormFunction);
8379
+ }
8380
+ if (props.data) {
8381
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8382
+ Object.keys(props.data).forEach(item => {
8383
+ this.enumValues.set(item, () => props.data[item]);
8384
+ });
8385
+ }
8386
+ if (!props.children) {
8387
+ return null;
8388
+ }
8389
+ if (props.formUrl) {
8390
+ this.baseEnumerator.formUrl = props.formUrl;
8391
+ }
8392
+ this.baseEnumerator.isFormSubmitted = (_props$isFormSubmitte = props.isFormSubmitted) != null ? _props$isFormSubmitte : false;
8393
+ this.baseEnumerator.autoPopulatedData = (_props$autoPopulatedD = props.autoPopulatedData) != null ? _props$autoPopulatedD : [];
8394
+ this.baseEnumerator.formId = props.formId;
8395
+ return jsx(JsonFormContext.Provider, {
8396
+ value: this.baseEnumerator,
8397
+ children: (_this$selfProps = this.selfProps) == null ? void 0 : _this$selfProps.children
8398
+ });
8399
+ };
8400
+ this.getContextProvider = () => {
8401
+ var _this$selfProps2;
8402
+ return jsx(JsonFormContext.Provider, {
8403
+ value: this.baseEnumerator,
8404
+ children: (_this$selfProps2 = this.selfProps) == null ? void 0 : _this$selfProps2.children
8405
+ });
8406
+ };
8407
+ this.getFormUrl = () => {
8408
+ var _this$selfProps3;
8409
+ return (_this$selfProps3 = this.selfProps) == null ? void 0 : _this$selfProps3.formUrl;
8410
+ };
8411
+ this.getAxiosInterceptorConfig = axios => {
8412
+ const requestId = axios.interceptors.request.use(req => {
8413
+ if (req.data === undefined) {
8414
+ throw new Error(`The URL: ${req.url} encountered a CORS error.`);
8415
+ }
8416
+ return req;
8417
+ });
8418
+ return [requestId, axios];
8419
+ };
8420
+ /**
8421
+ * Grabs data stored under a given key
8422
+ *
8423
+ */
8424
+ this.getFormContextData = key => {
8425
+ const dataFunction = this.baseEnumerator.data.get(key);
8426
+ return dataFunction && dataFunction();
8427
+ };
8428
+ /**
8429
+ * Grabs all data
8430
+ *
8431
+ */
8432
+ this.getAllFormContextData = () => {
8433
+ const allData = [];
8434
+ this.baseEnumerator.data.forEach((d, key) => {
8435
+ allData.push({
8436
+ [key]: d()
8437
+ });
8438
+ });
8439
+ return allData;
8440
+ };
8441
+ this.baseEnumerator = {
8442
+ data: this.enumValues,
8443
+ functions: this.enumFunctions,
8444
+ submitFunction: this.enumSubmitFunctions,
8445
+ saveFunction: this.enumSaveFunctions,
8446
+ addFormContextData: this.addFormContextData,
8447
+ getFormContextData: this.getFormContextData,
8448
+ getAllFormContextData: this.getAllFormContextData,
8449
+ formUrl: this.getFormUrl()
8450
+ };
8451
+ this.selfProps = {};
8452
+ }
8453
+ }
8454
+ const ContextProviderC = new ContextProviderClass();
8455
+ const ContextProviderFactory = () => new ContextProviderClass().setup;
8456
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8457
+ const JsonFormContext = /*#__PURE__*/createContext(null);
8458
+
8459
+ const REVIEW_CHANGE_ACTION = 'jsonforms/review/change';
8460
+ function reviewReducer(_state, action) {
8461
+ if (action.type === REVIEW_CHANGE_ACTION) {
8462
+ return action.payload;
8463
+ }
8464
+ return null;
8465
+ }
8466
+ const ReviewRenderContext = /*#__PURE__*/createContext(undefined);
8467
+ const ReviewRenderProvider = ({
8468
+ children,
8469
+ onReviewChange
8470
+ }) => {
8471
+ const [reviewChange, dispatch] = useReducer(reviewReducer, null);
8472
+ const onChangeDispatch = useCallback((stepId, scope) => {
8473
+ dispatch({
8474
+ type: REVIEW_CHANGE_ACTION,
8475
+ payload: {
8476
+ stepId,
8477
+ scope
8478
+ }
8479
+ });
8480
+ onReviewChange == null || onReviewChange(stepId, scope);
8481
+ }, [onReviewChange]);
8482
+ const context = useMemo(() => ({
8483
+ isProvided: true,
8484
+ onChangeDispatch,
8485
+ reviewChange
8486
+ }), [onChangeDispatch, reviewChange]);
8487
+ return jsx(ReviewRenderContext.Provider, {
8488
+ value: context,
8489
+ children: children
8490
+ });
8491
+ };
8492
+ const useReviewContext = () => {
8493
+ return useContext(ReviewRenderContext);
8494
+ };
8495
+
8496
+ const createStepperContextInitData = (props, options) => {
8091
8497
  var _uischema$options, _uischema$options2, _categorization$eleme;
8092
8498
  const {
8093
8499
  uischema,
@@ -8107,13 +8513,14 @@ const createStepperContextInitData = props => {
8107
8513
  const isCacheStatus = (_uischema$options2 = uischema.options) == null ? void 0 : _uischema$options2.cacheStatus;
8108
8514
  isCacheStatus && getIsVisitFromLocalStorage() || [];
8109
8515
  const categories = (_categorization$eleme = categorization.elements) == null ? void 0 : _categorization$eleme.map((c, id) => {
8110
- var _deriveLabelForUISche;
8516
+ var _options$visitedIds$h, _options$visitedIds, _deriveLabelForUISche;
8111
8517
  const scopes = pickPropertyValues(c, 'scope', 'ListWithDetail');
8112
- // A step is not visited on initial mount, so its status is driven by whether it already holds
8518
+ // On first mount nothing is visited, so status is driven by whether the step already holds
8113
8519
  // user-entered data. Auto-populated fields (system-filled from the user profile) are excluded
8114
8520
  // so an unopened page with only auto-populated values stays NotStarted, while a resumed form
8115
- // the user actually filled still shows its saved status.
8116
- let visited = false;
8521
+ // the user actually filled still shows its saved status. On the recomputes that follow every
8522
+ // data change, pages the user has already opened keep their visited state.
8523
+ let visited = (_options$visitedIds$h = options == null || (_options$visitedIds = options.visitedIds) == null ? void 0 : _options$visitedIds.has(id)) != null ? _options$visitedIds$h : false;
8117
8524
  const autoPopulatedScopes = getAutoPopulateControls(c).map(control => control.scope);
8118
8525
  const {
8119
8526
  status,
@@ -8124,7 +8531,8 @@ const createStepperContextInitData = props => {
8124
8531
  errors: filteredErrors != null ? filteredErrors : [],
8125
8532
  schema,
8126
8533
  visited,
8127
- autoPopulatedScopes
8534
+ autoPopulatedScopes,
8535
+ autoPopulatedValues: options == null ? void 0 : options.autoPopulatedValues
8128
8536
  });
8129
8537
  //If the step has all conditional fields, set visited to true so that the step status will be
8130
8538
  //completed to enable form to be saved.
@@ -8174,7 +8582,21 @@ const JsonFormsStepperContextProvider = ({
8174
8582
  data,
8175
8583
  uischema
8176
8584
  } = StepperProps;
8177
- const [stepperState, dispatch] = useReducer(stepperReducer, createStepperContextInitData(StepperProps));
8585
+ const formCtx = useContext(JsonFormContext);
8586
+ const autoPopulatedValues = formCtx == null ? void 0 : formCtx.autoPopulatedData;
8587
+ const formId = formCtx == null ? void 0 : formCtx.formId;
8588
+ // Steps opened in an earlier session. Seeding these on first mount is what keeps a step the user
8589
+ // has been through from dropping back to NotStarted on resume — including the case where they
8590
+ // edited an auto-populated field and then restored the original value, which leaves nothing in
8591
+ // the data to distinguish it from a step that was never opened.
8592
+ const persistedVisitedIds = useMemo(() => {
8593
+ var _getVisitedSteps;
8594
+ return new Set((_getVisitedSteps = getVisitedSteps(formId)) != null ? _getVisitedSteps : []);
8595
+ }, [formId]);
8596
+ const [stepperState, dispatch] = useReducer(stepperReducer, createStepperContextInitData(StepperProps, {
8597
+ visitedIds: persistedVisitedIds,
8598
+ autoPopulatedValues
8599
+ }));
8178
8600
  const stepperDispatch = (StepperProps == null ? void 0 : StepperProps.customDispatch) || dispatch;
8179
8601
  const isCacheStatus = (_uischema$options3 = uischema.options) == null ? void 0 : _uischema$options3.cacheStatus;
8180
8602
  //prevents infinite loop refresh
@@ -8276,12 +8698,31 @@ const JsonFormsStepperContextProvider = ({
8276
8698
  });
8277
8699
  //eslint-disable-next-line
8278
8700
  }, [ctx == null || (_ctx$core5 = ctx.core) == null ? void 0 : _ctx$core5.errors]);
8701
+ // Persist as the user goes rather than on unload: a draft resumed on another tab, or after a
8702
+ // crash or a killed mobile tab, never fires beforeunload and would otherwise lose the visits.
8703
+ // The categories array is rebuilt on every data change, so this effect runs on each keystroke —
8704
+ // only touch storage when the set has actually grown.
8705
+ const lastPersistedVisited = useRef(null);
8706
+ useEffect(() => {
8707
+ var _stepperState$categor3, _stepperState$categor4;
8708
+ const visitedIds = (_stepperState$categor3 = stepperState == null || (_stepperState$categor4 = stepperState.categories) == null ? void 0 : _stepperState$categor4.filter(c => c.isVisited).map(c => c.id)) != null ? _stepperState$categor3 : [];
8709
+ const merged = [...new Set([...persistedVisitedIds, ...visitedIds])].sort((a, b) => a - b);
8710
+ if (merged.length === 0) {
8711
+ return;
8712
+ }
8713
+ const serialized = JSON.stringify(merged);
8714
+ if (serialized === lastPersistedVisited.current) {
8715
+ return;
8716
+ }
8717
+ lastPersistedVisited.current = serialized;
8718
+ saveVisitedSteps(formId, merged);
8719
+ }, [formId, persistedVisitedIds, stepperState == null ? void 0 : stepperState.categories]);
8279
8720
  /* istanbul ignore next */
8280
8721
  useEffect(() => {
8281
8722
  const handleBeforeUnload = () => {
8282
8723
  if (isCacheStatus) {
8283
- var _stepperState$categor3;
8284
- saveIsVisitFromLocalStorage((stepperState == null || (_stepperState$categor3 = stepperState.categories) == null ? void 0 : _stepperState$categor3.map(c => c == null ? void 0 : c.isVisited)) || []);
8724
+ var _stepperState$categor5;
8725
+ saveIsVisitFromLocalStorage((stepperState == null || (_stepperState$categor5 = stepperState.categories) == null ? void 0 : _stepperState$categor5.map(c => c == null ? void 0 : c.isVisited)) || []);
8285
8726
  }
8286
8727
  };
8287
8728
  window.addEventListener('beforeunload', handleBeforeUnload);
@@ -8292,13 +8733,17 @@ const JsonFormsStepperContextProvider = ({
8292
8733
  }, [stepperState]);
8293
8734
  useEffect(() => {
8294
8735
  if ((context == null ? void 0 : context.isProvided) === true) {
8736
+ var _stepperState$categor6, _stepperState$categor7;
8295
8737
  /* The block is used to cache the state for the tenant web app review editor */
8296
8738
  stepperDispatch({
8297
8739
  type: 'update/uischema',
8298
8740
  payload: {
8299
8741
  state: createStepperContextInitData(Object.assign({}, StepperProps, {
8300
8742
  activeId: Math.min(stepperState == null ? void 0 : stepperState.activeId, stepperState.maxReachedStep)
8301
- }))
8743
+ }), {
8744
+ visitedIds: new Set([...persistedVisitedIds, ...((_stepperState$categor6 = stepperState == null || (_stepperState$categor7 = stepperState.categories) == null ? void 0 : _stepperState$categor7.filter(c => c.isVisited).map(c => c.id)) != null ? _stepperState$categor6 : [])]),
8745
+ autoPopulatedValues
8746
+ })
8302
8747
  }
8303
8748
  });
8304
8749
  if (stepperState.activeId !== stepperState.categories.length + 1) {
@@ -8467,14 +8912,14 @@ const GoAInputBaseControl = props => {
8467
8912
  });
8468
8913
  };
8469
8914
 
8470
- var $$a = _export;
8915
+ var $$9 = _export;
8471
8916
  var DESCRIPTORS$4 = descriptors;
8472
8917
  var global$4 = global$t;
8473
- var uncurryThis$a = functionUncurryThis;
8918
+ var uncurryThis$9 = functionUncurryThis;
8474
8919
  var hasOwn$2 = hasOwnProperty_1;
8475
8920
  var isCallable$1 = isCallable$t;
8476
8921
  var isPrototypeOf = objectIsPrototypeOf;
8477
- var toString$9 = toString$n;
8922
+ var toString$8 = toString$n;
8478
8923
  var defineBuiltInAccessor$3 = defineBuiltInAccessor$7;
8479
8924
  var copyConstructorProperties = copyConstructorProperties$3;
8480
8925
 
@@ -8488,7 +8933,7 @@ if (DESCRIPTORS$4 && isCallable$1(NativeSymbol) && (!('description' in SymbolPro
8488
8933
  var EmptyStringDescriptionStore = {};
8489
8934
  // wrap Symbol constructor for correct work with undefined description
8490
8935
  var SymbolWrapper = function Symbol() {
8491
- var description = arguments.length < 1 || arguments[0] === undefined ? undefined : toString$9(arguments[0]);
8936
+ var description = arguments.length < 1 || arguments[0] === undefined ? undefined : toString$8(arguments[0]);
8492
8937
  var result = isPrototypeOf(SymbolPrototype, this)
8493
8938
  ? new NativeSymbol(description)
8494
8939
  // in Edge 13, String(Symbol(undefined)) === 'Symbol(undefined)'
@@ -8502,11 +8947,11 @@ if (DESCRIPTORS$4 && isCallable$1(NativeSymbol) && (!('description' in SymbolPro
8502
8947
  SymbolPrototype.constructor = SymbolWrapper;
8503
8948
 
8504
8949
  var NATIVE_SYMBOL = String(NativeSymbol('description detection')) === 'Symbol(description detection)';
8505
- var thisSymbolValue = uncurryThis$a(SymbolPrototype.valueOf);
8506
- var symbolDescriptiveString = uncurryThis$a(SymbolPrototype.toString);
8950
+ var thisSymbolValue = uncurryThis$9(SymbolPrototype.valueOf);
8951
+ var symbolDescriptiveString = uncurryThis$9(SymbolPrototype.toString);
8507
8952
  var regexp = /^Symbol\((.*)\)[^)]+$/;
8508
- var replace$3 = uncurryThis$a(''.replace);
8509
- var stringSlice$3 = uncurryThis$a(''.slice);
8953
+ var replace$3 = uncurryThis$9(''.replace);
8954
+ var stringSlice$3 = uncurryThis$9(''.slice);
8510
8955
 
8511
8956
  defineBuiltInAccessor$3(SymbolPrototype, 'description', {
8512
8957
  configurable: true,
@@ -8519,7 +8964,7 @@ if (DESCRIPTORS$4 && isCallable$1(NativeSymbol) && (!('description' in SymbolPro
8519
8964
  }
8520
8965
  });
8521
8966
 
8522
- $$a({ global: true, constructor: true, forced: true }, {
8967
+ $$9({ global: true, constructor: true, forced: true }, {
8523
8968
  Symbol: SymbolWrapper
8524
8969
  });
8525
8970
  }
@@ -8529,7 +8974,7 @@ var fixRegExpWellKnownSymbolLogic = fixRegexpWellKnownSymbolLogic;
8529
8974
  var anObject$1 = anObject$t;
8530
8975
  var isNullOrUndefined = isNullOrUndefined$7;
8531
8976
  var toLength$2 = toLength$7;
8532
- var toString$8 = toString$n;
8977
+ var toString$7 = toString$n;
8533
8978
  var requireObjectCoercible$3 = requireObjectCoercible$e;
8534
8979
  var getMethod = getMethod$7;
8535
8980
  var advanceStringIndex = advanceStringIndex$3;
@@ -8543,13 +8988,13 @@ fixRegExpWellKnownSymbolLogic('match', function (MATCH, nativeMatch, maybeCallNa
8543
8988
  function match(regexp) {
8544
8989
  var O = requireObjectCoercible$3(this);
8545
8990
  var matcher = isNullOrUndefined(regexp) ? undefined : getMethod(regexp, MATCH);
8546
- return matcher ? call$3(matcher, regexp, O) : new RegExp(regexp)[MATCH](toString$8(O));
8991
+ return matcher ? call$3(matcher, regexp, O) : new RegExp(regexp)[MATCH](toString$7(O));
8547
8992
  },
8548
8993
  // `RegExp.prototype[@@match]` method
8549
8994
  // https://tc39.es/ecma262/#sec-regexp.prototype-@@match
8550
8995
  function (string) {
8551
8996
  var rx = anObject$1(this);
8552
- var S = toString$8(string);
8997
+ var S = toString$7(string);
8553
8998
  var res = maybeCallNative(nativeMatch, rx, S);
8554
8999
 
8555
9000
  if (res.done) return res.value;
@@ -8562,7 +9007,7 @@ fixRegExpWellKnownSymbolLogic('match', function (MATCH, nativeMatch, maybeCallNa
8562
9007
  var n = 0;
8563
9008
  var result;
8564
9009
  while ((result = regExpExec(rx, S)) !== null) {
8565
- var matchStr = toString$8(result[0]);
9010
+ var matchStr = toString$7(result[0]);
8566
9011
  A[n] = matchStr;
8567
9012
  if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength$2(rx.lastIndex), fullUnicode);
8568
9013
  n++;
@@ -8818,7 +9263,75 @@ const GoATextControl = props => jsx(GoAInputBaseControl, Object.assign({}, props
8818
9263
  const GoATextControlTester = rankWith(1, isStringControl);
8819
9264
  const GoAInputTextControl = withJsonFormsControlProps(GoATextControl);
8820
9265
 
8821
- const DEBOUNCE_DELAY = 550;
9266
+ const COMMIT_DELAY = 300;
9267
+ /**
9268
+ * Keeps a live, per-keystroke mirror of a control's value and pushes it into the form data only
9269
+ * once the user pauses typing.
9270
+ *
9271
+ * The GoA web components keep the value in their own DOM and report changes back a macrotask
9272
+ * late, while their update path writes an incoming `value` prop straight back into the field
9273
+ * whenever it differs from what is in the box. So a render that commits a value older than what
9274
+ * has been typed since wipes out the characters in between. Committing on every keystroke
9275
+ * re-renders and revalidates the whole form, which makes that window wide enough to swallow
9276
+ * characters; debouncing the commit keeps it to a single local render.
9277
+ *
9278
+ * The echo of our own commit is ignored while further edits are outstanding, so data arriving
9279
+ * back from the form can never overwrite what the user has typed in the meantime.
9280
+ *
9281
+ * @param externalValue the value held in the form data; must be referentially stable between
9282
+ * renders (memoize it when it is an object), otherwise the sync effect runs on every render
9283
+ * @param commit pushes a settled value into the form data
9284
+ * @param delay how long to wait for typing to stop before committing
9285
+ */
9286
+ function useDebouncedCommit(externalValue, commit, delay = COMMIT_DELAY) {
9287
+ const [value, setLocalValue] = useState(externalValue);
9288
+ // Set while the user has edits we have not pushed upstream yet.
9289
+ const pendingRef = useRef(null);
9290
+ const autoCommitRef = useRef(true);
9291
+ const commitRef = useRef(commit);
9292
+ useEffect(() => {
9293
+ commitRef.current = commit;
9294
+ });
9295
+ const debouncedValue = useDebounce(value, delay);
9296
+ const flush = useCallback(() => {
9297
+ const pending = pendingRef.current;
9298
+ if (pending === null) {
9299
+ return;
9300
+ }
9301
+ pendingRef.current = null;
9302
+ autoCommitRef.current = true;
9303
+ commitRef.current(pending);
9304
+ }, []);
9305
+ const setValue = useCallback((next, options) => {
9306
+ pendingRef.current = next;
9307
+ autoCommitRef.current = (options == null ? void 0 : options.autoCommit) !== false;
9308
+ setLocalValue(next);
9309
+ }, []);
9310
+ useEffect(() => {
9311
+ if (!autoCommitRef.current) {
9312
+ return;
9313
+ }
9314
+ // Only commit once the debounce has caught up with the latest keystroke.
9315
+ if (pendingRef.current === null || pendingRef.current !== debouncedValue) {
9316
+ return;
9317
+ }
9318
+ flush();
9319
+ }, [debouncedValue, flush]);
9320
+ useEffect(() => {
9321
+ if (pendingRef.current !== null) {
9322
+ return;
9323
+ }
9324
+ setLocalValue(current => isEqual$1(current, externalValue) ? current : externalValue);
9325
+ }, [externalValue]);
9326
+ // Don't drop the tail of what was typed when the control goes away, e.g. on stepper navigation.
9327
+ useEffect(() => flush, [flush]);
9328
+ return {
9329
+ value,
9330
+ setValue,
9331
+ flush
9332
+ };
9333
+ }
9334
+
8822
9335
  const MultiLineText = props => {
8823
9336
  var _uischema$options$com, _uischema$options, _uischema$options2, _uischema$options3, _uischema$options$com2, _uischema$options4, _uischema$options5;
8824
9337
  const {
@@ -8833,30 +9346,30 @@ const MultiLineText = props => {
8833
9346
  isVisited,
8834
9347
  errors,
8835
9348
  setIsVisited
8836
- } = props;
8837
- const [textAreaValue, setTextAreaValue] = React.useState(data || '');
8838
- const debouncedValue = useDebounce(textAreaValue, DEBOUNCE_DELAY);
8839
- useEffect(() => {
8840
- setTextAreaValue(data || '');
8841
- }, [data]);
8842
- /* istanbul ignore next */
8843
- useEffect(() => {
8844
- if (debouncedValue !== data && (debouncedValue !== '' || data !== undefined)) {
8845
- onChangeForInputControl({
8846
- value: debouncedValue,
8847
- controlProps: props
8848
- });
8849
- }
8850
- }, [debouncedValue]);
9349
+ } = props;
9350
+ const {
9351
+ value: textAreaValue,
9352
+ setValue: setTextAreaValue,
9353
+ flush: flushTextArea
9354
+ } = useDebouncedCommit(data || '', value => onChangeForInputControl({
9355
+ value,
9356
+ controlProps: props
9357
+ }));
8851
9358
  const appliedUiSchemaOptions = Object.assign({}, config, uischema == null ? void 0 : uischema.options);
8852
9359
  const placeholder = (appliedUiSchemaOptions == null ? void 0 : appliedUiSchemaOptions.placeholder) || (schema == null ? void 0 : schema.description) || '';
8853
9360
  const width = (_uischema$options$com = uischema == null || (_uischema$options = uischema.options) == null || (_uischema$options = _uischema$options.componentProps) == null ? void 0 : _uischema$options.width) != null ? _uischema$options$com : '100%';
8854
9361
  const autoCapitalize = (uischema == null || (_uischema$options2 = uischema.options) == null || (_uischema$options2 = _uischema$options2.componentProps) == null ? void 0 : _uischema$options2.autoCapitalize) === true || (uischema == null || (_uischema$options3 = uischema.options) == null ? void 0 : _uischema$options3.autoCapitalize) === true;
8855
9362
  const readOnly = (_uischema$options$com2 = uischema == null || (_uischema$options4 = uischema.options) == null || (_uischema$options4 = _uischema$options4.componentProps) == null ? void 0 : _uischema$options4.readOnly) != null ? _uischema$options$com2 : false;
8856
9363
  const textAreaName = `${label || path}-text-area` || '';
9364
+ const applyCapitalization = value => autoCapitalize ? value.toUpperCase() : value;
9365
+ const markVisited = () => {
9366
+ if (isVisited === false && setIsVisited) {
9367
+ setIsVisited();
9368
+ }
9369
+ };
8857
9370
  const txtAreaComponent = jsx(GoabTextArea, Object.assign({
8858
9371
  error: isVisited && errors.length > 0,
8859
- value: debouncedValue,
9372
+ value: textAreaValue,
8860
9373
  disabled: !enabled,
8861
9374
  readOnly: readOnly,
8862
9375
  placeholder: placeholder,
@@ -8865,21 +9378,21 @@ const MultiLineText = props => {
8865
9378
  width: width,
8866
9379
  // Note: Paul Jan-09-2023. The latest ui-component come with the maxCount. We need to uncomment the following line when the component is updated
8867
9380
  // maxCount={schema.maxLength || 256}
9381
+ // The component raises _change from its input event, so unlike _keyPress (keyup) this also
9382
+ // covers pasting, IME composition and held-key repeats.
9383
+ onChange: detail => {
9384
+ setTextAreaValue(applyCapitalization(detail.value));
9385
+ markVisited();
9386
+ },
8868
9387
  onKeyPress: detail => {
8869
- const newValue = autoCapitalize ? detail.value.toUpperCase() : detail.value;
8870
- setTextAreaValue(newValue);
8871
- if (isVisited === false && setIsVisited) {
8872
- setIsVisited();
8873
- }
9388
+ setTextAreaValue(applyCapitalization(detail.value));
9389
+ markVisited();
8874
9390
  },
8875
9391
  onBlur: detail => {
8876
- const newValue = autoCapitalize ? detail.value.toUpperCase() : detail.value;
8877
- setTextAreaValue(newValue);
8878
- if (isVisited === false && setIsVisited) {
8879
- setIsVisited();
8880
- }
8881
- },
8882
- onChange: detail => {}
9392
+ setTextAreaValue(applyCapitalization(detail.value));
9393
+ flushTextArea();
9394
+ markVisited();
9395
+ }
8883
9396
  }, uischema == null || (_uischema$options5 = uischema.options) == null ? void 0 : _uischema$options5.componentProps));
8884
9397
  return txtAreaComponent;
8885
9398
  };
@@ -8900,7 +9413,7 @@ function _objectWithoutPropertiesLoose(r, e) {
8900
9413
  }
8901
9414
 
8902
9415
  var toIntegerOrInfinity$1 = toIntegerOrInfinity$9;
8903
- var toString$7 = toString$n;
9416
+ var toString$6 = toString$n;
8904
9417
  var requireObjectCoercible$2 = requireObjectCoercible$e;
8905
9418
 
8906
9419
  var $RangeError$1 = RangeError;
@@ -8908,7 +9421,7 @@ var $RangeError$1 = RangeError;
8908
9421
  // `String.prototype.repeat` method implementation
8909
9422
  // https://tc39.es/ecma262/#sec-string.prototype.repeat
8910
9423
  var stringRepeat = function repeat(count) {
8911
- var str = toString$7(requireObjectCoercible$2(this));
9424
+ var str = toString$6(requireObjectCoercible$2(this));
8912
9425
  var result = '';
8913
9426
  var n = toIntegerOrInfinity$1(count);
8914
9427
  if (n < 0 || n === Infinity) throw new $RangeError$1('Wrong number of repetitions');
@@ -8917,23 +9430,23 @@ var stringRepeat = function repeat(count) {
8917
9430
  };
8918
9431
 
8919
9432
  // https://github.com/tc39/proposal-string-pad-start-end
8920
- var uncurryThis$9 = functionUncurryThis;
9433
+ var uncurryThis$8 = functionUncurryThis;
8921
9434
  var toLength$1 = toLength$7;
8922
- var toString$6 = toString$n;
9435
+ var toString$5 = toString$n;
8923
9436
  var $repeat = stringRepeat;
8924
9437
  var requireObjectCoercible$1 = requireObjectCoercible$e;
8925
9438
 
8926
- var repeat = uncurryThis$9($repeat);
8927
- var stringSlice$2 = uncurryThis$9(''.slice);
9439
+ var repeat = uncurryThis$8($repeat);
9440
+ var stringSlice$2 = uncurryThis$8(''.slice);
8928
9441
  var ceil = Math.ceil;
8929
9442
 
8930
9443
  // `String.prototype.{ padStart, padEnd }` methods implementation
8931
9444
  var createMethod = function (IS_END) {
8932
9445
  return function ($this, maxLength, fillString) {
8933
- var S = toString$6(requireObjectCoercible$1($this));
9446
+ var S = toString$5(requireObjectCoercible$1($this));
8934
9447
  var intMaxLength = toLength$1(maxLength);
8935
9448
  var stringLength = S.length;
8936
- var fillStr = fillString === undefined ? ' ' : toString$6(fillString);
9449
+ var fillStr = fillString === undefined ? ' ' : toString$5(fillString);
8937
9450
  var fillLen, stringFiller;
8938
9451
  if (intMaxLength <= stringLength || fillStr === '') return S;
8939
9452
  fillLen = intMaxLength - stringLength;
@@ -8949,17 +9462,17 @@ var stringPad = {
8949
9462
  start: createMethod(false)};
8950
9463
 
8951
9464
  // https://github.com/zloirock/core-js/issues/280
8952
- var userAgent$2 = engineUserAgent;
9465
+ var userAgent = engineUserAgent;
8953
9466
 
8954
- var stringPadWebkitBug = /Version\/10(?:\.\d+){1,2}(?: [\w./]+)?(?: Mobile\/\w+)? Safari\//.test(userAgent$2);
9467
+ var stringPadWebkitBug = /Version\/10(?:\.\d+){1,2}(?: [\w./]+)?(?: Mobile\/\w+)? Safari\//.test(userAgent);
8955
9468
 
8956
- var $$9 = _export;
9469
+ var $$8 = _export;
8957
9470
  var $padStart = stringPad.start;
8958
9471
  var WEBKIT_BUG = stringPadWebkitBug;
8959
9472
 
8960
9473
  // `String.prototype.padStart` method
8961
9474
  // https://tc39.es/ecma262/#sec-string.prototype.padstart
8962
- $$9({ target: 'String', proto: true, forced: WEBKIT_BUG }, {
9475
+ $$8({ target: 'String', proto: true, forced: WEBKIT_BUG }, {
8963
9476
  padStart: function padStart(maxLength /* , fillString = ' ' */) {
8964
9477
  return $padStart(this, maxLength, arguments.length > 1 ? arguments[1] : undefined);
8965
9478
  }
@@ -9960,19 +10473,11 @@ const GoInputBaseReview = props => jsx(GoAInputBaseControl, Object.assign({}, pr
9960
10473
  }));
9961
10474
  const GoAInputBaseReviewControl = withJsonFormsControlProps(GoInputBaseReview);
9962
10475
 
9963
- var tryToString = tryToString$5;
9964
-
9965
- var $TypeError = TypeError;
9966
-
9967
- var deletePropertyOrThrow$2 = function (O, P) {
9968
- if (!delete O[P]) throw new $TypeError('Cannot delete property ' + tryToString(P) + ' of ' + tryToString(O));
9969
- };
9970
-
9971
- var $$8 = _export;
9972
- var toObject$3 = toObject$c;
9973
- var lengthOfArrayLike$3 = lengthOfArrayLike$c;
10476
+ var $$7 = _export;
10477
+ var toObject$2 = toObject$c;
10478
+ var lengthOfArrayLike$2 = lengthOfArrayLike$c;
9974
10479
  var setArrayLength = arraySetLength;
9975
- var deletePropertyOrThrow$1 = deletePropertyOrThrow$2;
10480
+ var deletePropertyOrThrow = deletePropertyOrThrow$2;
9976
10481
  var doesNotExceedSafeInteger = doesNotExceedSafeInteger$3;
9977
10482
 
9978
10483
  // IE8-
@@ -9988,15 +10493,15 @@ var properErrorOnNonWritableLength = function () {
9988
10493
  }
9989
10494
  };
9990
10495
 
9991
- var FORCED$2 = INCORRECT_RESULT || !properErrorOnNonWritableLength();
10496
+ var FORCED$1 = INCORRECT_RESULT || !properErrorOnNonWritableLength();
9992
10497
 
9993
10498
  // `Array.prototype.unshift` method
9994
10499
  // https://tc39.es/ecma262/#sec-array.prototype.unshift
9995
- $$8({ target: 'Array', proto: true, arity: 1, forced: FORCED$2 }, {
10500
+ $$7({ target: 'Array', proto: true, arity: 1, forced: FORCED$1 }, {
9996
10501
  // eslint-disable-next-line no-unused-vars -- required for `.length`
9997
10502
  unshift: function unshift(item) {
9998
- var O = toObject$3(this);
9999
- var len = lengthOfArrayLike$3(O);
10503
+ var O = toObject$2(this);
10504
+ var len = lengthOfArrayLike$2(O);
10000
10505
  var argCount = arguments.length;
10001
10506
  if (argCount) {
10002
10507
  doesNotExceedSafeInteger(len + argCount);
@@ -10004,7 +10509,7 @@ $$8({ target: 'Array', proto: true, arity: 1, forced: FORCED$2 }, {
10004
10509
  while (k--) {
10005
10510
  var to = k + argCount;
10006
10511
  if (k in O) O[to] = O[k];
10007
- else deletePropertyOrThrow$1(O, to);
10512
+ else deletePropertyOrThrow(O, to);
10008
10513
  }
10009
10514
  for (var j = 0; j < argCount; j++) {
10010
10515
  O[j] = arguments[j];
@@ -11443,43 +11948,6 @@ class ListWithDetailControl extends React.Component {
11443
11948
  }
11444
11949
  }
11445
11950
 
11446
- const REVIEW_CHANGE_ACTION = 'jsonforms/review/change';
11447
- function reviewReducer(_state, action) {
11448
- if (action.type === REVIEW_CHANGE_ACTION) {
11449
- return action.payload;
11450
- }
11451
- return null;
11452
- }
11453
- const ReviewRenderContext = /*#__PURE__*/createContext(undefined);
11454
- const ReviewRenderProvider = ({
11455
- children,
11456
- onReviewChange
11457
- }) => {
11458
- const [reviewChange, dispatch] = useReducer(reviewReducer, null);
11459
- const onChangeDispatch = useCallback((stepId, scope) => {
11460
- dispatch({
11461
- type: REVIEW_CHANGE_ACTION,
11462
- payload: {
11463
- stepId,
11464
- scope
11465
- }
11466
- });
11467
- onReviewChange == null || onReviewChange(stepId, scope);
11468
- }, [onReviewChange]);
11469
- const context = useMemo(() => ({
11470
- isProvided: true,
11471
- onChangeDispatch,
11472
- reviewChange
11473
- }), [onChangeDispatch, reviewChange]);
11474
- return jsx(ReviewRenderContext.Provider, {
11475
- value: context,
11476
- children: children
11477
- });
11478
- };
11479
- const useReviewContext = () => {
11480
- return useContext(ReviewRenderContext);
11481
- };
11482
-
11483
11951
  const GoAInputBaseTableReview = props => {
11484
11952
  var _uischema$options, _uischema$scope2, _jsonForms$core, _uischema$options4, _uischema$options5, _uischema$options6;
11485
11953
  const {
@@ -12090,189 +12558,53 @@ const Center = styled.div(_t24 || (_t24 = _$6`
12090
12558
  const PageStepperRow = styled.tr(_t25 || (_t25 = _$6`
12091
12559
  ${0}
12092
12560
  `), ({
12093
- disabled
12094
- }) => disabled ? `
12095
- pointer-events: none;
12096
- opacity: 0.5;
12097
- cursor: not-allowed;
12098
- ` : `
12099
- cursor: pointer;
12100
-
12101
- &:hover td {
12102
- background-color: var(--goa-color-greyscale-100);
12103
- }
12104
-
12105
- td {
12106
- transition: background-color 0.2s ease-in-out;
12107
- }
12108
-
12109
-
12110
- &:focus-visible {
12111
- border-radius: 0.25rem;
12112
- outline: 3px solid var(--goa-color-interactive-focus);
12113
- }
12114
- `);
12115
- const SectionHeaderRowTr = styled.tr(_t26 || (_t26 = _$6`
12116
- & > td {
12117
- border: 0 !important;
12118
- padding-top: var(--goa-space-l);
12119
- padding-bottom: var(--goa-space-s);
12120
- padding-left: 0 !important;
12121
- }
12122
-
12123
- & + tr > td {
12124
- border-top: none !important;
12125
- }
12126
- `));
12127
- const SummaryRowLink = styled.a(_t27 || (_t27 = _$6`
12128
- position: relative;
12129
- top: var(--goa-space-xs);
12130
- &:focus-visible {
12131
- border-radius: 0.25rem;
12132
- outline: 3px solid var(--goa-color-interactive-focus);
12133
- }
12134
- padding: 0 var(--goa-space-s) var(--goa-space-xs); var(--goa-space-s);
12135
- `));
12136
- const SummaryTd = styled.td(_t28 || (_t28 = _$6`
12137
- border: 0 !important;
12138
- padding: 0 !important;
12139
- `));
12140
-
12141
- class ContextProviderClass {
12142
- async addDataByUrl(key, url, processDataFunction, token) {
12143
- let header = {};
12144
- const [requestId, axiosWithConfig] = this.getAxiosInterceptorConfig(axios);
12145
- if (token) {
12146
- header = Object.assign({}, header, {
12147
- Authorization: `Bearer ${token}`
12148
- });
12149
- }
12150
- await axiosWithConfig.get(url, header).then(response => {
12151
- const processedData = processDataFunction(response.data);
12152
- this.enumValues.set(key, () => processedData);
12153
- }).catch(err => {
12154
- if (err.message.includes('CORS')) {
12155
- console.warn(err.message);
12156
- } else {
12157
- console.warn(`addDataByUrl: ${err.message}`);
12158
- }
12159
- });
12160
- axiosWithConfig.interceptors.request.eject(requestId);
12161
- }
12162
- constructor() {
12163
- this.selfProps = void 0;
12164
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
12165
- this.enumValues = new Map();
12166
- this.enumFunctions = new Map();
12167
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
12168
- this.enumSubmitFunctions = new Map();
12169
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
12170
- this.enumSaveFunctions = new Map();
12171
- this.baseEnumerator = void 0;
12172
- this.addFormContextData = (key, data) => {
12173
- this.enumValues.set(key, () => data);
12174
- };
12175
- this.setup = props => {
12176
- var _props$isFormSubmitte, _this$selfProps;
12177
- this.selfProps = props;
12178
- if (props.fileManagement) {
12179
- const {
12180
- fileList,
12181
- uploadFile,
12182
- downloadFile,
12183
- deleteFile
12184
- } = props.fileManagement;
12185
- this.enumValues.set('file-list', () => fileList);
12186
- this.enumFunctions.set('upload-file', () => uploadFile);
12187
- this.enumFunctions.set('download-file', () => downloadFile);
12188
- this.enumFunctions.set('delete-file', () => deleteFile);
12189
- }
12190
- if (props.submit) {
12191
- const {
12192
- submitForm,
12193
- saveForm
12194
- } = props.submit;
12195
- const submitFunction = submitForm;
12196
- const saveFormFunction = saveForm;
12197
- this.enumSubmitFunctions.set('submit-form', () => submitFunction);
12198
- this.enumSaveFunctions.set('save-form', () => saveFormFunction);
12199
- }
12200
- if (props.data) {
12201
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
12202
- Object.keys(props.data).forEach(item => {
12203
- this.enumValues.set(item, () => props.data[item]);
12204
- });
12205
- }
12206
- if (!props.children) {
12207
- return null;
12208
- }
12209
- if (props.formUrl) {
12210
- this.baseEnumerator.formUrl = props.formUrl;
12211
- }
12212
- this.baseEnumerator.isFormSubmitted = (_props$isFormSubmitte = props.isFormSubmitted) != null ? _props$isFormSubmitte : false;
12213
- return jsx(JsonFormContext.Provider, {
12214
- value: this.baseEnumerator,
12215
- children: (_this$selfProps = this.selfProps) == null ? void 0 : _this$selfProps.children
12216
- });
12217
- };
12218
- this.getContextProvider = () => {
12219
- var _this$selfProps2;
12220
- return jsx(JsonFormContext.Provider, {
12221
- value: this.baseEnumerator,
12222
- children: (_this$selfProps2 = this.selfProps) == null ? void 0 : _this$selfProps2.children
12223
- });
12224
- };
12225
- this.getFormUrl = () => {
12226
- var _this$selfProps3;
12227
- return (_this$selfProps3 = this.selfProps) == null ? void 0 : _this$selfProps3.formUrl;
12228
- };
12229
- this.getAxiosInterceptorConfig = axios => {
12230
- const requestId = axios.interceptors.request.use(req => {
12231
- if (req.data === undefined) {
12232
- throw new Error(`The URL: ${req.url} encountered a CORS error.`);
12233
- }
12234
- return req;
12235
- });
12236
- return [requestId, axios];
12237
- };
12238
- /**
12239
- * Grabs data stored under a given key
12240
- *
12241
- */
12242
- this.getFormContextData = key => {
12243
- const dataFunction = this.baseEnumerator.data.get(key);
12244
- return dataFunction && dataFunction();
12245
- };
12246
- /**
12247
- * Grabs all data
12248
- *
12249
- */
12250
- this.getAllFormContextData = () => {
12251
- const allData = [];
12252
- this.baseEnumerator.data.forEach((d, key) => {
12253
- allData.push({
12254
- [key]: d()
12255
- });
12256
- });
12257
- return allData;
12258
- };
12259
- this.baseEnumerator = {
12260
- data: this.enumValues,
12261
- functions: this.enumFunctions,
12262
- submitFunction: this.enumSubmitFunctions,
12263
- saveFunction: this.enumSaveFunctions,
12264
- addFormContextData: this.addFormContextData,
12265
- getFormContextData: this.getFormContextData,
12266
- getAllFormContextData: this.getAllFormContextData,
12267
- formUrl: this.getFormUrl()
12268
- };
12269
- this.selfProps = {};
12561
+ disabled
12562
+ }) => disabled ? `
12563
+ pointer-events: none;
12564
+ opacity: 0.5;
12565
+ cursor: not-allowed;
12566
+ ` : `
12567
+ cursor: pointer;
12568
+
12569
+ &:hover td {
12570
+ background-color: var(--goa-color-greyscale-100);
12571
+ }
12572
+
12573
+ td {
12574
+ transition: background-color 0.2s ease-in-out;
12575
+ }
12576
+
12577
+
12578
+ &:focus-visible {
12579
+ border-radius: 0.25rem;
12580
+ outline: 3px solid var(--goa-color-interactive-focus);
12581
+ }
12582
+ `);
12583
+ const SectionHeaderRowTr = styled.tr(_t26 || (_t26 = _$6`
12584
+ & > td {
12585
+ border: 0 !important;
12586
+ padding-top: var(--goa-space-l);
12587
+ padding-bottom: var(--goa-space-s);
12588
+ padding-left: 0 !important;
12270
12589
  }
12271
- }
12272
- const ContextProviderC = new ContextProviderClass();
12273
- const ContextProviderFactory = () => new ContextProviderClass().setup;
12274
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
12275
- const JsonFormContext = /*#__PURE__*/createContext(null);
12590
+
12591
+ & + tr > td {
12592
+ border-top: none !important;
12593
+ }
12594
+ `));
12595
+ const SummaryRowLink = styled.a(_t27 || (_t27 = _$6`
12596
+ position: relative;
12597
+ top: var(--goa-space-xs);
12598
+ &:focus-visible {
12599
+ border-radius: 0.25rem;
12600
+ outline: 3px solid var(--goa-color-interactive-focus);
12601
+ }
12602
+ padding: 0 var(--goa-space-s) var(--goa-space-xs); var(--goa-space-s);
12603
+ `));
12604
+ const SummaryTd = styled.td(_t28 || (_t28 = _$6`
12605
+ border: 0 !important;
12606
+ padding: 0 !important;
12607
+ `));
12276
12608
 
12277
12609
  const RenderStepElements = props => {
12278
12610
  var _props$category;
@@ -12295,20 +12627,20 @@ const RenderStepElements = props => {
12295
12627
  });
12296
12628
  };
12297
12629
 
12298
- var $$7 = _export;
12630
+ var $$6 = _export;
12299
12631
  var flattenIntoArray = flattenIntoArray_1;
12300
- var toObject$2 = toObject$c;
12301
- var lengthOfArrayLike$2 = lengthOfArrayLike$c;
12632
+ var toObject$1 = toObject$c;
12633
+ var lengthOfArrayLike$1 = lengthOfArrayLike$c;
12302
12634
  var toIntegerOrInfinity = toIntegerOrInfinity$9;
12303
12635
  var arraySpeciesCreate = arraySpeciesCreate$2;
12304
12636
 
12305
12637
  // `Array.prototype.flat` method
12306
12638
  // https://tc39.es/ecma262/#sec-array.prototype.flat
12307
- $$7({ target: 'Array', proto: true }, {
12639
+ $$6({ target: 'Array', proto: true }, {
12308
12640
  flat: function flat(/* depthArg = 1 */) {
12309
12641
  var depthArg = arguments.length ? arguments[0] : undefined;
12310
- var O = toObject$2(this);
12311
- var sourceLen = lengthOfArrayLike$2(O);
12642
+ var O = toObject$1(this);
12643
+ var sourceLen = lengthOfArrayLike$1(O);
12312
12644
  var A = arraySpeciesCreate(O, 0);
12313
12645
  A.length = flattenIntoArray(A, O, O, sourceLen, 0, depthArg === undefined ? 1 : toIntegerOrInfinity(depthArg));
12314
12646
  return A;
@@ -12836,170 +13168,6 @@ const GoAContractInfoControlReview = withJsonFormsAllOfProps(ContractInfoControl
12836
13168
  const isContactInformation = createSchemaMatchTester(['email', 'phone', 'preferredContactMethod']);
12837
13169
  const ContactInformationTester = rankWith(4, isContactInformation);
12838
13170
 
12839
- var arraySlice$1 = arraySlice$4;
12840
-
12841
- var floor$2 = Math.floor;
12842
-
12843
- var sort = function (array, comparefn) {
12844
- var length = array.length;
12845
-
12846
- if (length < 8) {
12847
- // insertion sort
12848
- var i = 1;
12849
- var element, j;
12850
-
12851
- while (i < length) {
12852
- j = i;
12853
- element = array[i];
12854
- while (j && comparefn(array[j - 1], element) > 0) {
12855
- array[j] = array[--j];
12856
- }
12857
- if (j !== i++) array[j] = element;
12858
- }
12859
- } else {
12860
- // merge sort
12861
- var middle = floor$2(length / 2);
12862
- var left = sort(arraySlice$1(array, 0, middle), comparefn);
12863
- var right = sort(arraySlice$1(array, middle), comparefn);
12864
- var llength = left.length;
12865
- var rlength = right.length;
12866
- var lindex = 0;
12867
- var rindex = 0;
12868
-
12869
- while (lindex < llength || rindex < rlength) {
12870
- array[lindex + rindex] = (lindex < llength && rindex < rlength)
12871
- ? comparefn(left[lindex], right[rindex]) <= 0 ? left[lindex++] : right[rindex++]
12872
- : lindex < llength ? left[lindex++] : right[rindex++];
12873
- }
12874
- }
12875
-
12876
- return array;
12877
- };
12878
-
12879
- var arraySort$1 = sort;
12880
-
12881
- var userAgent$1 = engineUserAgent;
12882
-
12883
- var firefox = userAgent$1.match(/firefox\/(\d+)/i);
12884
-
12885
- var engineFfVersion = !!firefox && +firefox[1];
12886
-
12887
- var UA = engineUserAgent;
12888
-
12889
- var engineIsIeOrEdge = /MSIE|Trident/.test(UA);
12890
-
12891
- var userAgent = engineUserAgent;
12892
-
12893
- var webkit = userAgent.match(/AppleWebKit\/(\d+)\./);
12894
-
12895
- var engineWebkitVersion = !!webkit && +webkit[1];
12896
-
12897
- var $$6 = _export;
12898
- var uncurryThis$8 = functionUncurryThis;
12899
- var aCallable = aCallable$k;
12900
- var toObject$1 = toObject$c;
12901
- var lengthOfArrayLike$1 = lengthOfArrayLike$c;
12902
- var deletePropertyOrThrow = deletePropertyOrThrow$2;
12903
- var toString$5 = toString$n;
12904
- var fails$2 = fails$y;
12905
- var internalSort = arraySort$1;
12906
- var arrayMethodIsStrict = arrayMethodIsStrict$2;
12907
- var FF = engineFfVersion;
12908
- var IE_OR_EDGE = engineIsIeOrEdge;
12909
- var V8 = engineV8Version;
12910
- var WEBKIT = engineWebkitVersion;
12911
-
12912
- var test = [];
12913
- var nativeSort = uncurryThis$8(test.sort);
12914
- var push$4 = uncurryThis$8(test.push);
12915
-
12916
- // IE8-
12917
- var FAILS_ON_UNDEFINED = fails$2(function () {
12918
- test.sort(undefined);
12919
- });
12920
- // V8 bug
12921
- var FAILS_ON_NULL = fails$2(function () {
12922
- test.sort(null);
12923
- });
12924
- // Old WebKit
12925
- var STRICT_METHOD = arrayMethodIsStrict('sort');
12926
-
12927
- var STABLE_SORT = !fails$2(function () {
12928
- // feature detection can be too slow, so check engines versions
12929
- if (V8) return V8 < 70;
12930
- if (FF && FF > 3) return;
12931
- if (IE_OR_EDGE) return true;
12932
- if (WEBKIT) return WEBKIT < 603;
12933
-
12934
- var result = '';
12935
- var code, chr, value, index;
12936
-
12937
- // generate an array with more 512 elements (Chakra and old V8 fails only in this case)
12938
- for (code = 65; code < 76; code++) {
12939
- chr = String.fromCharCode(code);
12940
-
12941
- switch (code) {
12942
- case 66: case 69: case 70: case 72: value = 3; break;
12943
- case 68: case 71: value = 4; break;
12944
- default: value = 2;
12945
- }
12946
-
12947
- for (index = 0; index < 47; index++) {
12948
- test.push({ k: chr + index, v: value });
12949
- }
12950
- }
12951
-
12952
- test.sort(function (a, b) { return b.v - a.v; });
12953
-
12954
- for (index = 0; index < test.length; index++) {
12955
- chr = test[index].k.charAt(0);
12956
- if (result.charAt(result.length - 1) !== chr) result += chr;
12957
- }
12958
-
12959
- return result !== 'DGBEFHACIJK';
12960
- });
12961
-
12962
- var FORCED$1 = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || !STRICT_METHOD || !STABLE_SORT;
12963
-
12964
- var getSortCompare = function (comparefn) {
12965
- return function (x, y) {
12966
- if (y === undefined) return -1;
12967
- if (x === undefined) return 1;
12968
- if (comparefn !== undefined) return +comparefn(x, y) || 0;
12969
- return toString$5(x) > toString$5(y) ? 1 : -1;
12970
- };
12971
- };
12972
-
12973
- // `Array.prototype.sort` method
12974
- // https://tc39.es/ecma262/#sec-array.prototype.sort
12975
- $$6({ target: 'Array', proto: true, forced: FORCED$1 }, {
12976
- sort: function sort(comparefn) {
12977
- if (comparefn !== undefined) aCallable(comparefn);
12978
-
12979
- var array = toObject$1(this);
12980
-
12981
- if (STABLE_SORT) return comparefn === undefined ? nativeSort(array) : nativeSort(array, comparefn);
12982
-
12983
- var items = [];
12984
- var arrayLength = lengthOfArrayLike$1(array);
12985
- var itemsLength, index;
12986
-
12987
- for (index = 0; index < arrayLength; index++) {
12988
- if (index in array) push$4(items, array[index]);
12989
- }
12990
-
12991
- internalSort(items, getSortCompare(comparefn));
12992
-
12993
- itemsLength = lengthOfArrayLike$1(items);
12994
- index = 0;
12995
-
12996
- while (index < itemsLength) array[index] = items[index++];
12997
- while (index < arrayLength) deletePropertyOrThrow(array, index++);
12998
-
12999
- return array;
13000
- }
13001
- });
13002
-
13003
13171
  var $$5 = _export;
13004
13172
  var iterate = iterate$a;
13005
13173
  var createProperty$1 = createProperty$4;
@@ -18523,21 +18691,19 @@ const filterSuggestionsWithoutAddressCount = suggestions => {
18523
18691
  });
18524
18692
  };
18525
18693
  const mapSuggestionToAddress = suggestion => {
18526
- let addressLine1, addressLine2;
18527
- const suiteMatch = suggestion.Text.match(/(Suite|Apt|Unit|#)+/i);
18528
- const textParts = suggestion.Text.split(' ');
18529
- if (suiteMatch) {
18530
- addressLine1 = suggestion.Text.replace(textParts[0], '').trim();
18531
- addressLine2 = textParts[0].trim();
18532
- } else {
18533
- addressLine2 = '';
18534
- addressLine1 = suggestion.Text.trim();
18535
- }
18536
- const descriptionParts = suggestion.Description.split(',');
18537
- const municipality = descriptionParts[0].trim();
18538
- const provinceAndPostalCode = descriptionParts[1].trim().split(' ');
18539
- const subdivisionCode = provinceAndPostalCode[0];
18540
- const postalCode = descriptionParts[2].trim();
18694
+ var _suggestion$Text$trim, _suggestion$Text, _suggestion$Descripti;
18695
+ const text = (_suggestion$Text$trim = suggestion == null || (_suggestion$Text = suggestion.Text) == null ? void 0 : _suggestion$Text.trim()) != null ? _suggestion$Text$trim : '';
18696
+ const textParts = text.split(' ');
18697
+ const hasSuite = /(Suite|Apt|Unit|#)+/i.test(text) && textParts.length > 1;
18698
+ const addressLine1 = hasSuite ? text.replace(textParts[0], '').trim() : text;
18699
+ const addressLine2 = hasSuite ? textParts[0].trim() : '';
18700
+ // Descriptions usually read "municipality, province, postalCode", but the lookup also returns
18701
+ // "municipality, province postalCode" and, for partial matches, drops the postal code entirely.
18702
+ // Reading the parts positionally used to throw on anything but the three part form.
18703
+ const descriptionParts = ((_suggestion$Descripti = suggestion == null ? void 0 : suggestion.Description) != null ? _suggestion$Descripti : '').split(',').map(part => part.trim());
18704
+ const [municipality = '', provinceAndPostalCode = '', trailingPostalCode = ''] = descriptionParts;
18705
+ const [subdivisionCode = '', ...postalCodeParts] = provinceAndPostalCode.split(' ').filter(Boolean);
18706
+ const postalCode = postalCodeParts.length > 0 ? postalCodeParts.join(' ') : trailingPostalCode;
18541
18707
  return {
18542
18708
  addressLine1,
18543
18709
  addressLine2,
@@ -18639,17 +18805,18 @@ const AddressLookUpControl = props => {
18639
18805
  const [open, setOpen] = useState(false);
18640
18806
  const addressContainerRef = useRef(null);
18641
18807
  const label = typeof (uischema == null ? void 0 : uischema.label) === 'string' && uischema.label ? uischema.label : '';
18642
- const [address, setAddress] = useState(normalizeAddressData(data, isAlbertaAddress));
18808
+ const normalizedData = useMemo(() => normalizeAddressData(data, isAlbertaAddress), [data, isAlbertaAddress]);
18809
+ const {
18810
+ value: address,
18811
+ setValue: setAddress,
18812
+ flush: flushAddress
18813
+ } = useDebouncedCommit(normalizedData, updatedAddress => handleChange(path, updatedAddress));
18643
18814
  const [searchTerm, setSearchTerm] = useState('');
18644
18815
  const [suggestions, setSuggestions] = useState([]);
18645
18816
  const [loading, setLoading] = useState(false);
18646
18817
  const [errors, setErrors] = useState({});
18647
18818
  const requiredFields = schema.required;
18648
18819
  const [dropdownSelected, setDropdownSelected] = useState(false);
18649
- const updateFormData = updatedAddress => {
18650
- handleChange(path, updatedAddress);
18651
- };
18652
- const debouncedRenderAddress = useDebounce(searchTerm, 500);
18653
18820
  const [activeIndex, setActiveIndex] = useState(0);
18654
18821
  const dropdownRef = useRef(null);
18655
18822
  const debouncedTerm = useDebounce(searchTerm, 500);
@@ -18657,39 +18824,35 @@ const AddressLookUpControl = props => {
18657
18824
  const lastQueryRef = useRef('');
18658
18825
  const cacheRef = useRef(new Map());
18659
18826
  const spinnerTimerRef = useRef(null);
18660
- useEffect(() => {
18661
- const nextAddress = normalizeAddressData(data, isAlbertaAddress);
18662
- setAddress(currentAddress => {
18663
- const keys = ['addressLine1', 'addressLine2', 'municipality', 'postalCode', 'country', 'subdivisionCode'];
18664
- const unchanged = keys.every(key => currentAddress[key] === nextAddress[key]);
18665
- return unchanged ? currentAddress : nextAddress;
18666
- });
18667
- }, [data, isAlbertaAddress]);
18668
- const handleInputChange = (field, value) => {
18827
+ const handleInputChange = (field, value, options) => {
18669
18828
  var _schema$errorMessage;
18670
- if (field === 'addressLine1') {
18671
- setDropdownSelected(false);
18672
- }
18673
- let newAddress;
18829
+ let newValue = value;
18674
18830
  const postalCodeErrorMessage = (_schema$errorMessage = schema.errorMessage) == null || (_schema$errorMessage = _schema$errorMessage.properties) == null ? void 0 : _schema$errorMessage.postalCode;
18675
18831
  if (field === 'postalCode') {
18676
18832
  const validatePc = validatePostalCode(value);
18677
- setErrors(handlePostalCodeValidation(validatePc, postalCodeErrorMessage ? postalCodeErrorMessage : '', value, errors));
18678
- value = formatPostalCode(value);
18679
- newAddress = Object.assign({}, address, {
18680
- [field]: value.toUpperCase()
18681
- });
18833
+ setErrors(currentErrors => handlePostalCodeValidation(validatePc, postalCodeErrorMessage != null ? postalCodeErrorMessage : '', value, currentErrors));
18834
+ newValue = formatPostalCode(value).toUpperCase();
18682
18835
  } else {
18683
- newAddress = Object.assign({}, address, {
18684
- [field]: value
18836
+ setErrors(currentErrors => {
18837
+ if (!(field in currentErrors)) {
18838
+ return currentErrors;
18839
+ }
18840
+ const nextErrors = Object.assign({}, currentErrors);
18841
+ delete nextErrors[field];
18842
+ return nextErrors;
18685
18843
  });
18686
- delete errors[field];
18687
18844
  }
18688
- if (value === '' && field in newAddress) {
18845
+ const newAddress = Object.assign({}, address, {
18846
+ [field]: newValue
18847
+ });
18848
+ if (newValue === '') {
18689
18849
  delete newAddress[field];
18690
18850
  }
18691
- setAddress(newAddress);
18692
- updateFormData(newAddress);
18851
+ setAddress(newAddress, options);
18852
+ // Picking a province isn't typing, so there is nothing to wait for.
18853
+ if (field === 'subdivisionCode') {
18854
+ flushAddress();
18855
+ }
18693
18856
  };
18694
18857
  const renderHelp = () => {
18695
18858
  return jsx(HelpContentComponent, Object.assign({}, props, {
@@ -18697,70 +18860,46 @@ const AddressLookUpControl = props => {
18697
18860
  showLabel: false
18698
18861
  }));
18699
18862
  };
18700
- useEffect(() => {
18701
- const fetchSuggestions = async () => {
18702
- /* istanbul ignore next */
18703
- if (debouncedRenderAddress.length > 2 && dropdownSelected === false) {
18704
- setLoading(true);
18705
- setOpen(true);
18706
- try {
18707
- await fetchAddressSuggestions(formUrl, formatPostalCodeIfNeeded(searchTerm), isAlbertaAddress).then(response => {
18708
- const suggestions = filterSuggestionsWithoutAddressCount(response);
18709
- if (isAlbertaAddress) {
18710
- setSuggestions(filterAlbertaAddresses(suggestions));
18711
- } else {
18712
- setSuggestions(suggestions);
18713
- }
18714
- setLoading(false);
18715
- });
18716
- // eslint-disable-next-line
18717
- } catch (error) {
18718
- if (error.name !== 'AbortError') {
18719
- console.error('Address fetch failed:', error);
18720
- }
18721
- } finally {
18722
- setLoading(false);
18723
- }
18724
- } else {
18725
- setSuggestions([]);
18726
- setOpen(false);
18727
- }
18728
- };
18729
- fetchSuggestions();
18730
- }, [debouncedTerm]); // eslint-disable-line react-hooks/exhaustive-deps
18731
- const handleDropdownChange = value => {
18863
+ const handleAddressLine1Change = value => {
18732
18864
  setDropdownSelected(false);
18733
18865
  setSearchTerm(value);
18866
+ // Mirror the keystroke so the field never renders a stale value, but leave the form data alone
18867
+ // until blur or a suggestion is picked. Committing mid-lookup re-renders the whole form while
18868
+ // the search is still debouncing, which is what closed the suggestions dropdown.
18869
+ handleInputChange('addressLine1', value, {
18870
+ autoCommit: false
18871
+ });
18734
18872
  };
18735
18873
  /* istanbul ignore next */
18736
18874
  const handleSuggestionClick = suggestion => {
18737
18875
  const suggestAddress = mapSuggestionToAddress(suggestion);
18738
18876
  setAddress(suggestAddress);
18739
- handleChange(path, suggestAddress);
18877
+ flushAddress();
18740
18878
  setSuggestions([]);
18741
18879
  setErrors({});
18742
18880
  setDropdownSelected(true);
18743
18881
  };
18744
18882
  const handleRequiredFieldBlur = (name, value) => {
18745
- var _ref, _ref2, _ref3, _addressContainerRef$;
18746
- const err = Object.assign({}, errors);
18747
- const addressValue = name in address ? address[name] : undefined;
18748
- const liveInputValue = (_ref = (_ref2 = (_ref3 = value != null ? value : (_addressContainerRef$ = addressContainerRef.current) == null || (_addressContainerRef$ = _addressContainerRef$.querySelector(`goa-input[name="${name}"]`)) == null ? void 0 : _addressContainerRef$.value) != null ? _ref3 : addressValue) != null ? _ref2 : data == null ? void 0 : data[name]) != null ? _ref : '';
18749
- if (liveInputValue.trim() === '') {
18750
- err[name] = `${getAddressLookupFieldLabel(name)} is required`;
18751
- } else {
18752
- delete err[name];
18753
- }
18754
- setErrors(err);
18883
+ var _ref, _ref2;
18884
+ const liveInputValue = (_ref = (_ref2 = value != null ? value : address[name]) != null ? _ref2 : data == null ? void 0 : data[name]) != null ? _ref : '';
18885
+ setErrors(currentErrors => {
18886
+ const nextErrors = Object.assign({}, currentErrors);
18887
+ if (liveInputValue.trim() === '') {
18888
+ nextErrors[name] = `${getAddressLookupFieldLabel(name)} is required`;
18889
+ } else {
18890
+ delete nextErrors[name];
18891
+ }
18892
+ return nextErrors;
18893
+ });
18755
18894
  setSuggestions([]);
18756
18895
  setOpen(false);
18757
18896
  if (name === 'addressLine1' && value !== undefined) {
18758
- const newAddress = Object.assign({}, address, {
18897
+ setAddress(Object.assign({}, address, {
18759
18898
  addressLine1: value
18760
- });
18761
- setAddress(newAddress);
18762
- updateFormData(newAddress);
18899
+ }));
18763
18900
  }
18901
+ // Leaving the field ends the burst of typing, so push what is there now.
18902
+ flushAddress();
18764
18903
  };
18765
18904
  useEffect(() => {
18766
18905
  if (dropdownRef.current && activeIndex !== -1) {
@@ -18889,12 +19028,14 @@ const AddressLookUpControl = props => {
18889
19028
  ariaLabel: 'address-form-address1',
18890
19029
  placeholder: "Start typing the first line of your address, required.",
18891
19030
  value: (address == null ? void 0 : address.addressLine1) || '',
18892
- onChange: detail => handleDropdownChange(detail.value),
19031
+ onChange: detail => handleAddressLine1Change(detail.value),
18893
19032
  onBlur: detail => handleRequiredFieldBlur(detail.name, detail.value),
18894
19033
  width: "100%",
18895
19034
  onKeyPress: detail => {
18896
19035
  if (open) {
18897
- const newIndex = handleAddressKeyDown(detail.key, detail.value, activeIndex, suggestions, val => handleInputChange('addressLine1', val), suggestion => handleSuggestionClick(suggestion));
19036
+ const newIndex = handleAddressKeyDown(detail.key, detail.value, activeIndex, suggestions,
19037
+ // Navigating the suggestions must never blank out what has been typed.
19038
+ val => typeof val === 'string' && handleInputChange('addressLine1', val), suggestion => handleSuggestionClick(suggestion));
18898
19039
  setActiveIndex(newIndex);
18899
19040
  }
18900
19041
  }
@@ -18947,7 +19088,8 @@ const NameInputs = ({
18947
19088
  requiredFields,
18948
19089
  disabled,
18949
19090
  errors,
18950
- onFieldBlur
19091
+ onFieldBlur,
19092
+ onFieldCommit
18951
19093
  }) => {
18952
19094
  var _displayedErrors$firs, _displayedErrors$last;
18953
19095
  const [internalErrors, setInternalErrors] = useState({});
@@ -19001,6 +19143,7 @@ const NameInputs = ({
19001
19143
  };
19002
19144
  const displayedErrors = errors != null ? errors : internalErrors;
19003
19145
  const handleBlur = name => {
19146
+ onFieldCommit == null || onFieldCommit();
19004
19147
  if (onFieldBlur) {
19005
19148
  onFieldBlur(name);
19006
19149
  } else {
@@ -19047,6 +19190,7 @@ const NameInputs = ({
19047
19190
  ariaLabel: 'name-form-middle-name',
19048
19191
  value: middleName || '',
19049
19192
  onChange: detail => handleInputChange(detail.name, detail.value),
19193
+ onBlur: () => onFieldCommit == null ? void 0 : onFieldCommit(),
19050
19194
  width: "100%"
19051
19195
  })
19052
19196
  }), jsx(GoabFormItem, {
@@ -19137,24 +19281,19 @@ const FullNameControl = props => {
19137
19281
  uischema
19138
19282
  } = props;
19139
19283
  const requiredFields = schema.required;
19140
- const [nameData, setNameData] = useState(normalizeNameData(data));
19141
19284
  const controlRef = useRef(null);
19142
19285
  const formStepperCtx = useContext(JsonFormsStepperContext);
19143
19286
  const stepperState = formStepperCtx == null || formStepperCtx.selectStepperState == null ? void 0 : formStepperCtx.selectStepperState();
19144
- const updateFormData = updatedData => {
19145
- updatedData = Object.fromEntries(Object.entries(updatedData).filter(([_, value]) => value !== ''));
19146
- handleChange(path, updatedData);
19147
- };
19148
- useEffect(() => {
19149
- const nextData = normalizeNameData(data);
19150
- setNameData(currentData => currentData.firstName === nextData.firstName && currentData.middleName === nextData.middleName && currentData.lastName === nextData.lastName ? currentData : nextData);
19151
- }, [data]);
19287
+ const normalizedData = useMemo(() => normalizeNameData(data), [data]);
19288
+ const {
19289
+ value: nameData,
19290
+ setValue: setNameData,
19291
+ flush: flushName
19292
+ } = useDebouncedCommit(normalizedData, updatedData => handleChange(path, Object.fromEntries(Object.entries(updatedData).filter(([, value]) => value !== ''))));
19152
19293
  const handleInputChange = (field, value) => {
19153
- const updatedName = Object.assign({}, nameData, {
19294
+ setNameData(Object.assign({}, nameData, {
19154
19295
  [field]: value
19155
- });
19156
- setNameData(updatedName);
19157
- updateFormData(updatedName);
19296
+ }));
19158
19297
  };
19159
19298
  /* istanbul ignore next */
19160
19299
  useEffect(() => {
@@ -19197,7 +19336,8 @@ const FullNameControl = props => {
19197
19336
  handleInputChange: handleInputChange,
19198
19337
  data: data,
19199
19338
  disabled: !enabled,
19200
- requiredFields: requiredFields
19339
+ requiredFields: requiredFields,
19340
+ onFieldCommit: flushName
19201
19341
  })
19202
19342
  })
19203
19343
  });
@@ -19270,21 +19410,20 @@ const FullNameDobControl = props => {
19270
19410
  maxDate: currentDate.toISOString().substring(0, 10)
19271
19411
  };
19272
19412
  };
19273
- const [formData, setFormData] = useState(normalizeNameDobData(data));
19413
+ const normalizedData = useMemo(() => normalizeNameDobData(data), [data]);
19414
+ const {
19415
+ value: formData,
19416
+ setValue: setFormData,
19417
+ flush: flushFormData
19418
+ } = useDebouncedCommit(normalizedData, updatedData => handleChange(path, Object.fromEntries(Object.entries(updatedData).filter(([, value]) => value !== ''))));
19274
19419
  const updateFormData = updatedData => {
19275
- const nextData = Object.fromEntries(Object.entries(updatedData).filter(([_, value]) => value !== ''));
19276
- setFormData(nextData);
19277
- handleChange(path, nextData);
19420
+ setFormData(updatedData);
19421
+ flushFormData();
19278
19422
  };
19279
- useEffect(() => {
19280
- const nextData = normalizeNameDobData(data);
19281
- setFormData(currentData => currentData.firstName === nextData.firstName && currentData.middleName === nextData.middleName && currentData.lastName === nextData.lastName && currentData.dateOfBirth === nextData.dateOfBirth ? currentData : nextData);
19282
- }, [data]);
19283
19423
  const handleInputChange = (field, value) => {
19284
- const updatedData = Object.assign({}, formData, {
19424
+ setFormData(Object.assign({}, formData, {
19285
19425
  [field]: value
19286
- });
19287
- updateFormData(updatedData);
19426
+ }));
19288
19427
  };
19289
19428
  // eslint-disable-next-line
19290
19429
  const handleRequiredFieldBlur = (name, updatedData) => {
@@ -19348,7 +19487,8 @@ const FullNameDobControl = props => {
19348
19487
  disabled: !enabled,
19349
19488
  requiredFields: requiredFields,
19350
19489
  errors: errors,
19351
- onFieldBlur: handleRequiredFieldBlur
19490
+ onFieldBlur: handleRequiredFieldBlur,
19491
+ onFieldCommit: flushFormData
19352
19492
  }), jsx(GoabGrid, {
19353
19493
  minChildWidth: "0ch",
19354
19494
  gap: "s",
@@ -19369,7 +19509,7 @@ const FullNameDobControl = props => {
19369
19509
  value: formData == null ? void 0 : formData.dateOfBirth,
19370
19510
  onChange: detail => handleInputChange(detail.name, detail.value),
19371
19511
  onBlur: detail => {
19372
- /* istanbul ignore next */
19512
+ flushFormData();
19373
19513
  handleRequiredFieldBlur(detail.name);
19374
19514
  },
19375
19515
  width: "100%"