feat(a11y): add arrow buttons to monaco scrollbar (#52425)

This commit is contained in:
Bruce Blaser
2023-12-11 09:25:39 -08:00
committed by GitHub
parent 37c0be0aeb
commit cf9b89d2c0
3 changed files with 97 additions and 3 deletions

View File

@@ -192,3 +192,53 @@ textarea.inputarea {
.hint-status {
margin-bottom: 18px;
}
/* overwriting default arrow styles for accessibility */
:root {
--monaco-scrollbar-arrow-box-size: 0;
--monaco-scrollbar-arrow-icon-top-bottom: 0;
--monaco-scrollbar-arrow-icon-left: 0;
--monaco-scrollbar-arrow-icon-size: 11px;
--monaco-scrollbar-arrow-icon-font-size: 11px;
}
/* z-index is needed for arrox box and icons because the scrollbar may
overlap the arrow buttons when zoomed in */
/* arrow box - by default the width is the same as the scrollbar,
so we only need to ajdust the height */
.vs .monaco-scrollable-element .scrollbar .arrow-background {
height: var(--monaco-scrollbar-arrow-box-size) !important;
background-color: #666;
z-index: 998;
}
/* arrow icons - includes both up and down */
.vs .monaco-scrollable-element .scrollbar .scra {
top: var(--monaco-scrollbar-arrow-icon-top-bottom) !important;
left: var(--monaco-scrollbar-arrow-icon-left) !important;
width: var(--monaco-scrollbar-arrow-icon-size) !important;
height: var(--monaco-scrollbar-arrow-icon-size) !important;
font-size: var(--monaco-scrollbar-arrow-icon-font-size) !important;
color: white;
z-index: 999;
}
/* down arrow icon only */
.vs .monaco-scrollable-element .scrollbar .codicon-scrollbar-button-down {
top: unset !important;
bottom: var(--monaco-scrollbar-arrow-icon-top-bottom) !important;
}
/* we can live with with no color change for hover state if browser doesn't
support :has (the mouse cursor will still change to pointer) */
@supports (selector(html:has(body))) {
.vs .monaco-scrollable-element .scrollbar .arrow-background:hover,
.vs
.monaco-scrollable-element
.scrollbar
.arrow-background:has(+ .codicon:hover) {
cursor: pointer;
background-color: #222 !important;
}
}

View File

@@ -61,7 +61,10 @@ import {
isChallengeCompletedSelector
} from '../redux/selectors';
import GreenPass from '../../../assets/icons/green-pass';
import { enhancePrismAccessibility } from '../utils/index';
import {
enhancePrismAccessibility,
setScrollbarArrowStyles
} from '../utils/index';
import { getScrollbarWidth } from '../../../utils/scrollbar-width';
import LowerJaw from './lower-jaw';
@@ -291,9 +294,12 @@ const Editor = (props: EditorProps): JSX.Element => {
scrollbar: {
horizontal: 'hidden',
vertical: 'visible',
verticalHasArrows: false,
verticalHasArrows: true,
useShadows: false,
verticalScrollbarSize: getScrollbarWidth()
verticalScrollbarSize: getScrollbarWidth(),
// this helps the scroll bar fit properly between the arrows,
// but doesn't do anything for the arrows themselves
arrowSize: getScrollbarWidth()
},
parameterHints: {
enabled: false
@@ -602,6 +608,9 @@ const Editor = (props: EditorProps): JSX.Element => {
scrollGutterNode
);
editor.addContentWidget(scrollGutterWidget);
// update scrollbar arrows
setScrollbarArrowStyles(getScrollbarWidth());
};
const toggleAriaRoledescription = () => {

View File

@@ -74,3 +74,38 @@ export function enhancePrismAccessibility(
})
);
}
// Adjusts scrollbar arrows based on scrollbar width
export function setScrollbarArrowStyles(scrollbarWidth: number): void {
const root = document.documentElement;
// make the arrow box a square
root.style.setProperty(
'--monaco-scrollbar-arrow-box-size',
`${scrollbarWidth}px`
);
// adjust arrow icon size to fit arrow box
const iconSize = scrollbarWidth < 11 ? scrollbarWidth : scrollbarWidth - 5;
const iconFontSize =
scrollbarWidth < 11 ? scrollbarWidth : scrollbarWidth - 5;
root.style.setProperty('--monaco-scrollbar-arrow-icon-size', `${iconSize}px`);
root.style.setProperty(
'--monaco-scrollbar-arrow-icon-font-size',
`${iconFontSize}px`
);
// position arrow icon in arrow box
const iconTopBottom =
scrollbarWidth < 11 ? 0 : scrollbarWidth / 2 - iconFontSize / 2 - 1;
const iconLeftPosition =
scrollbarWidth < 11 ? 0 : (scrollbarWidth - iconFontSize) / 2;
root.style.setProperty(
'--monaco-scrollbar-arrow-icon-top-bottom',
`${iconTopBottom}px`
);
root.style.setProperty(
'--monaco-scrollbar-arrow-icon-left',
`${iconLeftPosition}px`
);
}