@aehrc/smart-forms-renderer 1.1.0 → 1.2.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/lib/components/FormComponents/GroupItem/TabButtonsWrapper.js +7 -4
- package/lib/components/FormComponents/GroupItem/TabButtonsWrapper.js.map +1 -1
- package/lib/components/Tabs/FormBodySingleTab.js +8 -5
- package/lib/components/Tabs/FormBodySingleTab.js.map +1 -1
- package/lib/stores/rendererConfigStore.d.ts +6 -0
- package/lib/stores/rendererConfigStore.js +3 -1
- package/lib/stores/rendererConfigStore.js.map +1 -1
- package/package.json +2 -2
- package/src/components/FormComponents/GroupItem/TabButtonsWrapper.tsx +8 -4
- package/src/components/Tabs/FormBodySingleTab.tsx +10 -5
- package/src/stores/rendererConfigStore.ts +9 -1
|
@@ -26,6 +26,7 @@ const TabButtonsWrapper = memo(function TabButtonsWrapper(props) {
|
|
|
26
26
|
const { currentTabIndex, tabs } = props;
|
|
27
27
|
const switchTab = useQuestionnaireStore.use.switchTab();
|
|
28
28
|
const disableTabButtons = useRendererConfigStore.use.disableTabButtons();
|
|
29
|
+
const disableHeadingFocusOnTabSwitch = useRendererConfigStore.use.disableHeadingFocusOnTabSwitch();
|
|
29
30
|
const { previousTabIndex, nextTabIndex, numOfVisibleTabs } = useNextAndPreviousVisibleTabs(currentTabIndex, tabs);
|
|
30
31
|
const focusHeading = useFocusTabHeading();
|
|
31
32
|
const tabsNotDefined = currentTabIndex === undefined || tabs === undefined;
|
|
@@ -37,10 +38,12 @@ const TabButtonsWrapper = memo(function TabButtonsWrapper(props) {
|
|
|
37
38
|
switchTab(previousTabIndex);
|
|
38
39
|
// Scroll to top of page
|
|
39
40
|
window.scrollTo(0, 0);
|
|
40
|
-
// Focus the first heading in the new tab panel
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
// Focus the first heading in the new tab panel if not disabled
|
|
42
|
+
if (!disableHeadingFocusOnTabSwitch) {
|
|
43
|
+
setTimeout(() => {
|
|
44
|
+
focusHeading(`tabpanel-${previousTabIndex}`);
|
|
45
|
+
}, 100); // Small delay to ensure panel is rendered
|
|
46
|
+
}
|
|
44
47
|
}
|
|
45
48
|
function handleNextTabButtonClick() {
|
|
46
49
|
if (nextTabIndex === null) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TabButtonsWrapper.js","sourceRoot":"","sources":["../../../../src/components/FormComponents/GroupItem/TabButtonsWrapper.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAc,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,GAAG,MAAM,mBAAmB,CAAC;AAEpC,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAChF,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,iBAAiB,MAAM,qBAAqB,CAAC;AACpD,OAAO,6BAA6B,MAAM,8CAA8C,CAAC;AACzF,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAOvE,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAS,iBAAiB,CAAC,KAA6B;IACrF,MAAM,EAAE,eAAe,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;IAExC,MAAM,SAAS,GAAG,qBAAqB,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;IACxD,MAAM,iBAAiB,GAAG,sBAAsB,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"TabButtonsWrapper.js","sourceRoot":"","sources":["../../../../src/components/FormComponents/GroupItem/TabButtonsWrapper.tsx"],"names":[],"mappings":"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"}
|
|
@@ -20,23 +20,26 @@ import Box from '@mui/material/Box';
|
|
|
20
20
|
import ListItemButton from '@mui/material/ListItemButton';
|
|
21
21
|
import ListItemText from '@mui/material/ListItemText';
|
|
22
22
|
import Typography from '@mui/material/Typography';
|
|
23
|
-
import { useQuestionnaireStore } from '../../stores';
|
|
23
|
+
import { useQuestionnaireStore, useRendererConfigStore } from '../../stores';
|
|
24
24
|
import ContextDisplayItem from '../FormComponents/ItemParts/ContextDisplayItem';
|
|
25
25
|
import { useFocusTabHeading } from '../../hooks/useFocusTabHeading';
|
|
26
26
|
import useDisplayCqfAndCalculatedExpression from '../../hooks/useDisplayCqfAndCalculatedExpression';
|
|
27
27
|
const FormBodySingleTab = memo(function FormBodySingleTab(props) {
|
|
28
28
|
const { qItem, contextDisplayItems, selected, tabLabel, listIndex } = props;
|
|
29
29
|
const switchTab = useQuestionnaireStore.use.switchTab();
|
|
30
|
+
const disableHeadingFocusOnTabSwitch = useRendererConfigStore.use.disableHeadingFocusOnTabSwitch();
|
|
30
31
|
const focusHeading = useFocusTabHeading();
|
|
31
32
|
// Get aria-label text if available
|
|
32
33
|
const itemTextAriaLabel = useDisplayCqfAndCalculatedExpression(qItem, 'item._text.aria-label') ?? undefined;
|
|
33
34
|
function handleTabClick() {
|
|
34
35
|
switchTab(listIndex);
|
|
35
36
|
window.scrollTo(0, 0);
|
|
36
|
-
// Focus the first heading in the new tab panel
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
// Focus the first heading in the new tab panel if not disabled
|
|
38
|
+
if (!disableHeadingFocusOnTabSwitch) {
|
|
39
|
+
setTimeout(() => {
|
|
40
|
+
focusHeading(`tabpanel-${listIndex}`);
|
|
41
|
+
}, 100); // Small delay to ensure panel is rendered
|
|
42
|
+
}
|
|
40
43
|
}
|
|
41
44
|
return (_jsx(_Fragment, { children: _jsx(ListItemButton, { selected: selected, sx: { my: 0.1, minHeight: '36px' }, onClick: handleTabClick, children: _jsx(ListItemText, { primary: _jsxs(Box, { display: "flex", alignItems: "center", justifyContent: "space-between", children: [_jsx(Typography, { id: `tab-${listIndex}`, component: "span", fontWeight: 600, fontSize: "0.8125rem", "aria-label": itemTextAriaLabel, children: tabLabel }), _jsx(Box, { display: "flex", minHeight: 24, minWidth: 24, ml: 1, children: contextDisplayItems.map((item) => {
|
|
42
45
|
return _jsx(ContextDisplayItem, { displayItem: item }, item.linkId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FormBodySingleTab.js","sourceRoot":"","sources":["../../../src/components/Tabs/FormBodySingleTab.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAc,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,GAAG,MAAM,mBAAmB,CAAC;AACpC,OAAO,cAAc,MAAM,8BAA8B,CAAC;AAC1D,OAAO,YAAY,MAAM,4BAA4B,CAAC;AACtD,OAAO,UAAU,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"FormBodySingleTab.js","sourceRoot":"","sources":["../../../src/components/Tabs/FormBodySingleTab.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAc,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,GAAG,MAAM,mBAAmB,CAAC;AACpC,OAAO,cAAc,MAAM,8BAA8B,CAAC;AAC1D,OAAO,YAAY,MAAM,4BAA4B,CAAC;AACtD,OAAO,UAAU,MAAM,0BAA0B,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAE7E,OAAO,kBAAkB,MAAM,gDAAgD,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,oCAAoC,MAAM,kDAAkD,CAAC;AAUpG,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAS,iBAAiB,CAAC,KAA6B;IACrF,MAAM,EAAE,KAAK,EAAE,mBAAmB,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAE5E,MAAM,SAAS,GAAG,qBAAqB,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;IACxD,MAAM,8BAA8B,GAClC,sBAAsB,CAAC,GAAG,CAAC,8BAA8B,EAAE,CAAC;IAE9D,MAAM,YAAY,GAAG,kBAAkB,EAAE,CAAC;IAE1C,mCAAmC;IACnC,MAAM,iBAAiB,GACrB,oCAAoC,CAAC,KAAK,EAAE,uBAAuB,CAAC,IAAI,SAAS,CAAC;IAEpF,SAAS,cAAc;QACrB,SAAS,CAAC,SAAS,CAAC,CAAC;QACrB,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAEtB,+DAA+D;QAC/D,IAAI,CAAC,8BAA8B,EAAE,CAAC;YACpC,UAAU,CAAC,GAAG,EAAE;gBACd,YAAY,CAAC,YAAY,SAAS,EAAE,CAAC,CAAC;YACxC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,0CAA0C;QACrD,CAAC;IACH,CAAC;IAED,OAAO,CACL,4BACE,KAAC,cAAc,IACb,QAAQ,EAAE,QAAQ,EAClB,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,EAClC,OAAO,EAAE,cAAc,YACvB,KAAC,YAAY,IACX,OAAO,EACL,MAAC,GAAG,IAAC,OAAO,EAAC,MAAM,EAAC,UAAU,EAAC,QAAQ,EAAC,cAAc,EAAC,eAAe,aACpE,KAAC,UAAU,IACT,EAAE,EAAE,OAAO,SAAS,EAAE,EACtB,SAAS,EAAC,MAAM,EAChB,UAAU,EAAE,GAAG,EACf,QAAQ,EAAC,WAAW,gBACR,iBAAiB,YAC5B,QAAQ,GACE,EACb,KAAC,GAAG,IAAC,OAAO,EAAC,MAAM,EAAC,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,YACnD,mBAAmB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;gCAChC,OAAO,KAAC,kBAAkB,IAAmB,WAAW,EAAE,IAAI,IAA9B,IAAI,CAAC,MAAM,CAAuB,CAAC;4BACrE,CAAC,CAAC,GACE,IACF,GAER,GACa,GAChB,CACJ,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,eAAe,iBAAiB,CAAC"}
|
|
@@ -54,6 +54,9 @@ import type { Breakpoints } from '@mui/material';
|
|
|
54
54
|
* @property disableTabButtons - If `true`, hides navigation buttons for tabs.
|
|
55
55
|
* - Default: `false`
|
|
56
56
|
*
|
|
57
|
+
* @property disableHeadingFocusOnTabSwitch - If `true`, the first heading will be focused when switching tabs.
|
|
58
|
+
* - Default: `false`
|
|
59
|
+
*
|
|
57
60
|
* @property readOnlyVisualStyle - If `true`, item.readOnly will result in form fields having MUI disabled property and styles (recommended from usability perspective). If `false`, item.readOnly will result in form fields having HTML readonly property (less stable, but recommended from accessibility perspective).
|
|
58
61
|
* - Default: `true`
|
|
59
62
|
*/
|
|
@@ -80,6 +83,7 @@ export interface RendererConfig {
|
|
|
80
83
|
disablePageCardView?: boolean;
|
|
81
84
|
disablePageButtons?: boolean;
|
|
82
85
|
disableTabButtons?: boolean;
|
|
86
|
+
disableHeadingFocusOnTabSwitch?: boolean;
|
|
83
87
|
}
|
|
84
88
|
/**
|
|
85
89
|
* RendererConfigStore properties and methods
|
|
@@ -109,6 +113,7 @@ export interface RendererConfigStoreType {
|
|
|
109
113
|
disablePageCardView: boolean;
|
|
110
114
|
disablePageButtons: boolean;
|
|
111
115
|
disableTabButtons: boolean;
|
|
116
|
+
disableHeadingFocusOnTabSwitch: boolean;
|
|
112
117
|
setRendererConfig: (params: RendererConfig) => void;
|
|
113
118
|
}
|
|
114
119
|
/**
|
|
@@ -139,6 +144,7 @@ export declare const useRendererConfigStore: import("zustand/vanilla").StoreApi<
|
|
|
139
144
|
disablePageCardView: () => boolean;
|
|
140
145
|
disablePageButtons: () => boolean;
|
|
141
146
|
disableTabButtons: () => boolean;
|
|
147
|
+
disableHeadingFocusOnTabSwitch: () => boolean;
|
|
142
148
|
setRendererConfig: () => (params: RendererConfig) => void;
|
|
143
149
|
};
|
|
144
150
|
};
|
|
@@ -42,6 +42,7 @@ export const rendererConfigStore = createStore()((set) => ({
|
|
|
42
42
|
disablePageCardView: false,
|
|
43
43
|
disablePageButtons: false,
|
|
44
44
|
disableTabButtons: false,
|
|
45
|
+
disableHeadingFocusOnTabSwitch: false,
|
|
45
46
|
setRendererConfig: (params) => {
|
|
46
47
|
set((state) => ({
|
|
47
48
|
readOnlyVisualStyle: params.readOnlyVisualStyle ?? state.readOnlyVisualStyle,
|
|
@@ -57,7 +58,8 @@ export const rendererConfigStore = createStore()((set) => ({
|
|
|
57
58
|
enableWhenAsReadOnly: params.enableWhenAsReadOnly ?? state.enableWhenAsReadOnly,
|
|
58
59
|
disablePageCardView: params.disablePageCardView ?? state.disablePageCardView,
|
|
59
60
|
disablePageButtons: params.disablePageButtons ?? state.disablePageButtons,
|
|
60
|
-
disableTabButtons: params.disableTabButtons ?? state.disableTabButtons
|
|
61
|
+
disableTabButtons: params.disableTabButtons ?? state.disableTabButtons,
|
|
62
|
+
disableHeadingFocusOnTabSwitch: params.disableHeadingFocusOnTabSwitch ?? state.disableHeadingFocusOnTabSwitch
|
|
61
63
|
}));
|
|
62
64
|
}
|
|
63
65
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rendererConfigStore.js","sourceRoot":"","sources":["../../src/stores/rendererConfigStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"rendererConfigStore.js","sourceRoot":"","sources":["../../src/stores/rendererConfigStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AA8H7C;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,WAAW,EAA2B,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAClF,mBAAmB,EAAE,UAAU;IAC/B,yBAAyB,EAAE,OAAO;IAClC,cAAc,EAAE;QACd,gBAAgB,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE;QACnC,gBAAgB,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE;QACnC,eAAe,EAAE,EAAE;QACnB,YAAY,EAAE,CAAC;KAChB;IACD,wBAAwB,EAAE;QACxB,kBAAkB,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE;QACtD,qBAAqB,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE;KAC1D;IACD,gBAAgB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;IAC9C,cAAc,EAAE,GAAG;IACnB,cAAc,EAAE,KAAK;IACrB,mBAAmB,EAAE,KAAK;IAC1B,eAAe,EAAE,KAAK;IACtB,2BAA2B,EAAE,KAAK;IAClC,oBAAoB,EAAE,KAAK;IAC3B,mBAAmB,EAAE,KAAK;IAC1B,kBAAkB,EAAE,KAAK;IACzB,iBAAiB,EAAE,KAAK;IACxB,8BAA8B,EAAE,KAAK;IACrC,iBAAiB,EAAE,CAAC,MAAsB,EAAE,EAAE;QAC5C,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACd,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,IAAI,KAAK,CAAC,mBAAmB;YAC5E,yBAAyB,EACvB,MAAM,CAAC,yBAAyB,IAAI,KAAK,CAAC,yBAAyB;YACrE,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc;YAC7D,wBAAwB,EAAE,MAAM,CAAC,wBAAwB,IAAI,KAAK,CAAC,wBAAwB;YAC3F,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,IAAI,KAAK,CAAC,gBAAgB;YACnE,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc;YAC7D,cAAc,EAAE,MAAM,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc;YAC7D,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,IAAI,KAAK,CAAC,mBAAmB;YAC5E,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,KAAK,CAAC,eAAe;YAChE,2BAA2B,EACzB,MAAM,CAAC,2BAA2B,IAAI,KAAK,CAAC,2BAA2B;YACzE,oBAAoB,EAAE,MAAM,CAAC,oBAAoB,IAAI,KAAK,CAAC,oBAAoB;YAC/E,mBAAmB,EAAE,MAAM,CAAC,mBAAmB,IAAI,KAAK,CAAC,mBAAmB;YAC5E,kBAAkB,EAAE,MAAM,CAAC,kBAAkB,IAAI,KAAK,CAAC,kBAAkB;YACzE,iBAAiB,EAAE,MAAM,CAAC,iBAAiB,IAAI,KAAK,CAAC,iBAAiB;YACtE,8BAA8B,EAC5B,MAAM,CAAC,8BAA8B,IAAI,KAAK,CAAC,8BAA8B;SAChF,CAAC,CAAC,CAAC;IACN,CAAC;CACF,CAAC,CAAC,CAAC;AAEJ,MAAM,CAAC,MAAM,sBAAsB,GAAG,eAAe,CAAC,mBAAmB,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aehrc/smart-forms-renderer",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "FHIR Structured Data Captured (SDC) rendering engine for Smart Forms",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"homepage": "https://github.com/aehrc/smart-forms#readme",
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@aehrc/sdc-populate": "^4.6.2",
|
|
32
|
-
"@aehrc/sdc-template-extract": "^1.0.
|
|
32
|
+
"@aehrc/sdc-template-extract": "^1.0.14",
|
|
33
33
|
"@emotion/react": "^11.14.0",
|
|
34
34
|
"@emotion/styled": "^11.14.1",
|
|
35
35
|
"@fontsource/inter": "^5.2.8",
|
|
@@ -34,6 +34,8 @@ const TabButtonsWrapper = memo(function TabButtonsWrapper(props: TabButtonsWrapp
|
|
|
34
34
|
|
|
35
35
|
const switchTab = useQuestionnaireStore.use.switchTab();
|
|
36
36
|
const disableTabButtons = useRendererConfigStore.use.disableTabButtons();
|
|
37
|
+
const disableHeadingFocusOnTabSwitch =
|
|
38
|
+
useRendererConfigStore.use.disableHeadingFocusOnTabSwitch();
|
|
37
39
|
|
|
38
40
|
const { previousTabIndex, nextTabIndex, numOfVisibleTabs } = useNextAndPreviousVisibleTabs(
|
|
39
41
|
currentTabIndex,
|
|
@@ -55,10 +57,12 @@ const TabButtonsWrapper = memo(function TabButtonsWrapper(props: TabButtonsWrapp
|
|
|
55
57
|
// Scroll to top of page
|
|
56
58
|
window.scrollTo(0, 0);
|
|
57
59
|
|
|
58
|
-
// Focus the first heading in the new tab panel
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
// Focus the first heading in the new tab panel if not disabled
|
|
61
|
+
if (!disableHeadingFocusOnTabSwitch) {
|
|
62
|
+
setTimeout(() => {
|
|
63
|
+
focusHeading(`tabpanel-${previousTabIndex}`);
|
|
64
|
+
}, 100); // Small delay to ensure panel is rendered
|
|
65
|
+
}
|
|
62
66
|
}
|
|
63
67
|
|
|
64
68
|
function handleNextTabButtonClick() {
|
|
@@ -20,7 +20,7 @@ import Box from '@mui/material/Box';
|
|
|
20
20
|
import ListItemButton from '@mui/material/ListItemButton';
|
|
21
21
|
import ListItemText from '@mui/material/ListItemText';
|
|
22
22
|
import Typography from '@mui/material/Typography';
|
|
23
|
-
import { useQuestionnaireStore } from '../../stores';
|
|
23
|
+
import { useQuestionnaireStore, useRendererConfigStore } from '../../stores';
|
|
24
24
|
import type { QuestionnaireItem } from 'fhir/r4';
|
|
25
25
|
import ContextDisplayItem from '../FormComponents/ItemParts/ContextDisplayItem';
|
|
26
26
|
import { useFocusTabHeading } from '../../hooks/useFocusTabHeading';
|
|
@@ -38,6 +38,9 @@ const FormBodySingleTab = memo(function FormBodySingleTab(props: FormBodySingleT
|
|
|
38
38
|
const { qItem, contextDisplayItems, selected, tabLabel, listIndex } = props;
|
|
39
39
|
|
|
40
40
|
const switchTab = useQuestionnaireStore.use.switchTab();
|
|
41
|
+
const disableHeadingFocusOnTabSwitch =
|
|
42
|
+
useRendererConfigStore.use.disableHeadingFocusOnTabSwitch();
|
|
43
|
+
|
|
41
44
|
const focusHeading = useFocusTabHeading();
|
|
42
45
|
|
|
43
46
|
// Get aria-label text if available
|
|
@@ -48,10 +51,12 @@ const FormBodySingleTab = memo(function FormBodySingleTab(props: FormBodySingleT
|
|
|
48
51
|
switchTab(listIndex);
|
|
49
52
|
window.scrollTo(0, 0);
|
|
50
53
|
|
|
51
|
-
// Focus the first heading in the new tab panel
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
// Focus the first heading in the new tab panel if not disabled
|
|
55
|
+
if (!disableHeadingFocusOnTabSwitch) {
|
|
56
|
+
setTimeout(() => {
|
|
57
|
+
focusHeading(`tabpanel-${listIndex}`);
|
|
58
|
+
}, 100); // Small delay to ensure panel is rendered
|
|
59
|
+
}
|
|
55
60
|
}
|
|
56
61
|
|
|
57
62
|
return (
|
|
@@ -74,6 +74,9 @@ import type { Breakpoints } from '@mui/material';
|
|
|
74
74
|
* @property disableTabButtons - If `true`, hides navigation buttons for tabs.
|
|
75
75
|
* - Default: `false`
|
|
76
76
|
*
|
|
77
|
+
* @property disableHeadingFocusOnTabSwitch - If `true`, the first heading will be focused when switching tabs.
|
|
78
|
+
* - Default: `false`
|
|
79
|
+
*
|
|
77
80
|
* @property readOnlyVisualStyle - If `true`, item.readOnly will result in form fields having MUI disabled property and styles (recommended from usability perspective). If `false`, item.readOnly will result in form fields having HTML readonly property (less stable, but recommended from accessibility perspective).
|
|
78
81
|
* - Default: `true`
|
|
79
82
|
*/
|
|
@@ -102,6 +105,7 @@ export interface RendererConfig {
|
|
|
102
105
|
disablePageCardView?: boolean;
|
|
103
106
|
disablePageButtons?: boolean;
|
|
104
107
|
disableTabButtons?: boolean;
|
|
108
|
+
disableHeadingFocusOnTabSwitch?: boolean;
|
|
105
109
|
}
|
|
106
110
|
|
|
107
111
|
/**
|
|
@@ -134,6 +138,7 @@ export interface RendererConfigStoreType {
|
|
|
134
138
|
disablePageCardView: boolean;
|
|
135
139
|
disablePageButtons: boolean;
|
|
136
140
|
disableTabButtons: boolean;
|
|
141
|
+
disableHeadingFocusOnTabSwitch: boolean;
|
|
137
142
|
setRendererConfig: (params: RendererConfig) => void;
|
|
138
143
|
}
|
|
139
144
|
|
|
@@ -163,6 +168,7 @@ export const rendererConfigStore = createStore<RendererConfigStoreType>()((set)
|
|
|
163
168
|
disablePageCardView: false,
|
|
164
169
|
disablePageButtons: false,
|
|
165
170
|
disableTabButtons: false,
|
|
171
|
+
disableHeadingFocusOnTabSwitch: false,
|
|
166
172
|
setRendererConfig: (params: RendererConfig) => {
|
|
167
173
|
set((state) => ({
|
|
168
174
|
readOnlyVisualStyle: params.readOnlyVisualStyle ?? state.readOnlyVisualStyle,
|
|
@@ -180,7 +186,9 @@ export const rendererConfigStore = createStore<RendererConfigStoreType>()((set)
|
|
|
180
186
|
enableWhenAsReadOnly: params.enableWhenAsReadOnly ?? state.enableWhenAsReadOnly,
|
|
181
187
|
disablePageCardView: params.disablePageCardView ?? state.disablePageCardView,
|
|
182
188
|
disablePageButtons: params.disablePageButtons ?? state.disablePageButtons,
|
|
183
|
-
disableTabButtons: params.disableTabButtons ?? state.disableTabButtons
|
|
189
|
+
disableTabButtons: params.disableTabButtons ?? state.disableTabButtons,
|
|
190
|
+
disableHeadingFocusOnTabSwitch:
|
|
191
|
+
params.disableHeadingFocusOnTabSwitch ?? state.disableHeadingFocusOnTabSwitch
|
|
184
192
|
}));
|
|
185
193
|
}
|
|
186
194
|
}));
|