Skip to content

Commit 4c6dd96

Browse files
authored
feat: added focus styles for interactive elements (#576)
* feat: adding focus styles for interactive elements
1 parent e058713 commit 4c6dd96

File tree

39 files changed

+231
-98
lines changed

39 files changed

+231
-98
lines changed

package-lock.json

Lines changed: 8 additions & 8 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
},
105105
"peerDependencies": {
106106
"@doc-tools/transform": "^3.3.2",
107-
"@gravity-ui/uikit": "^5.4.1",
107+
"@gravity-ui/uikit": "^5.12.0",
108108
"react": "^16.0.0 || ^17.0.0 || ^18.0.0"
109109
},
110110
"devDependencies": {
@@ -120,7 +120,7 @@
120120
"@gravity-ui/prettier-config": "^1.0.1",
121121
"@gravity-ui/stylelint-config": "^1.0.0",
122122
"@gravity-ui/tsconfig": "^1.0.0",
123-
"@gravity-ui/uikit": "^5.9.1",
123+
"@gravity-ui/uikit": "^5.12.2",
124124
"@storybook/addon-actions": "^7.1.0",
125125
"@storybook/addon-essentials": "^7.1.0",
126126
"@storybook/addon-knobs": "^7.0.2",

src/blocks/ContentLayout/ContentLayout.scss

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ $block: '.#{$ns}content-layout-block';
6060
padding: $indentXL;
6161
}
6262

63+
&_theme {
64+
&_dark {
65+
--g-color-line-focus: var(--pc-color-line-focus-dark);
66+
}
67+
}
68+
6369
@media (max-width: map-get($gridBreakpoints, 'sm')) {
6470
&_background {
6571
padding: $indentM;

src/blocks/ContentLayout/ContentLayout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export const ContentLayoutBlock = (props: ContentLayoutBlockProps) => {
4848
const colSizes = useMemo(() => getTextWidth(textWidth), [textWidth]);
4949

5050
return (
51-
<div className={b({size, background: Boolean(background)})}>
51+
<div className={b({size, theme, background: Boolean(background)})}>
5252
<Content
5353
className={b('content')}
5454
{...textContent}

src/blocks/Icons/Icons.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ $block: '.#{$ns}icons-block';
4343
@include reset-link-style();
4444
margin: 0 $indentXXXS $indentSM;
4545
}
46+
a#{$block}__item {
47+
@include focusable();
48+
border-radius: var(--g-focus-border-radius);
49+
}
4650

4751
&__image {
4852
max-width: 100%;

src/blocks/Questions/QuestionBlockItem/QuestionBlockItem.scss

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ $block: '.#{$ns}QuestionsBlockItem';
1313

1414
&__title {
1515
@include heading4();
16+
@include focusable();
1617

1718
position: relative;
1819
padding-right: 24px;
1920
cursor: pointer;
21+
border-radius: var(--g-focus-border-radius);
2022

2123
a {
2224
@include link();
@@ -27,11 +29,22 @@ $block: '.#{$ns}QuestionsBlockItem';
2729
position: absolute;
2830
right: 0;
2931
top: 0;
32+
bottom: 0;
33+
margin: auto;
3034
color: var(--g-color-text-primary);
3135
}
3236

3337
&__link {
3438
@include text-size(body-2);
39+
40+
@include add-specificity(&) {
41+
a {
42+
outline-offset: -2px; // as part of outline is hidden due to overflow: hidden from parent
43+
border-radius: calc(
44+
var(--g-focus-border-radius) + 2px
45+
); // as outline-offset is -2px
46+
}
47+
}
3548
}
3649

3750
&__text {

src/blocks/Slider/Arrow/Arrow.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ $block: '.#{$ns}slider-block-arrow';
4040
box-shadow: 0 4px 24px var(--pc-color-sfx-shadow), 0 2px 8px var(--pc-color-sfx-shadow);
4141

4242
transition: box-shadow 0.3s $ease-out-cubic, color 0.3s $ease-out-cubic;
43+
44+
@include focusable();
4345
}
4446

4547
&:hover {

src/blocks/Slider/Slider.tsx

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ export const SliderBlock = (props: WithChildren<SliderProps>) => {
251251
return (
252252
// To have this key differ from keys used in renderDot function, added `-accessible-bar` part
253253
<Fragment key={`${index}-accessible-bar`}>
254-
{slidesCountByBreakpoint > 1 && (
254+
{slidesCountByBreakpoint > 0 && (
255255
<li
256256
className={b('accessible-bar')}
257257
aria-current
@@ -266,8 +266,9 @@ export const SliderBlock = (props: WithChildren<SliderProps>) => {
266266
);
267267
};
268268

269-
const renderDot = (index: number) => {
269+
const getCurrentSlideNumber = (index: number) => {
270270
const currentIndexDiff = index - currentIndex;
271+
271272
let currentSlideNumber;
272273
if (0 <= currentIndexDiff && currentIndexDiff < slidesToShowCount) {
273274
currentSlideNumber = currentIndex + 1;
@@ -276,19 +277,26 @@ export const SliderBlock = (props: WithChildren<SliderProps>) => {
276277
} else {
277278
currentSlideNumber = index + 1;
278279
}
280+
return currentSlideNumber;
281+
};
282+
const isVisibleSlide = (index: number) => {
283+
const currentIndexDiff = index - currentIndex;
279284

285+
return (
286+
slidesCountByBreakpoint > 0 &&
287+
0 <= currentIndexDiff &&
288+
currentIndexDiff < slidesToShowCount
289+
);
290+
};
291+
292+
const renderDot = (index: number) => {
280293
return (
281294
<li
282295
key={index}
283296
className={b('dot', {active: index === currentIndex})}
284297
onClick={() => handleDotClick(index)}
285-
aria-hidden={
286-
(slidesCountByBreakpoint > 1 &&
287-
0 <= currentIndexDiff &&
288-
currentIndexDiff < slidesToShowCount) ||
289-
undefined
290-
}
291-
aria-label={`Slide ${currentSlideNumber} of ${barSlidesCount}`}
298+
aria-hidden={isVisibleSlide(index) ? true : undefined}
299+
aria-label={`Slide ${getCurrentSlideNumber(index)} of ${barSlidesCount}`}
292300
></li>
293301
);
294302
};

src/blocks/Slider/__tests__/Slider.test.tsx

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -41,30 +41,13 @@ describe('Slider', () => {
4141
const barDotsCount = CARDS_COUNT - slidesToShow + 1;
4242

4343
// Checking labels for the first slide
44-
if (slidesToShow > 1) {
45-
// There we have a bar covering `slidesToShow` dots
46-
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
47-
const accessibleBarElement = container.querySelector('.pc-SliderBlock__accessible-bar');
48-
expect(accessibleBarElement?.getAttribute('aria-label')).toBe(
49-
`Slide 1 of ${barDotsCount}`,
50-
);
51-
expect(
52-
queryHelpers.queryAllByAttribute(
53-
'aria-label',
54-
container,
55-
`Slide 1 of ${barDotsCount}`,
56-
),
57-
).toHaveLength(slidesToShow + 1);
58-
} else {
59-
// There is no bar covering dots
60-
expect(
61-
queryHelpers.queryAllByAttribute(
62-
'aria-label',
63-
container,
64-
`Slide 1 of ${barDotsCount}`,
65-
),
66-
).toHaveLength(1);
67-
}
44+
// There we have a bar covering `slidesToShow` dots
45+
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
46+
const accessibleBarElement = container.querySelector('.pc-SliderBlock__accessible-bar');
47+
expect(accessibleBarElement?.getAttribute('aria-label')).toBe(`Slide 1 of ${barDotsCount}`);
48+
expect(
49+
queryHelpers.queryAllByAttribute('aria-label', container, `Slide 1 of ${barDotsCount}`),
50+
).toHaveLength(slidesToShow + 1);
6851

6952
// Checking labels for the slides starting from 2
7053
Array(barDotsCount - 1)

src/components/Button/Button.scss

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
$block: '.#{$ns}button-block';
55

66
#{$block} {
7+
--yc-button-outline-color: var(--g-color-line-focus);
8+
79
&__content {
810
display: flex;
911
align-items: center;
@@ -34,6 +36,13 @@ $block: '.#{$ns}button-block';
3436
&_monochrome {
3537
@include monochrome-button();
3638
}
39+
40+
&_normal-contrast,
41+
&_raised {
42+
&:focus::before {
43+
outline-offset: 1px;
44+
}
45+
}
3746
}
3847

3948
&_size {

0 commit comments

Comments
 (0)