@abgov/jsonforms-components 2.73.0 → 2.73.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
@@ -9516,18 +9516,26 @@ const JsonFormsStepperContextProvider = ({
9516
9516
  if ((context == null ? void 0 : context.isProvided) === true) {
9517
9517
  var _stepperState$categor6, _stepperState$categor7;
9518
9518
  /* The block is used to cache the state for the tenant web app review editor */
9519
+ // The task list is the sentinel id past the last page, which sits above maxReachedStep until
9520
+ // the user opens something, so clamping would drop them onto the first page on the recompute
9521
+ // that follows mount. Real pages survive the clamp only because the goToPage pair below puts
9522
+ // them back, and that is deliberately skipped while the task list is showing.
9523
+ const isOnTaskList = stepperState.activeId === stepperState.categories.length + 1;
9519
9524
  stepperDispatch({
9520
9525
  type: 'update/uischema',
9521
9526
  payload: {
9522
9527
  state: createStepperContextInitData(Object.assign({}, StepperProps, {
9523
- activeId: Math.min(stepperState == null ? void 0 : stepperState.activeId, stepperState.maxReachedStep)
9528
+ // Leaving activeId out lets init recompute the sentinel from the categories this
9529
+ // recompute produced, so a conditional page appearing or disappearing still lands on
9530
+ // the task list rather than on the review page.
9531
+ activeId: isOnTaskList ? undefined : Math.min(stepperState == null ? void 0 : stepperState.activeId, stepperState.maxReachedStep)
9524
9532
  }), {
9525
9533
  visitedIds: new Set([...persistedVisitedIds, ...((_stepperState$categor6 = stepperState == null || (_stepperState$categor7 = stepperState.categories) == null ? void 0 : _stepperState$categor7.filter(c => c.isVisited).map(c => c.id)) != null ? _stepperState$categor6 : [])]),
9526
9534
  autoPopulatedValues
9527
9535
  })
9528
9536
  }
9529
9537
  });
9530
- if (stepperState.activeId !== stepperState.categories.length + 1) {
9538
+ if (!isOnTaskList) {
9531
9539
  context.goToPage(stepperState.maxReachedStep);
9532
9540
  context.goToPage(stepperState.activeId);
9533
9541
  }
@@ -12783,6 +12791,33 @@ class ListWithDetailControl extends React.Component {
12783
12791
  }
12784
12792
  }
12785
12793
 
12794
+ // clean-code-ignore: RULE-19 — covered by ./useReviewChange.spec.tsx, colocated. The rule looks for a
12795
+ // .test.ts sibling; the hook has to be exercised through a rendered component, so its spec is .tsx.
12796
+ /**
12797
+ * The single way a review summary's Change button reports a click.
12798
+ *
12799
+ * Two things have to happen and neither is optional. The stepper moves to the page, which is all a
12800
+ * host needs when the summary and the form are the same JsonForms instance. The review context is
12801
+ * also told, and that is the only signal a host whose summary lives on a *different* page can see —
12802
+ * it is what turns into a deep link back into the form.
12803
+ *
12804
+ * Renderers used to wire these up one at a time, and every renderer except the plain-input one
12805
+ * called goToPage alone, so a composite control's Change button was silently inert for a cross-page
12806
+ * host. Going through here makes forgetting the second half impossible.
12807
+ */
12808
+ const useReviewChange = () => {
12809
+ const stepperContext = useContext(JsonFormsStepperContext);
12810
+ const reviewContext = useReviewContext();
12811
+ return useCallback((stepId, scope) => {
12812
+ // Outside a stepper there is no page to move to, but the host may still resolve the field's
12813
+ // own page from the scope, so the report below happens either way.
12814
+ if (stepId !== undefined) {
12815
+ stepperContext == null || stepperContext.goToPage(stepId, scope);
12816
+ }
12817
+ reviewContext == null || reviewContext.onChangeDispatch(stepId, scope != null ? scope : '');
12818
+ }, [stepperContext, reviewContext]);
12819
+ };
12820
+
12786
12821
  const GoAInputBaseTableReview = props => {
12787
12822
  var _uischema$options, _uischema$scope2, _jsonForms$core, _uischema$options4, _uischema$options5, _uischema$options6;
12788
12823
  const {
@@ -12798,8 +12833,7 @@ const GoAInputBaseTableReview = props => {
12798
12833
  required,
12799
12834
  visible
12800
12835
  } = props;
12801
- const context = useContext(JsonFormsStepperContext);
12802
- const reviewCtx = useReviewContext();
12836
+ const reportChange = useReviewChange();
12803
12837
  const showChangeButtons = useShowChangeButtons();
12804
12838
  const jsonForms = useJsonForms();
12805
12839
  const reviewLabel = typeof ((_uischema$options = uischema.options) == null ? void 0 : _uischema$options.reviewLabel) === 'string' ? uischema.options.reviewLabel : '';
@@ -12971,8 +13005,7 @@ const GoAInputBaseTableReview = props => {
12971
13005
  // eslint-disable-next-line
12972
13006
  const stepId = (_uischema$options5 = uischema.options) == null ? void 0 : _uischema$options5.stepId;
12973
13007
  function handleChangeClick() {
12974
- context == null || context.goToPage(stepId, uischema.scope);
12975
- reviewCtx == null || reviewCtx.onChangeDispatch(stepId, uischema.scope);
13008
+ reportChange(stepId, uischema.scope);
12976
13009
  }
12977
13010
  const showInlineValue = reviewText === null || reviewText === undefined || typeof reviewText === 'string' || typeof reviewText === 'number' || /*#__PURE__*/React.isValidElement(reviewText) || Array.isArray(reviewText) && reviewText.length === 0;
12978
13011
  const isValueEmpty = !isBooleanRequiredError && (reviewText === null || reviewText === undefined || reviewText === '' || Array.isArray(reviewText) && reviewText.length === 0);
@@ -13513,7 +13546,7 @@ const FullNameTester = rankWith(4, isFullName);
13513
13546
 
13514
13547
  const FullNameControlReview = props => {
13515
13548
  var _props$uischema, _props$schema$require, _props$schema;
13516
- const context = useContext(JsonFormsStepperContext);
13549
+ const reportChange = useReviewChange();
13517
13550
  const showChangeButtons = useShowChangeButtons();
13518
13551
  const stepId = (_props$uischema = props.uischema) == null || (_props$uischema = _props$uischema.options) == null ? void 0 : _props$uischema.stepId;
13519
13552
  const {
@@ -13535,7 +13568,7 @@ const FullNameControlReview = props => {
13535
13568
  })]
13536
13569
  }), showChangeButtons && stepId !== undefined && !((_uischema$options = uischema.options) != null && (_uischema$options = _uischema$options.componentProps) != null && _uischema$options.readOnly) && jsx(GoabButton, {
13537
13570
  type: "text",
13538
- onClick: () => context == null ? void 0 : context.goToPage(stepId, uischema.scope),
13571
+ onClick: () => reportChange(stepId, uischema.scope),
13539
13572
  testId: `${fieldName}-change-btn`,
13540
13573
  children: "Change"
13541
13574
  })]
@@ -13567,7 +13600,7 @@ const FullNameDobReviewControl = props => {
13567
13600
  id,
13568
13601
  uischema
13569
13602
  } = props;
13570
- const context = useContext(JsonFormsStepperContext);
13603
+ const reportChange = useReviewChange();
13571
13604
  const showChangeButtons = useShowChangeButtons();
13572
13605
  const stepId = uischema == null || (_uischema$options = uischema.options) == null ? void 0 : _uischema$options.stepId;
13573
13606
  const requiredFields = (_props$schema$require = (_props$schema = props.schema) == null ? void 0 : _props$schema.required) != null ? _props$schema$require : [];
@@ -13585,7 +13618,7 @@ const FullNameDobReviewControl = props => {
13585
13618
  }), showChangeButtons && stepId !== undefined && !((_uischema$options2 = uischema.options) != null && (_uischema$options2 = _uischema$options2.componentProps) != null && _uischema$options2.readOnly) && jsx(GoabButton, {
13586
13619
  type: "text",
13587
13620
  size: "compact",
13588
- onClick: () => context == null ? void 0 : context.goToPage(stepId, uischema.scope),
13621
+ onClick: () => reportChange(stepId, uischema.scope),
13589
13622
  testId: `${fieldName}-change-btn`,
13590
13623
  children: "Change"
13591
13624
  })]
@@ -13954,7 +13987,7 @@ const ContractInfoControl = props => {
13954
13987
 
13955
13988
  const ContractInfoControlReview = props => {
13956
13989
  var _props$uischema, _schema$required, _options$enableEmail, _options$enablePhone, _options$emailFirst;
13957
- const context = useContext(JsonFormsStepperContext);
13990
+ const reportChange = useReviewChange();
13958
13991
  const showChangeButtons = useShowChangeButtons();
13959
13992
  const stepId = (_props$uischema = props.uischema) == null || (_props$uischema = _props$uischema.options) == null ? void 0 : _props$uischema.stepId;
13960
13993
  const {
@@ -13976,7 +14009,7 @@ const ContractInfoControlReview = props => {
13976
14009
  }), showChangeButtons && stepId !== undefined && !((_uischema$options = uischema.options) != null && (_uischema$options = _uischema$options.componentProps) != null && _uischema$options.readOnly) && jsx(GoabButton, {
13977
14010
  type: "text",
13978
14011
  size: "compact",
13979
- onClick: () => context == null ? void 0 : context.goToPage(stepId, uischema.scope),
14012
+ onClick: () => reportChange(stepId, uischema.scope),
13980
14013
  testId: `${fieldName}-change-btn`,
13981
14014
  children: "Change"
13982
14015
  })]
@@ -14603,7 +14636,7 @@ const ObjectArrayControl = props => {
14603
14636
  const [open, setOpen] = useState(false);
14604
14637
  const [rowData, setRowData] = useState(0);
14605
14638
  const [maxItemsError, setMaxItemsError] = useState('');
14606
- const context = useContext(JsonFormsStepperContext);
14639
+ const reportChange = useReviewChange();
14607
14640
  const showChangeButtons = useShowChangeButtons();
14608
14641
  const {
14609
14642
  label,
@@ -14790,7 +14823,7 @@ const ObjectArrayControl = props => {
14790
14823
  size: "compact",
14791
14824
  onClick: () => {
14792
14825
  var _uischema$options8;
14793
- return context == null ? void 0 : context.goToPage((_uischema$options8 = uischema.options) == null ? void 0 : _uischema$options8.stepId);
14826
+ return reportChange((_uischema$options8 = uischema.options) == null ? void 0 : _uischema$options8.stepId, uischema.scope);
14794
14827
  },
14795
14828
  children: "Change"
14796
14829
  })]
@@ -15308,7 +15341,7 @@ const AddressLoopUpControlTableReview = props => {
15308
15341
  } = props;
15309
15342
  const jsonForms = useJsonForms();
15310
15343
  const stepId = (_uischema$options = uischema.options) == null ? void 0 : _uischema$options.stepId;
15311
- const formStepperCtx = useContext(JsonFormsStepperContext);
15344
+ const reportChange = useReviewChange();
15312
15345
  const showChangeButtons = useShowChangeButtons();
15313
15346
  const isAlbertaAddress = (schema == null || (_schema$properties2 = schema.properties) == null || (_schema$properties2 = _schema$properties2.subdivisionCode) == null ? void 0 : _schema$properties2.const) === 'AB';
15314
15347
  const provinces = [{
@@ -15421,7 +15454,7 @@ const AddressLoopUpControlTableReview = props => {
15421
15454
  }), showButton && showChangeButtons && stepId !== undefined && !((_uischema$options2 = uischema.options) != null && (_uischema$options2 = _uischema$options2.componentProps) != null && _uischema$options2.readOnly) && jsx(GoabButton, {
15422
15455
  type: "text",
15423
15456
  size: "compact",
15424
- onClick: () => formStepperCtx == null ? void 0 : formStepperCtx.goToPage(stepId, targetScope),
15457
+ onClick: () => reportChange(stepId, targetScope),
15425
15458
  testId: "address-change-btn",
15426
15459
  children: "Change"
15427
15460
  })]
@@ -15447,7 +15480,7 @@ const AddressLoopUpControlTableReview = props => {
15447
15480
  }), showChangeButtons && stepId !== undefined && !((_uischema$options3 = uischema.options) != null && (_uischema$options3 = _uischema$options3.componentProps) != null && _uischema$options3.readOnly) && jsx(GoabButton, {
15448
15481
  type: "text",
15449
15482
  size: "compact",
15450
- onClick: () => formStepperCtx == null ? void 0 : formStepperCtx.goToPage(stepId, targetScope),
15483
+ onClick: () => reportChange(stepId, targetScope),
15451
15484
  testId: "address-change-btn",
15452
15485
  children: "Change"
15453
15486
  })]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abgov/jsonforms-components",
3
- "version": "2.73.0",
3
+ "version": "2.73.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-08-26T17:26:01.476Z",
4
- "sourceCommit": "9ea40f7686bb16ccaf589666adce6d56145233d2",
3
+ "generatedAt": "2026-09-03T16:05:02.694Z",
4
+ "sourceCommit": "55bf16918fad1678e853b202f152dcff366a54e8",
5
5
  "sourcePath": "libs/jsonforms-components/src/index.ts",
6
6
  "rendererCount": 33,
7
7
  "renderers": [
@@ -0,0 +1,13 @@
1
+ /**
2
+ * The single way a review summary's Change button reports a click.
3
+ *
4
+ * Two things have to happen and neither is optional. The stepper moves to the page, which is all a
5
+ * host needs when the summary and the form are the same JsonForms instance. The review context is
6
+ * also told, and that is the only signal a host whose summary lives on a *different* page can see —
7
+ * it is what turns into a deep link back into the form.
8
+ *
9
+ * Renderers used to wire these up one at a time, and every renderer except the plain-input one
10
+ * called goToPage alone, so a composite control's Change button was silently inert for a cross-page
11
+ * host. Going through here makes forgetting the second half impossible.
12
+ */
13
+ export declare const useReviewChange: () => ((stepId: number | undefined, scope?: string) => void);