Skip to content

Commit 40ba3d2

Browse files
authored
feat: add alt for navigation logo, focusable props for dropdown and lnks (#977)
* feat: add default text for logo image Add "alt" field for LogoProps and set default value * feat: make navigation items more accessible Make navigation items focusable. Add "aria-expanded" for drop-down list. Change <span> to <button> because screen reader doesn't read it with <span>. Add additional CSS styles because <button> has default styles. * feat: add translation for Logo alt text * fix: change typization in NavigationDropdown component Change useRef type from HTMLElement to HTMLButtonElement. Change "type" value to "button" because "type" field from props conflicts with button "type" attribute. * feat: add alt field for NavigationLogoData interface
1 parent 3bb75d9 commit 40ba3d2

File tree

8 files changed

+47
-6
lines changed

8 files changed

+47
-6
lines changed

src/models/navigation.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ export interface NavigationLogoData {
8383
text?: string;
8484
url?: string;
8585
urlTitle?: string;
86+
alt?: string;
8687
}
8788

8889
export type ThemedNavigationLogoData = NavigationLogoData & ThemeSupporting<NavigationLogoData>;

src/navigation/components/Logo/Logo.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,24 @@ import {useTheme} from '../../../context/theme';
88
import {ThemedNavigationLogoData} from '../../../models';
99
import {block, getLinkProps, getThemedValue} from '../../../utils';
1010

11+
import {i18n} from './i18n';
12+
1113
import './Logo.scss';
1214

1315
const b = block('logo');
1416

1517
export type LogoProps = ThemedNavigationLogoData & {
1618
className?: string;
19+
alt?: string;
1720
};
1821

19-
const Logo: React.FC<LogoProps> = (props) => {
22+
const Logo: React.FC<LogoProps> = ({alt = i18n('image-alt'), ...restProps}) => {
23+
const props: LogoProps = {...restProps, alt};
2024
const {hostname, Link} = useContext(LocationContext);
2125
const theme = useTheme();
2226
const themedLogoProps = getThemedValue(props, theme) || props;
2327
const imageData = getMediaImage(themedLogoProps.icon || props.icon);
28+
imageData.alt = alt;
2429
const textData = themedLogoProps.text || props.text;
2530
const url = themedLogoProps.url || props.url || '/';
2631
const urlTitle = themedLogoProps.urlTitle || props.urlTitle || textData;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"image-alt": "Logo icon"
3+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import {addComponentKeysets} from '@gravity-ui/uikit/i18n';
2+
3+
import {NAMESPACE} from '../../../../utils/cn';
4+
5+
import en from './en.json';
6+
import ru from './ru.json';
7+
8+
export const i18n = addComponentKeysets({en, ru}, `${NAMESPACE}Logo`);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"image-alt": "Иконка лого"
3+
}

src/navigation/components/NavigationItem/components/NavigationDropdown/NavigationDropdown.scss

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
11
@import '../../../../../../styles/variables';
2+
@import '../../../../../../styles/mixins';
23
@import '../../mixins';
34

45
$block: '.#{$ns}navigation-dropdown';
56

67
#{$block} {
78
@include navigation-item-display();
9+
@include focusable();
10+
11+
display: flex;
12+
align-items: center;
13+
height: 100%;
14+
background: inherit;
15+
font: inherit;
16+
color: var(--g-color-text-primary);
17+
border: none;
818

919
&__arrow {
1020
margin-left: 7px;

src/navigation/components/NavigationItem/components/NavigationDropdown/NavigationDropdown.tsx

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,30 @@ export const NavigationDropdown = ({
2727
...props
2828
}: NavigationDropdownProps) => {
2929
const iconData = icon && getMediaImage(icon);
30-
const anchorRef = useRef<HTMLElement>(null);
31-
30+
const anchorRef = useRef<HTMLButtonElement>(null);
3231
return (
3332
<Fragment>
34-
<span ref={anchorRef} {...props} className={b(null, className)}>
35-
<ContentWrapper text={text} icon={iconData} iconSize={iconSize} />
33+
<button
34+
ref={anchorRef}
35+
{...props}
36+
type="button"
37+
className={b(null, className)}
38+
aria-expanded={isActive}
39+
>
40+
<ContentWrapper
41+
text={text}
42+
icon={iconData}
43+
iconSize={iconSize}
44+
aria-expanded={isActive}
45+
/>
3646
<ToggleArrow
3747
className={b('arrow')}
3848
size={TOGGLE_ARROW_SIZE}
3949
type={'vertical'}
4050
iconType="navigation"
4151
open={isActive}
4252
/>
43-
</span>
53+
</button>
4454
<NavigationPopup
4555
open={isActive}
4656
onClose={hidePopup}

src/navigation/components/NavigationItem/components/NavigationLink/NavigationLink.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ $block: '.#{$ns}navigation-link';
77
#{$block} {
88
@include navigation-item();
99
@include navigation-item-display();
10+
@include focusable();
1011

1112
&__arrow {
1213
position: relative;

0 commit comments

Comments
 (0)