♿️(frontend) shortcuts table: semantic structure and kbd badge
caption, th scope, <kbd> for keys, no Tab stops on rows
This commit is contained in:
@@ -41,6 +41,7 @@ and this project adheres to
|
||||
- ♿️(frontend) improve accessibility of the IntroSlider carousel #1026
|
||||
- ♿️(frontend) add skip link component for keyboard navigation #1019
|
||||
- ♿️(frontend) announce mic/camera state to SR on shortcut toggle #1052
|
||||
- ✨(frontend) add Ctrl+Shift+/ to open shortcuts settings #1050
|
||||
|
||||
### Fixed
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ import { ScreenShareErrorModal } from '../components/ScreenShareErrorModal'
|
||||
import { useConnectionObserver } from '../hooks/useConnectionObserver'
|
||||
import { useNoiseReduction } from '../hooks/useNoiseReduction'
|
||||
import { useRegisterKeyboardShortcut } from '@/features/shortcuts/useRegisterKeyboardShortcut'
|
||||
import { settingsStore } from '@/stores/settings'
|
||||
import { useSettingsDialog } from '@/features/settings'
|
||||
import { SettingsDialogExtendedKey } from '@/features/settings/type'
|
||||
import { useVideoResolutionSubscription } from '../hooks/useVideoResolutionSubscription'
|
||||
import { SettingsDialogProvider } from '@/features/settings/components/SettingsDialogProvider'
|
||||
@@ -100,6 +100,7 @@ export function VideoConference({ ...props }: VideoConferenceProps) {
|
||||
const { t: tRooms } = useTranslation('rooms')
|
||||
const room = useRoomContext()
|
||||
const announce = useScreenReaderAnnounce()
|
||||
const { toggleSettingsDialog } = useSettingsDialog()
|
||||
|
||||
const getAnnouncementName = useCallback(
|
||||
(participant?: Participant | null) => {
|
||||
@@ -117,9 +118,8 @@ export function VideoConference({ ...props }: VideoConferenceProps) {
|
||||
useRegisterKeyboardShortcut({
|
||||
id: 'open-shortcuts',
|
||||
handler: useCallback(() => {
|
||||
settingsStore.defaultSelectedTab = SettingsDialogExtendedKey.SHORTCUTS
|
||||
settingsStore.areSettingsOpen = true
|
||||
}, []),
|
||||
toggleSettingsDialog(SettingsDialogExtendedKey.SHORTCUTS)
|
||||
}, [toggleSettingsDialog]),
|
||||
})
|
||||
|
||||
const tracks = useTracks(
|
||||
|
||||
@@ -3,15 +3,20 @@ import { ShortcutRow } from '@/features/shortcuts/components/ShortcutRow'
|
||||
import { css } from '@/styled-system/css'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { TabPanel, type TabPanelProps } from '@/primitives/Tabs'
|
||||
import { H } from '@/primitives'
|
||||
|
||||
const tableStyle = css({
|
||||
width: '100%',
|
||||
borderCollapse: 'collapse',
|
||||
overflowY: 'auto',
|
||||
'& caption': {
|
||||
fontWeight: 'bold',
|
||||
marginBottom: '0.75rem',
|
||||
textAlign: 'left',
|
||||
},
|
||||
'& th, & td': {
|
||||
padding: '0.65rem 0',
|
||||
textAlign: 'left',
|
||||
fontWeight: 'normal',
|
||||
},
|
||||
'& tbody tr': {
|
||||
borderBottom: '1px solid rgba(255,255,255,0.08)',
|
||||
@@ -29,12 +34,11 @@ export const ShortcutTab = ({ id }: Pick<TabPanelProps, 'id'>) => {
|
||||
className={css({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '0.75rem',
|
||||
})}
|
||||
>
|
||||
<H lvl={2}>{t('shortcuts.listLabel')}</H>
|
||||
<table className={tableStyle}>
|
||||
<thead className="sr-only">
|
||||
<caption>{t('shortcuts.listLabel')}</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">{t('shortcuts.columnAction')}</th>
|
||||
<th scope="col">{t('shortcuts.columnShortcut')}</th>
|
||||
|
||||
@@ -14,7 +14,25 @@ export const useSettingsDialog = () => {
|
||||
settingsStore.areSettingsOpen = true
|
||||
}
|
||||
|
||||
const closeSettingsDialog = () => {
|
||||
settingsStore.areSettingsOpen = false
|
||||
}
|
||||
|
||||
const toggleSettingsDialog = (
|
||||
defaultSelectedTab?: SettingsDialogExtendedKey
|
||||
) => {
|
||||
if (areSettingsOpen) {
|
||||
closeSettingsDialog()
|
||||
} else {
|
||||
if (defaultSelectedTab)
|
||||
settingsStore.defaultSelectedTab = defaultSelectedTab
|
||||
settingsStore.areSettingsOpen = true
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
openSettingsDialog,
|
||||
closeSettingsDialog,
|
||||
toggleSettingsDialog,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,9 +25,9 @@ export const ShortcutBadge: React.FC<ShortcutBadgeProps> = ({
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
<div className={cx(badgeStyle, className)} aria-hidden="true">
|
||||
<span>{visualLabel}</span>
|
||||
</div>
|
||||
<kbd className={cx(badgeStyle, className)} aria-hidden="true">
|
||||
{visualLabel}
|
||||
</kbd>
|
||||
{srLabel && <span className="sr-only">{srLabel}</span>}
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -31,9 +31,9 @@ export const ShortcutRow: React.FC<ShortcutRowProps> = ({ descriptor }) => {
|
||||
|
||||
return (
|
||||
<tr>
|
||||
<td className={text({ variant: 'body' })}>
|
||||
<th scope="row" className={text({ variant: 'body' })}>
|
||||
{t(`actions.${descriptor.id}`)}
|
||||
</td>
|
||||
</th>
|
||||
<td className={shortcutCellStyle}>
|
||||
<ShortcutBadge visualLabel={visualShortcut} srLabel={srShortcut} />
|
||||
</td>
|
||||
|
||||
Reference in New Issue
Block a user