@abgov/jsonforms-components 2.83.0 → 2.84.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
@@ -8909,6 +8909,51 @@ const stepperReducer = (state, action) => {
8909
8909
  }
8910
8910
  };
8911
8911
 
8912
+ const getStepInfo = ({
8913
+ categories,
8914
+ activeId
8915
+ }) => {
8916
+ const count = categories.length;
8917
+ if (activeId >= count) {
8918
+ return {
8919
+ isFirstStep: false,
8920
+ isLastStep: false,
8921
+ currentStep: 0,
8922
+ isOnReview: activeId === count,
8923
+ isOnTaskList: activeId > count
8924
+ };
8925
+ }
8926
+ const isVisible = visible => visible !== false;
8927
+ const hiddenBefore = categories.filter(c => !isVisible(c.visible) && c.id < activeId).length;
8928
+ const totalSteps = categories.filter(c => isVisible(c.visible)).length;
8929
+ const currentStep = activeId + 1 - hiddenBefore;
8930
+ return {
8931
+ isFirstStep: currentStep === 1,
8932
+ isLastStep: currentStep === totalSteps,
8933
+ currentStep,
8934
+ isOnReview: false,
8935
+ isOnTaskList: false
8936
+ };
8937
+ };
8938
+ const isSameStepInfo = (a, b) => !!a && a.isFirstStep === b.isFirstStep && a.isLastStep === b.isLastStep && a.currentStep === b.currentStep && a.isOnReview === b.isOnReview && a.isOnTaskList === b.isOnTaskList;
8939
+
8940
+ // Derives the step info and reports it on mount and whenever its value changes, so typing on a
8941
+ // step, a schema recompute or a new callback identity never reports twice.
8942
+ const useStepInfo = (state, onStepChange) => {
8943
+ const stepInfo = useMemo(() => getStepInfo(state), [state]);
8944
+ const onStepChangeRef = useRef(onStepChange);
8945
+ onStepChangeRef.current = onStepChange;
8946
+ const lastReported = useRef(undefined);
8947
+ useEffect(() => {
8948
+ if (isSameStepInfo(lastReported.current, stepInfo)) {
8949
+ return;
8950
+ }
8951
+ lastReported.current = stepInfo;
8952
+ onStepChangeRef.current == null || onStepChangeRef.current(stepInfo);
8953
+ }, [stepInfo]);
8954
+ return stepInfo;
8955
+ };
8956
+
8912
8957
  var isArray = isArray$6;
8913
8958
  var lengthOfArrayLike$4 = lengthOfArrayLike$d;
8914
8959
  var doesNotExceedSafeInteger$1 = doesNotExceedSafeInteger$3;
@@ -9301,7 +9346,7 @@ const autoPopulatePropertiesMonaco = [];
9301
9346
  // new context value for nothing.
9302
9347
  const NO_AUTO_POPULATED_DATA = [];
9303
9348
  // The props a host can change after mount. See the note where they are applied.
9304
- const HOST_CONTROLLED_KEYS = ['formUrl', 'isFormSubmitted', 'showChangeButtons', 'autoPopulatedData', 'formId', 'navigationTarget', 'onNavigationChange'];
9349
+ const HOST_CONTROLLED_KEYS = ['formUrl', 'isFormSubmitted', 'showChangeButtons', 'autoPopulatedData', 'formId', 'navigationTarget', 'onNavigationChange', 'onStepChange'];
9305
9350
  class ContextProviderClass {
9306
9351
  async addDataByUrl(key, url, processDataFunction, token) {
9307
9352
  let header = {};
@@ -9386,7 +9431,8 @@ class ContextProviderClass {
9386
9431
  autoPopulatedData: (_props$autoPopulatedD = props.autoPopulatedData) != null ? _props$autoPopulatedD : NO_AUTO_POPULATED_DATA,
9387
9432
  formId: props.formId,
9388
9433
  navigationTarget: props.navigationTarget,
9389
- onNavigationChange: props.onNavigationChange
9434
+ onNavigationChange: props.onNavigationChange,
9435
+ onStepChange: props.onStepChange
9390
9436
  });
9391
9437
  const hostControlledChanged = HOST_CONTROLLED_KEYS.some(key => next[key] !== this.baseEnumerator[key]);
9392
9438
  const fileManagementChanged = props.fileManagement !== previousFileManagement;
@@ -10371,6 +10417,7 @@ const JsonFormsStepperContextProvider = ({
10371
10417
  const formId = formCtx == null ? void 0 : formCtx.formId;
10372
10418
  const navigationTarget = formCtx == null ? void 0 : formCtx.navigationTarget;
10373
10419
  const onNavigationChange = formCtx == null ? void 0 : formCtx.onNavigationChange;
10420
+ const onStepChange = formCtx == null ? void 0 : formCtx.onStepChange;
10374
10421
  // Steps opened in an earlier session. Seeding these on first mount is what keeps a step the user
10375
10422
  // has been through from dropping back to NotStarted on resume — including the case where they
10376
10423
  // edited an auto-populated field and then restored the original value, which leaves nothing in
@@ -10443,6 +10490,7 @@ const JsonFormsStepperContextProvider = ({
10443
10490
  snapshotRef.current = computed;
10444
10491
  return computed;
10445
10492
  }, [stepperState, data, schema, ajv]);
10493
+ const stepInfo = useStepInfo(snapshot, onStepChange);
10446
10494
  const context = useMemo(() => {
10447
10495
  return {
10448
10496
  isProvided: true,
@@ -10466,6 +10514,7 @@ const JsonFormsStepperContextProvider = ({
10466
10514
  return snapshot.path;
10467
10515
  },
10468
10516
  selectStepperOptions: () => getStepperPageOptions(uischema),
10517
+ selectStepInfo: () => stepInfo,
10469
10518
  selectCategory: id => {
10470
10519
  return snapshot.categories[id];
10471
10520
  },
@@ -10504,7 +10553,7 @@ const JsonFormsStepperContextProvider = ({
10504
10553
  });
10505
10554
  }
10506
10555
  };
10507
- }, [stepperDispatch, snapshot, doValidatePage, uischema]);
10556
+ }, [stepperDispatch, snapshot, stepInfo, doValidatePage, uischema]);
10508
10557
  /* istanbul ignore next */
10509
10558
  useEffect(() => {
10510
10559
  var _ctx$core$errors, _ctx$core4;
@@ -13292,7 +13341,8 @@ const NonEmptyCellComponent$1 = /*#__PURE__*/React.memo(function NonEmptyCellCom
13292
13341
  };
13293
13342
  const hasNoElements = () => {
13294
13343
  var _uischema$elements2, _uischema$options9;
13295
- const hasNoLayoutElements = (uischema == null || (_uischema$elements2 = uischema.elements) == null ? void 0 : _uischema$elements2.length) === 0 && (uischema == null || (_uischema$options9 = uischema.options) == null || (_uischema$options9 = _uischema$options9.detail) == null || (_uischema$options9 = _uischema$options9.elements) == null ? void 0 : _uischema$options9.length) === 0;
13344
+ // A missing elements or detail list counts as empty, so a bare ListWithDetail still gets generated inputs.
13345
+ const hasNoLayoutElements = !(uischema != null && (_uischema$elements2 = uischema.elements) != null && _uischema$elements2.length) && !(uischema != null && (_uischema$options9 = uischema.options) != null && (_uischema$options9 = _uischema$options9.detail) != null && (_uischema$options9 = _uischema$options9.elements) != null && _uischema$options9.length);
13296
13346
  return hasNoLayoutElements;
13297
13347
  };
13298
13348
  return jsxs(Fragment, {
@@ -19013,6 +19063,22 @@ const CategorizationPagesRendererTester = rankWith(2, and(uiTypeIs('Categorizati
19013
19063
  return ((_uischema$options3 = uischema.options) == null ? void 0 : _uischema$options3.variant) === 'pages';
19014
19064
  }));
19015
19065
 
19066
+ // Host-side companion to ContextProvider's onStepChange: holds the reported step as state.
19067
+ const useStepChange = listener => {
19068
+ const [stepInfo, setStepInfo] = useState();
19069
+ const listenerRef = useRef(listener);
19070
+ listenerRef.current = listener;
19071
+ // Stable identity, so a host passing it to ContextProvider does not refresh the form context.
19072
+ const onStepChange = useCallback(next => {
19073
+ setStepInfo(next);
19074
+ listenerRef.current == null || listenerRef.current(next);
19075
+ }, []);
19076
+ return {
19077
+ stepInfo,
19078
+ onStepChange
19079
+ };
19080
+ };
19081
+
19016
19082
  const isSingleFileUrn = and(schemaTypeIs('string'), formatIs('file-urn'));
19017
19083
  const isFileUrnArray = and(schemaTypeIs('array'), schemaMatches(schema => {
19018
19084
  if (!(schema != null && schema.items) || Array.isArray(schema.items)) {
@@ -22290,4 +22356,4 @@ const goaRenderers = [...GoABaseRenderers, {
22290
22356
  const GoARenderers = memoizeRendererTesters(goaRenderers);
22291
22357
  const GoACells = [...InputCells];
22292
22358
 
22293
- 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, memoizeRendererTesters, memoizeTester, mergeAutoPopulatedData, predictiveOptionsMonaco, registerReducer, resolveRefs, toDateTimeLocalInputValue, tryResolveRefs, useRegisterUser, useReviewContext, useShowChangeButtons };
22359
+ 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, memoizeRendererTesters, memoizeTester, mergeAutoPopulatedData, predictiveOptionsMonaco, registerReducer, resolveRefs, toDateTimeLocalInputValue, tryResolveRefs, useRegisterUser, useReviewContext, useShowChangeButtons, useStepChange };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abgov/jsonforms-components",
3
- "version": "2.83.0",
3
+ "version": "2.84.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-11-09T17:34:00.090Z",
4
- "sourceCommit": "aa7e267b7b5409519d32f5159a697f615219d1f7",
3
+ "generatedAt": "2026-11-10T16:31:12.098Z",
4
+ "sourceCommit": "1333800b7b2910b80230058618eb775dbb6b51b6",
5
5
  "sourcePath": "libs/jsonforms-components/src/index.ts",
6
6
  "rendererCount": 23,
7
7
  "renderers": [
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { AxiosStatic } from 'axios';
3
3
  import type { NavigationOutcome, NavigationTarget } from '../Controls/FormStepper/util/navigationTarget';
4
+ import type { StepInfo } from '../Controls/FormStepper/context/types';
4
5
  interface AllData {
5
6
  [x: string]: any;
6
7
  }
@@ -33,6 +34,7 @@ export interface AutoPopulatedValue {
33
34
  export interface ExternalNavigationProps {
34
35
  navigationTarget?: NavigationTarget;
35
36
  onNavigationChange?: (outcome: NavigationOutcome) => void;
37
+ onStepChange?: (stepInfo: StepInfo) => void;
36
38
  }
37
39
  type Props = ExternalNavigationProps & {
38
40
  children?: React.ReactNode;
@@ -66,6 +68,7 @@ export declare class ContextProviderClass {
66
68
  formId?: string;
67
69
  navigationTarget?: NavigationTarget;
68
70
  onNavigationChange?: (outcome: NavigationOutcome) => void;
71
+ onStepChange?: (stepInfo: StepInfo) => void;
69
72
  };
70
73
  addFormContextData: (key: string, data: Record<string, unknown> | unknown[]) => void;
71
74
  addDataByUrl(key: string, url: string, processDataFunction: (data: object) => string[], token?: string): Promise<void>;
@@ -1,6 +1,6 @@
1
1
  import { ReactNode, Dispatch } from 'react';
2
2
  import { CategorizationStepperLayoutRendererProps } from '../types';
3
- import { StepperContextDataType, CategoryState } from './types';
3
+ import { StepperContextDataType, CategoryState, StepInfo } from './types';
4
4
  import { JsonFormStepperDispatch } from './reducer';
5
5
  import { JsonSchema } from '@jsonforms/core';
6
6
  import { ErrorObject } from 'ajv';
@@ -29,6 +29,7 @@ export interface JsonFormsStepperContextProps {
29
29
  validatePage: (id: number) => void;
30
30
  selectNumberOfCompletedCategories: () => number;
31
31
  selectStepperOptions: () => StepperPageOptions;
32
+ selectStepInfo: () => StepInfo;
32
33
  isProvided?: boolean;
33
34
  }
34
35
  export declare const JsonFormsStepperContext: import("react").Context<JsonFormsStepperContextProps | undefined>;
@@ -0,0 +1,3 @@
1
+ import { StepInfo, StepperContextDataType } from './types';
2
+ export declare const getStepInfo: ({ categories, activeId, }: Pick<StepperContextDataType, "categories" | "activeId">) => StepInfo;
3
+ export declare const isSameStepInfo: (a: StepInfo | undefined, b: StepInfo) => boolean;
@@ -41,3 +41,10 @@ export interface StepperContextDataType {
41
41
  validationTrigger?: number;
42
42
  }
43
43
  export type CategorizationElement = Category | Categorization;
44
+ export interface StepInfo {
45
+ isFirstStep: boolean;
46
+ isLastStep: boolean;
47
+ currentStep: number;
48
+ isOnReview: boolean;
49
+ isOnTaskList: boolean;
50
+ }
@@ -0,0 +1,6 @@
1
+ import { StepInfo } from './types';
2
+ export interface StepChange {
3
+ stepInfo?: StepInfo;
4
+ onStepChange: (stepInfo: StepInfo) => void;
5
+ }
6
+ export declare const useStepChange: (listener?: (stepInfo: StepInfo) => void) => StepChange;
@@ -0,0 +1,2 @@
1
+ import { StepInfo, StepperContextDataType } from './types';
2
+ export declare const useStepInfo: (state: Pick<StepperContextDataType, "categories" | "activeId">, onStepChange?: (stepInfo: StepInfo) => void) => StepInfo;
@@ -3,3 +3,5 @@ export * from './PageStepperControl';
3
3
  export * from './FormStepperTester';
4
4
  export * from './FormStepperReviewControl';
5
5
  export { getExternalFormPath, getNavigationTargetFromParams, getNavigationTargets, NAVIGATION_PARAMS, type FieldInfo, type FieldTarget, type NavigationOutcome, type NavigationTarget, type NavigationTargetInfo, type PageTarget, } from './util/navigationTarget';
6
+ export type { StepInfo } from './context/types';
7
+ export { useStepChange, type StepChange } from './context/useStepChange';