Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,66 @@ id: Code editor
section: components
---

A **code editor** is the open sourced monaco code editor wrapped in PatternFly controls and styles. PatternFly does not
manage the interactions or the code for the monaco editor itself.

**Keyboard users** should be able to focus on the code editor controls using **Tab** to move forward and
**Tab + Shift** to move backward through interactive elements. They should be able to select a focused control
using **Space** or **Enter**. Keyboard users should also be able to move focus onto the monaco
code editor using **Tab**, and then into the monaco code editor using the **Down arrow**. If focus is in the monaco
code editor, the user should be able to use **Tab + Shift** to move focus out of the monaco code editor.

**Screen reader users** should be able to navigate through the code editor controls, as well as into and out of the
monaco code editor. Each control should have an aria-label since they are designed to display only an icon with a
Tooltip. The Tooltips are not announced by the screen reader, so the aria-label must be descriptive and clear.

The following props/attributes have been added for you or are customizable in PatternFly:

| React prop | React component it should be applied to | Which HTML element it appears on in markup | Reason used |
| -- | -- | -- | -- |
| copyButtonAriaLabel | CodeEditor | `.pf-v5-c-code-editor__controls button` | Aria-label for the copy button |
| downloadButtonAriaLabel | CodeEditor | `.pf-v5-c-code-editor__controls button` | Aria-label for the download button |
| uploadButtonAriaLabel | CodeEditor | `.pf-v5-c-code-editor__controls button` | Aria-label for the upload button |
| 'aria-label' | CodeEditorControl | `.pf-v5-c-code-editor__controls button` | Aria-label for a custom control button |
| shortcutsPopoverButtonText | CodeEditor | `.pf-v5-c-code-editor__keyboard-shortcuts` | Text to show in the button to open the shortcut popover |
| shortcutsPopoverProps | CodeEditor | `.pf-v5-c-code-editor__controls button` | Properties for the shortcut popover. Should contain 'bodyContent' to provide keybaord shortcuts built into the code editor |

The monaco code editor comes with some keyboard shortcuts built in, so it is recommended that consumers communicate
information about the following built in key commands:

| Opt + F1 | Accessibility helps |
| F1 | View all editor shortcuts |
| Ctrl + Space | Activate auto complete |
| Cmd + S | Save |

Additionally, when implementing a **code editor**, a developer can add additional keyboard controls by adding a command
to the `editor` parameter passed via the `onEditorDidMount` prop. For example:
```
onEditorDidMount = (editor, monaco) => {
editor.addCommand(monaco.KeyMod.Shift | monaco.KeyCode.Space, () => {console.log("hello")});
};
```
Comment on lines -38 to -44
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't documented anywhere else I don't believe, but it doesn't really fit with a11y docs. I can open an issue in React to at least add an example showing how to add custom shortcuts unless there's a preferred alternative.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

opening an issue in react works!

import { Checkbox, List, ListItem } from '@patternfly/react-core';

## Accessibility

To implement an accessible PatternFly **code editor**:

- Ensure any code editor controls can be navigated to and interacted with via keyboard and other assistive technologies such as screen readers.
- Provide descriptive `aria-label` and tooltips to code editor controls that only display an icon. Refer to our [tooltip accessibility](/components/tooltip/accessibility) documentation for more information on accessible tooltips.
- Update a tooltip's content if the code editor control triggers an action that isn't immediately obvious to users, such as clicking a "copy to clipboard" control.
- Provide a shortcuts menu that can be accessed via mouse, keyboard, or other assistive technologies such as screen readers, especially when using custom, unfamiliar shortcuts.
- Include keyboard shortcuts for both PC and Mac keyboards
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't something we currently enforce, but I noticed in the shortcuts example that we list keys for Mac, but not PC. Would require some updating in React, but would be beneficial to try updating since the opposite OS keys may not be immediately known .

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm - that was included as part of a product design... Maybe we should have a conversation with design or content about what they'd want to put here given different OS. IDK if we know for sure whether or not products are using this pattern/feature.


## Testing

At a minimum, a chip and chip group should meet the following criteria:

<List isPlain>
<ListItem>
<Checkbox id="codeEditor-a11y-checkbox-1" label="Standard keyboard navigation can be used to navigate between code editor controls and the code editor itself." description={<span><kbd>Tab</kbd> navigates to the next control or to the code editor, <kbd>Down Arrow</kbd> while the code editor wrapper is focused navigates into the code editor, and <kbd>Shift</kbd> + <kbd>Tab</kbd> navigates to the previous control or out of the code editor.</span>} />
</ListItem>
<ListItem>
<Checkbox id="codeEditor-a11y-checkbox-2" label="Standard keyboard interaction can be used to activate or trigger a code editor control." description={<span><kbd>Enter</kbd> or <kbd>Space</kbd> should activate or trigger a button control.</span>} />
</ListItem>
<ListItem>
<Checkbox id="codeEditor-a11y-checkbox-3" label={<span>Each code editor control has either descriptive visible text content or, if the control content is an icon, a descriptive <code className="ws-code">aria-label</code> and tooltip</span>} description={<span>An <code className="ws-code">aria-label</code> will provide an accessible name to the control itself for assistive technologies such as screen readers, while a tooltip will convey the same information visually to users navigating via keyboard only.</span>} />
</ListItem>
<ListItem>
<Checkbox id="codeEditor-a11y-checkbox-4" label="If a code editor control triggers an action or change that isn't made immediately obvious to users, a tooltip's content is updated to convey the action was successful." description={`For example, clicking a control that copies content to the clipboard does not on its own convey that the action successfully triggered. Updating the tooltip content to "Copied to clipboard" will notify users that the action was successful.`} />
</ListItem>
<ListItem>
<Checkbox id="codeEditor-a11y-checkbox-5" label="If the code editor has keyboard shortcuts, a shortcuts menu is provided and navigable via keyboard." description="A shortcuts menu must be provided especially when the code editor has custom, unfamiliar controls." />
</ListItem>
<ListItem>
<Checkbox id="codeEditor-a11y-checkbox-6" label="If the code editor has keyboard shortcuts, the keyboard shortcuts include the keys for both PC and Mac keyboards." />
</ListItem>
</List>

## React customization

The following React props have been provided for more fine-tuned control over accessibility.

| Prop | Applied to | Reason |
|---|---|---|
| `copyButtonAriaLabel="[text that labels the copy button]"` | `CodeEditor` | Adds an accessible name to the code editor's copy button. |
| `copyButtonSuccessTooltipText="[tooltip text to display upon successful copy]"` | `CodeEditor` | Provides text to the code editor's copy button after being clicked. This should typically be a succinct success message, such as "Copied to clipboard". |
| `copyButtonToolTipText="[tooltip text to display for the copy button]"` | `CodeEditor` | Text to display inside the code editor's copy button tooltip. This should typically be the same as the `copyButtonAriaLabel`. |
| `downloadButtonAriaLabel="[text that labels the download button]"` | `CodeEditor` | Adds an accessible name to the code editor's download button. |
| `downloadButtonToolTipText="[tooltip text to display for the download button]"` | `CodeEditor` | Text to display inside the code editor's download button tooltip. This should typically be the same as the `downloadButtonAriaLabel`. |
| `toolTipCopyExitDelay={[number in millseconds]}` | `CodeEditor` | The delay in milliseconds before the code editor's copy button tooltip transitions out. Typically it is best to avoid making this delay `0` or too low in general, as it may make it difficult for users with motor control issues to hover the tooltip and keep it displayed long enough to read its content. |
| `toolTipDelay={[number in millseconds]}` | `CodeEditor` | The delay in milliseconds before any of the code editor's tooltips transition out. Typically it is best to avoid making this delay `0` or too low in general, as it may make it difficult for users with motor control issues to hover the tooltip and keep it displayed long enough to read its content. |
| `uploadButtonAriaLabel="[text that labels the upload button]"` | `CodeEditor` | Adds an accessible name to the code editor's upload button. |
| `uploadButtonToolTipText="[tooltip text to display for the upload button]"` | `CodeEditor` | Text to display inside the code editor's upload button tooltip. This should typically be the same as the `uploadButtonAriaLabel`. |
| `aria-label="[text that labels the code editor control button]"` | `CodeEditorControl` | Adds an accessible name to the code editor control button. |
| `tooltipProps={{props object for the code editor control tooltip}}` | `CodeEditorControl` | An object of tooltip props for the code editor control button. Refer to our [tooltip props](/components/tooltip#props) documentation for more information. Typically the `content` of a code editor control tooltip should be the same as its `aria-label`. |

## HTML/CSS customization

The following HTML attributes and PatternFly classes can be used for more fine-tuned control over accessibility.

| Attribute or class | Applied to | Reason |
|---|---|---|
| `aria-label="[text that labels the code editor control]"` | `.pf-v5-c-code-editor__controls > button` | Adds an accessible name to a code editor control button. **Required** when the control button content is only an icon. |
| `aria-hidden="true"` | `.pf-v5-c-code-editor__controls > button > i` | Removes the control button icon from the accessibility tree, preventing assistive technologies from potentially announcing duplicate or unnecessary information without visually hiding it. **Required** if the control button contains an icon. |
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ At a minimum, a tooltip should meet the following criteria:
<Checkbox id="tooltip-a11y-checkbox-4" label={<span>If the tooltip is meant to act as supplementary information, the trigger has the <code className="ws-code">aria-describedby</code> attribute linked to the tooltip contents.</span>} />
</ListItem>
<ListItem>
<Checkbox id="tooltip-a11y-checkbox-5" label="Using a mouse to hover over the triggering element causes the tooltip to trigger, and the tooltip persists while hovering over the trigger or the tooltip itself." />
<Checkbox id="tooltip-a11y-checkbox-5" label="Using a mouse to hover over the triggering element causes the tooltip to trigger, and the tooltip persists while hovering over the trigger or the tooltip itself." description="The exit delay for a tooltip should typically be greater than 0 so that users have enough time to hover the tooltip with their mouse. Too short of an exit delay can make it difficult for users with motor control issues to hover the tooltip before it transitions out." />
</ListItem>
<ListItem>
<Checkbox id="tooltip-a11y-checkbox-6" label="The triggering element can receive focus via keyboard in order to trigger the tooltip, and the tooltip persists as long as the triggering element has focus." />
Expand Down