@abgov/jsonforms-components 2.74.0 → 2.75.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 +476 -229
- package/package.json +1 -1
- package/renderer-catalog.json +2 -2
- package/src/lib/Controls/Inputs/InputTextControl.d.ts +0 -1
- package/src/lib/Controls/Inputs/type.d.ts +11 -0
- package/src/lib/util/inputControlUtils.d.ts +4 -0
- package/src/lib/util/patternForm.d.ts +41 -0
- package/src/lib/util/useMaskedInput.d.ts +21 -0
package/index.esm.js
CHANGED
|
@@ -4821,6 +4821,166 @@ const UTCToFullLocalTime = (fullTime, useUTC = false) => {
|
|
|
4821
4821
|
}).replace('p.m.', 'PM').replace('a.m.', 'AM');
|
|
4822
4822
|
};
|
|
4823
4823
|
|
|
4824
|
+
// Default formats keyed by type; the mask can be overridden per field via UI schema options.
|
|
4825
|
+
const DEFAULT_PATTERNS = {
|
|
4826
|
+
phone: {
|
|
4827
|
+
mask: '(###) ###-####',
|
|
4828
|
+
pattern: /^\(?\d{3}\)?[- ]?\d{3}[- ]?\d{4}$/,
|
|
4829
|
+
error: 'Must be a valid 10-digit phone number in format (000) 000-0000',
|
|
4830
|
+
allowedKeys: /[0-9]/
|
|
4831
|
+
},
|
|
4832
|
+
sin: {
|
|
4833
|
+
mask: '### ### ###',
|
|
4834
|
+
pattern: /^\d{3} \d{3} \d{3}$/,
|
|
4835
|
+
error: 'Must be three groups of three digits.',
|
|
4836
|
+
allowedKeys: /[0-9]/
|
|
4837
|
+
},
|
|
4838
|
+
postalCode: {
|
|
4839
|
+
mask: '### ###',
|
|
4840
|
+
pattern: /^[A-Za-z]\d[A-Za-z] \d[A-Za-z]\d$/,
|
|
4841
|
+
error: 'Must be in A0A 0A0 capital letters and numbers format',
|
|
4842
|
+
allowedKeys: /[A-Za-z0-9]/
|
|
4843
|
+
},
|
|
4844
|
+
driverId: {
|
|
4845
|
+
// Alberta driver's licence: six digits, a dash, then three digits.
|
|
4846
|
+
mask: '######-###',
|
|
4847
|
+
pattern: /^\d{6}-\d{3}$/,
|
|
4848
|
+
error: "Must be a valid driver's licence number in format 000000-000",
|
|
4849
|
+
allowedKeys: /[0-9]/
|
|
4850
|
+
},
|
|
4851
|
+
mvid: {
|
|
4852
|
+
// Motor vehicle ID: four digits, a dash, then five digits.
|
|
4853
|
+
mask: '####-#####',
|
|
4854
|
+
pattern: /^\d{4}-\d{5}$/,
|
|
4855
|
+
error: 'Must be a valid motor vehicle ID in format 0000-00000',
|
|
4856
|
+
allowedKeys: /[0-9]/
|
|
4857
|
+
}
|
|
4858
|
+
};
|
|
4859
|
+
// Mask placeholder characters; each consumes one input character. Any other mask character is treated as a literal.
|
|
4860
|
+
const MASK_PLACEHOLDERS = new Set(['#', '*', '_']);
|
|
4861
|
+
const isPlaceholder = char => MASK_PLACEHOLDERS.has(char);
|
|
4862
|
+
// Navigation/editing keys that keystroke filtering must always let through.
|
|
4863
|
+
const MASK_CONTROL_KEYS = new Set(['Backspace', 'Delete', 'Tab', 'Enter', 'Escape', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End']);
|
|
4864
|
+
// A single-character key should be blocked when the format restricts input and the key isn't allowed.
|
|
4865
|
+
const shouldBlockKey = (key, allowedKeys) => !!allowedKeys && key.length === 1 && !MASK_CONTROL_KEYS.has(key) && !allowedKeys.test(key);
|
|
4866
|
+
// Removes characters the format doesn't allow (e.g. letters from a digit-only field), for paste/programmatic input.
|
|
4867
|
+
const filterAllowedKeys = (value, allowedKeys) => allowedKeys ? [...(value != null ? value : '')].filter(char => allowedKeys.test(char)).join('') : value != null ? value : '';
|
|
4868
|
+
// A mask slot holds one content character (letter or digit); everything else in the value is a separator.
|
|
4869
|
+
const NON_CONTENT = /[^a-zA-Z0-9]/g;
|
|
4870
|
+
const IS_CONTENT = /[a-zA-Z0-9]/;
|
|
4871
|
+
// Number of fill slots in a mask (its placeholder characters).
|
|
4872
|
+
const maskDigitCount = mask => [...mask].filter(isPlaceholder).length;
|
|
4873
|
+
// Formats a value into a placeholder mask (e.g. '(###) ###-####'), filling only the content entered so far.
|
|
4874
|
+
// Placeholder characters consume one content character each; every other mask character is a literal.
|
|
4875
|
+
const formatWithPattern = (value, mask) => {
|
|
4876
|
+
const maxContent = maskDigitCount(mask);
|
|
4877
|
+
const content = (value != null ? value : '').replace(NON_CONTENT, '').slice(0, maxContent);
|
|
4878
|
+
let index = 0;
|
|
4879
|
+
let formatted = '';
|
|
4880
|
+
for (const maskChar of mask) {
|
|
4881
|
+
if (index >= content.length) {
|
|
4882
|
+
break;
|
|
4883
|
+
}
|
|
4884
|
+
formatted += isPlaceholder(maskChar) ? content[index++] : maskChar;
|
|
4885
|
+
}
|
|
4886
|
+
return formatted;
|
|
4887
|
+
};
|
|
4888
|
+
// Fills the mask with the value's content, leaving the placeholder character for positions not yet entered.
|
|
4889
|
+
const toMaskTemplate = (value, mask) => {
|
|
4890
|
+
const maxContent = maskDigitCount(mask);
|
|
4891
|
+
const content = (value != null ? value : '').replace(NON_CONTENT, '').slice(0, maxContent);
|
|
4892
|
+
let index = 0;
|
|
4893
|
+
let display = '';
|
|
4894
|
+
for (const maskChar of mask) {
|
|
4895
|
+
display += isPlaceholder(maskChar) ? index < content.length ? content[index++] : maskChar : maskChar;
|
|
4896
|
+
}
|
|
4897
|
+
return display;
|
|
4898
|
+
};
|
|
4899
|
+
// Caret position just after the Nth content character within a rendered mask, so in-place edits keep the cursor in place.
|
|
4900
|
+
const caretAfterDigits = (display, digitCount) => {
|
|
4901
|
+
if (digitCount <= 0) {
|
|
4902
|
+
return 0;
|
|
4903
|
+
}
|
|
4904
|
+
let seen = 0;
|
|
4905
|
+
for (let i = 0; i < display.length; i++) {
|
|
4906
|
+
if (IS_CONTENT.test(display[i])) {
|
|
4907
|
+
seen += 1;
|
|
4908
|
+
if (seen === digitCount) {
|
|
4909
|
+
return i + 1;
|
|
4910
|
+
}
|
|
4911
|
+
}
|
|
4912
|
+
}
|
|
4913
|
+
return display.length;
|
|
4914
|
+
};
|
|
4915
|
+
// Computes an in-place masked edit from the raw input and caret index: what to show, what to store, where to put the caret.
|
|
4916
|
+
const computeMaskEdit = (rawValue, caretIndex, mask) => {
|
|
4917
|
+
const digitsBeforeCaret = rawValue.slice(0, caretIndex).replace(NON_CONTENT, '').length;
|
|
4918
|
+
const display = toMaskTemplate(rawValue, mask);
|
|
4919
|
+
const stored = formatWithPattern(rawValue, mask);
|
|
4920
|
+
const caret = caretAfterDigits(display, Math.min(digitsBeforeCaret, maskDigitCount(mask)));
|
|
4921
|
+
return {
|
|
4922
|
+
display,
|
|
4923
|
+
stored,
|
|
4924
|
+
caret
|
|
4925
|
+
};
|
|
4926
|
+
};
|
|
4927
|
+
// True once the value has as many content characters as the mask has fill slots.
|
|
4928
|
+
const isMaskFilled = (value, mask) => value.replace(NON_CONTENT, '').length >= maskDigitCount(mask);
|
|
4929
|
+
// A human placeholder for a mask, e.g. '(###) ###-####' -> '(000) 000-0000'.
|
|
4930
|
+
const maskPlaceholder = mask => [...mask].map(char => isPlaceholder(char) ? '0' : char).join('');
|
|
4931
|
+
// Extracts the underlying input element from a GoA change/keypress detail, if available.
|
|
4932
|
+
const getMaskInputTarget = detail => {
|
|
4933
|
+
var _detail$event$target, _detail$event;
|
|
4934
|
+
return (_detail$event$target = (_detail$event = detail.event) == null ? void 0 : _detail$event.target) != null ? _detail$event$target : undefined;
|
|
4935
|
+
};
|
|
4936
|
+
// Applies an in-place edit to the DOM: forces the (fixed-length) value and restores the caret after React commits.
|
|
4937
|
+
const applyInPlaceEdit = (target, edit) => {
|
|
4938
|
+
if (!target) {
|
|
4939
|
+
return;
|
|
4940
|
+
}
|
|
4941
|
+
target.value = edit.display;
|
|
4942
|
+
if (target.setSelectionRange) {
|
|
4943
|
+
requestAnimationFrame(() => target.setSelectionRange == null ? void 0 : target.setSelectionRange(edit.caret, edit.caret));
|
|
4944
|
+
}
|
|
4945
|
+
};
|
|
4946
|
+
/**
|
|
4947
|
+
* Applies a mask template to a value, e.g. mask "(###) ###-####" turns "7801234567" into "(780) 123-4567".
|
|
4948
|
+
* '#' consumes one content character from the input; every other character is a literal inserted into the output.
|
|
4949
|
+
* The mask's literal characters are stripped from the input first so an already formatted value re-formats cleanly.
|
|
4950
|
+
* Returns the original value unchanged when the mask is empty or no content characters remain.
|
|
4951
|
+
* @param value - The raw input value
|
|
4952
|
+
* @param mask - The mask template string
|
|
4953
|
+
* @returns The masked value
|
|
4954
|
+
*/
|
|
4955
|
+
const applyFormatPattern = (value, mask) => {
|
|
4956
|
+
if (!mask || !value) {
|
|
4957
|
+
return value;
|
|
4958
|
+
}
|
|
4959
|
+
const literals = new Set(mask.split('').filter(char => !isPlaceholder(char)));
|
|
4960
|
+
const content = value.split('').filter(char => !literals.has(char));
|
|
4961
|
+
if (content.length === 0) {
|
|
4962
|
+
return value;
|
|
4963
|
+
}
|
|
4964
|
+
let contentIndex = 0;
|
|
4965
|
+
let result = '';
|
|
4966
|
+
for (const maskChar of mask) {
|
|
4967
|
+
if (contentIndex >= content.length) {
|
|
4968
|
+
break;
|
|
4969
|
+
}
|
|
4970
|
+
if (isPlaceholder(maskChar)) {
|
|
4971
|
+
result += content[contentIndex];
|
|
4972
|
+
contentIndex += 1;
|
|
4973
|
+
} else {
|
|
4974
|
+
result += maskChar;
|
|
4975
|
+
}
|
|
4976
|
+
}
|
|
4977
|
+
// Append any remaining content characters that did not fit the mask.
|
|
4978
|
+
if (contentIndex < content.length) {
|
|
4979
|
+
result += content.slice(contentIndex).join('');
|
|
4980
|
+
}
|
|
4981
|
+
return result;
|
|
4982
|
+
};
|
|
4983
|
+
|
|
4824
4984
|
/**
|
|
4825
4985
|
* Checks input controls data value to determine is required and has any data.
|
|
4826
4986
|
* @param props - The JsonForm control props
|
|
@@ -8325,6 +8485,12 @@ const createAutoPopulateMiddleware = (uischema, user) => (state, action, default
|
|
|
8325
8485
|
*/
|
|
8326
8486
|
const autoPopulatePropertiesMonaco = [];
|
|
8327
8487
|
|
|
8488
|
+
// clean-code-ignore: RULE-19 — see the file-header note; ./context.spec.tsx covers this.
|
|
8489
|
+
// A shared empty default: a fresh [] on every render would read as a change and hand consumers a
|
|
8490
|
+
// new context value for nothing.
|
|
8491
|
+
const NO_AUTO_POPULATED_DATA = [];
|
|
8492
|
+
// The props a host can change after mount. See the note where they are applied.
|
|
8493
|
+
const HOST_CONTROLLED_KEYS = ['formUrl', 'isFormSubmitted', 'showChangeButtons', 'autoPopulatedData', 'formId', 'navigationTarget', 'onNavigationChange'];
|
|
8328
8494
|
class ContextProviderClass {
|
|
8329
8495
|
async addDataByUrl(key, url, processDataFunction, token) {
|
|
8330
8496
|
let header = {};
|
|
@@ -8393,15 +8559,25 @@ class ContextProviderClass {
|
|
|
8393
8559
|
if (!props.children) {
|
|
8394
8560
|
return null;
|
|
8395
8561
|
}
|
|
8396
|
-
|
|
8397
|
-
|
|
8562
|
+
// Everything below is a value a host can change while the form is mounted, so it is applied by
|
|
8563
|
+
// replacing the enumerator rather than by writing into it. The consumers all sit behind
|
|
8564
|
+
// JsonForms' memoised renderers, which re-render only when the form's own state changes — React
|
|
8565
|
+
// reaches past that memoisation for a context consumer, but only when the provider's value is a
|
|
8566
|
+
// different object. Mutating the enumerator in place left every one of these stale until
|
|
8567
|
+
// something else happened to re-render the form: a navigation target a host set on a Change
|
|
8568
|
+
// click was simply never seen.
|
|
8569
|
+
const next = Object.assign({}, this.baseEnumerator, {
|
|
8570
|
+
formUrl: props.formUrl || this.baseEnumerator.formUrl,
|
|
8571
|
+
isFormSubmitted: (_props$isFormSubmitte = props.isFormSubmitted) != null ? _props$isFormSubmitte : false,
|
|
8572
|
+
showChangeButtons: (_props$showChangeButt = props.showChangeButtons) != null ? _props$showChangeButt : true,
|
|
8573
|
+
autoPopulatedData: (_props$autoPopulatedD = props.autoPopulatedData) != null ? _props$autoPopulatedD : NO_AUTO_POPULATED_DATA,
|
|
8574
|
+
formId: props.formId,
|
|
8575
|
+
navigationTarget: props.navigationTarget,
|
|
8576
|
+
onNavigationChange: props.onNavigationChange
|
|
8577
|
+
});
|
|
8578
|
+
if (HOST_CONTROLLED_KEYS.some(key => next[key] !== this.baseEnumerator[key])) {
|
|
8579
|
+
this.baseEnumerator = next;
|
|
8398
8580
|
}
|
|
8399
|
-
this.baseEnumerator.isFormSubmitted = (_props$isFormSubmitte = props.isFormSubmitted) != null ? _props$isFormSubmitte : false;
|
|
8400
|
-
this.baseEnumerator.showChangeButtons = (_props$showChangeButt = props.showChangeButtons) != null ? _props$showChangeButt : true;
|
|
8401
|
-
this.baseEnumerator.autoPopulatedData = (_props$autoPopulatedD = props.autoPopulatedData) != null ? _props$autoPopulatedD : [];
|
|
8402
|
-
this.baseEnumerator.formId = props.formId;
|
|
8403
|
-
this.baseEnumerator.navigationTarget = props.navigationTarget;
|
|
8404
|
-
this.baseEnumerator.onNavigationChange = props.onNavigationChange;
|
|
8405
8581
|
return jsx(JsonFormContext.Provider, {
|
|
8406
8582
|
value: this.baseEnumerator,
|
|
8407
8583
|
children: (_this$selfProps = this.selfProps) == null ? void 0 : _this$selfProps.children
|
|
@@ -9794,54 +9970,6 @@ if (DESCRIPTORS$1 && isCallable(NativeSymbol) && (!('description' in SymbolProto
|
|
|
9794
9970
|
});
|
|
9795
9971
|
}
|
|
9796
9972
|
|
|
9797
|
-
var call$2 = functionCall;
|
|
9798
|
-
var fixRegExpWellKnownSymbolLogic = fixRegexpWellKnownSymbolLogic;
|
|
9799
|
-
var anObject = anObject$t;
|
|
9800
|
-
var isNullOrUndefined = isNullOrUndefined$7;
|
|
9801
|
-
var toLength$2 = toLength$7;
|
|
9802
|
-
var toString$5 = toString$n;
|
|
9803
|
-
var requireObjectCoercible$3 = requireObjectCoercible$e;
|
|
9804
|
-
var getMethod = getMethod$7;
|
|
9805
|
-
var advanceStringIndex = advanceStringIndex$3;
|
|
9806
|
-
var regExpExec = regexpExecAbstract;
|
|
9807
|
-
|
|
9808
|
-
// @@match logic
|
|
9809
|
-
fixRegExpWellKnownSymbolLogic('match', function (MATCH, nativeMatch, maybeCallNative) {
|
|
9810
|
-
return [
|
|
9811
|
-
// `String.prototype.match` method
|
|
9812
|
-
// https://tc39.es/ecma262/#sec-string.prototype.match
|
|
9813
|
-
function match(regexp) {
|
|
9814
|
-
var O = requireObjectCoercible$3(this);
|
|
9815
|
-
var matcher = isNullOrUndefined(regexp) ? undefined : getMethod(regexp, MATCH);
|
|
9816
|
-
return matcher ? call$2(matcher, regexp, O) : new RegExp(regexp)[MATCH](toString$5(O));
|
|
9817
|
-
},
|
|
9818
|
-
// `RegExp.prototype[@@match]` method
|
|
9819
|
-
// https://tc39.es/ecma262/#sec-regexp.prototype-@@match
|
|
9820
|
-
function (string) {
|
|
9821
|
-
var rx = anObject(this);
|
|
9822
|
-
var S = toString$5(string);
|
|
9823
|
-
var res = maybeCallNative(nativeMatch, rx, S);
|
|
9824
|
-
|
|
9825
|
-
if (res.done) return res.value;
|
|
9826
|
-
|
|
9827
|
-
if (!rx.global) return regExpExec(rx, S);
|
|
9828
|
-
|
|
9829
|
-
var fullUnicode = rx.unicode;
|
|
9830
|
-
rx.lastIndex = 0;
|
|
9831
|
-
var A = [];
|
|
9832
|
-
var n = 0;
|
|
9833
|
-
var result;
|
|
9834
|
-
while ((result = regExpExec(rx, S)) !== null) {
|
|
9835
|
-
var matchStr = toString$5(result[0]);
|
|
9836
|
-
A[n] = matchStr;
|
|
9837
|
-
if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength$2(rx.lastIndex), fullUnicode);
|
|
9838
|
-
n++;
|
|
9839
|
-
}
|
|
9840
|
-
return n === 0 ? null : A;
|
|
9841
|
-
}
|
|
9842
|
-
];
|
|
9843
|
-
});
|
|
9844
|
-
|
|
9845
9973
|
//type DebounceValueType = string | boolean | number | Record<string, unknown>;
|
|
9846
9974
|
/**
|
|
9847
9975
|
* A helper util to return a value at a certain delay. The delay is reset if the value arg changes
|
|
@@ -9872,23 +10000,6 @@ function fetchRegisterConfigFromOptions$1(options) {
|
|
|
9872
10000
|
const config = Object.assign({}, options);
|
|
9873
10001
|
return config;
|
|
9874
10002
|
}
|
|
9875
|
-
const formattedSinPattern = /^\d{3}-\d{3}-\d{3}$/;
|
|
9876
|
-
const allowedSinInputPattern = /^[\d-]*$/;
|
|
9877
|
-
const allowedSinKeyPattern = /^[\d-]$/;
|
|
9878
|
-
const allowedSinControlKeys = new Set(['Backspace', 'Delete', 'Tab', 'Enter', 'Escape', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End']);
|
|
9879
|
-
const formatSinForDisplay = value => value.replace(/ /g, '-');
|
|
9880
|
-
const formatSinForSchema = value => value.replace(/-/g, ' ');
|
|
9881
|
-
const formatSin = value => {
|
|
9882
|
-
var _digits$match$join, _digits$match;
|
|
9883
|
-
if (!allowedSinInputPattern.test(value)) {
|
|
9884
|
-
return '';
|
|
9885
|
-
}
|
|
9886
|
-
if (formattedSinPattern.test(value)) {
|
|
9887
|
-
return value;
|
|
9888
|
-
}
|
|
9889
|
-
const digits = value == null ? void 0 : value.replace(/\D/g, '').slice(0, 9);
|
|
9890
|
-
return (_digits$match$join = digits == null || (_digits$match = digits.match(/.{1,3}/g)) == null ? void 0 : _digits$match.join('-')) != null ? _digits$match$join : '';
|
|
9891
|
-
};
|
|
9892
10003
|
const resetInputValue = (detail, value) => {
|
|
9893
10004
|
var _detail$event;
|
|
9894
10005
|
const target = (_detail$event = detail.event) == null ? void 0 : _detail$event.target;
|
|
@@ -9896,6 +10007,13 @@ const resetInputValue = (detail, value) => {
|
|
|
9896
10007
|
target.value = value;
|
|
9897
10008
|
}
|
|
9898
10009
|
};
|
|
10010
|
+
// Resolve the mask format for a field: schema.format must match a DEFAULT_PATTERNS key.
|
|
10011
|
+
const resolveFormatConfig = schema => {
|
|
10012
|
+
if (schema.format && schema.format in DEFAULT_PATTERNS) {
|
|
10013
|
+
return DEFAULT_PATTERNS[schema.format];
|
|
10014
|
+
}
|
|
10015
|
+
return schema.title === sinTitle ? DEFAULT_PATTERNS.sin : undefined;
|
|
10016
|
+
};
|
|
9899
10017
|
const GoAInputText = props => {
|
|
9900
10018
|
return jsxs(JsonFormRegisterProvider, {
|
|
9901
10019
|
defaultRegisters: undefined,
|
|
@@ -9903,7 +10021,7 @@ const GoAInputText = props => {
|
|
|
9903
10021
|
});
|
|
9904
10022
|
};
|
|
9905
10023
|
const InnerGoAInputText = props => {
|
|
9906
|
-
var _uischema$options$
|
|
10024
|
+
var _formatConfig$mask, _uischema$options, _uischema$options2, _uischema$options$com, _uischema$options3, _props$uischema, _uischema$options4, _uischema$options5, _uischema$options$pla, _uischema$options6, _props$uischema2, _uischema$options7, _uischema$options8, _uischema$options$com2, _uischema$options9, _uischema$options0, _uischema$options1, _uischema$options10;
|
|
9907
10025
|
const {
|
|
9908
10026
|
data,
|
|
9909
10027
|
config,
|
|
@@ -9918,18 +10036,37 @@ const InnerGoAInputText = props => {
|
|
|
9918
10036
|
isVisited,
|
|
9919
10037
|
setIsVisited
|
|
9920
10038
|
} = props;
|
|
9921
|
-
|
|
9922
|
-
const
|
|
10039
|
+
// Detect the mask format from the JSON schema `format` (with the SIN title kept for backward compatibility).
|
|
10040
|
+
const formatConfig = resolveFormatConfig(schema);
|
|
10041
|
+
const mask = (_formatConfig$mask = formatConfig == null ? void 0 : formatConfig.mask) != null ? _formatConfig$mask : uischema == null || (_uischema$options = uischema.options) == null ? void 0 : _uischema$options.mask;
|
|
10042
|
+
const allowedKeys = formatConfig == null ? void 0 : formatConfig.allowedKeys;
|
|
10043
|
+
// In-place shows the fill-in template and keeps the caret in place while editing.
|
|
10044
|
+
const inPlace = !!mask && (uischema == null || (_uischema$options2 = uischema.options) == null ? void 0 : _uischema$options2.inPlace) === true;
|
|
10045
|
+
const toDisplay = value => {
|
|
10046
|
+
if (!mask) {
|
|
10047
|
+
return value;
|
|
10048
|
+
}
|
|
10049
|
+
const str = typeof value === 'string' ? value : '';
|
|
10050
|
+
return inPlace ? toMaskTemplate(str, mask) : formatWithPattern(str, mask);
|
|
10051
|
+
};
|
|
9923
10052
|
const [manualInput, setManualInput] = useState(false);
|
|
9924
|
-
|
|
10053
|
+
// In-place mounts empty then sets the template so the web component reflects it (a value change forces the paint).
|
|
10054
|
+
const [localValue, setLocalValue] = useState(inPlace ? '' : toDisplay(data));
|
|
10055
|
+
useEffect(() => {
|
|
10056
|
+
if (inPlace) {
|
|
10057
|
+
setLocalValue(toDisplay(data));
|
|
10058
|
+
}
|
|
10059
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
10060
|
+
}, []);
|
|
9925
10061
|
const debouncedValue = useDebounce(localValue, 300);
|
|
9926
10062
|
const hasDefault = Object.prototype.hasOwnProperty.call(schema, 'default');
|
|
9927
10063
|
useEffect(() => {
|
|
9928
10064
|
if (data === undefined || data === null) {
|
|
9929
10065
|
return;
|
|
9930
10066
|
}
|
|
9931
|
-
setLocalValue(
|
|
9932
|
-
|
|
10067
|
+
setLocalValue(toDisplay(data));
|
|
10068
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
10069
|
+
}, [data, mask]);
|
|
9933
10070
|
useEffect(() => {
|
|
9934
10071
|
if (typeof handleChange === 'function' && hasDefault && data === undefined && !manualInput) {
|
|
9935
10072
|
handleChange(props.path, schema.default);
|
|
@@ -9939,17 +10076,19 @@ const InnerGoAInputText = props => {
|
|
|
9939
10076
|
}, [schema.default, data]);
|
|
9940
10077
|
/* istanbul ignore next */
|
|
9941
10078
|
useEffect(() => {
|
|
9942
|
-
const dataForInput =
|
|
10079
|
+
const dataForInput = toDisplay(data);
|
|
9943
10080
|
if (debouncedValue === dataForInput) return;
|
|
9944
10081
|
// Only sync if debouncedValue differs from data and is not initial empty state
|
|
9945
10082
|
if (debouncedValue !== dataForInput && (debouncedValue !== '' || data !== undefined)) {
|
|
9946
10083
|
onChangeForInputControl({
|
|
9947
|
-
value
|
|
10084
|
+
// Normalize to the clean value; for in-place this drops the unfilled template characters.
|
|
10085
|
+
value: mask ? formatWithPattern(debouncedValue, mask) : debouncedValue,
|
|
9948
10086
|
controlProps: props
|
|
9949
10087
|
});
|
|
9950
10088
|
}
|
|
10089
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
9951
10090
|
}, [debouncedValue]);
|
|
9952
|
-
const width = (_uischema$options$com = uischema == null || (_uischema$
|
|
10091
|
+
const width = (_uischema$options$com = uischema == null || (_uischema$options3 = uischema.options) == null || (_uischema$options3 = _uischema$options3.componentProps) == null ? void 0 : _uischema$options3.width) != null ? _uischema$options$com : '100%';
|
|
9953
10092
|
const registerCtx = useContext(JsonFormsRegisterContext);
|
|
9954
10093
|
const registerConfig = fetchRegisterConfigFromOptions$1((_props$uischema = props.uischema) == null || (_props$uischema = _props$uischema.options) == null ? void 0 : _props$uischema.register);
|
|
9955
10094
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -9957,9 +10096,9 @@ const InnerGoAInputText = props => {
|
|
|
9957
10096
|
if (registerConfig) {
|
|
9958
10097
|
registerData = registerCtx == null ? void 0 : registerCtx.selectRegisterData(registerConfig);
|
|
9959
10098
|
}
|
|
9960
|
-
const labelPath = (uischema == null || (_uischema$
|
|
9961
|
-
const valuePath = (uischema == null || (_uischema$
|
|
9962
|
-
const dropDownPlaceholder = (_uischema$options$pla = uischema == null || (_uischema$
|
|
10099
|
+
const labelPath = (uischema == null || (_uischema$options4 = uischema.options) == null ? void 0 : _uischema$options4.label) || 'label';
|
|
10100
|
+
const valuePath = (uischema == null || (_uischema$options5 = uischema.options) == null ? void 0 : _uischema$options5.value) || 'value';
|
|
10101
|
+
const dropDownPlaceholder = (_uischema$options$pla = uischema == null || (_uischema$options6 = uischema.options) == null ? void 0 : _uischema$options6.placeholder) != null ? _uischema$options$pla : 'Select an option';
|
|
9963
10102
|
const autoCompletion = ((_props$uischema2 = props.uischema) == null || (_props$uischema2 = _props$uischema2.options) == null ? void 0 : _props$uischema2.autoComplete) === true;
|
|
9964
10103
|
const mergedOptions = useMemo(() => {
|
|
9965
10104
|
var _registerData;
|
|
@@ -9996,32 +10135,10 @@ const InnerGoAInputText = props => {
|
|
|
9996
10135
|
}, [registerCtx, registerConfig]);
|
|
9997
10136
|
const appliedUiSchemaOptions = Object.assign({}, config, uischema == null ? void 0 : uischema.options);
|
|
9998
10137
|
const placeholder = (appliedUiSchemaOptions == null ? void 0 : appliedUiSchemaOptions.placeholder) || (schema == null ? void 0 : schema.description) || '';
|
|
9999
|
-
const autoCapitalize = (uischema == null || (_uischema$
|
|
10000
|
-
const readOnly = (_uischema$options$com2 = uischema == null || (_uischema$
|
|
10001
|
-
const
|
|
10002
|
-
if (!isSinField || allowedSinControlKeys.has(event.key) || event.metaKey || event.ctrlKey || event.altKey || allowedSinKeyPattern.test(event.key)) {
|
|
10003
|
-
return;
|
|
10004
|
-
}
|
|
10005
|
-
event.preventDefault();
|
|
10006
|
-
};
|
|
10007
|
-
const preventInvalidSinBeforeInput = event => {
|
|
10008
|
-
if (!isSinField) {
|
|
10009
|
-
return;
|
|
10010
|
-
}
|
|
10011
|
-
const data = event.nativeEvent.data;
|
|
10012
|
-
if (data && !allowedSinInputPattern.test(data)) {
|
|
10013
|
-
event.preventDefault();
|
|
10014
|
-
}
|
|
10015
|
-
};
|
|
10016
|
-
const preventInvalidSinPaste = event => {
|
|
10017
|
-
if (isSinField && !allowedSinInputPattern.test(event.clipboardData.getData('text'))) {
|
|
10018
|
-
event.preventDefault();
|
|
10019
|
-
}
|
|
10020
|
-
};
|
|
10138
|
+
const autoCapitalize = (uischema == null || (_uischema$options7 = uischema.options) == null || (_uischema$options7 = _uischema$options7.componentProps) == null ? void 0 : _uischema$options7.autoCapitalize) === true || (uischema == null || (_uischema$options8 = uischema.options) == null ? void 0 : _uischema$options8.autoCapitalize) === true;
|
|
10139
|
+
const readOnly = (_uischema$options$com2 = uischema == null || (_uischema$options9 = uischema.options) == null || (_uischema$options9 = _uischema$options9.componentProps) == null ? void 0 : _uischema$options9.readOnly) != null ? _uischema$options$com2 : false;
|
|
10140
|
+
const formatPattern = uischema == null || (_uischema$options0 = uischema.options) == null ? void 0 : _uischema$options0.formatPattern;
|
|
10021
10141
|
return jsx("div", {
|
|
10022
|
-
onKeyDownCapture: preventInvalidSinKey,
|
|
10023
|
-
onBeforeInputCapture: preventInvalidSinBeforeInput,
|
|
10024
|
-
onPasteCapture: preventInvalidSinPaste,
|
|
10025
10142
|
children: mergedOptions.length > 1 ? jsx(GoabDropdown, {
|
|
10026
10143
|
name: `jsonforms-${path}-dropdown`,
|
|
10027
10144
|
value: data,
|
|
@@ -10042,22 +10159,29 @@ const InnerGoAInputText = props => {
|
|
|
10042
10159
|
value: localValue,
|
|
10043
10160
|
width: width,
|
|
10044
10161
|
readonly: readOnly,
|
|
10045
|
-
maxLength:
|
|
10046
|
-
placeholder: placeholder,
|
|
10162
|
+
maxLength: inPlace ? undefined : mask ? mask.length : undefined,
|
|
10163
|
+
placeholder: inPlace ? undefined : mask ? maskPlaceholder(mask) : placeholder,
|
|
10047
10164
|
name: (appliedUiSchemaOptions == null ? void 0 : appliedUiSchemaOptions.name) || `${id || label}-input`,
|
|
10048
10165
|
ariaLabel: (appliedUiSchemaOptions == null ? void 0 : appliedUiSchemaOptions.name) || `${id || label}-input`,
|
|
10049
10166
|
testId: (appliedUiSchemaOptions == null ? void 0 : appliedUiSchemaOptions.testId) || `${id}-input`
|
|
10050
|
-
}, (_uischema$
|
|
10167
|
+
}, (_uischema$options1 = uischema.options) == null ? void 0 : _uischema$options1.componentProps, {
|
|
10051
10168
|
onChange: detail => {
|
|
10052
|
-
|
|
10053
|
-
if (
|
|
10054
|
-
|
|
10055
|
-
|
|
10056
|
-
|
|
10057
|
-
|
|
10058
|
-
|
|
10169
|
+
const cleaned = allowedKeys ? filterAllowedKeys(detail.value, allowedKeys) : detail.value;
|
|
10170
|
+
if (inPlace && mask) {
|
|
10171
|
+
var _target$selectionStar;
|
|
10172
|
+
const target = getMaskInputTarget(detail);
|
|
10173
|
+
const caretIndex = (_target$selectionStar = target == null ? void 0 : target.selectionStart) != null ? _target$selectionStar : cleaned.length;
|
|
10174
|
+
const edit = computeMaskEdit(cleaned, caretIndex, mask);
|
|
10175
|
+
applyInPlaceEdit(target, edit);
|
|
10176
|
+
setLocalValue(edit.display);
|
|
10177
|
+
} else {
|
|
10178
|
+
const formattedValue = mask && cleaned !== '' ? formatWithPattern(cleaned, mask) : cleaned;
|
|
10179
|
+
// If characters were rejected, force the input to show the cleaned value.
|
|
10180
|
+
if (allowedKeys && cleaned !== detail.value) {
|
|
10181
|
+
resetInputValue(detail, formattedValue);
|
|
10182
|
+
}
|
|
10183
|
+
setLocalValue(formattedValue);
|
|
10059
10184
|
}
|
|
10060
|
-
setLocalValue(formattedValue);
|
|
10061
10185
|
setManualInput(true);
|
|
10062
10186
|
if (isVisited === false && setIsVisited) {
|
|
10063
10187
|
setIsVisited();
|
|
@@ -10067,19 +10191,29 @@ const InnerGoAInputText = props => {
|
|
|
10067
10191
|
if (isVisited === false && setIsVisited) {
|
|
10068
10192
|
setIsVisited();
|
|
10069
10193
|
}
|
|
10194
|
+
const capitalizedValue = autoCapitalize ? detail.value.toUpperCase() : detail.value;
|
|
10195
|
+
if (formatPattern) {
|
|
10196
|
+
const formattedValue = applyFormatPattern(capitalizedValue, formatPattern);
|
|
10197
|
+
setLocalValue(formattedValue);
|
|
10198
|
+
handleChange(path, formattedValue);
|
|
10199
|
+
return;
|
|
10200
|
+
}
|
|
10070
10201
|
onBlurForTextControl({
|
|
10071
10202
|
name: detail.name,
|
|
10072
10203
|
controlProps: props,
|
|
10073
|
-
value:
|
|
10204
|
+
value: capitalizedValue
|
|
10074
10205
|
});
|
|
10075
10206
|
},
|
|
10076
10207
|
onKeyPress: detail => {
|
|
10077
|
-
|
|
10208
|
+
const blockDisallowed = shouldBlockKey(detail.key, allowedKeys);
|
|
10209
|
+
// In-place has no length cap, so also block content keys once the template is full.
|
|
10210
|
+
const blockOverflow = inPlace && !!mask && /^[A-Za-z0-9]$/.test(detail.key) && isMaskFilled(localValue, mask);
|
|
10211
|
+
if (blockDisallowed || blockOverflow) {
|
|
10078
10212
|
var _detail$event2;
|
|
10079
10213
|
(_detail$event2 = detail.event) == null || _detail$event2.preventDefault();
|
|
10080
10214
|
}
|
|
10081
10215
|
}
|
|
10082
|
-
}, uischema == null || (_uischema$
|
|
10216
|
+
}, uischema == null || (_uischema$options10 = uischema.options) == null ? void 0 : _uischema$options10.componentProps))
|
|
10083
10217
|
});
|
|
10084
10218
|
};
|
|
10085
10219
|
const GoATextControl = props => jsx(GoAInputBaseControl, Object.assign({}, props, {
|
|
@@ -10238,15 +10372,15 @@ function _objectWithoutPropertiesLoose(r, e) {
|
|
|
10238
10372
|
}
|
|
10239
10373
|
|
|
10240
10374
|
var toIntegerOrInfinity$1 = toIntegerOrInfinity$9;
|
|
10241
|
-
var toString$
|
|
10242
|
-
var requireObjectCoercible$
|
|
10375
|
+
var toString$5 = toString$n;
|
|
10376
|
+
var requireObjectCoercible$3 = requireObjectCoercible$e;
|
|
10243
10377
|
|
|
10244
10378
|
var $RangeError$1 = RangeError;
|
|
10245
10379
|
|
|
10246
10380
|
// `String.prototype.repeat` method implementation
|
|
10247
10381
|
// https://tc39.es/ecma262/#sec-string.prototype.repeat
|
|
10248
10382
|
var stringRepeat = function repeat(count) {
|
|
10249
|
-
var str = toString$
|
|
10383
|
+
var str = toString$5(requireObjectCoercible$3(this));
|
|
10250
10384
|
var result = '';
|
|
10251
10385
|
var n = toIntegerOrInfinity$1(count);
|
|
10252
10386
|
if (n < 0 || n === Infinity) throw new $RangeError$1('Wrong number of repetitions');
|
|
@@ -10256,10 +10390,10 @@ var stringRepeat = function repeat(count) {
|
|
|
10256
10390
|
|
|
10257
10391
|
// https://github.com/tc39/proposal-string-pad-start-end
|
|
10258
10392
|
var uncurryThis$4 = functionUncurryThis;
|
|
10259
|
-
var toLength$
|
|
10260
|
-
var toString$
|
|
10393
|
+
var toLength$2 = toLength$7;
|
|
10394
|
+
var toString$4 = toString$n;
|
|
10261
10395
|
var $repeat = stringRepeat;
|
|
10262
|
-
var requireObjectCoercible$
|
|
10396
|
+
var requireObjectCoercible$2 = requireObjectCoercible$e;
|
|
10263
10397
|
|
|
10264
10398
|
var repeat = uncurryThis$4($repeat);
|
|
10265
10399
|
var stringSlice$1 = uncurryThis$4(''.slice);
|
|
@@ -10268,10 +10402,10 @@ var ceil = Math.ceil;
|
|
|
10268
10402
|
// `String.prototype.{ padStart, padEnd }` methods implementation
|
|
10269
10403
|
var createMethod = function (IS_END) {
|
|
10270
10404
|
return function ($this, maxLength, fillString) {
|
|
10271
|
-
var S = toString$
|
|
10272
|
-
var intMaxLength = toLength$
|
|
10405
|
+
var S = toString$4(requireObjectCoercible$2($this));
|
|
10406
|
+
var intMaxLength = toLength$2(maxLength);
|
|
10273
10407
|
var stringLength = S.length;
|
|
10274
|
-
var fillStr = fillString === undefined ? ' ' : toString$
|
|
10408
|
+
var fillStr = fillString === undefined ? ' ' : toString$4(fillString);
|
|
10275
10409
|
var fillLen, stringFiller;
|
|
10276
10410
|
if (intMaxLength <= stringLength || fillStr === '') return S;
|
|
10277
10411
|
fillLen = intMaxLength - stringLength;
|
|
@@ -11315,6 +11449,54 @@ const GoInputBaseReview = props => jsx(GoAInputBaseControl, Object.assign({}, pr
|
|
|
11315
11449
|
}));
|
|
11316
11450
|
const GoAInputBaseReviewControl = withJsonFormsControlProps(GoInputBaseReview);
|
|
11317
11451
|
|
|
11452
|
+
var call$2 = functionCall;
|
|
11453
|
+
var fixRegExpWellKnownSymbolLogic = fixRegexpWellKnownSymbolLogic;
|
|
11454
|
+
var anObject = anObject$t;
|
|
11455
|
+
var isNullOrUndefined = isNullOrUndefined$7;
|
|
11456
|
+
var toLength$1 = toLength$7;
|
|
11457
|
+
var toString$3 = toString$n;
|
|
11458
|
+
var requireObjectCoercible$1 = requireObjectCoercible$e;
|
|
11459
|
+
var getMethod = getMethod$7;
|
|
11460
|
+
var advanceStringIndex = advanceStringIndex$3;
|
|
11461
|
+
var regExpExec = regexpExecAbstract;
|
|
11462
|
+
|
|
11463
|
+
// @@match logic
|
|
11464
|
+
fixRegExpWellKnownSymbolLogic('match', function (MATCH, nativeMatch, maybeCallNative) {
|
|
11465
|
+
return [
|
|
11466
|
+
// `String.prototype.match` method
|
|
11467
|
+
// https://tc39.es/ecma262/#sec-string.prototype.match
|
|
11468
|
+
function match(regexp) {
|
|
11469
|
+
var O = requireObjectCoercible$1(this);
|
|
11470
|
+
var matcher = isNullOrUndefined(regexp) ? undefined : getMethod(regexp, MATCH);
|
|
11471
|
+
return matcher ? call$2(matcher, regexp, O) : new RegExp(regexp)[MATCH](toString$3(O));
|
|
11472
|
+
},
|
|
11473
|
+
// `RegExp.prototype[@@match]` method
|
|
11474
|
+
// https://tc39.es/ecma262/#sec-regexp.prototype-@@match
|
|
11475
|
+
function (string) {
|
|
11476
|
+
var rx = anObject(this);
|
|
11477
|
+
var S = toString$3(string);
|
|
11478
|
+
var res = maybeCallNative(nativeMatch, rx, S);
|
|
11479
|
+
|
|
11480
|
+
if (res.done) return res.value;
|
|
11481
|
+
|
|
11482
|
+
if (!rx.global) return regExpExec(rx, S);
|
|
11483
|
+
|
|
11484
|
+
var fullUnicode = rx.unicode;
|
|
11485
|
+
rx.lastIndex = 0;
|
|
11486
|
+
var A = [];
|
|
11487
|
+
var n = 0;
|
|
11488
|
+
var result;
|
|
11489
|
+
while ((result = regExpExec(rx, S)) !== null) {
|
|
11490
|
+
var matchStr = toString$3(result[0]);
|
|
11491
|
+
A[n] = matchStr;
|
|
11492
|
+
if (matchStr === '') rx.lastIndex = advanceStringIndex(S, toLength$1(rx.lastIndex), fullUnicode);
|
|
11493
|
+
n++;
|
|
11494
|
+
}
|
|
11495
|
+
return n === 0 ? null : A;
|
|
11496
|
+
}
|
|
11497
|
+
];
|
|
11498
|
+
});
|
|
11499
|
+
|
|
11318
11500
|
var $$6 = _export;
|
|
11319
11501
|
var toObject$2 = toObject$c;
|
|
11320
11502
|
var lengthOfArrayLike$2 = lengthOfArrayLike$c;
|
|
@@ -13640,107 +13822,83 @@ const FullNameDobReviewControl = props => {
|
|
|
13640
13822
|
};
|
|
13641
13823
|
const GoAInputBaseFullNameDobControlReview = withJsonFormsAllOfProps(FullNameDobReviewControl);
|
|
13642
13824
|
|
|
13643
|
-
|
|
13644
|
-
|
|
13645
|
-
|
|
13646
|
-
|
|
13647
|
-
|
|
13648
|
-
|
|
13649
|
-
|
|
13650
|
-
|
|
13651
|
-
|
|
13652
|
-
|
|
13653
|
-
|
|
13654
|
-
}
|
|
13655
|
-
`));
|
|
13656
|
-
const PHONE_REGEX = /^\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$/;
|
|
13657
|
-
const normalizePhoneData = value => ({
|
|
13658
|
-
type: (value == null ? void 0 : value.type) || '',
|
|
13659
|
-
number: (value == null ? void 0 : value.number) || ''
|
|
13660
|
-
});
|
|
13661
|
-
const PhoneNumberWithTypeControl = props => {
|
|
13662
|
-
const {
|
|
13663
|
-
data,
|
|
13664
|
-
path,
|
|
13665
|
-
handleChange,
|
|
13666
|
-
enabled,
|
|
13667
|
-
visible,
|
|
13668
|
-
required
|
|
13669
|
-
} = props;
|
|
13670
|
-
const [formData, setFormData] = useState(normalizePhoneData(data));
|
|
13671
|
-
const [error, setError] = useState(undefined);
|
|
13825
|
+
// Encapsulates masked-input state for a GoA input: display value, mount reflection, and change/keypress handling.
|
|
13826
|
+
const useMaskedInput = ({
|
|
13827
|
+
mask,
|
|
13828
|
+
inPlace,
|
|
13829
|
+
data,
|
|
13830
|
+
onCommit
|
|
13831
|
+
}) => {
|
|
13832
|
+
const format = value => inPlace ? toMaskTemplate(value, mask) : formatWithPattern(value, mask);
|
|
13833
|
+
const initialDisplay = format(typeof data === 'string' ? data : '');
|
|
13834
|
+
// In-place mounts empty then sets the template so the web component reflects it (a value change forces the paint).
|
|
13835
|
+
const [value, setValue] = useState(inPlace ? '' : initialDisplay);
|
|
13672
13836
|
useEffect(() => {
|
|
13673
|
-
|
|
13674
|
-
|
|
13675
|
-
}, [data]);
|
|
13676
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13677
|
-
const updateFormData = updated => {
|
|
13678
|
-
setFormData(updated);
|
|
13679
|
-
if (updated.number && !PHONE_REGEX.test(updated.number)) {
|
|
13680
|
-
setError('Enter a valid phone number (e.g., (780) 123-4567)');
|
|
13681
|
-
} else {
|
|
13682
|
-
setError(undefined);
|
|
13837
|
+
if (inPlace) {
|
|
13838
|
+
setValue(initialDisplay);
|
|
13683
13839
|
}
|
|
13684
|
-
|
|
13840
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
13841
|
+
}, []);
|
|
13842
|
+
const handleChange = detail => {
|
|
13843
|
+
var _target$selectionStar;
|
|
13844
|
+
const rawValue = detail.value;
|
|
13845
|
+
if (!inPlace) {
|
|
13846
|
+
const stored = formatWithPattern(rawValue, mask);
|
|
13847
|
+
setValue(stored);
|
|
13848
|
+
onCommit(stored);
|
|
13849
|
+
return;
|
|
13850
|
+
}
|
|
13851
|
+
const target = getMaskInputTarget(detail);
|
|
13852
|
+
const caretIndex = (_target$selectionStar = target == null ? void 0 : target.selectionStart) != null ? _target$selectionStar : rawValue.length;
|
|
13853
|
+
const edit = computeMaskEdit(rawValue, caretIndex, mask);
|
|
13854
|
+
applyInPlaceEdit(target, edit);
|
|
13855
|
+
setValue(edit.display);
|
|
13856
|
+
onCommit(edit.stored);
|
|
13857
|
+
};
|
|
13858
|
+
// In-place mode has no native length cap, so block extra content characters at the source.
|
|
13859
|
+
const handleKeyPress = detail => {
|
|
13860
|
+
if (inPlace && /^[A-Za-z0-9]$/.test(detail.key) && isMaskFilled(value, mask)) {
|
|
13861
|
+
var _detail$event;
|
|
13862
|
+
(_detail$event = detail.event) == null || _detail$event.preventDefault();
|
|
13863
|
+
}
|
|
13864
|
+
};
|
|
13865
|
+
return {
|
|
13866
|
+
value,
|
|
13867
|
+
handleChange,
|
|
13868
|
+
handleKeyPress
|
|
13685
13869
|
};
|
|
13686
|
-
return jsx(Visible, {
|
|
13687
|
-
"$visible": visible,
|
|
13688
|
-
children: jsxs(PhoneGrid, {
|
|
13689
|
-
children: [jsx(GoabFormItem, {
|
|
13690
|
-
label: "Phone type",
|
|
13691
|
-
requirement: required ? 'required' : undefined,
|
|
13692
|
-
children: jsxs(GoabDropdown, {
|
|
13693
|
-
name: "type",
|
|
13694
|
-
value: formData.type || '',
|
|
13695
|
-
disabled: !enabled,
|
|
13696
|
-
onChange: detail => updateFormData(Object.assign({}, formData, {
|
|
13697
|
-
type: detail.value
|
|
13698
|
-
})),
|
|
13699
|
-
children: [jsx(GoabDropdownItem, {
|
|
13700
|
-
value: "Mobile"
|
|
13701
|
-
}), jsx(GoabDropdownItem, {
|
|
13702
|
-
value: "Landline"
|
|
13703
|
-
})]
|
|
13704
|
-
})
|
|
13705
|
-
}), jsx(GoabFormItem, {
|
|
13706
|
-
label: "Phone number",
|
|
13707
|
-
error: error,
|
|
13708
|
-
requirement: required ? 'required' : undefined,
|
|
13709
|
-
children: jsx(GoabInput, {
|
|
13710
|
-
type: "tel",
|
|
13711
|
-
name: "number",
|
|
13712
|
-
placeholder: "(000) 000-0000",
|
|
13713
|
-
value: formData.number || '',
|
|
13714
|
-
disabled: !enabled,
|
|
13715
|
-
onChange: detail => updateFormData(Object.assign({}, formData, {
|
|
13716
|
-
number: detail.value
|
|
13717
|
-
}))
|
|
13718
|
-
})
|
|
13719
|
-
})]
|
|
13720
|
-
})
|
|
13721
|
-
});
|
|
13722
13870
|
};
|
|
13723
|
-
const GoAPhoneNumberWithTypeControl = withJsonFormsControlProps(PhoneNumberWithTypeControl);
|
|
13724
13871
|
|
|
13725
13872
|
const PhoneNumberControl = props => {
|
|
13873
|
+
var _uischema$options, _uischema$options2;
|
|
13726
13874
|
const {
|
|
13727
13875
|
data,
|
|
13728
13876
|
path,
|
|
13729
13877
|
schema,
|
|
13878
|
+
uischema,
|
|
13730
13879
|
handleChange,
|
|
13731
13880
|
enabled,
|
|
13732
13881
|
visible,
|
|
13733
13882
|
required
|
|
13734
13883
|
} = props;
|
|
13884
|
+
// Default mask can be overridden per field via the UI schema options.
|
|
13885
|
+
const phoneMask = (uischema == null || (_uischema$options = uischema.options) == null ? void 0 : _uischema$options.phoneMask) || DEFAULT_PATTERNS.phone.mask;
|
|
13886
|
+
// When in-place, the field shows the fill-in template and edits keep the caret in place.
|
|
13887
|
+
const inPlace = (uischema == null || (_uischema$options2 = uischema.options) == null ? void 0 : _uischema$options2.inPlace) === true;
|
|
13735
13888
|
const [error, setError] = useState('');
|
|
13736
|
-
const
|
|
13737
|
-
|
|
13738
|
-
|
|
13739
|
-
|
|
13740
|
-
|
|
13889
|
+
const {
|
|
13890
|
+
value,
|
|
13891
|
+
handleChange: handleMaskChange,
|
|
13892
|
+
handleKeyPress
|
|
13893
|
+
} = useMaskedInput({
|
|
13894
|
+
mask: phoneMask,
|
|
13895
|
+
inPlace,
|
|
13896
|
+
data,
|
|
13897
|
+
onCommit: stored => {
|
|
13898
|
+
setError(stored && !DEFAULT_PATTERNS.phone.pattern.test(stored) ? DEFAULT_PATTERNS.phone.error : '');
|
|
13899
|
+
handleChange(path, stored);
|
|
13741
13900
|
}
|
|
13742
|
-
|
|
13743
|
-
};
|
|
13901
|
+
});
|
|
13744
13902
|
return jsx(Visible, {
|
|
13745
13903
|
"$visible": visible,
|
|
13746
13904
|
children: jsx(GoabFormItem, {
|
|
@@ -13754,9 +13912,11 @@ const PhoneNumberControl = props => {
|
|
|
13754
13912
|
disabled: !enabled,
|
|
13755
13913
|
"aria-label": "phone number input",
|
|
13756
13914
|
testId: `phone-input-${path}`,
|
|
13757
|
-
value:
|
|
13758
|
-
|
|
13759
|
-
placeholder:
|
|
13915
|
+
value: value,
|
|
13916
|
+
maxLength: inPlace ? undefined : phoneMask.length,
|
|
13917
|
+
placeholder: inPlace ? undefined : maskPlaceholder(phoneMask),
|
|
13918
|
+
onChange: detail => handleMaskChange(detail),
|
|
13919
|
+
onKeyPress: inPlace ? detail => handleKeyPress(detail) : undefined,
|
|
13760
13920
|
width: "100%"
|
|
13761
13921
|
})
|
|
13762
13922
|
})
|
|
@@ -13766,14 +13926,14 @@ const GoAPhoneNumberControl = withJsonFormsControlProps(PhoneNumberControl);
|
|
|
13766
13926
|
|
|
13767
13927
|
const PhoneNumberTester = rankWith(4, and(isControl$1, schemaTypeIs('string'), formatIs('phone')));
|
|
13768
13928
|
|
|
13769
|
-
let _$
|
|
13770
|
-
_t$
|
|
13929
|
+
let _$5 = t => t,
|
|
13930
|
+
_t$6,
|
|
13771
13931
|
_t2$2,
|
|
13772
13932
|
_t3$1,
|
|
13773
13933
|
_t4$1,
|
|
13774
13934
|
_t5,
|
|
13775
13935
|
_t6;
|
|
13776
|
-
const SearchBox = styled.div(_t$
|
|
13936
|
+
const SearchBox = styled.div(_t$6 || (_t$6 = _$5`
|
|
13777
13937
|
position: relative;
|
|
13778
13938
|
|
|
13779
13939
|
.suggestions {
|
|
@@ -13815,7 +13975,7 @@ const SearchBox = styled.div(_t$5 || (_t$5 = _$4`
|
|
|
13815
13975
|
pointer-events: none; /* Prevent spinner from interfering with clicks */
|
|
13816
13976
|
}
|
|
13817
13977
|
`));
|
|
13818
|
-
const AddressIndent = styled.div(_t2$2 || (_t2$2 = _$
|
|
13978
|
+
const AddressIndent = styled.div(_t2$2 || (_t2$2 = _$5`
|
|
13819
13979
|
margin: 0 0 var(--goa-space-m) 0;
|
|
13820
13980
|
text-wrap: wrap;
|
|
13821
13981
|
word-break: break-word;
|
|
@@ -13823,15 +13983,15 @@ const AddressIndent = styled.div(_t2$2 || (_t2$2 = _$4`
|
|
|
13823
13983
|
border-radius: var(--goa-border-radius-xl);
|
|
13824
13984
|
padding: var(--goa-space-l);
|
|
13825
13985
|
`));
|
|
13826
|
-
const TextWrap = styled.p(_t3$1 || (_t3$1 = _$
|
|
13986
|
+
const TextWrap = styled.p(_t3$1 || (_t3$1 = _$5`
|
|
13827
13987
|
text-wrap: auto;
|
|
13828
13988
|
word-break: break-word;
|
|
13829
13989
|
`));
|
|
13830
|
-
const TextWrapDiv = styled.div(_t4$1 || (_t4$1 = _$
|
|
13990
|
+
const TextWrapDiv = styled.div(_t4$1 || (_t4$1 = _$5`
|
|
13831
13991
|
text-wrap: auto;
|
|
13832
13992
|
word-break: break-word;
|
|
13833
13993
|
`));
|
|
13834
|
-
const LabelDiv = styled.div(_t5 || (_t5 = _$
|
|
13994
|
+
const LabelDiv = styled.div(_t5 || (_t5 = _$5`
|
|
13835
13995
|
color: var(--goa-color-text-default);
|
|
13836
13996
|
font: var(--goa-typography-body-m);
|
|
13837
13997
|
min-height: 2.625rem;
|
|
@@ -13841,7 +14001,7 @@ const LabelDiv = styled.div(_t5 || (_t5 = _$4`
|
|
|
13841
14001
|
word-break: break-word;
|
|
13842
14002
|
`));
|
|
13843
14003
|
/* istanbul ignore next */
|
|
13844
|
-
const ListItem = styled.li(_t6 || (_t6 = _$
|
|
14004
|
+
const ListItem = styled.li(_t6 || (_t6 = _$5`
|
|
13845
14005
|
background-color: ${0};
|
|
13846
14006
|
color: ${0};
|
|
13847
14007
|
font-weight: ${0};
|
|
@@ -13878,6 +14038,88 @@ const PhoneNumberReviewControl = props => {
|
|
|
13878
14038
|
};
|
|
13879
14039
|
const GoabInputBasePhoneNumberReviewControl = withJsonFormsAllOfProps(PhoneNumberReviewControl);
|
|
13880
14040
|
|
|
14041
|
+
let _$4 = t => t,
|
|
14042
|
+
_t$5;
|
|
14043
|
+
const PhoneGrid = styled.div(_t$5 || (_t$5 = _$4`
|
|
14044
|
+
display: grid;
|
|
14045
|
+
grid-template-columns: 1fr 2fr;
|
|
14046
|
+
gap: 0.2rem;
|
|
14047
|
+
align-items: start;
|
|
14048
|
+
margin-bottom: var(--goa-space-l) !important;
|
|
14049
|
+
|
|
14050
|
+
goa-form-item {
|
|
14051
|
+
margin-right: 0 !important;
|
|
14052
|
+
}
|
|
14053
|
+
`));
|
|
14054
|
+
const PHONE_REGEX = /^\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$/;
|
|
14055
|
+
const normalizePhoneData = value => ({
|
|
14056
|
+
type: (value == null ? void 0 : value.type) || '',
|
|
14057
|
+
number: (value == null ? void 0 : value.number) || ''
|
|
14058
|
+
});
|
|
14059
|
+
const PhoneNumberWithTypeControl = props => {
|
|
14060
|
+
const {
|
|
14061
|
+
data,
|
|
14062
|
+
path,
|
|
14063
|
+
handleChange,
|
|
14064
|
+
enabled,
|
|
14065
|
+
visible,
|
|
14066
|
+
required
|
|
14067
|
+
} = props;
|
|
14068
|
+
const [formData, setFormData] = useState(normalizePhoneData(data));
|
|
14069
|
+
const [error, setError] = useState(undefined);
|
|
14070
|
+
useEffect(() => {
|
|
14071
|
+
const nextData = normalizePhoneData(data);
|
|
14072
|
+
setFormData(currentData => currentData.type === nextData.type && currentData.number === nextData.number ? currentData : nextData);
|
|
14073
|
+
}, [data]);
|
|
14074
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
14075
|
+
const updateFormData = updated => {
|
|
14076
|
+
setFormData(updated);
|
|
14077
|
+
if (updated.number && !PHONE_REGEX.test(updated.number)) {
|
|
14078
|
+
setError('Enter a valid phone number (e.g., (780) 123-4567)');
|
|
14079
|
+
} else {
|
|
14080
|
+
setError(undefined);
|
|
14081
|
+
}
|
|
14082
|
+
handleChange(path, updated);
|
|
14083
|
+
};
|
|
14084
|
+
return jsx(Visible, {
|
|
14085
|
+
"$visible": visible,
|
|
14086
|
+
children: jsxs(PhoneGrid, {
|
|
14087
|
+
children: [jsx(GoabFormItem, {
|
|
14088
|
+
label: "Phone type",
|
|
14089
|
+
requirement: required ? 'required' : undefined,
|
|
14090
|
+
children: jsxs(GoabDropdown, {
|
|
14091
|
+
name: "type",
|
|
14092
|
+
value: formData.type || '',
|
|
14093
|
+
disabled: !enabled,
|
|
14094
|
+
onChange: detail => updateFormData(Object.assign({}, formData, {
|
|
14095
|
+
type: detail.value
|
|
14096
|
+
})),
|
|
14097
|
+
children: [jsx(GoabDropdownItem, {
|
|
14098
|
+
value: "Mobile"
|
|
14099
|
+
}), jsx(GoabDropdownItem, {
|
|
14100
|
+
value: "Landline"
|
|
14101
|
+
})]
|
|
14102
|
+
})
|
|
14103
|
+
}), jsx(GoabFormItem, {
|
|
14104
|
+
label: "Phone number",
|
|
14105
|
+
error: error,
|
|
14106
|
+
requirement: required ? 'required' : undefined,
|
|
14107
|
+
children: jsx(GoabInput, {
|
|
14108
|
+
type: "tel",
|
|
14109
|
+
name: "number",
|
|
14110
|
+
placeholder: "(000) 000-0000",
|
|
14111
|
+
value: formData.number || '',
|
|
14112
|
+
disabled: !enabled,
|
|
14113
|
+
onChange: detail => updateFormData(Object.assign({}, formData, {
|
|
14114
|
+
number: detail.value
|
|
14115
|
+
}))
|
|
14116
|
+
})
|
|
14117
|
+
})]
|
|
14118
|
+
})
|
|
14119
|
+
});
|
|
14120
|
+
};
|
|
14121
|
+
const GoAPhoneNumberWithTypeControl = withJsonFormsControlProps(PhoneNumberWithTypeControl);
|
|
14122
|
+
|
|
13881
14123
|
const isPhoneNumberWithType = createSchemaMatchTester(['number', 'type'], true);
|
|
13882
14124
|
const PhoneNumberWithTypeTester = rankWith(4, isPhoneNumberWithType);
|
|
13883
14125
|
|
|
@@ -20300,6 +20542,8 @@ const GoAErrorControlTester = rankWith(1000, (uischema, schema, context) => {
|
|
|
20300
20542
|
});
|
|
20301
20543
|
var GoAErrorControl = withJsonFormsControlProps(ErrorControl);
|
|
20302
20544
|
|
|
20545
|
+
// Allow empty values so incomplete fields are not treated as format errors.
|
|
20546
|
+
const optionalFormat = pattern => input => !input || pattern.test(input);
|
|
20303
20547
|
const createDefaultAjv = (...schemas) => {
|
|
20304
20548
|
const ajv = new Ajv({
|
|
20305
20549
|
allErrors: true,
|
|
@@ -20313,6 +20557,9 @@ const createDefaultAjv = (...schemas) => {
|
|
|
20313
20557
|
addErrors(ajv);
|
|
20314
20558
|
addFormats(ajv);
|
|
20315
20559
|
ajv.addFormat('time', /^([01]\d|2[0-3]):[0-5]\d(:[0-5]\d)?$/);
|
|
20560
|
+
Object.entries(DEFAULT_PATTERNS).forEach(([format, config]) => {
|
|
20561
|
+
ajv.addFormat(format, optionalFormat(config.pattern));
|
|
20562
|
+
});
|
|
20316
20563
|
ajv.addFormat('phone', PHONE_REGEX);
|
|
20317
20564
|
ajv.addFormat('computed', /^[a-zA-Z0-9._-]+$/);
|
|
20318
20565
|
ajv.addFormat('file-urn', {
|
|
@@ -20664,4 +20911,4 @@ const GoARenderers = [...GoABaseRenderers, {
|
|
|
20664
20911
|
}];
|
|
20665
20912
|
const GoACells = [...InputCells];
|
|
20666
20913
|
|
|
20667
|
-
export { ADD_DATALIST_ACTION, ADD_NO_ANONYMOUS_ACTION, ADD_REGISTER_DATA_ACTION, ADD_REGISTER_DATA_ERROR, ADD_USER_ACTION, AUTO_POPULATE_SOURCES, AddressLookUpControl, AddressLookUpControlReview, AddressLookUpTester, AddressLoopUpControlTableReview, ArrayControl, ArrayControlBase, ArrayControlReview, BooleanComponent, BooleanControl, BooleanRadioComponent, BooleanRadioControl, CategorizationPagesRendererTester, CategorizationStepperRendererTester, CheckboxGroup, ContactInformationTester, ContextProviderC, ContextProviderClass, ContextProviderFactory, ContractInfoControl, ContractInfoControlReview, EnumCheckboxControl, EnumRadioControl, EnumSelect, FileUploader, FileUploaderReview, FileUploaderTester, FormPageStepper, FormPagesView, FormStepper, FormStepperControl, FormStepperPagesControl, FormStepperReviewControl, FormStepperReviewer, FormStepperView, FullNameControl, FullNameControlReview, FullNameDobControl, FullNameDobReviewControl, FullNameDobTester, FullNameReviewControl, FullNameTester, GoAArrayControlRenderer, GoAArrayControlReviewRenderer, GoAArrayControlTester, GoABaseInputReviewComponent, GoABaseRenderers, GoABaseReviewRenderers, GoABaseTableReviewRenderers, GoABooleanControl, GoABooleanControlTester, GoABooleanRadioControl, GoABooleanRadioControlTester, GoACalculationControl, GoACalculationControlTester, GoACells, GoACheckoutGroupControlTester, GoAContractInfoControlReview, GoADateControl, GoADateControlTester, GoADateInput, GoADateTimeControl, GoADateTimeControlTester, GoADateTimeInput, GoAEmailControl, GoAEmailControlTester, GoAEmailInput, GoAEnumCheckboxGroupControl, GoAEnumControl, GoAEnumControlTester, GoAEnumRadioGroupControl, GoAInputBaseControl, GoAInputBaseFullNameControlReview, GoAInputBaseFullNameDobControlReview, GoAInputBaseReviewControl, GoAInputBaseTableReview, GoAInputBaseTableReviewControl, GoAInputDateControl, GoAInputDateTimeControl, GoAInputEmailControl, GoAInputIntegerControl, GoAInputNumberControl, GoAInputText, GoAInputTextControl, GoAInputTimeControl, GoAIntegerControl, GoAIntegerControlTester, GoAListWithDetailsControlRenderer, GoAListWithDetailsTester, GoANumberControl, GoANumberControlTester, GoANumberInput, GoAPhoneNumberControl, GoAPhoneNumberWithTypeControl, GoAPrimitiveArrayRenderer, GoAPrimitiveArrayTester, GoARadioGroupControlTester, GoARenderers, GoAReviewRenderers, GoATextControl, GoATextControlTester, GoATimeControl, GoATimeControlTester, GoATimeInput, GoInputBaseReview, GoabInputBasePhoneNumberReviewControl, GoabInputBasePhoneNumberWithTypeReviewControl, GoabInputInteger, InnerGoAInputText, JsonFormContext, JsonFormRegisterProvider, JsonFormsRegisterContext, ListWithDetailsControl, MultiLineText, MultiLineTextControl, MultiLineTextControlInput, MultiLineTextControlTester, NAVIGATION_PARAMS, OPTION_DEFINITIONS, PHONE_REGEX, PhoneGrid, PhoneNumberControl, PhoneNumberReviewControl, PhoneNumberTester, PhoneNumberWithTypeControl, PhoneNumberWithTypeReviewControl, PhoneNumberWithTypeTester, PrimitiveArrayControl, REVIEW_CHANGE_ACTION, RadioGroup, ReviewRenderContext, ReviewRenderProvider, USER_FIELD_DEFINITIONS, autoPopulatePropertiesMonaco, autoPopulateValue, categoriesAreValid, createAutoPopulateMiddleware, createDefaultAjv, enumControl, errMalformedDate, fetchRegisterConfigFromOptions$1 as fetchRegisterConfigFromOptions,
|
|
20914
|
+
export { ADD_DATALIST_ACTION, ADD_NO_ANONYMOUS_ACTION, ADD_REGISTER_DATA_ACTION, ADD_REGISTER_DATA_ERROR, ADD_USER_ACTION, AUTO_POPULATE_SOURCES, AddressLookUpControl, AddressLookUpControlReview, AddressLookUpTester, AddressLoopUpControlTableReview, ArrayControl, ArrayControlBase, ArrayControlReview, BooleanComponent, BooleanControl, BooleanRadioComponent, BooleanRadioControl, CategorizationPagesRendererTester, CategorizationStepperRendererTester, CheckboxGroup, ContactInformationTester, ContextProviderC, ContextProviderClass, ContextProviderFactory, ContractInfoControl, ContractInfoControlReview, EnumCheckboxControl, EnumRadioControl, EnumSelect, FileUploader, FileUploaderReview, FileUploaderTester, FormPageStepper, FormPagesView, FormStepper, FormStepperControl, FormStepperPagesControl, FormStepperReviewControl, FormStepperReviewer, FormStepperView, FullNameControl, FullNameControlReview, FullNameDobControl, FullNameDobReviewControl, FullNameDobTester, FullNameReviewControl, FullNameTester, GoAArrayControlRenderer, GoAArrayControlReviewRenderer, GoAArrayControlTester, GoABaseInputReviewComponent, GoABaseRenderers, GoABaseReviewRenderers, GoABaseTableReviewRenderers, GoABooleanControl, GoABooleanControlTester, GoABooleanRadioControl, GoABooleanRadioControlTester, GoACalculationControl, GoACalculationControlTester, GoACells, GoACheckoutGroupControlTester, GoAContractInfoControlReview, GoADateControl, GoADateControlTester, GoADateInput, GoADateTimeControl, GoADateTimeControlTester, GoADateTimeInput, GoAEmailControl, GoAEmailControlTester, GoAEmailInput, GoAEnumCheckboxGroupControl, GoAEnumControl, GoAEnumControlTester, GoAEnumRadioGroupControl, GoAInputBaseControl, GoAInputBaseFullNameControlReview, GoAInputBaseFullNameDobControlReview, GoAInputBaseReviewControl, GoAInputBaseTableReview, GoAInputBaseTableReviewControl, GoAInputDateControl, GoAInputDateTimeControl, GoAInputEmailControl, GoAInputIntegerControl, GoAInputNumberControl, GoAInputText, GoAInputTextControl, GoAInputTimeControl, GoAIntegerControl, GoAIntegerControlTester, GoAListWithDetailsControlRenderer, GoAListWithDetailsTester, GoANumberControl, GoANumberControlTester, GoANumberInput, GoAPhoneNumberControl, GoAPhoneNumberWithTypeControl, GoAPrimitiveArrayRenderer, GoAPrimitiveArrayTester, GoARadioGroupControlTester, GoARenderers, GoAReviewRenderers, GoATextControl, GoATextControlTester, GoATimeControl, GoATimeControlTester, GoATimeInput, GoInputBaseReview, GoabInputBasePhoneNumberReviewControl, GoabInputBasePhoneNumberWithTypeReviewControl, GoabInputInteger, InnerGoAInputText, JsonFormContext, JsonFormRegisterProvider, JsonFormsRegisterContext, ListWithDetailsControl, MultiLineText, MultiLineTextControl, MultiLineTextControlInput, MultiLineTextControlTester, NAVIGATION_PARAMS, OPTION_DEFINITIONS, PHONE_REGEX, PhoneGrid, PhoneNumberControl, PhoneNumberReviewControl, PhoneNumberTester, PhoneNumberWithTypeControl, PhoneNumberWithTypeReviewControl, PhoneNumberWithTypeTester, PrimitiveArrayControl, REVIEW_CHANGE_ACTION, RadioGroup, ReviewRenderContext, ReviewRenderProvider, USER_FIELD_DEFINITIONS, autoPopulatePropertiesMonaco, autoPopulateValue, categoriesAreValid, createAutoPopulateMiddleware, createDefaultAjv, enumControl, errMalformedDate, fetchRegisterConfigFromOptions$1 as fetchRegisterConfigFromOptions, getAutoPopulateControls, getAutoPopulatedData, getByJsonPointer, getCategoryScopes, getExternalFormPath, getNavigationTargetFromParams, getNavigationTargets, hasDataInScopes, hasDataValue, isAddressLookup, isContactInformation, isFullName, isFullNameDoB, isPhoneNumberWithType, mergeAutoPopulatedData, predictiveOptionsMonaco, registerReducer, resolveRefs, toDateTimeLocalInputValue, tryResolveRefs, useRegisterUser, useReviewContext, useShowChangeButtons };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abgov/jsonforms-components",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.75.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"description": "Government of Alberta - React renderers for JSON Forms based on the design system.",
|
|
6
6
|
"repository": "https://github.com/GovAlta/adsp-monorepo",
|
package/renderer-catalog.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "1.0.0",
|
|
3
|
-
"generatedAt": "2026-09-
|
|
4
|
-
"sourceCommit": "
|
|
3
|
+
"generatedAt": "2026-09-08T14:57:25.870Z",
|
|
4
|
+
"sourceCommit": "4bfd7a826d9a48271e8d7b7e77fbee5e560c102f",
|
|
5
5
|
"sourcePath": "libs/jsonforms-components/src/index.ts",
|
|
6
6
|
"rendererCount": 33,
|
|
7
7
|
"renderers": [
|
|
@@ -4,7 +4,6 @@ import { WithInputProps } from './type';
|
|
|
4
4
|
import { RegisterConfig } from '../../Context/register';
|
|
5
5
|
export type GoAInputTextProps = CellProps & WithClassname & WithInputProps;
|
|
6
6
|
export declare function fetchRegisterConfigFromOptions(options: Record<string, unknown> | undefined): RegisterConfig | undefined;
|
|
7
|
-
export declare const formatSin: (value: string) => string;
|
|
8
7
|
export declare const GoAInputText: (props: GoAInputTextProps) => JSX.Element;
|
|
9
8
|
export declare const InnerGoAInputText: (props: GoAInputTextProps) => JSX.Element;
|
|
10
9
|
export declare const GoATextControl: (props: ControlProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -4,6 +4,17 @@ export interface WithInputProps {
|
|
|
4
4
|
isVisited?: boolean;
|
|
5
5
|
setIsVisited?: () => void;
|
|
6
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
* UI schema options recognized by the text input control.
|
|
9
|
+
*/
|
|
10
|
+
export interface InputControlOptions {
|
|
11
|
+
/**
|
|
12
|
+
* Mask template applied to the value on blur, e.g. "(###) ###-####".
|
|
13
|
+
* '#' consumes one input character; every other character is inserted as a literal.
|
|
14
|
+
* Formatting only; validation is still driven by the JSON schema `pattern`.
|
|
15
|
+
*/
|
|
16
|
+
formatPattern?: string;
|
|
17
|
+
}
|
|
7
18
|
/**
|
|
8
19
|
* Base event control props to handle event controls
|
|
9
20
|
*/
|
|
@@ -32,6 +32,10 @@ export declare const onKeyPressForTimeControl: (props: EventKeyPressControlProps
|
|
|
32
32
|
* @param props - EventKeyPressControlProps
|
|
33
33
|
*/
|
|
34
34
|
export declare const onKeyPressForDateControl: (props: EventKeyPressControlProps) => void;
|
|
35
|
+
/**
|
|
36
|
+
* Re-exported from ./patternForm to keep existing import paths stable.
|
|
37
|
+
*/
|
|
38
|
+
export { applyFormatPattern } from './patternForm';
|
|
35
39
|
/**
|
|
36
40
|
* Helper function to process onBlur events for text controls.
|
|
37
41
|
* @param props - EventBlurControlProps
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export interface MaskPattern {
|
|
2
|
+
mask: string;
|
|
3
|
+
pattern: RegExp;
|
|
4
|
+
error: string;
|
|
5
|
+
allowedKeys?: RegExp;
|
|
6
|
+
}
|
|
7
|
+
export declare const DEFAULT_PATTERNS: Record<string, MaskPattern>;
|
|
8
|
+
export declare const MASK_PLACEHOLDERS: Set<string>;
|
|
9
|
+
export declare const MASK_CONTROL_KEYS: Set<string>;
|
|
10
|
+
export declare const shouldBlockKey: (key: string, allowedKeys?: RegExp) => boolean;
|
|
11
|
+
export declare const filterAllowedKeys: (value: string, allowedKeys?: RegExp) => string;
|
|
12
|
+
export declare const maskDigitCount: (mask: string) => number;
|
|
13
|
+
export declare const formatWithPattern: (value: string, mask: string) => string;
|
|
14
|
+
export declare const toMaskTemplate: (value: string, mask: string) => string;
|
|
15
|
+
export declare const caretAfterDigits: (display: string, digitCount: number) => number;
|
|
16
|
+
export interface MaskEdit {
|
|
17
|
+
display: string;
|
|
18
|
+
stored: string;
|
|
19
|
+
caret: number;
|
|
20
|
+
}
|
|
21
|
+
export declare const computeMaskEdit: (rawValue: string, caretIndex: number, mask: string) => MaskEdit;
|
|
22
|
+
export declare const isMaskFilled: (value: string, mask: string) => boolean;
|
|
23
|
+
export declare const maskPlaceholder: (mask: string) => string;
|
|
24
|
+
type MaskInputTarget = (HTMLInputElement & {
|
|
25
|
+
setSelectionRange?: (start: number, end: number) => void;
|
|
26
|
+
}) | undefined;
|
|
27
|
+
export declare const getMaskInputTarget: (detail: {
|
|
28
|
+
event?: Event;
|
|
29
|
+
}) => MaskInputTarget;
|
|
30
|
+
export declare const applyInPlaceEdit: (target: MaskInputTarget, edit: MaskEdit) => void;
|
|
31
|
+
/**
|
|
32
|
+
* Applies a mask template to a value, e.g. mask "(###) ###-####" turns "7801234567" into "(780) 123-4567".
|
|
33
|
+
* '#' consumes one content character from the input; every other character is a literal inserted into the output.
|
|
34
|
+
* The mask's literal characters are stripped from the input first so an already formatted value re-formats cleanly.
|
|
35
|
+
* Returns the original value unchanged when the mask is empty or no content characters remain.
|
|
36
|
+
* @param value - The raw input value
|
|
37
|
+
* @param mask - The mask template string
|
|
38
|
+
* @returns The masked value
|
|
39
|
+
*/
|
|
40
|
+
export declare const applyFormatPattern: (value: string, mask: string | undefined) => string;
|
|
41
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
interface MaskChangeDetail {
|
|
2
|
+
value: string;
|
|
3
|
+
event?: Event;
|
|
4
|
+
}
|
|
5
|
+
interface MaskKeyPressDetail {
|
|
6
|
+
key: string;
|
|
7
|
+
event?: Event;
|
|
8
|
+
}
|
|
9
|
+
interface UseMaskedInputOptions {
|
|
10
|
+
mask: string;
|
|
11
|
+
inPlace: boolean;
|
|
12
|
+
data: unknown;
|
|
13
|
+
onCommit: (stored: string) => void;
|
|
14
|
+
}
|
|
15
|
+
interface UseMaskedInputResult {
|
|
16
|
+
value: string;
|
|
17
|
+
handleChange: (detail: MaskChangeDetail) => void;
|
|
18
|
+
handleKeyPress: (detail: MaskKeyPressDetail) => void;
|
|
19
|
+
}
|
|
20
|
+
export declare const useMaskedInput: ({ mask, inPlace, data, onCommit }: UseMaskedInputOptions) => UseMaskedInputResult;
|
|
21
|
+
export {};
|