@abgov/jsonforms-components 2.55.0 → 2.55.2

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
@@ -3055,6 +3055,17 @@ const sinTitle = 'Social insurance number';
3055
3055
  const invalidSin = 'Social insurance number is invalid';
3056
3056
  const DEFAULT_MAX_ITEMS = 50;
3057
3057
  const REQUIRED_PROPERTY_ERROR = 'is a required property';
3058
+ const ADDRESS_LOOKUP_LABELS = {
3059
+ addressLine1: 'Address line 1',
3060
+ addressLine2: 'Address line 2',
3061
+ municipality: 'City',
3062
+ postalCode: 'Postal code',
3063
+ subdivisionCode: 'Province',
3064
+ country: 'Country'
3065
+ };
3066
+ const getAddressLookupFieldLabel = fieldName => {
3067
+ return ADDRESS_LOOKUP_LABELS[fieldName] || fieldName;
3068
+ };
3058
3069
 
3059
3070
  /**
3060
3071
  * Sets the first word to be capitalized so that it is sentence cased.
@@ -3246,23 +3257,6 @@ const convertToReadableFormat = input => {
3246
3257
  }
3247
3258
  return input.replace(/([a-z])([A-Z])/g, '$1 $2').split(' ').map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(' ');
3248
3259
  };
3249
- /**
3250
- * Converts a input to sentence case (eg: incomeThresholdExample or IncomeThresholdExample)
3251
- * to 'Income threshold example' with the first letter in the sentence capitalized.
3252
- *
3253
- * @param input - The camelCase or PascalCase string (e.g., "incomeThresholdExample").
3254
- * @returns A formatted string with spaces and capitalization (e.g., "Income threshold example").
3255
- */
3256
- const convertToSentenceCase = input => {
3257
- if (!input) {
3258
- return input;
3259
- }
3260
- const convertedInput = convertToReadableFormat(input);
3261
- if (!convertedInput) return convertedInput;
3262
- const firstWord = convertedInput.split(' ').splice(0, 1);
3263
- const newWords = convertedInput.split(' ').splice(1).map(word => word.charAt(0).toLowerCase() + word.slice(1).toLowerCase()).join(' ');
3264
- return firstWord.concat(newWords).join(' ');
3265
- };
3266
3260
 
3267
3261
  var $$y = _export;
3268
3262
  var call$e = functionCall;
@@ -7214,7 +7208,7 @@ const GoAInputText = props => {
7214
7208
  });
7215
7209
  };
7216
7210
  const InnerGoAInputText = props => {
7217
- var _ref, _ref2, _uischema$options$com, _uischema$options, _props$uischema, _props$uischema2, _uischema$options2, _uischema$options3, _uischema$options$com2, _uischema$options4, _uischema$options5, _uischema$options6;
7211
+ var _ref, _ref2, _schema$default, _uischema$options$com, _uischema$options, _props$uischema, _props$uischema2, _uischema$options2, _uischema$options3, _uischema$options$com2, _uischema$options4, _uischema$options5, _uischema$options6;
7218
7212
  const {
7219
7213
  data,
7220
7214
  config,
@@ -7230,21 +7224,29 @@ const InnerGoAInputText = props => {
7230
7224
  setIsVisited
7231
7225
  } = props;
7232
7226
  const user = useRegisterUser();
7233
- const initialValue = (_ref = (_ref2 = user && autoPopulateValue(user, props)) != null ? _ref2 : data) != null ? _ref : '';
7227
+ const initialValue = (_ref = (_ref2 = (_schema$default = schema.default) != null ? _schema$default : user && autoPopulateValue(user, props)) != null ? _ref2 : data) != null ? _ref : '';
7234
7228
  const [localValue, setLocalValue] = useState(initialValue);
7235
7229
  const debouncedValue = useDebounce(localValue, 300);
7236
7230
  useEffect(() => {
7237
- setLocalValue(initialValue);
7231
+ setLocalValue(data);
7238
7232
  }, [data]);
7239
7233
  useEffect(() => {
7234
+ if (!user || data) return;
7240
7235
  const autoPopulatedValue = schema.default || user && autoPopulateValue(user, props);
7241
7236
  if (autoPopulatedValue && autoPopulatedValue !== data) {
7242
7237
  handleChange(props.path, autoPopulatedValue);
7243
7238
  }
7244
7239
  // eslint-disable-next-line react-hooks/exhaustive-deps
7245
- }, [schema, data, user]);
7240
+ }, [schema, user]);
7241
+ useEffect(() => {
7242
+ if (typeof handleChange === 'function' && (schema == null ? void 0 : schema.default) !== undefined) {
7243
+ handleChange(props.path, schema.default);
7244
+ }
7245
+ // eslint-disable-next-line react-hooks/exhaustive-deps
7246
+ }, [schema.default]);
7246
7247
  /* istanbul ignore next */
7247
7248
  useEffect(() => {
7249
+ if (debouncedValue === data) return;
7248
7250
  // Only sync if debouncedValue differs from data and is not initial empty state
7249
7251
  if (debouncedValue !== data && (debouncedValue !== '' || data !== undefined)) {
7250
7252
  onChangeForInputControl({
@@ -8688,6 +8690,7 @@ const SideMenuItem = styled.div(_t8$1 || (_t8$1 = _$7`
8688
8690
  `));
8689
8691
  const RowFlex = styled.div(_t9$1 || (_t9$1 = _$7`
8690
8692
  display: flex;
8693
+ margin: 1.5rem 0 1.5rem 0;
8691
8694
 
8692
8695
  align-items: flex-start;
8693
8696
  `));
@@ -8715,7 +8718,6 @@ const RowFlexMenuLeft = styled.div(_t1$1 || (_t1$1 = _$7`
8715
8718
  border: 1px solid var(--goa-color-greyscale-300);
8716
8719
  border-radius: var(--goa-border-radius-m);
8717
8720
  margin-top: var(--goa-space-xs);
8718
- background-color: var(--goa-color-greyscale-white);
8719
8721
  padding: 0;
8720
8722
  gap: 0;
8721
8723
  position: relative;
@@ -9767,14 +9769,13 @@ class ListWithDetailControl extends React.Component {
9767
9769
  // eslint-disable-next-line
9768
9770
  const listTitle = (_ref = (_ref2 = (_ref3 = (_uischema$label = uischema == null ? void 0 : uischema.label) != null ? _uischema$label : uischema == null || (_uischema$options15 = uischema.options) == null ? void 0 : _uischema$options15.title) != null ? _ref3 : getItemsTitle(schema)) != null ? _ref2 : schema == null ? void 0 : schema.title) != null ? _ref : label;
9769
9771
  const withLeftTab = uischema == null || (_uischema$options16 = uischema.options) == null || (_uischema$options16 = _uischema$options16.componentProps) == null ? void 0 : _uischema$options16.withLeftTab;
9770
- const noLeftTabBlankButton = this.state.currentListPage === 0 && data === 0;
9771
- const showMainItems = withLeftTab || this.state.currentListPage === 0;
9772
- const showSecondaryButton = withLeftTab || noLeftTabBlankButton;
9772
+ this.state.currentListPage === 0 && data === 0;
9773
+ const editMode = this.state.currentListPage !== 0 && !withLeftTab;
9773
9774
  return jsxs(Visible, {
9774
9775
  visible: visible,
9775
9776
  "data-testid": "jsonforms-object-list-wrapper",
9776
9777
  children: [jsxs(ToolBarHeader, {
9777
- children: [listTitle && showMainItems && jsx(MarginTop, {
9778
+ children: [listTitle && jsx(MarginTop, {
9778
9779
  children: jsxs(ObjectArrayTitle, {
9779
9780
  children: [listTitle, " ", jsx("span", {
9780
9781
  children: additionalProps.required && '(required)'
@@ -9786,7 +9787,7 @@ class ListWithDetailControl extends React.Component {
9786
9787
  children: this.state.maxItemsError
9787
9788
  })]
9788
9789
  })
9789
- }), showSecondaryButton && jsx(ObjectArrayToolBar, {
9790
+ }), jsx(ObjectArrayToolBar, {
9790
9791
  data: data,
9791
9792
  errors: errors,
9792
9793
  label: label,
@@ -9798,7 +9799,7 @@ class ListWithDetailControl extends React.Component {
9798
9799
  uischema: controlElement,
9799
9800
  schema: schema,
9800
9801
  rootSchema: rootSchema,
9801
- enabled: enabled,
9802
+ enabled: enabled && !editMode,
9802
9803
  setCurrentListPage: listPage => {
9803
9804
  this.setState({
9804
9805
  currentListPage: listPage
@@ -9829,33 +9830,13 @@ class ListWithDetailControl extends React.Component {
9829
9830
  currentListPage: this.state.currentListPage,
9830
9831
  listTitle: listTitle
9831
9832
  }, additionalProps))
9832
- }), !showSecondaryButton && jsx(ObjectArrayToolBar, {
9833
- data: data,
9834
- errors: errors,
9835
- label: label,
9836
- addItem: (path, value) => () => {
9837
- this.addItem(path, value);
9838
- },
9839
- numColumns: 0,
9840
- path: path,
9841
- uischema: controlElement,
9842
- schema: schema,
9843
- rootSchema: rootSchema,
9844
- enabled: enabled,
9845
- setCurrentListPage: listPage => {
9846
- this.setState({
9847
- currentListPage: listPage
9848
- });
9849
- },
9850
- currentListPage: this.state.currentListPage,
9851
- buttonType: "tertiary"
9852
9833
  })]
9853
9834
  });
9854
9835
  }
9855
9836
  }
9856
9837
 
9857
9838
  const GoAInputBaseTableReview = props => {
9858
- var _uischema$options, _jsonForms$core, _uischema$options4;
9839
+ var _uischema$options, _uischema$scope, _jsonForms$core, _uischema$options4;
9859
9840
  const {
9860
9841
  data,
9861
9842
  uischema,
@@ -9869,10 +9850,16 @@ const GoAInputBaseTableReview = props => {
9869
9850
  } = props;
9870
9851
  const context = useContext(JsonFormsStepperContext);
9871
9852
  const jsonForms = useJsonForms();
9872
- let labelToUpdate = (_uischema$options = uischema.options) != null && _uischema$options.reviewLabel ? uischema.options.reviewLabel : convertToSentenceCase(getLabelText(uischema.scope, label || ''));
9873
- if (labelToUpdate === '') {
9853
+ const reviewLabel = typeof ((_uischema$options = uischema.options) == null ? void 0 : _uischema$options.reviewLabel) === 'string' ? uischema.options.reviewLabel : '';
9854
+ const propLabel = typeof label === 'string' ? label : '';
9855
+ let labelToUpdate = '';
9856
+ if (reviewLabel.trim() !== '') {
9857
+ labelToUpdate = reviewLabel;
9858
+ } else if (propLabel.trim() !== '') {
9859
+ labelToUpdate = propLabel;
9860
+ } else if ((_uischema$scope = uischema.scope) != null && _uischema$scope.startsWith('#/')) {
9874
9861
  const scopeName = uischema.scope ? getLastSegmentFromPointer(uischema.scope) : '';
9875
- labelToUpdate = convertToSentenceCase(scopeName);
9862
+ labelToUpdate = convertToReadableFormat(scopeName);
9876
9863
  }
9877
9864
  let reviewText = data;
9878
9865
  const isBoolean = typeof data === 'boolean';
@@ -9901,7 +9888,7 @@ const GoAInputBaseTableReview = props => {
9901
9888
  checkboxLabel = uischema.options.text.trim();
9902
9889
  } else if (uischema.scope && uischema.scope.startsWith('#/')) {
9903
9890
  const fallbackLabel = getLastSegmentFromPointer(uischema.scope);
9904
- checkboxLabel = fallbackLabel.charAt(0).toUpperCase() + fallbackLabel.slice(1);
9891
+ checkboxLabel = convertToReadableFormat(fallbackLabel);
9905
9892
  }
9906
9893
  if (((_uischema$options3 = uischema.options) == null ? void 0 : _uischema$options3.radio) === true) {
9907
9894
  reviewText = data ? `Yes` : `No`;
@@ -9963,13 +9950,13 @@ const GoAInputBaseTableReview = props => {
9963
9950
  // Fallback: try to extract missing property name and create a friendly message
9964
9951
  if (matchedError.keyword === 'required' && (_matchedError$params = matchedError.params) != null && _matchedError$params.missingProperty) {
9965
9952
  const missing = matchedError.params.missingProperty;
9966
- const missingPropertyLabel = convertToSentenceCase(missing);
9953
+ const missingPropertyLabel = convertToReadableFormat(missing);
9967
9954
  activeError = `${missingPropertyLabel} is required`;
9968
9955
  } else {
9969
9956
  var _matchedError$message;
9970
9957
  const propertyMatch = (_matchedError$message = matchedError.message) == null ? void 0 : _matchedError$message.match(/'([^']+)'/);
9971
9958
  if (propertyMatch && propertyMatch[1]) {
9972
- const missingPropertyLabel = convertToSentenceCase(propertyMatch[1]);
9959
+ const missingPropertyLabel = convertToReadableFormat(propertyMatch[1]);
9973
9960
  activeError = `${missingPropertyLabel} is required`;
9974
9961
  } else {
9975
9962
  activeError = matchedError.message;
@@ -10166,12 +10153,19 @@ const GoAEmailInput = props => {
10166
10153
  splitErrors[splintIndex] = `${primaryLabel} is required`;
10167
10154
  const finalErrors = splitErrors.join('\n');
10168
10155
  useEffect(() => {
10156
+ if (!user || data) return;
10169
10157
  const autoPopulatedValue = schema.default || user && autoPopulateValue(user, props);
10170
10158
  if (autoPopulatedValue && autoPopulatedValue !== data) {
10171
10159
  handleChange(props.path, autoPopulatedValue);
10172
10160
  }
10173
10161
  // eslint-disable-next-line react-hooks/exhaustive-deps
10174
- }, [schema, data, user]);
10162
+ }, [schema, user]);
10163
+ useEffect(() => {
10164
+ if (typeof handleChange === 'function' && (schema == null ? void 0 : schema.default) !== undefined) {
10165
+ handleChange(props.path, schema.default);
10166
+ }
10167
+ // eslint-disable-next-line react-hooks/exhaustive-deps
10168
+ }, [schema.default]);
10175
10169
  return jsx(Visible, {
10176
10170
  visible: visible,
10177
10171
  children: jsx(JsonFormRegisterProvider, {
@@ -12247,9 +12241,6 @@ const AddressLoopUpControlTableReview = props => {
12247
12241
  label: 'Yukon'
12248
12242
  }];
12249
12243
  const provinceLabel = isAlbertaAddress ? 'Alberta' : ((_provinces$find = provinces.find(p => p.value === (data == null ? void 0 : data.subdivisionCode))) == null ? void 0 : _provinces$find.label) || (data == null ? void 0 : data.subdivisionCode);
12250
- function prettify(prop) {
12251
- return prop.replace(/([A-Z])/g, ' $1').replace(/[_-]/g, ' ').replace(/^./, c => c.toUpperCase());
12252
- }
12253
12244
  const getError = propName => {
12254
12245
  var _jsonForms$core;
12255
12246
  const normalizePath = p => p.replace(/\[(\d+)\]/g, '.$1').replace(/^\./, '').replace(/\//g, '.');
@@ -12288,7 +12279,7 @@ const AddressLoopUpControlTableReview = props => {
12288
12279
  if (raw != null && raw.includes('must have required property') || raw != null && raw.includes(REQUIRED_PROPERTY_ERROR)) {
12289
12280
  const propertyMatch = raw.match(/'([^']+)'/);
12290
12281
  if (propertyMatch && propertyMatch[1]) {
12291
- return prettify(propertyMatch[1]) + ' is required';
12282
+ return `${getAddressLookupFieldLabel(propertyMatch[1])} is required`;
12292
12283
  }
12293
12284
  }
12294
12285
  return raw;
@@ -12348,7 +12339,7 @@ const AddressLoopUpControlTableReview = props => {
12348
12339
  })]
12349
12340
  })
12350
12341
  })
12351
- }), renderRow('Address line 1', data == null ? void 0 : data.addressLine1, 'addressLine1', false), (data == null ? void 0 : data.addressLine2) && renderRow('Address line 2', data.addressLine2, 'addressLine2', false), renderRow('City', data == null ? void 0 : data.municipality, 'municipality', false), renderRow('Postal Code', data == null ? void 0 : data.postalCode, 'postalCode', false), renderRow('Province', provinceLabel, 'subdivisionCode', false), renderRow('Country', 'Canada', 'country', false)]
12342
+ }), renderRow(getAddressLookupFieldLabel('addressLine1'), data == null ? void 0 : data.addressLine1, 'addressLine1', false), (data == null ? void 0 : data.addressLine2) && renderRow(getAddressLookupFieldLabel('addressLine2'), data.addressLine2, 'addressLine2', false), renderRow(getAddressLookupFieldLabel('municipality'), data == null ? void 0 : data.municipality, 'municipality', false), renderRow(getAddressLookupFieldLabel('postalCode'), data == null ? void 0 : data.postalCode, 'postalCode', false), renderRow(getAddressLookupFieldLabel('subdivisionCode'), provinceLabel, 'subdivisionCode', false), renderRow(getAddressLookupFieldLabel('country'), 'Canada', 'country', false)]
12352
12343
  });
12353
12344
  };
12354
12345
 
@@ -16641,7 +16632,7 @@ const AddressLookUpControl = props => {
16641
16632
  const handleRequiredFieldBlur = name => {
16642
16633
  const err = Object.assign({}, errors);
16643
16634
  if (!(data != null && data[name]) || data[name] === '' || (data == null ? void 0 : data[name]) === undefined) {
16644
- err[name] = name === 'municipality' ? 'city is required' : `${name} is required`;
16635
+ err[name] = `${getAddressLookupFieldLabel(name)} is required`;
16645
16636
  setErrors(err);
16646
16637
  } else {
16647
16638
  delete errors[name];
@@ -16700,8 +16691,7 @@ const AddressLookUpControl = props => {
16700
16691
  try {
16701
16692
  const response = await fetchAddressSuggestions(formUrl, q, isAlbertaAddress, {
16702
16693
  signal: controller.signal
16703
- } //update util to accept signal
16704
- );
16694
+ });
16705
16695
  const filtered = filterSuggestionsWithoutAddressCount(response);
16706
16696
  const finalList = isAlbertaAddress ? filterAlbertaAddresses(filtered) : filtered;
16707
16697
  cacheRef.current.set(q, finalList);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abgov/jsonforms-components",
3
- "version": "2.55.0",
3
+ "version": "2.55.2",
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-03-13T21:22:44.360Z",
4
- "sourceCommit": "5047dd40017f2ab1c4c03f0c795313e703317099",
3
+ "generatedAt": "2026-03-17T21:52:22.881Z",
4
+ "sourceCommit": "f73629414bf1125cb5192c06f4b0aafd1cdbdc45",
5
5
  "sourcePath": "libs/jsonforms-components/src/index.ts",
6
6
  "rendererCount": 32,
7
7
  "renderers": [
@@ -2,3 +2,12 @@ export declare const sinTitle = "Social insurance number";
2
2
  export declare const invalidSin = "Social insurance number is invalid";
3
3
  export declare const DEFAULT_MAX_ITEMS = 50;
4
4
  export declare const REQUIRED_PROPERTY_ERROR = "is a required property";
5
+ export declare const ADDRESS_LOOKUP_LABELS: {
6
+ readonly addressLine1: "Address line 1";
7
+ readonly addressLine2: "Address line 2";
8
+ readonly municipality: "City";
9
+ readonly postalCode: "Postal code";
10
+ readonly subdivisionCode: "Province";
11
+ readonly country: "Country";
12
+ };
13
+ export declare const getAddressLookupFieldLabel: (fieldName: string) => string;