Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: aria-label и role у компонентов #1611

Merged
merged 35 commits into from May 31, 2021
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
9f1aee4
Badge: change div to span
eugpoloz May 20, 2021
bcb74de
Cell: add htmlFor
eugpoloz May 20, 2021
7c8c95e
Checkbox: clean up markup
eugpoloz May 20, 2021
285c9f4
Gallery: hide decorative bullets
eugpoloz May 20, 2021
fa63c6c
IconButton: add explicit aria-label to props
eugpoloz May 20, 2021
fc35986
InfoRow: use span instead of div; refactor
eugpoloz May 20, 2021
efaf196
MiniInfoCell: use span instead of div
eugpoloz May 20, 2021
5a559d5
ModalDismissButton: add aria-label w/ default text
eugpoloz May 20, 2021
3f43369
PanelHeaderBack: add aria-label w/ default text
eugpoloz May 20, 2021
4e41ca1
PanelHeaderClose: add aria-label
eugpoloz May 20, 2021
903a68b
WriteBarIcon: add aria-label & refactor
eugpoloz May 20, 2021
f331b14
UsersStack: add role & aria tags
eugpoloz May 20, 2021
b55394e
Removable: clean up labels, add button role
eugpoloz May 20, 2021
7fdfedb
Radio: use proper components for valid markup
eugpoloz May 20, 2021
62c4dc0
SubnavigationButton: add aria-label
eugpoloz May 20, 2021
50f22e2
ScreenSpinner: add aria-label
eugpoloz May 20, 2021
c8149b5
PanelHeaderSubmit: add aria-label
eugpoloz May 20, 2021
c4162dd
PanelHeaderEdit: add aria-label
eugpoloz May 20, 2021
aa51f80
PullToRefreshSpinner: add aria-label
eugpoloz May 20, 2021
d20cb34
PanelHeaderBack: add aria-label; refactor
eugpoloz May 20, 2021
1d397a1
PanelHeaderButton: get rid of default export
eugpoloz May 20, 2021
12ad5ff
PanelHeaderButton: add aria-label
eugpoloz May 20, 2021
27d8d9b
Chip: add screenshot tests for removable
eugpoloz May 21, 2021
e80eeb9
Chip: use <button/> instead of <div/>
eugpoloz May 21, 2021
eda0bf2
Chip: fix tests
eugpoloz May 21, 2021
23a3f8d
Banner: add e2e tests
eugpoloz May 21, 2021
93c9527
Banner: change div to button
eugpoloz May 21, 2021
e4d99ca
HorizontalScrollArrow: change <div/> to <button/>
eugpoloz May 21, 2021
628112d
chore: fix quotes for default props
eugpoloz May 21, 2021
a5df145
a11y: add aria-labels to READMEs
eugpoloz May 21, 2021
fc7c3c3
build: update @vkontakte/icons to 1.100.0
eugpoloz May 21, 2021
a62e5d2
Chip: revert remove button to role="button"
eugpoloz May 25, 2021
b7fa920
Cell: fix cell marker
eugpoloz May 25, 2021
a3928d0
WriteBarIcon: use children when icon is empty
eugpoloz May 31, 2021
59662f0
CHORE: Update screenshots
eugpoloz May 31, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -43,7 +43,7 @@
"@typescript-eslint/parser": "^2.0.0",
"@vkontakte/appearance": "https://github.com/VKCOM/Appearance#v9.2.0",
"@vkontakte/eslint-config": "2.5.0",
"@vkontakte/icons": "^1.91.0",
"@vkontakte/icons": "^1.100.0",
"@vkontakte/vk-bridge": "^2.1.3",
"@vkontakte/vkjs": "^0.20.0",
"autoprefixer": "^9.8.0",
Expand Down
1 change: 1 addition & 0 deletions src/components/Badge/Badge.css
@@ -1,4 +1,5 @@
.Badge {
display: block;
flex-grow: 0;
flex-shrink: 0;
width: 6px;
Expand Down
4 changes: 2 additions & 2 deletions src/components/Badge/Badge.tsx
Expand Up @@ -14,13 +14,13 @@ export const Badge: FunctionComponent<BadgeProps> = ({
const platform = usePlatform();

return (
<div
<span
vkuiClass={classNames(
getClassName('Badge', platform),
`Badge--${mode}`,
)}
{...restProps}>
</div>
</span>
);
};

Expand Down
10 changes: 4 additions & 6 deletions src/components/Badge/Readme.md
Expand Up @@ -6,17 +6,15 @@
<PanelHeader>Бейдж</PanelHeader>

<Group header={<Header mode="secondary">В пунктах меню</Header>}>
<Cell expandable before={<Icon28Notifications />} badge={<Badge />}>
<Cell expandable before={<Icon28Notifications />} badge={<Badge aria-label="Есть новые" />}>
Уведомления
</Cell>
</Group>

<Group header={<Header mode="secondary">В переключателях</Header>}>
<Tabs>
<TabsItem after={<Badge mode="prominent" />}>Диалоги</TabsItem>
<TabsItem selected after={<Badge mode="prominent" />}>
Сообщения
</TabsItem>
<TabsItem after={<Badge mode="prominent" aria-label="Есть новые" />}>Диалоги</TabsItem>
<TabsItem selected after={<Badge mode="prominent" aria-label="Есть новые" />}>Сообщения</TabsItem>
</Tabs>
</Group>

Expand All @@ -27,7 +25,7 @@
<TabbarItem indicator={<Counter size="s" mode="prominent">12</Counter>} text="Сообщения">
<Icon28MessageOutline />
</TabbarItem>
<TabbarItem indicator={<Badge mode="prominent" />} text="Клипы">
<TabbarItem indicator={<Badge mode="prominent" aria-label="Новый раздел" />} text="Клипы">
<Icon28ClipOutline />
</TabbarItem>
</Tabbar>
Expand Down
8 changes: 5 additions & 3 deletions src/components/Banner/Banner.css
Expand Up @@ -71,10 +71,12 @@
z-index: 2;
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
margin: 0;
padding: 12px;
color: var(--icon_tertiary);
border: none;
background-color: transparent;
cursor: pointer;
}

.Banner__dismissIcon:active {
Expand Down
18 changes: 18 additions & 0 deletions src/components/Banner/Banner.e2e.tsx
@@ -0,0 +1,18 @@
import Avatar from '../Avatar/Avatar';
import Banner, { BannerProps } from './Banner';
import Button from '../Button/Button';
import { describeScreenshotFuzz } from '../../testing/e2e/utils';

describe('Banner', () => {
describeScreenshotFuzz((props: BannerProps ) => (
<Banner
before={<Avatar size={96} mode="image" src="https://sun9-63.userapi.com/yOEQYPHrNHjZEoanbqPb65HPl5iojmiLgLzfGA/W3geVMMt8TI.jpg" />}
header="Баста в Ледовом"
subheader="Большой концерт"
asideMode="dismiss"
actions={<Button>Подробнее</Button>}
{...props}
/>), [{
size: ['s', 'm'],
}]);
});
10 changes: 7 additions & 3 deletions src/components/Banner/Banner.tsx
Expand Up @@ -27,7 +27,7 @@ export interface BannerProps extends HTMLAttributes<HTMLDivElement> {
/**
* Срабатывает при клике на иконку крестика при `asideMode="dismiss"`.
*/
onDismiss?: MouseEventHandler<HTMLDivElement>;
onDismiss?: MouseEventHandler<HTMLButtonElement>;
/**
* Содержимое, отображаемое в левой части баннера.
*/
Expand Down Expand Up @@ -137,10 +137,14 @@ const Banner: FunctionComponent<BannerProps> = (props: BannerProps) => {

{asideMode === 'dismiss' &&
<div vkuiClass="Banner__dismiss">
<div vkuiClass="Banner__dismissIcon" onClick={onDismiss}>
<button
type="button"
vkuiClass="Banner__dismissIcon"
onClick={onDismiss}
>
{(platform === ANDROID || platform === VKCOM) && <Icon24Cancel />}
{platform === IOS && (mode === 'image' ? <Icon24DismissDark /> : <Icon24DismissSubstract />)}
</div>
</button>
</div>
}
</InnerComponent>
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 14 additions & 18 deletions src/components/Cell/Cell.css
Expand Up @@ -26,35 +26,31 @@
.Cell__checkbox {
display: none;
}
/* TODO избавиться от специфичного селектора после облегчения селекторов SimpleCell */
.Cell .Cell__marker {

.Cell--selectable .Cell__marker {
position: relative;
flex-shrink: 0;
width: 24px;
height: 24px;
margin-right: 16px;
padding: 0;
}
/* TODO избавиться от специфичного селектора после облегчения селекторов SimpleCell */
.Cell .Cell__marker--off {
display: block;
color: var(--icon_tertiary);
}
/* TODO избавиться от специфичного селектора после облегчения селекторов SimpleCell */
.Cell .Cell__marker--on {
display: none;
}

.Cell--selectable .Cell__marker {
margin-right: 16px;
.Cell--selectable .Cell__marker-in--checked {
position: absolute;
top: 0;
left: 0;
visibility: hidden;
color: var(--accent);
}

.Cell--selectable.Cell--disabled {
opacity: .6;
}

.Cell__checkbox:checked ~ .Cell__marker--on {
display: block;
}

.Cell__checkbox:checked ~ .Cell__marker--off {
display: none;
.Cell--selectable .Cell__checkbox:checked ~ .Cell__marker .Cell__marker-in--checked {
visibility: initial;
}

.Cell--removable .SimpleCell {
Expand Down
7 changes: 5 additions & 2 deletions src/components/Cell/Cell.tsx
Expand Up @@ -164,6 +164,7 @@ export const Cell: FC<CellProps> = (props: CellProps) => {
{...restProps}
disabled={draggable || removable || disabled}
Component={selectable ? 'label' : Component}
htmlFor={selectable ? name : undefined}
before={
<Fragment>
{(platform === ANDROID || platform === VKCOM) && draggable && (
Expand All @@ -186,8 +187,10 @@ export const Cell: FC<CellProps> = (props: CellProps) => {
checked={checked}
disabled={disabled}
/>
<Icon24CheckCircleOff vkuiClass="Cell__marker Cell__marker--off" />
<Icon24CheckCircleOn vkuiClass="Cell__marker Cell__marker--on" />
<span vkuiClass="Cell__marker">
<Icon24CheckCircleOff vkuiClass="Cell__marker-in" />
<Icon24CheckCircleOn vkuiClass="Cell__marker-in Cell__marker-in--checked" />
</span>
</Fragment>
)}
{before}
Expand Down
6 changes: 3 additions & 3 deletions src/components/CellButton/Readme.md
Expand Up @@ -11,9 +11,9 @@
<CellButton before={<Icon28DeleteOutline />} mode="danger">Удалить беседу</CellButton>
</Group>
<Group header={<Header mode="secondary">Аватарки</Header>}>
<CellButton before={<Avatar shadow={false} size={40} ><Icon24Add /></Avatar>}>Добавить участников</CellButton>
<CellButton before={<Avatar shadow={false} size={48} ><Icon28AddOutline /></Avatar>}>Создать беседу</CellButton>
<CellButton before={<Avatar shadow={false} size={72} mode="image" ><Icon28AddOutline /></Avatar>}>Создать плейлист</CellButton>
<CellButton before={<Avatar shadow={false} size={40}><Icon24Add /></Avatar>}>Добавить участников</CellButton>
<CellButton before={<Avatar shadow={false} size={48}><Icon28AddOutline /></Avatar>}>Создать беседу</CellButton>
<CellButton before={<Avatar shadow={false} size={72} mode="image"><Icon28AddOutline /></Avatar>}>Создать плейлист</CellButton>
</Group>
<Group header={<Header mode="secondary">Центрирование</Header>}>
<CellButton centered before={<Icon24Add />}>Создать беседу</CellButton>
Expand Down
14 changes: 6 additions & 8 deletions src/components/Checkbox/Checkbox.tsx
Expand Up @@ -44,17 +44,15 @@ export const Checkbox: React.FunctionComponent<CheckboxProps> = ({
<input {...restProps} type="checkbox" vkuiClass="Checkbox__input" ref={getRef} />
<div vkuiClass="Checkbox__container">
<div vkuiClass="Checkbox__icon Checkbox__icon--on">
{sizeY === SizeType.COMPACT || platform === VKCOM ?
<Icon20CheckBoxOn />
:
<Icon24CheckBoxOn />
{sizeY === SizeType.COMPACT || platform === VKCOM
? <Icon20CheckBoxOn />
: <Icon24CheckBoxOn />
}
</div>
<div vkuiClass="Checkbox__icon Checkbox__icon--off">
{sizeY === SizeType.COMPACT || platform === VKCOM ?
<Icon20CheckBoxOff />
:
<Icon24CheckBoxOff />
{sizeY === SizeType.COMPACT || platform === VKCOM
? <Icon20CheckBoxOff />
: <Icon24CheckBoxOff />
}
</div>
<ContentComponent weight="regular" vkuiClass="Checkbox__content">{children}</ContentComponent>
Expand Down
3 changes: 3 additions & 0 deletions src/components/Chip/Chip.css
Expand Up @@ -25,6 +25,9 @@
.Chip__remove {
margin-left: 4px;
margin-right: -2px;
padding: 0;
border: none;
background: transparent;
cursor: pointer;
}

Expand Down
8 changes: 8 additions & 0 deletions src/components/Chip/Chip.e2e.tsx
@@ -0,0 +1,8 @@
import Chip, { ChipProps } from './Chip';
import { describeScreenshotFuzz } from '../../testing/e2e/utils';

describe('Chip', () => {
describeScreenshotFuzz((props: ChipProps) => (<Chip value="arctic_monkeys" {...props}>Arctic Monkeys</Chip>), [{
removable: [false, true],
}]);
});
2 changes: 1 addition & 1 deletion src/components/Chip/Chip.test.tsx
Expand Up @@ -13,7 +13,7 @@ describe('Chip', () => {
<Chip value="white" onRemove={onRemove}>Белый</Chip>,
);

userEvent.click(screen.queryByLabelText('Удалить чип'));
userEvent.click(screen.getByRole('button'));

expect(onRemove).toHaveBeenCalled();
});
Expand Down
5 changes: 3 additions & 2 deletions src/components/Chip/Chip.tsx
Expand Up @@ -29,11 +29,12 @@ const Chip: FC<ChipProps> = (props: ChipProps) => {
{hasReactNode(after) && <div vkuiClass="Chip__after">{after}</div>}
{removable &&
<div
aria-label="Удалить чип"
role="button"
tabIndex={0}
vkuiClass="Chip__remove"
onClick={onRemoveWrapper}
>
<Icon16Cancel fill="var(--icon_secondary)" aria-hidden="true" />
<Icon16Cancel fill="var(--icon_secondary)" />
</div>
}
</div>
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 4 additions & 5 deletions src/components/ChipsInput/Readme.md
@@ -1,6 +1,4 @@
Множественное добавление значений. Поддерживаются любые модели данных с помощью пропсов `getOptionValue`, `getOptionLabel` и `getNewOptionData`.

Изменить визуальное оформление значений можно с помощью `renderChip`.
Множественное добавление значений. Поддерживаются любые модели данных с помощью пропсов `getOptionValue`, `getOptionLabel` и `getNewOptionData`. Изменить визуальное оформление значений можно с помощью `renderChip`.

Поле ввода принимает все валидные для `<input>` значения.

Expand Down Expand Up @@ -38,9 +36,10 @@ class Example extends React.Component {
<ChipsInput readOnly
value={[{value: '1', label: 'Arctic Monkeys', src: getAvatarUrl('audio_arctic_monkeys')}, {value: '2', label: 'Звери', src: getAvatarUrl('audio_leto_zveri')}, {value: '4', label: 'FACE', src: getAvatarUrl('audio_face')}, {value: '3', label: 'Depeche Mode', src: getAvatarUrl('audio_depeche_mode')}, {value: '5', label: 'Linkin Park', src: getAvatarUrl('audio_linkin_park')}]}
renderChip={({ value, label, option: { src }, ...rest }) => (
<Chip value={value}
<Chip
value={value}
removable={false}
before={<Avatar size={20} src={src} />}
before={<Avatar size={20} src={src} role="presentation" />}
{...rest}
>
{label}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Gallery/Gallery.tsx
Expand Up @@ -400,7 +400,7 @@ class BaseGallery extends Component<BaseGalleryProps & DOMProps & AdaptivityProp
</Touch>

{bullets &&
<div vkuiClass={classNames('Gallery__bullets', `Gallery__bullets--${bullets}`)}>
<div aria-hidden="true" vkuiClass={classNames('Gallery__bullets', `Gallery__bullets--${bullets}`)}>
{React.Children.map(children, (_item: ReactElement, index: number) =>
<div
vkuiClass={classNames('Gallery__bullet', { 'Gallery__bullet--active': index === slideIndex })}
Expand Down
4 changes: 2 additions & 2 deletions src/components/Group/Readme.md
Expand Up @@ -39,14 +39,14 @@ class App extends React.Component {
header={<Header>Последняя активность</Header>}
>
<SimpleCell
after={<IconButton><Icon16MoreVertical /></IconButton>}
after={<IconButton aria-label="Подробнее"><Icon16MoreVertical /></IconButton>}
description="Санкт-Петербург, Россия"
before={<Avatar size={32} mode="app" />}
>
VK · Приложение для iPhone
</SimpleCell>
<SimpleCell
after={<IconButton><Icon16MoreVertical /></IconButton>}
after={<IconButton aria-label="Подробнее"><Icon16MoreVertical /></IconButton>}
description="Санкт-Петербург, Россия"
before={<Avatar size={32} mode="app" />}
>
Expand Down
6 changes: 3 additions & 3 deletions src/components/HorizontalScroll/HorizontalScrollArrow.css
Expand Up @@ -4,11 +4,11 @@
user-select: auto;
top: 0;
height: 100%;
padding: 0;
opacity: 0;
z-index: 3;
display: flex;
flex-direction: column;
justify-content: center;
border: none;
background-color: transparent;
transition: opacity .15s;
}

Expand Down
12 changes: 8 additions & 4 deletions src/components/HorizontalScroll/HorizontalScrollArrow.tsx
Expand Up @@ -9,11 +9,15 @@ export interface HorizontalScrollArrowProps {
const HorizontalScrollArrow: FC<HorizontalScrollArrowProps> = (props: HorizontalScrollArrowProps) => {
const { onClick, direction } = props;
return (
<div vkuiClass={`HorizontalScroll__arrow HorizontalScroll__arrow-${direction}`} onClick={onClick}>
<div vkuiClass="HorizontalScroll__arrow-icon">
<button
type="button"
vkuiClass={`HorizontalScroll__arrow HorizontalScroll__arrow-${direction}`}
onClick={onClick}
>
<span vkuiClass="HorizontalScroll__arrow-icon">
<Icon24Chevron />
</div>
</div>
</span>
</button>
);
};

Expand Down