diff --git a/docker/templates/non_proxy_headers.conf.template b/docker/templates/non_proxy_headers.conf.template index 6989c94f4..473a3e0b5 100644 --- a/docker/templates/non_proxy_headers.conf.template +++ b/docker/templates/non_proxy_headers.conf.template @@ -7,5 +7,5 @@ add_header Strict-Transport-Security "max-age=63072000; includeSubdomains;" alwa add_header X-Frame-Options "SAMEORIGIN" always; add_header X-XSS-Protection "1; mode=block" always; add_header X-Content-Type-Options "nosniff" always; -add_header Feature-Policy "geolocation 'self'; midi 'none'; notifications 'none'; push 'none'; sync-xhr 'none'; microphone 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'; speaker 'none'; vibrate 'none'; fullscreen 'none'; payment 'none'; usb 'none';"; +add_header Feature-Policy "geolocation 'self'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera 'none'; magnetometer 'none'; gyroscope 'none'; fullscreen 'none'; payment 'none'; usb 'none';"; add_header Permissions-Policy "geolocation=(self)"; diff --git a/src/components/elements/ButtonTooltipContainer.tsx b/src/components/elements/ButtonTooltipContainer.tsx index 338858985..c4d727648 100644 --- a/src/components/elements/ButtonTooltipContainer.tsx +++ b/src/components/elements/ButtonTooltipContainer.tsx @@ -8,7 +8,16 @@ const ButtonTooltipContainer = ({ if (!title) return children; return ( - + {children} ); diff --git a/src/components/elements/SkipToContentButton.tsx b/src/components/elements/SkipToContentButton.tsx new file mode 100644 index 000000000..61f43e18d --- /dev/null +++ b/src/components/elements/SkipToContentButton.tsx @@ -0,0 +1,55 @@ +import { Button } from '@mui/material'; +import { ReactNode } from 'react'; + +type SkipToContentProps = { + focusTargetId: string; + children?: ReactNode; +}; + +const SkipToContent: React.FC = ({ + focusTargetId, + children, +}) => { + const handleClick = () => { + const container = document.getElementById(focusTargetId); + if (container) { + // First ensure the container is focusable + if (!container.hasAttribute('tabindex')) { + container.setAttribute('tabindex', '-1'); + } + container.focus({ preventScroll: true }); + } + }; + + return ( + + ); +}; + +export default SkipToContent; diff --git a/src/components/layout/BasicBreadcrumbPageLayout.tsx b/src/components/layout/BasicBreadcrumbPageLayout.tsx index fd3bd2396..90388cf1d 100644 --- a/src/components/layout/BasicBreadcrumbPageLayout.tsx +++ b/src/components/layout/BasicBreadcrumbPageLayout.tsx @@ -4,6 +4,7 @@ import { ReactNode } from 'react'; import { ContextHeaderAppBar } from './dashboard/contextHeader/ContextHeader'; import Breadcrumbs, { Breadcrumb } from '@/components/elements/Breadcrumbs'; +import { FOCUSABLE_MAIN_TARGET_ID } from '@/components/layout/MainLayout'; const BasicBreadcrumbPageLayout = ({ crumbs, @@ -21,7 +22,12 @@ const BasicBreadcrumbPageLayout = ({ - + {children} diff --git a/src/components/layout/MainLayout.tsx b/src/components/layout/MainLayout.tsx index d1573fb6b..7960e68b0 100644 --- a/src/components/layout/MainLayout.tsx +++ b/src/components/layout/MainLayout.tsx @@ -14,6 +14,7 @@ import PrintViewButton from './PrintViewButton'; import WarehouseLinkBar from './WarehouseLinkBar'; import Loading from '@/components/elements/Loading'; +import SkipToContentButton from '@/components/elements/SkipToContentButton'; import MobileMenu from '@/components/layout/nav/MobileMenu'; import ToolbarMenu from '@/components/layout/nav/ToolbarMenu'; import { useIsDashboard } from '@/components/layout/nav/useIsDashboard'; @@ -29,6 +30,8 @@ interface Props { children: React.ReactNode; } +export const FOCUSABLE_MAIN_TARGET_ID = 'focusable-main'; + const MainLayout: React.FC = ({ mobileMenuContext, children }) => { const { appName } = useHmisAppSettings(); const isPrint = useIsPrintView(); @@ -99,6 +102,7 @@ const MainLayout: React.FC = ({ mobileMenuContext, children }) => { sx={{ px: isMobile ? 1 : 3, minHeight: APP_BAR_HEIGHT }} disableGutters={isMobile} > + = ({ handleCloseMobileMenu={handleCloseMobileMenu} handleCloseDesktopMenu={handleCloseDesktopMenu} label={navLabel} + skipNavFocusTargetId={FOCUSABLE_MAIN_TARGET_ID} > {sidebar} @@ -121,6 +123,7 @@ const DashboardContentContainer: React.FC = ({ ( )} +