diff --git a/src/frontend/src/hooks/useScreenReaderAnnounce.ts b/src/frontend/src/hooks/useScreenReaderAnnounce.ts new file mode 100644 index 00000000..50382734 --- /dev/null +++ b/src/frontend/src/hooks/useScreenReaderAnnounce.ts @@ -0,0 +1,15 @@ +import { useCallback } from 'react' +import { + announceToScreenReader, + type Politeness, +} from '@/stores/screenReaderAnnouncer' + +export const useScreenReaderAnnounce = () => { + return useCallback( + (message: string, politeness: Politeness = 'polite') => { + announceToScreenReader(message, politeness) + }, + [] + ) +} + diff --git a/src/frontend/src/layout/Layout.tsx b/src/frontend/src/layout/Layout.tsx index 8fd51920..ce2235d8 100644 --- a/src/frontend/src/layout/Layout.tsx +++ b/src/frontend/src/layout/Layout.tsx @@ -4,6 +4,7 @@ import { Header } from './Header' import { layoutStore } from '@/stores/layout' import { useSnapshot } from 'valtio' import { Footer } from '@/layout/Footer' +import { ScreenReaderAnnouncer } from '@/primitives' export type Layout = 'fullpage' | 'centered' @@ -41,6 +42,7 @@ export const Layout = ({ children }: { children: ReactNode }) => { flexDirection: 'column', })} > + {children} diff --git a/src/frontend/src/primitives/ScreenReaderAnnouncer.tsx b/src/frontend/src/primitives/ScreenReaderAnnouncer.tsx new file mode 100644 index 00000000..0f43fcc8 --- /dev/null +++ b/src/frontend/src/primitives/ScreenReaderAnnouncer.tsx @@ -0,0 +1,20 @@ +import { useSnapshot } from 'valtio' +import { screenReaderAnnouncerStore } from '@/stores/screenReaderAnnouncer' + +export const ScreenReaderAnnouncer = () => { + const { announcement } = useSnapshot(screenReaderAnnouncerStore) + + return ( +
+ {announcement.message} +
+ ) +} + diff --git a/src/frontend/src/primitives/index.ts b/src/frontend/src/primitives/index.ts index b8fc32c3..ebae0d8b 100644 --- a/src/frontend/src/primitives/index.ts +++ b/src/frontend/src/primitives/index.ts @@ -24,6 +24,7 @@ export { Menu } from './Menu' export { MenuList } from './MenuList' export { P } from './P' export { Popover } from './Popover' +export { ScreenReaderAnnouncer } from './ScreenReaderAnnouncer' export { Text } from './Text' export { ToggleButton } from './ToggleButton' export { Ul } from './Ul' diff --git a/src/frontend/src/stores/screenReaderAnnouncer.ts b/src/frontend/src/stores/screenReaderAnnouncer.ts index bdbca17d..97f7ddb2 100644 --- a/src/frontend/src/stores/screenReaderAnnouncer.ts +++ b/src/frontend/src/stores/screenReaderAnnouncer.ts @@ -1,6 +1,6 @@ import { proxy } from 'valtio' -type Politeness = 'polite' | 'assertive' +export type Politeness = 'polite' | 'assertive' type ScreenReaderAnnouncement = { message: string