@abgov/jsonforms-components 2.75.0 → 2.75.1

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
@@ -4928,20 +4928,49 @@ const computeMaskEdit = (rawValue, caretIndex, mask) => {
4928
4928
  const isMaskFilled = (value, mask) => value.replace(NON_CONTENT, '').length >= maskDigitCount(mask);
4929
4929
  // A human placeholder for a mask, e.g. '(###) ###-####' -> '(000) 000-0000'.
4930
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.
4931
+ // GoA retargets composed events to the host, so prefer the inner native input from the composed path.
4932
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;
4933
+ var _target$shadowRoot$qu, _target$shadowRoot;
4934
+ const event = detail.event;
4935
+ if (!event) {
4936
+ return undefined;
4937
+ }
4938
+ const path = typeof event.composedPath === 'function' ? event.composedPath() : [];
4939
+ const fromPath = path.find(node => node instanceof HTMLInputElement);
4940
+ if (fromPath) {
4941
+ return fromPath;
4942
+ }
4943
+ const target = event.target;
4944
+ if (target instanceof HTMLInputElement) {
4945
+ return target;
4946
+ }
4947
+ return (_target$shadowRoot$qu = target == null || (_target$shadowRoot = target.shadowRoot) == null ? void 0 : _target$shadowRoot.querySelector('input')) != null ? _target$shadowRoot$qu : undefined;
4948
+ };
4949
+ const applyMaskValue = (target, edit) => {
4950
+ target.value = edit.display;
4951
+ target.setSelectionRange == null || target.setSelectionRange(edit.caret, edit.caret);
4935
4952
  };
4936
- // Applies an in-place edit to the DOM: forces the (fixed-length) value and restores the caret after React commits.
4953
+ // Applies an in-place edit to the inner input and re-applies after the web component paints.
4937
4954
  const applyInPlaceEdit = (target, edit) => {
4938
4955
  if (!target) {
4939
4956
  return;
4940
4957
  }
4941
- target.value = edit.display;
4942
- if (target.setSelectionRange) {
4943
- requestAnimationFrame(() => target.setSelectionRange == null ? void 0 : target.setSelectionRange(edit.caret, edit.caret));
4958
+ applyMaskValue(target, edit);
4959
+ requestAnimationFrame(() => applyMaskValue(target, edit));
4960
+ };
4961
+ // When the template is already filled, extra content characters must be rejected rather than shifting the value.
4962
+ const overflowMaskEdit = (previousDisplay, rawValue, caretIndex, mask) => {
4963
+ if (!isMaskFilled(previousDisplay, mask)) {
4964
+ return undefined;
4965
+ }
4966
+ if ((rawValue != null ? rawValue : '').replace(NON_CONTENT, '').length <= maskDigitCount(mask)) {
4967
+ return undefined;
4944
4968
  }
4969
+ return {
4970
+ display: previousDisplay,
4971
+ stored: formatWithPattern(previousDisplay, mask),
4972
+ caret: Math.min(Math.max(caretIndex, 0), previousDisplay.length)
4973
+ };
4945
4974
  };
4946
4975
  /**
4947
4976
  * Applies a mask template to a value, e.g. mask "(###) ###-####" turns "7801234567" into "(780) 123-4567".
@@ -10171,6 +10200,11 @@ const InnerGoAInputText = props => {
10171
10200
  var _target$selectionStar;
10172
10201
  const target = getMaskInputTarget(detail);
10173
10202
  const caretIndex = (_target$selectionStar = target == null ? void 0 : target.selectionStart) != null ? _target$selectionStar : cleaned.length;
10203
+ const overflow = overflowMaskEdit(localValue, cleaned, caretIndex, mask);
10204
+ if (overflow) {
10205
+ applyInPlaceEdit(target, overflow);
10206
+ return;
10207
+ }
10174
10208
  const edit = computeMaskEdit(cleaned, caretIndex, mask);
10175
10209
  applyInPlaceEdit(target, edit);
10176
10210
  setLocalValue(edit.display);
@@ -10205,12 +10239,22 @@ const InnerGoAInputText = props => {
10205
10239
  });
10206
10240
  },
10207
10241
  onKeyPress: detail => {
10242
+ const keyPressDetail = detail;
10208
10243
  const blockDisallowed = shouldBlockKey(detail.key, allowedKeys);
10209
- // In-place has no length cap, so also block content keys once the template is full.
10244
+ // In-place has no maxLength, and GoA keyPress fires on keyup after the character is inserted.
10210
10245
  const blockOverflow = inPlace && !!mask && /^[A-Za-z0-9]$/.test(detail.key) && isMaskFilled(localValue, mask);
10211
10246
  if (blockDisallowed || blockOverflow) {
10212
- var _detail$event2;
10213
- (_detail$event2 = detail.event) == null || _detail$event2.preventDefault();
10247
+ var _keyPressDetail$event;
10248
+ (_keyPressDetail$event = keyPressDetail.event) == null || _keyPressDetail$event.preventDefault();
10249
+ }
10250
+ if (blockOverflow && mask) {
10251
+ var _ref, _target$value, _target$selectionStar2;
10252
+ const target = getMaskInputTarget(keyPressDetail);
10253
+ const rawValue = (_ref = (_target$value = target == null ? void 0 : target.value) != null ? _target$value : detail.value) != null ? _ref : localValue;
10254
+ const overflow = overflowMaskEdit(localValue, rawValue, (_target$selectionStar2 = target == null ? void 0 : target.selectionStart) != null ? _target$selectionStar2 : localValue.length, mask);
10255
+ if (overflow) {
10256
+ applyInPlaceEdit(target, overflow);
10257
+ }
10214
10258
  }
10215
10259
  }
10216
10260
  }, uischema == null || (_uischema$options10 = uischema.options) == null ? void 0 : _uischema$options10.componentProps))
@@ -13850,16 +13894,28 @@ const useMaskedInput = ({
13850
13894
  }
13851
13895
  const target = getMaskInputTarget(detail);
13852
13896
  const caretIndex = (_target$selectionStar = target == null ? void 0 : target.selectionStart) != null ? _target$selectionStar : rawValue.length;
13897
+ const overflow = overflowMaskEdit(value, rawValue, caretIndex, mask);
13898
+ if (overflow) {
13899
+ applyInPlaceEdit(target, overflow);
13900
+ return;
13901
+ }
13853
13902
  const edit = computeMaskEdit(rawValue, caretIndex, mask);
13854
13903
  applyInPlaceEdit(target, edit);
13855
13904
  setValue(edit.display);
13856
13905
  onCommit(edit.stored);
13857
13906
  };
13858
- // In-place mode has no native length cap, so block extra content characters at the source.
13907
+ // In-place has no maxLength (the template is already full length) and GoA keyPress is keyup, so restore on overflow.
13859
13908
  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();
13909
+ var _detail$event, _target$value, _target$selectionStar2;
13910
+ if (!inPlace || !/^[A-Za-z0-9]$/.test(detail.key) || !isMaskFilled(value, mask)) {
13911
+ return;
13912
+ }
13913
+ (_detail$event = detail.event) == null || _detail$event.preventDefault();
13914
+ const target = getMaskInputTarget(detail);
13915
+ const rawValue = (_target$value = target == null ? void 0 : target.value) != null ? _target$value : value;
13916
+ const overflow = overflowMaskEdit(value, rawValue, (_target$selectionStar2 = target == null ? void 0 : target.selectionStart) != null ? _target$selectionStar2 : value.length, mask);
13917
+ if (overflow) {
13918
+ applyInPlaceEdit(target, overflow);
13863
13919
  }
13864
13920
  };
13865
13921
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abgov/jsonforms-components",
3
- "version": "2.75.0",
3
+ "version": "2.75.1",
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",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-09-08T14:57:25.870Z",
4
- "sourceCommit": "4bfd7a826d9a48271e8d7b7e77fbee5e560c102f",
3
+ "generatedAt": "2026-09-08T16:38:31.930Z",
4
+ "sourceCommit": "769e0871a07d4049577cd0a6f97d1dc56258481b",
5
5
  "sourcePath": "libs/jsonforms-components/src/index.ts",
6
6
  "rendererCount": 33,
7
7
  "renderers": [
@@ -28,6 +28,7 @@ export declare const getMaskInputTarget: (detail: {
28
28
  event?: Event;
29
29
  }) => MaskInputTarget;
30
30
  export declare const applyInPlaceEdit: (target: MaskInputTarget, edit: MaskEdit) => void;
31
+ export declare const overflowMaskEdit: (previousDisplay: string, rawValue: string, caretIndex: number, mask: string) => MaskEdit | undefined;
31
32
  /**
32
33
  * Applies a mask template to a value, e.g. mask "(###) ###-####" turns "7801234567" into "(780) 123-4567".
33
34
  * '#' consumes one content character from the input; every other character is a literal inserted into the output.