Skip to content

Commit

Permalink
Various HTML updates to webR Demo App to improve accessibility (#318)
Browse files Browse the repository at this point in the history
* Add confirmation dialog when clearing plots

Fixes #273.

* Add labels for Terminal pane

* Add labels for Plotting pane

Fixes #272

* Improve Editor labels and button accessibility

Fixes #274

* Improve accessibility of Files pane

* Allow escaping from terminal with tab navigation

* Reorder components for more logical tab navigation

* Add CodeMirror description to Editor component

Including a description of how to move focus away from the Editor.

* Update NEWS.md

* Keep the linter happy
  • Loading branch information
georgestagg authored Nov 14, 2023
1 parent 1e12d7a commit 7df7964
Show file tree
Hide file tree
Showing 9 changed files with 211 additions and 81 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

* Certain graphical properties, e.g `lty` & `lwd`, now work correctly in the webR `canvas()` graphics device. (#289, #304).

* Various updates for the webR Demo App to improve accessibility. (#267, #269, #270, #271, #272, #273, #274).

# webR 0.2.1

## New features
Expand Down
3 changes: 2 additions & 1 deletion src/repl/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ body {
border-style: solid;
border-color: var(--bg-secondary);
border-width: 0px 2px 2px 0px;
padding-top: 5px;
}

.term {
Expand All @@ -53,7 +54,7 @@ body {
border-color: var(--bg-secondary);
border-width: 0px 0px 2px 2px;
overflow: auto;
padding: 4px 0;
padding: 5px 0;
}

.plot {
Expand Down
2 changes: 1 addition & 1 deletion src/repl/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ function App() {
terminalInterface={terminalInterface}
filesInterface={filesInterface}
/>
<Terminal webR={webR} terminalInterface={terminalInterface}/>
<Files webR={webR} filesInterface={filesInterface}/>
<Terminal webR={webR} terminalInterface={terminalInterface}/>
<Plot plotInterface={plotInterface}/>
</div>
);
Expand Down
55 changes: 43 additions & 12 deletions src/repl/components/Editor.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.editor {
position: relative;
display: grid;
grid-template-rows: auto 1fr;
}
Expand All @@ -8,41 +9,58 @@
justify-content: space-between;
align-items: center;
border-bottom: 1px solid var(--bg-dark);
padding: 5px 5px 0 5px;
padding: 0 5px;
}

.editor-actions {
position: absolute;
top: 5px;
right: 0;
}

.editor-actions > button {
background-color: transparent;
border: none;
color: var(--secondary);
font-size: 14px;
padding: 5px;
}

.editor-actions > button:hover {
color: var(--primary);
}

.editor-files > button {
font-size: 14px;
height: 26px;
.editor-files {
display: flex;
}

.editor-file {
position: relative;
display: flex;
padding: 0 5px;
gap: 5px;
background-color: var(--bg-secondary);
color: var(--secondary);
border: 1px solid var(--bg-dark);
border-bottom: none;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
padding: 0 5px;
}

.editor-files > button.active {
.editor-file > .editor-filename {
font-size: 14px;
height: 26px;
line-height: 26px;
}

.editor-file.active {
color: var(--primary);
background-color: var(--bg-primary);
border-color: var(--bg-dark);
border-bottom-color: transparent;
position: relative;
}

.editor-files > button.active::after {
.editor-file.active::after {
content: "";
position: absolute;
width: 100%;
Expand All @@ -52,14 +70,27 @@
background-color: var(--bg-primary);
}

.editor-files .editor-closebutton {
padding-left: 5px;
display: inline-block;
.editor-file > button {
background: transparent;
border: none;
padding: 0;
}

.editor-file > button.editor-switch {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}

.editor-file > button.editor-close {
color: var(--secondary);
font-weight: bold;
z-index: 1;
}

.editor-files .editor-closebutton:hover {
.editor-file > button.editor-close:hover {
color: var(--primary);
}

Expand Down
79 changes: 61 additions & 18 deletions src/repl/components/Editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,34 @@ export function FileTabs({
closeFile: (e: React.SyntheticEvent, index: number) => void;
}) {
return (
<div className="editor-files">
<div
role="tablist"
aria-label="Currently Open Files"
className="editor-files"
>
{files.map((f, index) =>
<button
<div
key={index}
className={activeFileIdx === index ? 'active' : undefined}
onClick={() => setActiveFileIdx(index)}
className={'editor-file' + (activeFileIdx === index ? ' active' : '')}
role="tab"
id={`filetab-${index}`}
aria-label={f.name}
>
{f.name}
<span
className="editor-closebutton"
aria-label="Close file"
<button
className="editor-switch"
aria-label={`Switch to ${f.name}`}
onClick={() => setActiveFileIdx(index)}
>
</button>
<div
className="editor-filename"
aria-hidden="true"
>
{f.name}
</div>
<button
className="editor-close"
aria-label={`Close ${f.name}`}
onClick={(e) => {
if (!f.ref.editorState.readOnly && !confirm('Close ' + f.name + '?')) {
e.stopPropagation();
Expand All @@ -56,9 +73,9 @@ export function FileTabs({
closeFile(e, index);
}}
>
&times;
</span>
</button>
<div aria-hidden="true">&times;</div>
</button>
</div>
)}
</div>
);
Expand Down Expand Up @@ -292,7 +309,11 @@ export function Editor({
return editorView.domAtPos(0).node;
}
});
editorView.focus();

// Update accessibility labelling
const container = editorView.contentDOM.parentElement;
container?.setAttribute('role', 'tabpanel');
container?.setAttribute('aria-labelledby', `filetab-${activeFileIdx}`);

// Before switching to a new file, save the state and scroll position
return function cleanup() {
Expand All @@ -303,22 +324,44 @@ export function Editor({
const displayStyle = files.length === 0 ? { display: 'none' } : undefined;

return (
<div className="editor" style={displayStyle}>
<div role="region"
aria-label="Editor Pane"
className="editor"
style={displayStyle}
>
<div className="editor-header">
<FileTabs
files={files}
activeFileIdx={activeFileIdx}
setActiveFileIdx={setActiveFileIdx}
closeFile={closeFile}
/>
<div className="editor-actions">
</div>
<div
aria-label="Editor"
aria-describedby="editor-desc"
className="editor-container"
ref={editorRef}
>
</div>
<p style={{ display: 'none' }} id="editor-desc">
This component is an instance of the <a href="https://codemirror.net/">CodeMirror</a> interactive text editor.
The editor has been configured so that the Tab key controls the indentation of code.
To move focus away from the editor, press the Escape key, and then press the Tab key directly after it.
Escape and then Shift-Tab can also be used to move focus backwards.
</p>
<div
role="toolbar"
aria-label="Editor Toolbar"
className="editor-actions"
>
{isRFile && <button onClick={runFile}>
<FaPlay aria-hidden="true" className="icon" /> Run
</button>}
{!isReadOnly && <button onClick={saveFile}>
<FaRegSave className="icon" /> Save
<FaRegSave aria-hidden="true" className="icon" /> Save
</button>}
{isRFile && <button onClick={runFile}><FaPlay className="icon" /> Run</button>}
</div>
</div>
<div className="editor-container" ref={editorRef}></div>
</div>
);
}
Expand Down
12 changes: 6 additions & 6 deletions src/repl/components/Files.css
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,14 @@

.directory .tree-node {
cursor: pointer;
border-left: 2px solid transparent;
}

.directory .tree-node:hover {
background: var(--bg-secondary);
}

.directory .tree .tree-node--focused {
background: var(--bg-secondary);
.directory .tree-node:hover,
.directory .tree-node:focus,
.directory .tree-branch-wrapper:focus > .tree-node
{
border-left: 2px solid var(--secondary);
}

.directory .tree .tree-node--selected {
Expand Down
Loading

0 comments on commit 7df7964

Please sign in to comment.