@abgov/jsonforms-components 2.52.6 → 2.54.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
@@ -1,6 +1,6 @@
1
1
  import * as runtime from 'react/jsx-runtime';
2
2
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
3
- import React, { createContext, useContext, useReducer, useMemo, useEffect, useCallback, useRef, useState, useLayoutEffect } from 'react';
3
+ import React, { useContext, useReducer, useMemo, useEffect, createContext, useCallback, useRef, useState, useLayoutEffect } from 'react';
4
4
  import { GoabFormItem, GoabDropdown, GoabDropdownItem, GoabInput, GoabTextArea, GoabCallout, GoabRadioGroup, GoabRadioItem, GoabCheckbox, GoabIcon, GoabButton, GoabGrid, GoabIconButton, GoabTable, GoabModal, GoabButtonGroup, GoabContainer, GoabDetails, GoabFormStepper, GoabFormStep, GoabPages, GoabBadge, GoabText, GoabFileUploadInput, GoabCircularProgress, GoabSpinner } from '@abgov/react-components';
5
5
  import styled from 'styled-components';
6
6
  import axios from 'axios';
@@ -3596,6 +3596,7 @@ const Visible = styled.div(_t2$6 || (_t2$6 = _$a`
3596
3596
  const ADD_REGISTER_DATA_ACTION = 'jsonforms/register/data/add';
3597
3597
  const ADD_NO_ANONYMOUS_ACTION = 'jsonforms/register/no_anonymous';
3598
3598
  const ADD_DATALIST_ACTION = 'jsonforms/register/add_datalist_action';
3599
+ const ADD_USER_ACTION = 'jsonforms/register/add_user_action';
3599
3600
  const ADD_REGISTER_DATA_ERROR = 'jsonforms/register/add_register_data_error';
3600
3601
 
3601
3602
  var classof$5 = classofRaw$2;
@@ -3715,6 +3716,12 @@ function registerReducer(state, action) {
3715
3716
  nonExistent: action.payload.nonExistent || []
3716
3717
  });
3717
3718
  }
3719
+ case ADD_USER_ACTION:
3720
+ {
3721
+ return Object.assign({}, state, {
3722
+ user: action.payload.user
3723
+ });
3724
+ }
3718
3725
  }
3719
3726
  return state;
3720
3727
  }
@@ -5078,12 +5085,14 @@ const JsonFormRegisterProvider = ({
5078
5085
  registerData: [],
5079
5086
  nonAnonymous: [],
5080
5087
  nonExistent: [],
5088
+ user: defaultRegisters == null ? void 0 : defaultRegisters.user,
5081
5089
  errors: {}
5082
5090
  });
5083
5091
  const context = useMemo(() => {
5084
5092
  return {
5085
5093
  isProvided: true,
5086
5094
  registerDispatch: dispatch,
5095
+ user: registers.user,
5087
5096
  selectRegisterData: criteria => {
5088
5097
  if (criteria != null && criteria.url) {
5089
5098
  var _registers$registerDa;
@@ -5196,6 +5205,14 @@ const JsonFormRegisterProvider = ({
5196
5205
  }
5197
5206
  });
5198
5207
  }
5208
+ if (defaultRegisters != null && defaultRegisters.user) {
5209
+ dispatch({
5210
+ type: ADD_USER_ACTION,
5211
+ payload: {
5212
+ user: defaultRegisters == null ? void 0 : defaultRegisters.user
5213
+ }
5214
+ });
5215
+ }
5199
5216
  }
5200
5217
  }, [dispatch, defaultRegisters]);
5201
5218
  /* The client might use the context outside of the Jsonform to provide custom register data */
@@ -5210,6 +5227,13 @@ const JsonFormRegisterProvider = ({
5210
5227
  children: children
5211
5228
  });
5212
5229
  };
5230
+ const useRegisterUser = () => {
5231
+ const ctx = useContext(JsonFormsRegisterContext);
5232
+ if (!ctx) {
5233
+ throw new Error('useRegisterUser must be used inside JsonFormRegisterProvider');
5234
+ }
5235
+ return ctx.user;
5236
+ };
5213
5237
 
5214
5238
  let _$9 = t => t,
5215
5239
  _t$a,
@@ -7088,6 +7112,82 @@ function useDebounce(value, delay) {
7088
7112
  return debouncedValue;
7089
7113
  }
7090
7114
 
7115
+ const defineFields = fields => fields;
7116
+ const autoLabel = name => `${name} (auto from user profile)`;
7117
+ const buildInsertText = (key, schema) => `${key}": ${JSON.stringify(schema, null, 2)}`;
7118
+ const USER_FIELD_DEFINITIONS = defineFields({
7119
+ fullName: {
7120
+ schema: {
7121
+ type: 'string',
7122
+ minLength: 3,
7123
+ description: 'Please enter your full name'
7124
+ },
7125
+ getValue: user => user == null ? void 0 : user.name
7126
+ },
7127
+ name: {
7128
+ schema: {
7129
+ type: 'string',
7130
+ minLength: 3,
7131
+ description: 'Please enter your full name'
7132
+ },
7133
+ getValue: user => user == null ? void 0 : user.name
7134
+ },
7135
+ firstName: {
7136
+ schema: {
7137
+ type: 'string',
7138
+ minLength: 3,
7139
+ description: 'Please enter your first name'
7140
+ },
7141
+ getValue: user => getNameParts(user).first
7142
+ },
7143
+ lastName: {
7144
+ schema: {
7145
+ type: 'string',
7146
+ minLength: 3,
7147
+ description: 'Please enter your last name'
7148
+ },
7149
+ getValue: user => getNameParts(user).last
7150
+ },
7151
+ userName: {
7152
+ schema: {
7153
+ type: 'string',
7154
+ minLength: 3,
7155
+ description: 'Please enter your username'
7156
+ },
7157
+ getValue: user => (user == null ? void 0 : user.preferredUsername) || (user == null ? void 0 : user.email) || ''
7158
+ },
7159
+ email: {
7160
+ schema: {
7161
+ type: 'string',
7162
+ format: 'email',
7163
+ maxLength: 100,
7164
+ pattern: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,}$',
7165
+ description: 'Please enter a valid email address (e.g., name@example.com).',
7166
+ errorMessage: {
7167
+ pattern: '(e.g., name@example.com).',
7168
+ maxLength: 'Email must be less than 100 characters.'
7169
+ }
7170
+ },
7171
+ getValue: user => (user == null ? void 0 : user.email) || ''
7172
+ }
7173
+ });
7174
+ const autoPopulateValue = (user, props) => {
7175
+ const field = USER_FIELD_DEFINITIONS[props.path];
7176
+ if (!field) return undefined;
7177
+ return field.getValue(user);
7178
+ };
7179
+ Object.entries(USER_FIELD_DEFINITIONS).map(([key, field]) => ({
7180
+ label: autoLabel(key),
7181
+ insertText: buildInsertText(key, field.schema)
7182
+ }));
7183
+ const getNameParts = user => {
7184
+ const [first = '', last = ''] = ((user == null ? void 0 : user.name) || '').split(' ');
7185
+ return {
7186
+ first,
7187
+ last
7188
+ };
7189
+ };
7190
+
7091
7191
  function fetchRegisterConfigFromOptions$1(options) {
7092
7192
  if (!(options != null && options.url) && !(options != null && options.urn)) return undefined;
7093
7193
  const config = Object.assign({}, options);
@@ -7108,7 +7208,13 @@ const formatSin = value => {
7108
7208
  return formatVal;
7109
7209
  };
7110
7210
  const GoAInputText = props => {
7111
- var _uischema$options$com, _uischema$options, _props$uischema, _props$uischema2, _uischema$options2, _uischema$options3, _uischema$options$com2, _uischema$options4, _uischema$options5, _uischema$options6;
7211
+ return jsxs(JsonFormRegisterProvider, {
7212
+ defaultRegisters: undefined,
7213
+ children: [jsx(InnerGoAInputText, Object.assign({}, props)), ' ']
7214
+ });
7215
+ };
7216
+ 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;
7112
7218
  const {
7113
7219
  data,
7114
7220
  config,
@@ -7123,11 +7229,20 @@ const GoAInputText = props => {
7123
7229
  isVisited,
7124
7230
  setIsVisited
7125
7231
  } = props;
7126
- const [localValue, setLocalValue] = useState(data != null ? data : '');
7232
+ const user = useRegisterUser();
7233
+ const initialValue = (_ref = (_ref2 = user && autoPopulateValue(user, props)) != null ? _ref2 : data) != null ? _ref : '';
7234
+ const [localValue, setLocalValue] = useState(initialValue);
7127
7235
  const debouncedValue = useDebounce(localValue, 300);
7128
7236
  useEffect(() => {
7129
- setLocalValue(data != null ? data : '');
7237
+ setLocalValue(initialValue);
7130
7238
  }, [data]);
7239
+ useEffect(() => {
7240
+ const autoPopulatedValue = schema.default || user && autoPopulateValue(user, props);
7241
+ if (autoPopulatedValue && autoPopulatedValue !== data) {
7242
+ handleChange(props.path, autoPopulatedValue);
7243
+ }
7244
+ // eslint-disable-next-line react-hooks/exhaustive-deps
7245
+ }, [schema, data, user]);
7131
7246
  /* istanbul ignore next */
7132
7247
  useEffect(() => {
7133
7248
  // Only sync if debouncedValue differs from data and is not initial empty state
@@ -7256,7 +7371,10 @@ const MultiLineText = props => {
7256
7371
  const {
7257
7372
  required
7258
7373
  } = props;
7259
- const [textAreaValue, _] = React.useState(data);
7374
+ const [textAreaValue, setTextAreaValue] = React.useState(data || '');
7375
+ useEffect(() => {
7376
+ setTextAreaValue(data || '');
7377
+ }, [data]);
7260
7378
  const appliedUiSchemaOptions = Object.assign({}, config, uischema == null ? void 0 : uischema.options);
7261
7379
  const placeholder = (appliedUiSchemaOptions == null ? void 0 : appliedUiSchemaOptions.placeholder) || (schema == null ? void 0 : schema.description) || '';
7262
7380
  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%';
@@ -8764,7 +8882,7 @@ const ObjectArrayToolBar = /*#__PURE__*/React.memo(function TableToolbar({
8764
8882
  });
8765
8883
  });
8766
8884
 
8767
- const _excluded$4 = ["label", "path", "schema", "rootSchema", "uischema", "errors", "openDeleteDialog", "visible", "enabled", "cells", "data", "config"];
8885
+ const _excluded$5 = ["label", "path", "schema", "rootSchema", "uischema", "errors", "openDeleteDialog", "visible", "enabled", "cells", "data", "config"];
8768
8886
  const getItemsTitle = schema => {
8769
8887
  const items = schema == null ? void 0 : schema.items;
8770
8888
  if (items && !Array.isArray(items) && typeof items === 'object') {
@@ -9644,7 +9762,7 @@ class ListWithDetailControl extends React.Component {
9644
9762
  data,
9645
9763
  config
9646
9764
  } = _this$props,
9647
- additionalProps = _objectWithoutPropertiesLoose(_this$props, _excluded$4);
9765
+ additionalProps = _objectWithoutPropertiesLoose(_this$props, _excluded$5);
9648
9766
  const controlElement = uischema;
9649
9767
  // eslint-disable-next-line
9650
9768
  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;
@@ -10024,12 +10142,14 @@ const GoAEmailInput = props => {
10024
10142
  errors,
10025
10143
  schema,
10026
10144
  required,
10027
- label
10145
+ label,
10146
+ handleChange
10028
10147
  } = props;
10029
10148
  const defaultSchema = schema;
10030
10149
  const appliedUiSchemaOptions = Object.assign({}, config, uischema == null ? void 0 : uischema.options);
10031
10150
  const readOnly = (_uischema$options$com = uischema == null || (_uischema$options = uischema.options) == null || (_uischema$options = _uischema$options.componentProps) == null ? void 0 : _uischema$options.readOnly) != null ? _uischema$options$com : false;
10032
10151
  const width = (_uischema$options$com2 = uischema == null || (_uischema$options2 = uischema.options) == null || (_uischema$options2 = _uischema$options2.componentProps) == null ? void 0 : _uischema$options2.width) != null ? _uischema$options$com2 : '100%';
10152
+ const user = useRegisterUser();
10033
10153
  const formStepperCtx = useContext(JsonFormsStepperContext);
10034
10154
  const stepperState = formStepperCtx == null || formStepperCtx.selectStepperState == null ? void 0 : formStepperCtx.selectStepperState();
10035
10155
  const currentCategory = stepperState == null || (_stepperState$categor = stepperState.categories) == null ? void 0 : _stepperState$categor[stepperState == null ? void 0 : stepperState.activeId];
@@ -10045,43 +10165,53 @@ const GoAEmailInput = props => {
10045
10165
  const splintIndex = splitErrors.findIndex(e => e === REQUIRED_PROPERTY_ERROR);
10046
10166
  splitErrors[splintIndex] = `${primaryLabel} is required`;
10047
10167
  const finalErrors = splitErrors.join('\n');
10168
+ useEffect(() => {
10169
+ const autoPopulatedValue = schema.default || user && autoPopulateValue(user, props);
10170
+ if (autoPopulatedValue && autoPopulatedValue !== data) {
10171
+ handleChange(props.path, autoPopulatedValue);
10172
+ }
10173
+ // eslint-disable-next-line react-hooks/exhaustive-deps
10174
+ }, [schema, data, user]);
10048
10175
  return jsx(Visible, {
10049
10176
  visible: visible,
10050
- children: jsx(FormFieldWrapper, {
10051
- children: jsx(GoabFormItem, {
10052
- error: isVisited && finalErrors,
10053
- testId: "form-email-input-wrapper",
10054
- requirement: required ? 'required' : undefined,
10055
- label: primaryLabel,
10056
- children: jsx(GoabInput, {
10057
- error: isVisited && finalErrors.length > 0,
10058
- type: 'email',
10059
- width: width,
10060
- name: "Email address",
10061
- value: data,
10062
- testId: (appliedUiSchemaOptions == null ? void 0 : appliedUiSchemaOptions.testId) || `${id}-input`,
10063
- disabled: !enabled,
10064
- readonly: readOnly,
10065
- onChange: detail => {
10066
- if (!isVisited) {
10067
- setIsVisited(true);
10068
- }
10069
- onChangeForInputControl({
10070
- name: detail.name,
10071
- value: detail.value,
10072
- controlProps: props
10073
- });
10074
- },
10075
- onBlur: detail => {
10076
- if (!isVisited) {
10077
- setIsVisited(true);
10177
+ children: jsx(JsonFormRegisterProvider, {
10178
+ defaultRegisters: undefined,
10179
+ children: jsx(FormFieldWrapper, {
10180
+ children: jsx(GoabFormItem, {
10181
+ error: isVisited && finalErrors,
10182
+ testId: "form-email-input-wrapper",
10183
+ requirement: required ? 'required' : undefined,
10184
+ label: primaryLabel,
10185
+ children: jsx(GoabInput, {
10186
+ error: isVisited && finalErrors.length > 0,
10187
+ type: 'email',
10188
+ width: width,
10189
+ name: "Email address",
10190
+ value: data,
10191
+ testId: (appliedUiSchemaOptions == null ? void 0 : appliedUiSchemaOptions.testId) || `${id}-input`,
10192
+ disabled: !enabled,
10193
+ readonly: readOnly,
10194
+ onChange: detail => {
10195
+ if (!isVisited) {
10196
+ setIsVisited(true);
10197
+ }
10198
+ onChangeForInputControl({
10199
+ name: detail.name,
10200
+ value: detail.value,
10201
+ controlProps: props
10202
+ });
10203
+ },
10204
+ onBlur: detail => {
10205
+ if (!isVisited) {
10206
+ setIsVisited(true);
10207
+ }
10208
+ onBlurForTextControl({
10209
+ name: detail.name,
10210
+ value: detail.value,
10211
+ controlProps: props
10212
+ });
10078
10213
  }
10079
- onBlurForTextControl({
10080
- name: detail.name,
10081
- value: detail.value,
10082
- controlProps: props
10083
- });
10084
- }
10214
+ })
10085
10215
  })
10086
10216
  })
10087
10217
  })
@@ -11049,7 +11179,7 @@ const renderCellColumn = ({
11049
11179
  return null;
11050
11180
  };
11051
11181
 
11052
- const _excluded$3 = ["label", "path", "schema", "rootSchema", "uischema", "errors", "visible", "enabled", "cells", "data", "config", "isStepperReview", "handleChange", "removeItems"];
11182
+ const _excluded$4 = ["label", "path", "schema", "rootSchema", "uischema", "errors", "visible", "enabled", "cells", "data", "config", "isStepperReview", "handleChange", "removeItems"];
11053
11183
  const GenerateRows = (Cell, schema, rowPath, enabled, openDeleteDialog, handleChange, cells, uischema, isInReview, count, data, errors) => {
11054
11184
  if ((schema == null ? void 0 : schema.type) === 'object') {
11055
11185
  const props = {
@@ -11456,7 +11586,7 @@ const ObjectArrayControl = props => {
11456
11586
  config,
11457
11587
  isStepperReview
11458
11588
  } = props,
11459
- additionalProps = _objectWithoutPropertiesLoose(props, _excluded$3);
11589
+ additionalProps = _objectWithoutPropertiesLoose(props, _excluded$4);
11460
11590
  const parsedData = Array.isArray(data) ? data : [];
11461
11591
  const latestData = Array.isArray(data) ? Object.fromEntries(parsedData.map((item, index) => [String(index), item])) : (_registers$categories = (_registers$categories2 = registers.categories[path]) == null ? void 0 : _registers$categories2.data) != null ? _registers$categories : {};
11462
11592
  const latestCount = Array.isArray(data) ? parsedData.length : (_registers$categories3 = (_registers$categories4 = registers.categories[path]) == null ? void 0 : _registers$categories4.count) != null ? _registers$categories3 : Object.keys(latestData).length;
@@ -12552,7 +12682,7 @@ const RenderLink = props => {
12552
12682
  });
12553
12683
  };
12554
12684
 
12555
- const _excluded$2 = ["isParent", "showLabel"];
12685
+ const _excluded$3 = ["isParent", "showLabel"];
12556
12686
  const HelpContentReviewComponent = () => {
12557
12687
  return jsx(Fragment, {
12558
12688
  children: " "
@@ -12597,7 +12727,7 @@ const HelpContentComponent = _ref => {
12597
12727
  isParent = true,
12598
12728
  showLabel = true
12599
12729
  } = _ref,
12600
- props = _objectWithoutPropertiesLoose(_ref, _excluded$2);
12730
+ props = _objectWithoutPropertiesLoose(_ref, _excluded$3);
12601
12731
  const labelClass = isParent ? 'parent-label' : 'child-label';
12602
12732
  const marginClass = isParent ? 'parent-margin' : 'child-margin';
12603
12733
  // eslint-disable-next-line
@@ -13361,7 +13491,7 @@ const SummaryRow = ({
13361
13491
  });
13362
13492
  };
13363
13493
 
13364
- const _excluded$1 = ["type"];
13494
+ const _excluded$2 = ["type"];
13365
13495
  const AdditionalInstructionsRow = ({
13366
13496
  additionalInstructions,
13367
13497
  componentProps
@@ -13370,7 +13500,7 @@ const AdditionalInstructionsRow = ({
13370
13500
  const calloutType = (componentProps == null ? void 0 : componentProps.type) || 'information';
13371
13501
  const type = validTypes.includes(calloutType) ? calloutType : 'information';
13372
13502
  const _ref = componentProps || {},
13373
- otherProps = _objectWithoutPropertiesLoose(_ref, _excluded$1);
13503
+ otherProps = _objectWithoutPropertiesLoose(_ref, _excluded$2);
13374
13504
  const sanitizedHtml = sanitizeHtml(additionalInstructions);
13375
13505
  return jsx("tr", {
13376
13506
  children: jsx("td", {
@@ -13925,7 +14055,7 @@ let _2 = t => t,
13925
14055
  _t2,
13926
14056
  _t3,
13927
14057
  _t4;
13928
- const _excluded = ["data", "path", "handleChange", "uischema"];
14058
+ const _excluded$1 = ["data", "path", "handleChange", "uischema"];
13929
14059
  const DELAY_DELETE_TIMEOUT_MS = 5;
13930
14060
  const FileUploaderReview = props => {
13931
14061
  return FileUploader(Object.assign({}, props, {
@@ -13939,7 +14069,7 @@ const FileUploader = _ref => {
13939
14069
  handleChange,
13940
14070
  uischema
13941
14071
  } = _ref,
13942
- props = _objectWithoutPropertiesLoose(_ref, _excluded);
14072
+ props = _objectWithoutPropertiesLoose(_ref, _excluded$1);
13943
14073
  const enumerators = useContext(JsonFormContext);
13944
14074
  const uploadTriggerFunction = enumerators == null || (_enumerators$function = enumerators.functions) == null ? void 0 : _enumerators$function.get('upload-file');
13945
14075
  const uploadTrigger = uploadTriggerFunction && uploadTriggerFunction();
@@ -16361,7 +16491,25 @@ function handleAddressKeyDown(key, value, activeIndex, suggestions, onInputChang
16361
16491
  return activeIndex;
16362
16492
  }
16363
16493
 
16494
+ const _excluded = ["provinceState"];
16364
16495
  const ADDRESS_PATH = 'api/gateway/v1/address/v1/find';
16496
+ const normalizeAddressData = (value, isAlbertaAddress) => {
16497
+ const defaults = isAlbertaAddress ? {
16498
+ country: 'CA',
16499
+ subdivisionCode: 'AB'
16500
+ } : {
16501
+ country: 'CA'
16502
+ };
16503
+ const source = value || {};
16504
+ const {
16505
+ provinceState
16506
+ } = source,
16507
+ rest = _objectWithoutPropertiesLoose(source, _excluded);
16508
+ const subdivisionCode = rest.subdivisionCode || provinceState;
16509
+ return Object.assign({}, defaults, rest, subdivisionCode ? {
16510
+ subdivisionCode
16511
+ } : {});
16512
+ };
16365
16513
  const AddressLookUpControl = props => {
16366
16514
  var _schema$properties, _uischema$options, _uischema$options$com, _uischema$options2, _errors$addressLine;
16367
16515
  const {
@@ -16382,18 +16530,7 @@ const AddressLookUpControl = props => {
16382
16530
  const [open, setOpen] = useState(false);
16383
16531
  const addressContainerRef = useRef(null);
16384
16532
  const label = typeof (uischema == null ? void 0 : uischema.label) === 'string' && uischema.label ? uischema.label : '';
16385
- let defaultAddress = {};
16386
- if (isAlbertaAddress) {
16387
- defaultAddress = {
16388
- country: 'CA',
16389
- subdivisionCode: 'AB'
16390
- };
16391
- } else {
16392
- defaultAddress = {
16393
- country: 'CA'
16394
- };
16395
- }
16396
- const [address, setAddress] = useState(data || defaultAddress);
16533
+ const [address, setAddress] = useState(normalizeAddressData(data, isAlbertaAddress));
16397
16534
  const [searchTerm, setSearchTerm] = useState('');
16398
16535
  const [suggestions, setSuggestions] = useState([]);
16399
16536
  const [loading, setLoading] = useState(false);
@@ -16411,6 +16548,14 @@ const AddressLookUpControl = props => {
16411
16548
  const lastQueryRef = useRef('');
16412
16549
  const cacheRef = useRef(new Map());
16413
16550
  const spinnerTimerRef = useRef(null);
16551
+ useEffect(() => {
16552
+ const nextAddress = normalizeAddressData(data, isAlbertaAddress);
16553
+ setAddress(currentAddress => {
16554
+ const keys = ['addressLine1', 'addressLine2', 'municipality', 'postalCode', 'country', 'subdivisionCode'];
16555
+ const unchanged = keys.every(key => currentAddress[key] === nextAddress[key]);
16556
+ return unchanged ? currentAddress : nextAddress;
16557
+ });
16558
+ }, [data, isAlbertaAddress]);
16414
16559
  const handleInputChange = (field, value) => {
16415
16560
  var _schema$errorMessage;
16416
16561
  if (field === 'addressLine1') {
@@ -16762,6 +16907,11 @@ const NameInputs = ({
16762
16907
  });
16763
16908
  };
16764
16909
 
16910
+ const normalizeNameData = value => ({
16911
+ firstName: (value == null ? void 0 : value.firstName) || '',
16912
+ middleName: (value == null ? void 0 : value.middleName) || '',
16913
+ lastName: (value == null ? void 0 : value.lastName) || ''
16914
+ });
16765
16915
  const FullNameReviewControl = props => {
16766
16916
  var _errors$firstName, _props$data3, _props$data4, _errors$lastName, _props$data5;
16767
16917
  const requiredFields = props.schema.required;
@@ -16822,8 +16972,7 @@ const FullNameControl = props => {
16822
16972
  uischema
16823
16973
  } = props;
16824
16974
  const requiredFields = schema.required;
16825
- const defaultName = {};
16826
- const [nameData, setNameData] = useState(data || defaultName);
16975
+ const [nameData, setNameData] = useState(normalizeNameData(data));
16827
16976
  const controlRef = useRef(null);
16828
16977
  const formStepperCtx = useContext(JsonFormsStepperContext);
16829
16978
  const stepperState = formStepperCtx == null || formStepperCtx.selectStepperState == null ? void 0 : formStepperCtx.selectStepperState();
@@ -16831,6 +16980,10 @@ const FullNameControl = props => {
16831
16980
  updatedData = Object.fromEntries(Object.entries(updatedData).filter(([_, value]) => value !== ''));
16832
16981
  handleChange(path, updatedData);
16833
16982
  };
16983
+ useEffect(() => {
16984
+ const nextData = normalizeNameData(data);
16985
+ setNameData(currentData => currentData.firstName === nextData.firstName && currentData.middleName === nextData.middleName && currentData.lastName === nextData.lastName ? currentData : nextData);
16986
+ }, [data]);
16834
16987
  const handleInputChange = (field, value) => {
16835
16988
  const updatedName = Object.assign({}, nameData, {
16836
16989
  [field]: value
@@ -16918,6 +17071,12 @@ handleRequiredFieldBlur) {
16918
17071
  }, [formData]);
16919
17072
  }
16920
17073
 
17074
+ const normalizeNameDobData = value => ({
17075
+ firstName: (value == null ? void 0 : value.firstName) || '',
17076
+ middleName: (value == null ? void 0 : value.middleName) || '',
17077
+ lastName: (value == null ? void 0 : value.lastName) || '',
17078
+ dateOfBirth: (value == null ? void 0 : value.dateOfBirth) || ''
17079
+ });
16921
17080
  const FullNameDobControl = props => {
16922
17081
  var _schema$required, _errors$firstName, _schema$required2, _schema$required3, _errors$lastName, _errors$dateOfBirth;
16923
17082
  const {
@@ -16934,7 +17093,6 @@ const FullNameDobControl = props => {
16934
17093
  const controlRef = useRef(null);
16935
17094
  const formStepperCtx = useContext(JsonFormsStepperContext);
16936
17095
  const stepperState = formStepperCtx == null || formStepperCtx.selectStepperState == null ? void 0 : formStepperCtx.selectStepperState();
16937
- const defaultNameAndDob = {};
16938
17096
  const validDates = () => {
16939
17097
  const currentDate = new Date();
16940
17098
  const minDate = new Date(currentDate.getFullYear() - 150, currentDate.getMonth(), currentDate.getDate()).toISOString().substring(0, 10);
@@ -16943,12 +17101,16 @@ const FullNameDobControl = props => {
16943
17101
  maxDate: currentDate.toISOString().substring(0, 10)
16944
17102
  };
16945
17103
  };
16946
- const [formData, setFormData] = useState(data || defaultNameAndDob);
17104
+ const [formData, setFormData] = useState(normalizeNameDobData(data));
16947
17105
  const updateFormData = updatedData => {
16948
17106
  updatedData = Object.fromEntries(Object.entries(updatedData).filter(([_, value]) => value !== ''));
16949
17107
  setFormData(updatedData);
16950
17108
  handleChange(path, updatedData);
16951
17109
  };
17110
+ useEffect(() => {
17111
+ const nextData = normalizeNameDobData(data);
17112
+ setFormData(currentData => currentData.firstName === nextData.firstName && currentData.middleName === nextData.middleName && currentData.lastName === nextData.lastName && currentData.dateOfBirth === nextData.dateOfBirth ? currentData : nextData);
17113
+ }, [data]);
16952
17114
  const handleInputChange = (field, value) => {
16953
17115
  const updatedData = Object.assign({}, formData, {
16954
17116
  [field]: value
@@ -17113,6 +17275,10 @@ const PhoneGrid = styled.div(_t || (_t = _`
17113
17275
  }
17114
17276
  `));
17115
17277
  const PHONE_REGEX = /^\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$/;
17278
+ const normalizePhoneData = value => ({
17279
+ type: (value == null ? void 0 : value.type) || '',
17280
+ number: (value == null ? void 0 : value.number) || ''
17281
+ });
17116
17282
  const PhoneNumberWithTypeControl = props => {
17117
17283
  const {
17118
17284
  data,
@@ -17122,8 +17288,12 @@ const PhoneNumberWithTypeControl = props => {
17122
17288
  visible,
17123
17289
  required
17124
17290
  } = props;
17125
- const [formData, setFormData] = useState(data || {});
17291
+ const [formData, setFormData] = useState(normalizePhoneData(data));
17126
17292
  const [error, setError] = useState(undefined);
17293
+ useEffect(() => {
17294
+ const nextData = normalizePhoneData(data);
17295
+ setFormData(currentData => currentData.type === nextData.type && currentData.number === nextData.number ? currentData : nextData);
17296
+ }, [data]);
17127
17297
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
17128
17298
  const updateFormData = updated => {
17129
17299
  setFormData(updated);
@@ -17390,7 +17560,7 @@ function evaluateExpression(expression, data, opts) {
17390
17560
  const sumScope = sumMatch[1];
17391
17561
  return evaluateSum(sumScope, data, opts);
17392
17562
  }
17393
- const scopeRegex = /#\/(?:properties\/)?[^\s"'()]+/g;
17563
+ const scopeRegex = /#\/(?:properties\/)?[^\s"'(),]+/g;
17394
17564
  const matches = trimmed.match(scopeRegex) || [];
17395
17565
  const uniqueScopes = Array.from(new Set(matches));
17396
17566
  const normalizedScopes = uniqueScopes.map(s => s.replace(/^#\/(properties\/)?/, '#/properties/'));
@@ -18069,4 +18239,4 @@ const GoARenderers = [...GoABaseRenderers, {
18069
18239
  }];
18070
18240
  const GoACells = [...InputCells];
18071
18241
 
18072
- export { ADD_DATALIST_ACTION, ADD_NO_ANONYMOUS_ACTION, ADD_REGISTER_DATA_ACTION, ADD_REGISTER_DATA_ERROR, AddressLookUpControl, AddressLookUpControlReview, AddressLookUpTester, AddressLoopUpControlTableReview, ArrayControl, ArrayControlBase, ArrayControlReview, BooleanComponent, BooleanControl, BooleanRadioComponent, BooleanRadioControl, CategorizationPagesRendererTester, CategorizationStepperRendererTester, CheckboxGroup, ContextProviderC, ContextProviderClass, ContextProviderFactory, 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, 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, JsonFormContext, JsonFormRegisterProvider, JsonFormsRegisterContext, ListWithDetailsControl, MultiLineText, MultiLineTextControl, MultiLineTextControlInput, MultiLineTextControlTester, PHONE_REGEX, PhoneGrid, PhoneNumberControl, PhoneNumberReviewControl, PhoneNumberTester, PhoneNumberWithTypeControl, PhoneNumberWithTypeReviewControl, PhoneNumberWithTypeTester, PrimitiveArrayControl, RadioGroup, categoriesAreValid, createDefaultAjv, enumControl, errMalformedDate, formatSin, getByJsonPointer, getCategoryScopes, hasDataInScopes, hasDataValue, isAddressLookup, isFullName, isFullNameDoB, isPhoneNumber, isPhoneNumberWithType, registerReducer, resolveRefs, tryResolveRefs };
18242
+ export { ADD_DATALIST_ACTION, ADD_NO_ANONYMOUS_ACTION, ADD_REGISTER_DATA_ACTION, ADD_REGISTER_DATA_ERROR, ADD_USER_ACTION, AddressLookUpControl, AddressLookUpControlReview, AddressLookUpTester, AddressLoopUpControlTableReview, ArrayControl, ArrayControlBase, ArrayControlReview, BooleanComponent, BooleanControl, BooleanRadioComponent, BooleanRadioControl, CategorizationPagesRendererTester, CategorizationStepperRendererTester, CheckboxGroup, ContextProviderC, ContextProviderClass, ContextProviderFactory, 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, 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, PHONE_REGEX, PhoneGrid, PhoneNumberControl, PhoneNumberReviewControl, PhoneNumberTester, PhoneNumberWithTypeControl, PhoneNumberWithTypeReviewControl, PhoneNumberWithTypeTester, PrimitiveArrayControl, RadioGroup, categoriesAreValid, createDefaultAjv, enumControl, errMalformedDate, fetchRegisterConfigFromOptions$1 as fetchRegisterConfigFromOptions, formatSin, getByJsonPointer, getCategoryScopes, hasDataInScopes, hasDataValue, isAddressLookup, isFullName, isFullNameDoB, isPhoneNumber, isPhoneNumberWithType, registerReducer, resolveRefs, tryResolveRefs, useRegisterUser };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abgov/jsonforms-components",
3
- "version": "2.52.6",
3
+ "version": "2.54.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",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-03-12T17:06:12.099Z",
4
- "sourceCommit": "8e70c36cadefa29ed84a8d37cfaab8454a468304",
3
+ "generatedAt": "2026-03-13T20:38:10.020Z",
4
+ "sourceCommit": "748fb227701ff354e6276b45c8d91aeb3e984ca1",
5
5
  "sourcePath": "libs/jsonforms-components/src/index.ts",
6
6
  "rendererCount": 32,
7
7
  "renderers": [
@@ -1,7 +1,9 @@
1
1
  import { Dispatch } from 'react';
2
+ import { User } from './registerContext';
2
3
  export declare const ADD_REGISTER_DATA_ACTION = "jsonforms/register/data/add";
3
4
  export declare const ADD_NO_ANONYMOUS_ACTION = "jsonforms/register/no_anonymous";
4
5
  export declare const ADD_DATALIST_ACTION = "jsonforms/register/add_datalist_action";
6
+ export declare const ADD_USER_ACTION = "jsonforms/register/add_user_action";
5
7
  export declare const ADD_REGISTER_DATA_ERROR = "jsonforms/register/add_register_data_error";
6
8
  export interface RegisterConfig {
7
9
  urn?: string;
@@ -27,6 +29,7 @@ export interface RegisterConfigData extends RegisterConfig {
27
29
  errors?: Record<string, Errors>;
28
30
  nonAnonymous?: string[];
29
31
  nonExistent?: string[];
32
+ user?: User;
30
33
  }
31
34
  export type RegisterData = RegisterConfigData[];
32
35
  export type RegisterDataResponse = {
@@ -34,6 +37,7 @@ export type RegisterDataResponse = {
34
37
  nonExistent: string[];
35
38
  nonAnonymous: string[];
36
39
  errors: Record<string, Errors>;
40
+ user?: User;
37
41
  };
38
42
  type AddDataAction = {
39
43
  type: string;
@@ -1,7 +1,9 @@
1
1
  import { RegisterActions, RegisterData, RegisterDataResponse, Errors } from './actions';
2
+ import { User } from './registerContext';
2
3
  export declare function registerReducer(state: {
3
4
  registerData: RegisterData;
4
5
  nonExistent: string[];
5
6
  nonAnonymous: string[];
6
7
  errors: Record<string, Errors>;
8
+ user?: User;
7
9
  }, action: RegisterActions): RegisterDataResponse;
@@ -1,11 +1,19 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { RegisterConfig, RegisterData, JsonFormRegisterDispatch, RegisterDataType } from './actions';
3
+ export interface User {
4
+ id: string;
5
+ name: string;
6
+ email: string;
7
+ roles: string[];
8
+ preferredUsername: string;
9
+ }
3
10
  interface JsonFormsRegisterContextProps {
4
11
  registerDispatch: JsonFormRegisterDispatch;
5
12
  fetchRegisterByUrl: (registerConfig: RegisterConfig) => Promise<void>;
6
13
  selectRegisterData: (registerConfig: RegisterConfig) => RegisterDataType;
7
14
  fetchErrors: (registerConfig: RegisterConfig) => string;
8
15
  isProvided: boolean;
16
+ user?: User;
9
17
  }
10
18
  export declare const JsonFormsRegisterContext: import("react").Context<JsonFormsRegisterContextProps | undefined>;
11
19
  interface JsonFormsRegisterProviderProps {
@@ -14,7 +22,9 @@ interface JsonFormsRegisterProviderProps {
14
22
  registerData: RegisterData;
15
23
  dataList: string[];
16
24
  nonAnonymous: string[];
25
+ user?: User;
17
26
  } | undefined;
18
27
  }
19
28
  export declare const JsonFormRegisterProvider: ({ children, defaultRegisters, }: JsonFormsRegisterProviderProps) => JSX.Element;
29
+ export declare const useRegisterUser: () => User | undefined;
20
30
  export {};
@@ -1,9 +1,12 @@
1
1
  import React from 'react';
2
2
  import { CellProps, WithClassname, ControlProps, RankedTester } from '@jsonforms/core';
3
3
  import { WithInputProps } from './type';
4
+ import { RegisterConfig } from '../../Context/register';
4
5
  export type GoAInputTextProps = CellProps & WithClassname & WithInputProps;
6
+ export declare function fetchRegisterConfigFromOptions(options: Record<string, unknown> | undefined): RegisterConfig | undefined;
5
7
  export declare const formatSin: (value: string) => string;
6
8
  export declare const GoAInputText: (props: GoAInputTextProps) => JSX.Element;
9
+ export declare const InnerGoAInputText: (props: GoAInputTextProps) => JSX.Element;
7
10
  export declare const GoATextControl: (props: ControlProps) => import("react/jsx-runtime").JSX.Element;
8
11
  export declare const GoATextControlTester: RankedTester;
9
12
  export declare const GoAInputTextControl: React.ComponentType<import("@jsonforms/core").OwnPropsOfControl>;
@@ -0,0 +1,65 @@
1
+ import { User } from '../Context/register';
2
+ export declare const USER_FIELD_DEFINITIONS: {
3
+ fullName: {
4
+ schema: {
5
+ type: string;
6
+ minLength: number;
7
+ description: string;
8
+ };
9
+ getValue: (user: User) => string;
10
+ };
11
+ name: {
12
+ schema: {
13
+ type: string;
14
+ minLength: number;
15
+ description: string;
16
+ };
17
+ getValue: (user: User) => string;
18
+ };
19
+ firstName: {
20
+ schema: {
21
+ type: string;
22
+ minLength: number;
23
+ description: string;
24
+ };
25
+ getValue: (user: User) => string;
26
+ };
27
+ lastName: {
28
+ schema: {
29
+ type: string;
30
+ minLength: number;
31
+ description: string;
32
+ };
33
+ getValue: (user: User) => string;
34
+ };
35
+ userName: {
36
+ schema: {
37
+ type: string;
38
+ minLength: number;
39
+ description: string;
40
+ };
41
+ getValue: (user: User) => string;
42
+ };
43
+ email: {
44
+ schema: {
45
+ type: string;
46
+ format: string;
47
+ maxLength: number;
48
+ pattern: string;
49
+ description: string;
50
+ errorMessage: {
51
+ pattern: string;
52
+ maxLength: string;
53
+ };
54
+ };
55
+ getValue: (user: User) => string;
56
+ };
57
+ };
58
+ export type UserField = keyof typeof USER_FIELD_DEFINITIONS;
59
+ export declare const autoPopulateValue: (user: User, props: {
60
+ path: string;
61
+ }) => string | undefined;
62
+ export declare const autoPopulatePropertiesMonaco: {
63
+ label: string;
64
+ insertText: string;
65
+ }[];