@openg2p/registry-widgets 1.1.0-dev.9 → 1.1.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.
@@ -38,6 +38,12 @@ export interface SectionRendererProps {
38
38
  onPreviousSection?: (index: number) => void;
39
39
  /** IntakeForm mode: when true or undefined, sections are editable; when false, sections are readonly */
40
40
  isDraft?: boolean;
41
+ /**
42
+ * IntakeForm mode: when true the accordion header is clickable so the user can open/close this
43
+ * section freely. False (default) locks the header — navigation is only via Next/Previous.
44
+ * SectionsContainer sets this to true for every visited section plus the one immediately after.
45
+ */
46
+ isAccessible?: boolean;
41
47
  /** RegistryView: called when this section enters or exits edit mode. Used by SectionsContainer to enforce single-edit. */
42
48
  onEditModeChange?: (sectionId: string, editing: boolean) => void;
43
49
  /** RegistryView: when true, forces this section out of edit mode (another section took over). */
@@ -51,5 +57,5 @@ export interface SectionRendererProps {
51
57
  * - Panels wrap when they exceed available width
52
58
  * - Sections can sit side-by-side if there's space
53
59
  */
54
- export declare const SectionRenderer: ({ section, dataSourceRequestHandler: propDataSourceRequestHandler, schemaData, onValueChange, gridColumnSpan, onSectionSave, hideEditButton, mode, namespace, changeRequestType, showChangeRequestLabel, dbSectionId, sectionRegisterId, onSectionDirtyChange, sectionIndex, sectionCount, expandedSectionIndex, onExpandSection, onSectionSaveSuccess, onPreviousSection, isDraft, onEditModeChange, forceExitEdit, }: SectionRendererProps) => import("react/jsx-runtime").JSX.Element;
60
+ export declare const SectionRenderer: ({ section, dataSourceRequestHandler: propDataSourceRequestHandler, schemaData, onValueChange, gridColumnSpan, onSectionSave, hideEditButton, mode, namespace, changeRequestType, showChangeRequestLabel, dbSectionId, sectionRegisterId, onSectionDirtyChange, sectionIndex, sectionCount, expandedSectionIndex, onExpandSection, onSectionSaveSuccess, onPreviousSection, isDraft, isAccessible, onEditModeChange, forceExitEdit, }: SectionRendererProps) => import("react/jsx-runtime").JSX.Element;
55
61
  //# sourceMappingURL=SectionRenderer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SectionRenderer.d.ts","sourceRoot":"","sources":["../../src/components/SectionRenderer.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAyC,MAAM,UAAU,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAQ9D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AA2ClD,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,aAAa,CAAC;IACvB,wBAAwB,CAAC,EAAE,oBAAoB,CAAC,0BAA0B,CAAC,CAAC;IAC5E,UAAU,CAAC,EAAE,oBAAoB,CAAC,YAAY,CAAC,CAAC;IAChD,aAAa,CAAC,EAAE,oBAAoB,CAAC,eAAe,CAAC,CAAC;IACtD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAClC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAGjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,2GAA2G;IAC3G,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAErE,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sFAAsF;IACtF,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,oGAAoG;IACpG,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,uGAAuG;IACvG,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,4FAA4F;IAC5F,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,wGAAwG;IACxG,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB,0HAA0H;IAC1H,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACjE,iGAAiG;IACjG,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAGD;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAAI,wZAwB7B,oBAAoB,4CAm9CtB,CAAC"}
1
+ {"version":3,"file":"SectionRenderer.d.ts","sourceRoot":"","sources":["../../src/components/SectionRenderer.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAyC,MAAM,UAAU,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAQ9D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AA2ClD,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,aAAa,CAAC;IACvB,wBAAwB,CAAC,EAAE,oBAAoB,CAAC,0BAA0B,CAAC,CAAC;IAC5E,UAAU,CAAC,EAAE,oBAAoB,CAAC,YAAY,CAAC,CAAC;IAChD,aAAa,CAAC,EAAE,oBAAoB,CAAC,eAAe,CAAC,CAAC;IACtD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAClC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAGjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,2GAA2G;IAC3G,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAErE,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,sFAAsF;IACtF,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,oGAAoG;IACpG,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,uGAAuG;IACvG,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,4FAA4F;IAC5F,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,wGAAwG;IACxG,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,0HAA0H;IAC1H,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACjE,iGAAiG;IACjG,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAGD;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAAI,saAyB7B,oBAAoB,4CAo+CtB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"SectionsContainer.d.ts","sourceRoot":"","sources":["../../src/components/SectionsContainer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAmB,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAOpE,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEnE,uHAAuH;AACvH,MAAM,WAAW,kBAAkB;IACjC,qEAAqE;IACrE,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7B,qEAAqE;IACrE,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,qFAAqF;IACrF,kBAAkB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAClD;;;OAGG;IACD,iBAAiB,IAAI,cAAc,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,wBAAwB,CAAC,EAAE,wBAAwB,CAAC;IACpD,UAAU,CAAC,EAAE,oBAAoB,CAAC,YAAY,CAAC,CAAC;IAChD,aAAa,CAAC,EAAE,oBAAoB,CAAC,eAAe,CAAC,CAAC;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,wGAAwG;IACxG,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;IAEpE,wHAAwH;IACxH,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACrE,0JAA0J;IAC1J,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACpD;AAoFD;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,GAAI,yMAa/B,sBAAsB,4CA4TxB,CAAC"}
1
+ {"version":3,"file":"SectionsContainer.d.ts","sourceRoot":"","sources":["../../src/components/SectionsContainer.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAmB,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAOpE,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,QAAQ,GAAG,YAAY,CAAC;AAEnE,uHAAuH;AACvH,MAAM,WAAW,kBAAkB;IACjC,qEAAqE;IACrE,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7B,qEAAqE;IACrE,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,qFAAqF;IACrF,kBAAkB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAClD;;;OAGG;IACD,iBAAiB,IAAI,cAAc,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,wBAAwB,CAAC,EAAE,wBAAwB,CAAC;IACpD,UAAU,CAAC,EAAE,oBAAoB,CAAC,YAAY,CAAC,CAAC;IAChD,aAAa,CAAC,EAAE,oBAAoB,CAAC,eAAe,CAAC,CAAC;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,wGAAwG;IACxG,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;IAEpE,wHAAwH;IACxH,oBAAoB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACrE,0JAA0J;IAC1J,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;CACpD;AAoFD;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,GAAI,yMAa/B,sBAAsB,4CAqUxB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useBaseWidget.d.ts","sourceRoot":"","sources":["../../src/hooks/useBaseWidget.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AAgBtE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,gBAAgB,CAAC;IACzB,wBAAwB,CAAC,EAAE,wBAAwB,CAAC;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;CACxD;AAMD,eAAO,MAAM,aAAa,GAAI,SAAS,oBAAoB;;;;;;;;;yBAsM5C,GAAG,aAAY,OAAO;;uBA2Td,MAAM,EAAE;;;;;;;0BAhMpB,MAAM;;;CAqMhB,CAAC"}
1
+ {"version":3,"file":"useBaseWidget.d.ts","sourceRoot":"","sources":["../../src/hooks/useBaseWidget.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AAgBtE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,gBAAgB,CAAC;IACzB,wBAAwB,CAAC,EAAE,wBAAwB,CAAC;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;CACxD;AAMD,eAAO,MAAM,aAAa,GAAI,SAAS,oBAAoB;;;;;;;;;yBAsM5C,GAAG,aAAY,OAAO;;uBAgUd,MAAM,EAAE;;;;;;;0BArMpB,MAAM;;;CA0MhB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -707,6 +707,12 @@ interface SectionRendererProps {
707
707
  onPreviousSection?: (index: number) => void;
708
708
  /** IntakeForm mode: when true or undefined, sections are editable; when false, sections are readonly */
709
709
  isDraft?: boolean;
710
+ /**
711
+ * IntakeForm mode: when true the accordion header is clickable so the user can open/close this
712
+ * section freely. False (default) locks the header — navigation is only via Next/Previous.
713
+ * SectionsContainer sets this to true for every visited section plus the one immediately after.
714
+ */
715
+ isAccessible?: boolean;
710
716
  /** RegistryView: called when this section enters or exits edit mode. Used by SectionsContainer to enforce single-edit. */
711
717
  onEditModeChange?: (sectionId: string, editing: boolean) => void;
712
718
  /** RegistryView: when true, forces this section out of edit mode (another section took over). */
@@ -720,7 +726,7 @@ interface SectionRendererProps {
720
726
  * - Panels wrap when they exceed available width
721
727
  * - Sections can sit side-by-side if there's space
722
728
  */
723
- declare const SectionRenderer: ({ section, dataSourceRequestHandler: propDataSourceRequestHandler, schemaData, onValueChange, gridColumnSpan, onSectionSave, hideEditButton, mode, namespace, changeRequestType, showChangeRequestLabel, dbSectionId, sectionRegisterId, onSectionDirtyChange, sectionIndex, sectionCount, expandedSectionIndex, onExpandSection, onSectionSaveSuccess, onPreviousSection, isDraft, onEditModeChange, forceExitEdit, }: SectionRendererProps) => react_jsx_runtime.JSX.Element;
729
+ declare const SectionRenderer: ({ section, dataSourceRequestHandler: propDataSourceRequestHandler, schemaData, onValueChange, gridColumnSpan, onSectionSave, hideEditButton, mode, namespace, changeRequestType, showChangeRequestLabel, dbSectionId, sectionRegisterId, onSectionDirtyChange, sectionIndex, sectionCount, expandedSectionIndex, onExpandSection, onSectionSaveSuccess, onPreviousSection, isDraft, isAccessible, onEditModeChange, forceExitEdit, }: SectionRendererProps) => react_jsx_runtime.JSX.Element;
724
730
 
725
731
  interface SectionBuilderProps {
726
732
  initialSection?: SectionConfig;
package/dist/index.esm.js CHANGED
@@ -1077,16 +1077,12 @@ const getApiDataSource = async (dataSource, allValues, dataSourceRequestHandler,
1077
1077
  console.error('[getApiDataSource] API data source missing endpoint. Use "endpoint" field to specify the operation (e.g., "get_g2p_geo_level_values")');
1078
1078
  return [];
1079
1079
  }
1080
- let response;
1081
- try {
1082
- response = await dataSourceRequestHandler(service, endpoint, method, requestParams, {
1083
- headers: dataSource.headers,
1084
- });
1085
- }
1086
- catch (error) {
1087
- console.error('[getApiDataSource] Handler error:', error);
1088
- throw error;
1089
- }
1080
+ // Call handler — let any throw propagate to the outer catch so it is logged once
1081
+ // by useBaseWidget rather than double-logged here (which can cascade when
1082
+ // intercept-console-error.js converts console.error calls into thrown errors).
1083
+ const response = await dataSourceRequestHandler(service, endpoint, method, requestParams, {
1084
+ headers: dataSource.headers,
1085
+ });
1090
1086
  // Handle OpenG2P response format (response_body.response_payload)
1091
1087
  if (response && typeof response === 'object') {
1092
1088
  if (response.response_body?.response_payload && Array.isArray(response.response_body.response_payload)) {
@@ -1109,8 +1105,8 @@ const getApiDataSource = async (dataSource, allValues, dataSourceRequestHandler,
1109
1105
  return [];
1110
1106
  }
1111
1107
  catch (error) {
1112
- console.error('Error fetching API data source:', error);
1113
- return [];
1108
+ // Rethrow so useBaseWidget's catch can log it with full widget context
1109
+ throw error;
1114
1110
  }
1115
1111
  };
1116
1112
  /**
@@ -2304,7 +2300,7 @@ const useBaseWidget = (options) => {
2304
2300
  dispatch(setDataSource({ widgetId, data: transformed }));
2305
2301
  }
2306
2302
  catch (error) {
2307
- console.error(`[useBaseWidget] ERROR loading data source for ${widgetId}:`, error);
2303
+ console.error(`[useBaseWidget] ERROR loading data source for widget "${widgetId}" (type="${dataSource.type}"):`, error, '\nWidget config:', config, '\ndataSourceRequestHandler provided:', Boolean(dataSourceRequestHandler));
2308
2304
  dispatch(setDataSource({ widgetId, data: [] }));
2309
2305
  }
2310
2306
  finally {
@@ -3946,7 +3942,7 @@ function scopedClassSelectors(sectionClassId, classNames) {
3946
3942
  * - Panels wrap when they exceed available width
3947
3943
  * - Sections can sit side-by-side if there's space
3948
3944
  */
3949
- const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequestHandler, schemaData, onValueChange, gridColumnSpan, onSectionSave, hideEditButton = false, mode = 'RegistryView', namespace, changeRequestType, showChangeRequestLabel = true, dbSectionId, sectionRegisterId, onSectionDirtyChange, sectionIndex, sectionCount, expandedSectionIndex, onExpandSection, onSectionSaveSuccess, onPreviousSection, isDraft, onEditModeChange, forceExitEdit, }) => {
3945
+ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequestHandler, schemaData, onValueChange, gridColumnSpan, onSectionSave, hideEditButton = false, mode = 'RegistryView', namespace, changeRequestType, showChangeRequestLabel = true, dbSectionId, sectionRegisterId, onSectionDirtyChange, sectionIndex, sectionCount, expandedSectionIndex, onExpandSection, onSectionSaveSuccess, onPreviousSection, isDraft, isAccessible = false, onEditModeChange, forceExitEdit, }) => {
3950
3946
  const { translateConfig, translate } = useWidgetTranslation();
3951
3947
  const resolvedTheme = useWidgetTheme();
3952
3948
  const portalCSSVariables = useMemo(() => themeToCSSVariables(resolvedTheme), [resolvedTheme]);
@@ -4012,16 +4008,25 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4012
4008
  const isExpandedFromContainer = typeof sectionIndex === 'number' && expandedSectionIndex === sectionIndex;
4013
4009
  const isExpandedStandalone = sectionIndex === undefined && standaloneExpanded;
4014
4010
  const isExpanded = mode === 'IntakeForm' && (isExpandedFromContainer || isExpandedStandalone);
4011
+ // IntakeForm only: tracks whether the user has clicked Next on this section at least once.
4012
+ // Used to unlock the accordion header so the user can navigate back to a visited section.
4013
+ const [hasBeenSavedByUser, setHasBeenSavedByUser] = useState(false);
4014
+ // Accordion header click behaviour in IntakeForm mode:
4015
+ // - Standalone (no sectionIndex): always toggleable.
4016
+ // - Managed by SectionsContainer: toggleable only when isAccessible is true
4017
+ // (i.e. the section has been visited OR is the immediate next one).
4018
+ // Sections beyond that remain locked.
4015
4019
  const handleAccordionToggle = useCallback(() => {
4016
4020
  if (mode !== 'IntakeForm')
4017
4021
  return;
4018
- if (typeof sectionIndex === 'number' && onExpandSection) {
4019
- onExpandSection(sectionIndex);
4020
- }
4021
- else if (sectionIndex === undefined) {
4022
+ if (sectionIndex === undefined) {
4022
4023
  setStandaloneExpanded(prev => !prev);
4023
4024
  }
4024
- }, [mode, sectionIndex, onExpandSection]);
4025
+ else if (isAccessible && onExpandSection) {
4026
+ onExpandSection(sectionIndex);
4027
+ }
4028
+ // Intentionally no-op for locked sections (isAccessible === false)
4029
+ }, [mode, sectionIndex, isAccessible, onExpandSection]);
4025
4030
  // Recursively count all vertical panels, especially those nested inside horizontal panels
4026
4031
  // Typically: horizontal panels at first level contain vertical panels at second level
4027
4032
  // Accounts for panel-column-span: a panel with column-span 3 counts as 3 columns
@@ -4356,8 +4361,6 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4356
4361
  const baselineSnapshotRef = useRef(null);
4357
4362
  // IntakeForm only: increment when baseline is updated after save - forces badge to update (refs don't trigger re-renders)
4358
4363
  const [intakeFormBaselineTrigger, setIntakeFormBaselineTrigger] = useState(0);
4359
- // IntakeForm only: tracks whether the user has actually saved this section (prevents "Saved" badge on initial load)
4360
- const [hasBeenSavedByUser, setHasBeenSavedByUser] = useState(false);
4361
4364
  // IntakeForm: treat as edit mode for dirty tracking when isDraft. RegistryView: use isEditMode.
4362
4365
  const effectiveEditModeForDirty = mode === 'IntakeForm' ? (isDraft !== false) : isEditMode;
4363
4366
  // Compute isDirty: compare current store state to baseline (only when in edit mode)
@@ -4590,6 +4593,11 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4590
4593
  }
4591
4594
  onSectionDirtyChange?.(sectionId, false);
4592
4595
  }
4596
+ else if (mode === 'IntakeForm') {
4597
+ // No onSectionSave provided, but still mark section as visited so the
4598
+ // user can navigate back to it by clicking the accordion header.
4599
+ setHasBeenSavedByUser(true);
4600
+ }
4593
4601
  // Always navigate to the next section
4594
4602
  onSectionSaveSuccess?.(sectionIndex);
4595
4603
  }, [store, onSectionSave, onSectionSaveSuccess, sectionIndex, originalSection, schemaData, contextSchemaData, namespace, hasSupportingDocuments, dbSectionId, sectionRegisterId, dispatch, buildSectionSnapshot, sectionId, onSectionDirtyChange, mode, isDraft]);
@@ -4808,13 +4816,17 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4808
4816
  .${sectionClassId}.intake-form-accordion-item .intake-form-accordion-header h2 {
4809
4817
  color: var(--owt-color-primary-dark, #F07B1A);
4810
4818
  }
4811
- .${sectionClassId}.intake-form-accordion-item .intake-form-accordion-header:hover {
4819
+ /* Hover / focus only shown when the header is actually interactive (standalone mode) */
4820
+ .${sectionClassId}.intake-form-accordion-item .intake-form-accordion-header[data-interactive="true"]:hover {
4812
4821
  opacity: 0.85;
4813
4822
  }
4814
- .${sectionClassId}.intake-form-accordion-item .intake-form-accordion-header:focus-visible {
4823
+ .${sectionClassId}.intake-form-accordion-item .intake-form-accordion-header[data-interactive="true"]:focus-visible {
4815
4824
  outline: 2px solid var(--owt-color-primary, #F5BB1A);
4816
4825
  outline-offset: 2px;
4817
4826
  }
4827
+ .${sectionClassId}.intake-form-accordion-item .intake-form-accordion-header[data-interactive="false"]:focus-visible {
4828
+ outline: none;
4829
+ }
4818
4830
  .${sectionClassId}.intake-form-accordion-item .intake-form-accordion-content {
4819
4831
  padding-top: 8px;
4820
4832
  padding-bottom: 0px;
@@ -4857,7 +4869,7 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4857
4869
  }),
4858
4870
  }, children: mode === 'IntakeForm' ? (
4859
4871
  /* IntakeForm: accordion layout - header always visible, content only when expanded */
4860
- jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs("button", { type: "button", id: `intake-form-accordion-header-${sectionId}`, className: "intake-form-accordion-header", onClick: handleAccordionToggle, "aria-expanded": isExpanded, "aria-controls": isExpanded ? `intake-form-accordion-content-${sectionId}` : undefined, style: {
4872
+ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [jsxRuntimeExports.jsxs("button", { type: "button", id: `intake-form-accordion-header-${sectionId}`, className: "intake-form-accordion-header", onClick: handleAccordionToggle, "aria-expanded": isExpanded, "aria-controls": isExpanded ? `intake-form-accordion-content-${sectionId}` : undefined, "data-interactive": sectionIndex === undefined || isAccessible ? 'true' : 'false', style: {
4861
4873
  width: '100%',
4862
4874
  display: 'flex',
4863
4875
  alignItems: 'flex-start',
@@ -4867,7 +4879,7 @@ const SectionRenderer = ({ section, dataSourceRequestHandler: propDataSourceRequ
4867
4879
  marginBottom: 0,
4868
4880
  background: 'none',
4869
4881
  border: 'none',
4870
- cursor: 'pointer',
4882
+ cursor: sectionIndex === undefined || isAccessible ? 'pointer' : 'default',
4871
4883
  textAlign: 'left',
4872
4884
  fontFamily: 'Roboto, sans-serif',
4873
4885
  }, children: [jsxRuntimeExports.jsxs("div", { style: { flex: 1, display: 'flex', alignItems: 'center', gap: '12px', minWidth: 0 }, children: [jsxRuntimeExports.jsx("h2", { className: "text-xl font-semibold", style: { margin: 0 }, children: sectionToRender['section-title']
@@ -5165,6 +5177,11 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
5165
5177
  const dataSourceRequestHandler = propDataSourceRequestHandler || contextDataSourceRequestHandler;
5166
5178
  // IntakeForm mode: accordion state - which section is expanded (null = none; first expanded by default)
5167
5179
  const [expandedSectionIndex, setExpandedSectionIndex] = useState(0);
5180
+ // IntakeForm mode: high-water mark of the furthest section the user has clicked Next on.
5181
+ // A section at index i is accessible when i <= maxVisitedIndex + 1
5182
+ // (i.e. every visited section plus the one immediately after it).
5183
+ // Starts at -1 so only section 0 is accessible before any Next is clicked.
5184
+ const [maxVisitedIndex, setMaxVisitedIndex] = useState(-1);
5168
5185
  // RegistryView: track which section is currently in edit mode (by section-id); null = none
5169
5186
  const [editingSectionId, setEditingSectionId] = useState(null);
5170
5187
  const handleEditModeChange = useCallback((sectionId, editing) => {
@@ -5189,8 +5206,9 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
5189
5206
  const handleExpandSection = useCallback((index) => {
5190
5207
  setExpandedSectionIndex(prev => (prev === index ? null : index));
5191
5208
  }, []);
5192
- // IntakeForm mode: called after section save - collapse current, expand next
5209
+ // IntakeForm mode: called after section save - advance high-water mark, collapse current, expand next
5193
5210
  const handleSectionSaveSuccess = useCallback((index) => {
5211
+ setMaxVisitedIndex(prev => Math.max(prev, index));
5194
5212
  if (index + 1 < safeSections.length) {
5195
5213
  setExpandedSectionIndex(index + 1);
5196
5214
  }
@@ -5384,6 +5402,8 @@ const SectionsContainer = ({ sections, dataSourceRequestHandler: propDataSourceR
5384
5402
  onSectionSaveSuccess: handleSectionSaveSuccess,
5385
5403
  onPreviousSection: handlePreviousSection,
5386
5404
  isDraft,
5405
+ // Accessible = every visited section + the one immediately after
5406
+ isAccessible: index <= maxVisitedIndex + 1,
5387
5407
  }
5388
5408
  : {};
5389
5409
  // RegistryView: single-edit coordination props
@@ -7366,7 +7386,7 @@ const NumberInputWidget = ({ config }) => {
7366
7386
  if (parsed === null) {
7367
7387
  // Allow empty input or partial input (e.g., "-", ".")
7368
7388
  if (inputValue === '' || inputValue === '-' || inputValue === '.') {
7369
- onChange('');
7389
+ onChange(null);
7370
7390
  }
7371
7391
  // Don't update if invalid - let user continue typing
7372
7392
  return;
@@ -9730,10 +9750,13 @@ const TextAreaWidget = ({ config }) => {
9730
9750
  // For readonly mode, render as preformatted text using <pre> tag
9731
9751
  if (isReadonly) {
9732
9752
  const displayValue = getStringValue() || '-';
9733
- return (jsxRuntimeExports.jsxs("div", { className: "mb-[10px] TextAreaDisplayWidget flex flex-col sm:flex-row sm:items-start", children: [label && (jsxRuntimeExports.jsxs("div", { className: "text-base text-gray-600 font-medium md:min-w-[120px] sm:pr-4 mb-1 sm:mb-0", style: { fontFamily: 'Roboto, sans-serif' }, title: label, children: [label, ":"] })), jsxRuntimeExports.jsx("div", { className: "flex-1", children: jsxRuntimeExports.jsx("pre", { className: "text-base text-gray-900 font-medium whitespace-pre-wrap", title: String(displayValue), style: {
9753
+ return (jsxRuntimeExports.jsxs("div", { className: "mb-[10px] TextAreaDisplayWidget flex flex-col sm:flex-row sm:items-start", children: [label && (jsxRuntimeExports.jsxs("div", { className: "text-base text-gray-600 font-medium md:min-w-[120px] sm:pr-4 mb-1 sm:mb-0", style: { fontFamily: 'Roboto, sans-serif' }, title: label, children: [label, ":"] })), jsxRuntimeExports.jsx("div", { className: "flex-1", children: jsxRuntimeExports.jsx("div", { title: String(displayValue), className: "text-base text-gray-900 font-medium overflow-y-auto whitespace-pre-wrap break-words", style: {
9734
9754
  fontFamily: 'Roboto, sans-serif',
9735
- margin: 0,
9736
- padding: 0,
9755
+ height: '56px',
9756
+ minHeight: '56px',
9757
+ maxHeight: '56px',
9758
+ lineHeight: '20px',
9759
+ padding: '8px 0',
9737
9760
  backgroundColor: 'transparent',
9738
9761
  border: 'none',
9739
9762
  }, children: displayValue }) })] }));