(frontend) unify tab focus style for better visual consistency

standardizes keyboard focus appearance to improve UI coherence

Signed-off-by: Cyril <c.gromoff@gmail.com>
This commit is contained in:
Cyril
2025-09-05 14:45:42 +02:00
parent 9cb2b6a6fb
commit 9f9fae96e5
8 changed files with 49 additions and 36 deletions

View File

@@ -8,7 +8,10 @@ and this project adheres to
## [Unreleased] ## [Unreleased]
### Added - ⚡️(frontend) improve accessibility:
- #1341
### Added
- ✨(api) add API route to fetch document content #1206 - ✨(api) add API route to fetch document content #1206

View File

@@ -28,17 +28,18 @@ const StyledButton = styled(Button)<StyledButtonProps>`
border: none; border: none;
background: none; background: none;
outline: none; outline: none;
transition: all 0.2s ease-in-out;
font-weight: 500; font-weight: 500;
font-size: 0.938rem; font-size: 0.938rem;
padding: 0; padding: 0;
${({ $css }) => $css}; ${({ $css }) => $css};
&:hover {
background-color: var(
--c--components--button--primary-text--background--color-hover
);
}
&:focus-visible { &:focus-visible {
outline: 2px solid var(--c--theme--colors--primary-500); box-shadow: 0 0 0 2px var(--c--theme--colors--primary-400);
outline-offset: 2px;
border-radius: 4px; border-radius: 4px;
transition: none;
} }
`; `;

View File

@@ -207,14 +207,13 @@ export const DropdownMenu = ({
} }
&:focus-visible { &:focus-visible {
outline: 2px solid var(--c--theme--colors--primary-500); outline: 2px solid var(--c--theme--colors--primary-400);
outline-offset: -2px; outline-offset: -2px;
background-color: var(--c--theme--colors--greyscale-050); background-color: var(--c--theme--colors--greyscale-050);
} }
${isFocused && ${isFocused &&
css` css`
outline: 2px solid var(--c--theme--colors--primary-500);
outline-offset: -2px; outline-offset: -2px;
background-color: var(--c--theme--colors--greyscale-050); background-color: var(--c--theme--colors--greyscale-050);
`} `}

View File

@@ -2,7 +2,8 @@ import { Button } from '@openfun/cunningham-react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { css } from 'styled-components'; import { css } from 'styled-components';
import { BoxButton } from '@/components'; import { Box, BoxButton } from '@/components';
import { useCunninghamTheme } from '@/cunningham';
import ProConnectImg from '../assets/button-proconnect.svg'; import ProConnectImg from '../assets/button-proconnect.svg';
import { useAuth } from '../hooks'; import { useAuth } from '../hooks';
@@ -11,6 +12,7 @@ import { gotoLogin, gotoLogout } from '../utils';
export const ButtonLogin = () => { export const ButtonLogin = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const { authenticated } = useAuth(); const { authenticated } = useAuth();
const { colorsTokens } = useCunninghamTheme();
if (!authenticated) { if (!authenticated) {
return ( return (
@@ -26,14 +28,23 @@ export const ButtonLogin = () => {
} }
return ( return (
<Button <Box
onClick={gotoLogout} $css={css`
color="primary-text" .--docs--button-logout:focus-visible {
aria-label={t('Logout')} box-shadow: 0 0 0 2px ${colorsTokens['primary-400']} !important;
className="--docs--button-logout" border-radius: 4px;
}
`}
> >
{t('Logout')} <Button
</Button> onClick={gotoLogout}
color="primary-text"
aria-label={t('Logout')}
className="--docs--button-logout"
>
{t('Logout')}
</Button>
</Box>
); );
}; };

View File

@@ -43,6 +43,13 @@ export const Header = () => {
href="/" href="/"
data-testid="header-logo-link" data-testid="header-logo-link"
aria-label={t('Back to homepage')} aria-label={t('Back to homepage')}
$css={css`
outline: none;
&:focus-visible {
box-shadow: 0 0 0 2px var(--c--theme--colors--primary-400) !important;
border-radius: 4px;
}
`}
> >
<Box <Box
$align="center" $align="center"

View File

@@ -41,15 +41,7 @@ export const LanguagePicker = () => {
showArrow showArrow
label={t('Select language')} label={t('Select language')}
buttonCss={css` buttonCss={css`
&:hover { transition: all 0.15s ease-in-out !important;
background-color: var(
--c--components--button--primary-text--background--color-hover
);
}
&:focus-visible {
outline: 2px solid var(--c--theme--colors--primary-500);
outline-offset: 2px;
}
border-radius: 4px; border-radius: 4px;
padding: 0.5rem 0.6rem; padding: 0.5rem 0.6rem;
& > div { & > div {

View File

@@ -85,8 +85,9 @@ export const LeftPanelTargetFilters = () => {
background-color: ${colorsTokens['greyscale-100']}; background-color: ${colorsTokens['greyscale-100']};
} }
&:focus-visible { &:focus-visible {
outline: 2px solid ${colorsTokens['primary-500']}; outline: none !important;
outline-offset: 2px; box-shadow: 0 0 0 2px ${colorsTokens['primary-500']} !important;
border-radius: 4px;
} }
`} `}
> >

View File

@@ -31,27 +31,26 @@ export const LeftPanelFavoriteItem = ({ doc }: LeftPanelFavoriteItemProps) => {
.pinned-actions { .pinned-actions {
opacity: ${isDesktop ? 0 : 1}; opacity: ${isDesktop ? 0 : 1};
} }
&:hover, &:hover {
background-color: ${colorsTokens['greyscale-100']};
}
&:focus-within { &:focus-within {
cursor: pointer; cursor: pointer;
box-shadow: 0 0 0 2px ${colorsTokens['primary-500']} !important;
background-color: var(--c--theme--colors--greyscale-100);
.pinned-actions { .pinned-actions {
opacity: 1; opacity: 1;
} }
} }
&:focus-visible {
outline: 2px solid ${colorsTokens['primary-500']};
outline-offset: 2px;
border-radius: ${spacingsTokens['3xs']};
}
`} `}
key={doc.id} key={doc.id}
className="--docs--left-panel-favorite-item" className="--docs--left-panel-favorite-item"
> >
<StyledLink <StyledLink
href={`/docs/${doc.id}`} href={`/docs/${doc.id}`}
$css="overflow: auto;" $css={css`
overflow: auto;
outline: none !important;
`}
aria-label={`${doc.title}, ${t('Updated')} ${DateTime.fromISO(doc.updated_at).toRelative()}`} aria-label={`${doc.title}, ${t('Updated')} ${DateTime.fromISO(doc.updated_at).toRelative()}`}
> >
<SimpleDocItem showAccesses doc={doc} /> <SimpleDocItem showAccesses doc={doc} />