From 7ad192d73ccf6aa0625ec1690fe0e83f47609ea4 Mon Sep 17 00:00:00 2001 From: Eric Olkowski Date: Thu, 31 Mar 2022 13:41:53 -0400 Subject: [PATCH 1/7] docs(Tooltip): add a11y docs --- .../content/accessibility/tooltip/tooltip.md | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 packages/v4/patternfly-docs/content/accessibility/tooltip/tooltip.md diff --git a/packages/v4/patternfly-docs/content/accessibility/tooltip/tooltip.md b/packages/v4/patternfly-docs/content/accessibility/tooltip/tooltip.md new file mode 100644 index 0000000000..e279333aa0 --- /dev/null +++ b/packages/v4/patternfly-docs/content/accessibility/tooltip/tooltip.md @@ -0,0 +1,22 @@ +--- +id: Tooltip +section: components +--- + +A **tooltip** is in-app messaging used to identify elements on a page with short, clarifying text. The contents of a tooltip should be accessible to all users, regardless of the device or method used to navigate to the element that triggers the tooltip. + +**Mouse users** should be able to trigger a tooltip by hovering over the triggering element. The tooltip should also be hoverable and persist until the mouse pointer is no longer hovering over the triggering element or the tooltip itself. + +**Keyboard users** should be able to place focus on the triggering element in order to trigger the tooltip. The tooltip should persist as long as the triggering element has focus. + +**Screen reader users** should have the contents of the tooltip announced to them when it is triggered. This can be best achieved by using the `children` prop and wrapping the tooltip around the intended trigger. + +
+ +The Tooltip must also meet the following criteria in order to be accessible: + +- It must be dismissable without needing to move the mouse pointer or remove focus from the trigger, such as by pressing the **Escape** key. +- It must be dismissed if the content of the tooltip is no longer valid. + +
+ From 696183b9e71fe153a574e8bd0ecb51867f4d09b3 Mon Sep 17 00:00:00 2001 From: Eric Olkowski Date: Wed, 4 May 2022 15:22:51 -0400 Subject: [PATCH 2/7] Update documentation --- .../content/accessibility/tooltip/tooltip.md | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/packages/v4/patternfly-docs/content/accessibility/tooltip/tooltip.md b/packages/v4/patternfly-docs/content/accessibility/tooltip/tooltip.md index e279333aa0..df8ce4e32c 100644 --- a/packages/v4/patternfly-docs/content/accessibility/tooltip/tooltip.md +++ b/packages/v4/patternfly-docs/content/accessibility/tooltip/tooltip.md @@ -9,14 +9,28 @@ A **tooltip** is in-app messaging used to identify elements on a page with short **Keyboard users** should be able to place focus on the triggering element in order to trigger the tooltip. The tooltip should persist as long as the triggering element has focus. -**Screen reader users** should have the contents of the tooltip announced to them when it is triggered. This can be best achieved by using the `children` prop and wrapping the tooltip around the intended trigger. +**Screen reader users** should have the contents of the tooltip announced to them when it is triggered. This can be best achieved by using the `children` prop and wrapping the tooltip around the intended trigger. Additionally, if a tooltip's contents is expected or intended to dynamically update (such as in response to a user action), the updated content should be announced to users. -
+## Accessibility application + +The preferred method of using the tooltip is by wrapping it around its trigger via the `children` prop. However, there are situations where additional props must be passed in or where using the `reference` prop is needed or desired. -The Tooltip must also meet the following criteria in order to be accessible: +To ensure the tooltip is used accessibly, follow these steps when applicable: -- It must be dismissable without needing to move the mouse pointer or remove focus from the trigger, such as by pressing the **Escape** key. -- It must be dismissed if the content of the tooltip is no longer valid. +- When adding a tooltip to a static element, such as a `span` or `div`, you must ensure: + - The static element has `tabindex="0"` passed in, so that keyboard users can place focus on it to trigger the tooltip, and there is some form of styling to visually let users know the element can be focused/hovered (usually an underline on the text). + - When using the `children` prop, `aria-live="polite"` and `aria="none"` are passed into the tooltip. Tooltips on static elements do not always get announced by assistive technologies by default, so passing in `aria-live` allows the tooltip contents to be announced while `aria="none"` ensures the tooltip does not get announced more than once. +- When the tooltip content is expected or intended to dynamically update and the `children` prop is being used, you must also pass in `aria-live="polite"` and `aria="none"` to ensure the updated content gets announced to users and that the the tooltip does not get announced more than once. +- When passing in the `id` prop and using the `children` prop you should also pass in `aria="none"`, and then either `aria-describedby` or `aria-labelledby` to the tooltips' trigger. The aria attribute passed into the trigger should have the tooltips' `id` prop passed in as a value. +- A tooltip must be dismissable without needing to move the mouse pointer or remove focus from the trigger, such as by pressing the **Escape** key. +- A tooltip must be automatically dismissed if its content is no longer valid.
+The following props/attributes have been added for you or are customizable in PatternFly: + +| React prop/attribute | React component that it should be applied to | Which HTML element it appears on in markup | Reason used | +| -- | -- | -- | -- | +| `aria-live` | Tooltip | .pf-c-tooltip | Used when a tooltips' content is expected or intended to dynamically update, or when a tooltip is placed on a static element. Only use a value of "polite" and only when also using the `children` prop (`aria-live="polite"` is set by default when using the `reference` prop). | +| `aria` | Tooltip | .pf-c-tooltip | Used to decide whether the trigger is described by the tooltip (default behavior) or is labelled by it (`aria="labelledby"`). A value of "none" can also be passed in to prevent the tooltip from being announced or to set `aria-describedby` or `aria-labelledby`manually on the trigger. | +| `id` | Tooltip | .pf-c-tooltip | Used to manually pass in the `id` attribute, which can be then be passed in as a value to a triggers' `aria-describedby` or `aria-labelledby` attribute. | \ No newline at end of file From f91cdd251a31055fb5e51d6f0f79c4c8c0cd4366 Mon Sep 17 00:00:00 2001 From: Eric Olkowski Date: Wed, 11 May 2022 09:33:33 -0400 Subject: [PATCH 3/7] Align verbiage with intended design --- .../content/accessibility/tooltip/tooltip.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/v4/patternfly-docs/content/accessibility/tooltip/tooltip.md b/packages/v4/patternfly-docs/content/accessibility/tooltip/tooltip.md index df8ce4e32c..3368405629 100644 --- a/packages/v4/patternfly-docs/content/accessibility/tooltip/tooltip.md +++ b/packages/v4/patternfly-docs/content/accessibility/tooltip/tooltip.md @@ -17,20 +17,19 @@ The preferred method of using the tooltip is by wrapping it around its trigger v To ensure the tooltip is used accessibly, follow these steps when applicable: -- When adding a tooltip to a static element, such as a `span` or `div`, you must ensure: - - The static element has `tabindex="0"` passed in, so that keyboard users can place focus on it to trigger the tooltip, and there is some form of styling to visually let users know the element can be focused/hovered (usually an underline on the text). - - When using the `children` prop, `aria-live="polite"` and `aria="none"` are passed into the tooltip. Tooltips on static elements do not always get announced by assistive technologies by default, so passing in `aria-live` allows the tooltip contents to be announced while `aria="none"` ensures the tooltip does not get announced more than once. -- When the tooltip content is expected or intended to dynamically update and the `children` prop is being used, you must also pass in `aria-live="polite"` and `aria="none"` to ensure the updated content gets announced to users and that the the tooltip does not get announced more than once. -- When passing in the `id` prop and using the `children` prop you should also pass in `aria="none"`, and then either `aria-describedby` or `aria-labelledby` to the tooltips' trigger. The aria attribute passed into the trigger should have the tooltips' `id` prop passed in as a value. +- Tooltips should not be added to static elements, such as a `div` or `span`. +- When a tooltip should act as the primary label for an element, pass in `aria="labelledby"`. When a tooltip should act as supplementary information, keep the default `aria="describedby"`. + - This pattern should also be followed when manually passing in the `aria-labelledby` or `aria-describedby` attribute to a trigger. +- When using the `reference` prop, you should also pass in the `id` prop and then manually pass in `aria-labelledby` or `aria-describedby` to the trigger. The aria attribute passed into the trigger should have the tooltip `id` passed in as a value. + - If you are instead using the `children` prop and you want to manually pass in `aria-describedby` or `aria-labelledby` to a trigger, you should also pass in `aria="none"` to the tooltip. +- When the tooltip content is expected or intended to dynamically update and the `children` prop is being used, you must also pass in `aria-live="polite"` to ensure the updated content gets announced to users. This functionality gets set by default when using the `reference` prop. - A tooltip must be dismissable without needing to move the mouse pointer or remove focus from the trigger, such as by pressing the **Escape** key. - A tooltip must be automatically dismissed if its content is no longer valid. -
- The following props/attributes have been added for you or are customizable in PatternFly: | React prop/attribute | React component that it should be applied to | Which HTML element it appears on in markup | Reason used | | -- | -- | -- | -- | -| `aria-live` | Tooltip | .pf-c-tooltip | Used when a tooltips' content is expected or intended to dynamically update, or when a tooltip is placed on a static element. Only use a value of "polite" and only when also using the `children` prop (`aria-live="polite"` is set by default when using the `reference` prop). | -| `aria` | Tooltip | .pf-c-tooltip | Used to decide whether the trigger is described by the tooltip (default behavior) or is labelled by it (`aria="labelledby"`). A value of "none" can also be passed in to prevent the tooltip from being announced or to set `aria-describedby` or `aria-labelledby`manually on the trigger. | -| `id` | Tooltip | .pf-c-tooltip | Used to manually pass in the `id` attribute, which can be then be passed in as a value to a triggers' `aria-describedby` or `aria-labelledby` attribute. | \ No newline at end of file +| `aria-live` | Tooltip | .pf-c-tooltip | Used when a tooltips' content is expected or intended to dynamically update. Only use a value of "polite" and only when also using the `children` prop (`aria-live="polite"` is set by default when using the `reference` prop). | +| `aria` | Tooltip | .pf-c-tooltip | Used to decide whether the tooltip acts as supplementary information (default behavior with `aria="describedby"`) or acts as a primary label (`aria="labelledby"`). A value of "none" can also be passed in to prevent the tooltip from being announced or to set `aria-describedby` or `aria-labelledby`manually on a trigger. | +| `id` | Tooltip | .pf-c-tooltip | Used to manually pass in the `id` attribute, which can then be passed in as a value to a triggers' `aria-describedby` or `aria-labelledby` attribute. | \ No newline at end of file From 286015df4f4a269b5c74b5463cdf6937c317c45c Mon Sep 17 00:00:00 2001 From: Eric Olkowski Date: Tue, 28 Jun 2022 16:19:17 -0400 Subject: [PATCH 4/7] Convert doc to align with new guidelines --- .../content/accessibility/tooltip/tooltip.md | 135 +++++++++++++++--- 1 file changed, 114 insertions(+), 21 deletions(-) diff --git a/packages/v4/patternfly-docs/content/accessibility/tooltip/tooltip.md b/packages/v4/patternfly-docs/content/accessibility/tooltip/tooltip.md index 3368405629..8aba7720a5 100644 --- a/packages/v4/patternfly-docs/content/accessibility/tooltip/tooltip.md +++ b/packages/v4/patternfly-docs/content/accessibility/tooltip/tooltip.md @@ -3,33 +3,126 @@ id: Tooltip section: components --- -A **tooltip** is in-app messaging used to identify elements on a page with short, clarifying text. The contents of a tooltip should be accessible to all users, regardless of the device or method used to navigate to the element that triggers the tooltip. +import { Checkbox, List, ListItem } from '@patternfly/react-core'; -**Mouse users** should be able to trigger a tooltip by hovering over the triggering element. The tooltip should also be hoverable and persist until the mouse pointer is no longer hovering over the triggering element or the tooltip itself. +## Accessibility -**Keyboard users** should be able to place focus on the triggering element in order to trigger the tooltip. The tooltip should persist as long as the triggering element has focus. +To implement an accessible PatternFly **tooltip**: -**Screen reader users** should have the contents of the tooltip announced to them when it is triggered. This can be best achieved by using the `children` prop and wrapping the tooltip around the intended trigger. Additionally, if a tooltip's contents is expected or intended to dynamically update (such as in response to a user action), the updated content should be announced to users. +- Avoid using tooltips on static elements such as a `div` or `span`, except in cases of truncation. +- Pass in `role="tooltip"` (HTML/CSS) to the element acting as the tooltip component. +- Pass in `aria="labelledby"` to the tooltip component (PatternFly React) or the `aria-labelledby` attribute to the trigger (HTML/CSS) when the tooltip should act as the primary label for its trigger: + ```noLive + // PatternFly React + + + -## Accessibility application + // HTML/CSS + + + ``` +- Pass in the `aria-describedby` attribute to the trigger (HTML/CSS) when the tooltip should act as supplementary information (this is the default behavior for PatternFly React): + ```noLive + // HTML/CSS + + + ``` -The preferred method of using the tooltip is by wrapping it around its trigger via the `children` prop. However, there are situations where additional props must be passed in or where using the `reference` prop is needed or desired. +## Testing -To ensure the tooltip is used accessibly, follow these steps when applicable: +At a minimumm, a tooltip should meet the following criteria: -- Tooltips should not be added to static elements, such as a `div` or `span`. -- When a tooltip should act as the primary label for an element, pass in `aria="labelledby"`. When a tooltip should act as supplementary information, keep the default `aria="describedby"`. - - This pattern should also be followed when manually passing in the `aria-labelledby` or `aria-describedby` attribute to a trigger. -- When using the `reference` prop, you should also pass in the `id` prop and then manually pass in `aria-labelledby` or `aria-describedby` to the trigger. The aria attribute passed into the trigger should have the tooltip `id` passed in as a value. - - If you are instead using the `children` prop and you want to manually pass in `aria-describedby` or `aria-labelledby` to a trigger, you should also pass in `aria="none"` to the tooltip. -- When the tooltip content is expected or intended to dynamically update and the `children` prop is being used, you must also pass in `aria-live="polite"` to ensure the updated content gets announced to users. This functionality gets set by default when using the `reference` prop. -- A tooltip must be dismissable without needing to move the mouse pointer or remove focus from the trigger, such as by pressing the **Escape** key. -- A tooltip must be automatically dismissed if its content is no longer valid. + + + + + + If using the HTML/CSS library, role="tooltip" is passed into the tooltip component.} /> + + + If the tooltip is meant to act as a primary label, the trigger has the aria-labelledby attribute linked to the tooltip contents.} description="One use-case for this is when a button contains only an icon and no visible text label." /> + + + If the tooltip is meant to act as supplementary information, the trigger has the aria-describedby attribute linked to the tooltip contents.} /> + + + + + + + + + + + + The tooltip can be dismissed by pressing Escape.} /> + + + + + -The following props/attributes have been added for you or are customizable in PatternFly: +## React customization -| React prop/attribute | React component that it should be applied to | Which HTML element it appears on in markup | Reason used | -| -- | -- | -- | -- | -| `aria-live` | Tooltip | .pf-c-tooltip | Used when a tooltips' content is expected or intended to dynamically update. Only use a value of "polite" and only when also using the `children` prop (`aria-live="polite"` is set by default when using the `reference` prop). | -| `aria` | Tooltip | .pf-c-tooltip | Used to decide whether the tooltip acts as supplementary information (default behavior with `aria="describedby"`) or acts as a primary label (`aria="labelledby"`). A value of "none" can also be passed in to prevent the tooltip from being announced or to set `aria-describedby` or `aria-labelledby`manually on a trigger. | -| `id` | Tooltip | .pf-c-tooltip | Used to manually pass in the `id` attribute, which can then be passed in as a value to a triggers' `aria-describedby` or `aria-labelledby` attribute. | \ No newline at end of file +Various React props have been provided for more fine-tuned control over accessibility. + +| Prop | Applied to | Reason | +|---|---|---| +| aria-live | Tooltip | When a value of "polite" is passed in, allows screen readers to announce the tooltip contents when it is expected or intended to dynamically update, such as in response to a user action. This should only be passed in when the `children` prop is also used on the tooltip.

`aria-live="polite"` is set by default when using the `reference` prop in order to allow screen readers to correctly announce tooltip contents regardless if it will dynamically update or not. | +| aria | Tooltip | When a value of "describedby" (default behavior) or "labelledby" is passed in, allows screen readers to announce the tooltip contents when it is triggered. A value of "describedby" sets the trigger's `aria-describedby` attribute and should be used when the tooltip should act as supplementary information. A value of "labelledby" sets the trigger's `aria-labelledby` attribute and should be used when the tooltip should act as a primary label.

When a value of "none" is passed in, prevents `aria-labelledby` and `aria-describedby` from being set on the trigger. Only pass in a value of "none" when either `aria-labelledby` or `aria-describedby` is manually set on the trigger and the `id` prop is manually passed into the tooltip.

This prop should only be passed in when the `children` prop is also used on the tooltip. | +| id | Tooltip | Sets the `id` attribute on the tooltip, which can be passed in as the value to a trigger's `aria-labelledby` or `aria-describedby` attribute. **Required** when either `aria-labelledby` or `aria-describedby` is manually set on the trigger or when the `reference` prop is passed into the tooltip. | +| reference | Tooltip | Links the tooltip to a trigger when the `children` prop cannot be used. When passing in this prop, the `id` prop must also be passed in, and either `aria-labelledby` or `aria-describedby` must be set on the trigger with a value of the tooltip's `id`. | + +### Aria-live + +```noLive +const [tooltipContent, setTooltipContent] = React.useState("Copy to clipboard"); + +const onClick = () => { + setTooltipContent('Successfully copied to clipboard!") +} + + + + +``` + +### Aria + +```noLive + + + +``` + +### Reference + +```noLive +const tooltipRef = React.useRef(); + + + +``` From b40c7db9ba4e5a1e10087c233c1c22dfd255ba03 Mon Sep 17 00:00:00 2001 From: Eric Olkowski Date: Wed, 29 Jun 2022 10:41:38 -0400 Subject: [PATCH 5/7] Update docs to new template --- .../content/accessibility/tooltip/tooltip.md | 49 ++++++++++++++++--- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/packages/v4/patternfly-docs/content/accessibility/tooltip/tooltip.md b/packages/v4/patternfly-docs/content/accessibility/tooltip/tooltip.md index 8aba7720a5..817af392f1 100644 --- a/packages/v4/patternfly-docs/content/accessibility/tooltip/tooltip.md +++ b/packages/v4/patternfly-docs/content/accessibility/tooltip/tooltip.md @@ -31,8 +31,15 @@ To implement an accessible PatternFly **tooltip**: ``` -- Pass in the `aria-describedby` attribute to the trigger (HTML/CSS) when the tooltip should act as supplementary information (this is the default behavior for PatternFly React): +- Pass in the `aria-describedby` attribute to the trigger (HTML/CSS) when the tooltip should act as supplementary information (this is the default behavior for PatternFly React when the tooltip wraps the trigger): ```noLive + // PatternFly React + + + + // HTML/CSS