Skip to content

DSD-1900: ARIA landmarks guide #1806

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: development
Choose a base branch
from

Conversation

7emansell
Copy link
Collaborator

@7emansell 7emansell commented Apr 28, 2025

Fixes JIRA ticket DSD-1900

This PR does the following:

  • Adds guide to ARIA landmarks to Storybook documentation

How has this been tested?

Accessibility concerns or updates

Accessibility Checklist

  • Checked Storybook's "Accessibility" tab for color contrast and other issues.
  • The feature works with keyboard inputs including tabbing back and forward and pressing space, enter, arrow, and esc keys.
  • For hidden text or when aria-live is used, a screenreader was used to verify the text is read.
  • For features that involve UI updates and focusing on DOM refs, focus management was reviewed.
  • The feature works when the page is zoomed in to 200% and 400%.

Open Questions

Checklist:

  • I have updated the Storybook documentation and changelog accordingly.
  • I have added relevant accessibility documentation for this pull request.
  • All new and existing tests passed.

Front End Review:

  • Review the Vercel preview deployment once it is ready.

Copy link

vercel bot commented Apr 28, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
nypl-design-system ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 6, 2025 8:09pm

export const WithSearchElement: Story = {
render: () => (
<search>
<SearchBar
Copy link
Member

@EdwinGuzman EdwinGuzman Apr 28, 2025

Choose a reason for hiding this comment

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

SearchBar still contains role="search" so this is technically not the appropriate pattern (and it won't be until v4 where the DOM is updated). I think you should replace SearchBar with separate heading, input, button, and checkbox components.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh true. Then maybe this should go into v4 since the original intention of this guide was to clarify how the search landmark should be used, and I'd like to keep this specific example with Searchbar

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Discussed in standup– this is not gonna go into v4 so replacing the searchbar with a TextInput for now so the pattern is clear

Copy link
Member

@EdwinGuzman EdwinGuzman left a comment

Choose a reason for hiding this comment

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

This is great, thanks! Just some minor comments.


Landmarks can be indicated with `role="landmark"` or by using the landmark's HTML element.

**Some Reservoir components already define their own landmark roles, and some landmarks must be defined by the consuming app since they could wrap many components.**
Copy link
Member

Choose a reason for hiding this comment

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

This makes it seem like the components are defining roles beyond the eight native ones.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Does this update make it clearer

@EdwinGuzman EdwinGuzman added the Needs Review Pull requests that are ready for peer review. label Apr 28, 2025
Copy link
Member

@EdwinGuzman EdwinGuzman left a comment

Choose a reason for hiding this comment

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

Minor comments but not blockers.

render: () => (
<search>
{/* TODO: Replace with Searchbar component. */}
<TextInput id={"search-input"} labelText={"Search"} />
Copy link
Member

Choose a reason for hiding this comment

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

nit: you don't need braces around string prop values.

Copy link
Member

Choose a reason for hiding this comment

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

This could also use a simple button component.

Copy link
Collaborator

@oliviawongnyc oliviawongnyc left a comment

Choose a reason for hiding this comment

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

I learned a lot from this! Some small suggestions included.


Elements under [Navigation](../?path=/docs/components-navigation) should be wrapped by the `navigation` landmark.

### region
Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder how to differentiate between complementary and region. Could you include something about how to think about this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Added a note below

Copy link
Collaborator

Choose a reason for hiding this comment

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

Great! Small typo: "content should supports or modifies" - remove extra s's.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Further, should region landmarks be nested inside the main landmark or do they typically sit outside main?

Copy link
Member

@EdwinGuzman EdwinGuzman left a comment

Choose a reason for hiding this comment

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

Approving latest update, thanks for swapping the searchbar out.

Copy link
Collaborator

@bigfishdesign13 bigfishdesign13 left a comment

Choose a reason for hiding this comment

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

Great information. I just have some suggestions.

| region | `<section>` |
| search | `<search>` |

Landmarks can be indicated with `role="landmark"` or by using the landmark's HTML element– both methods mean the same thing in the document.
Copy link
Collaborator

Choose a reason for hiding this comment

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

If you can get away with it, replace the dash with (em dash). If that does not render properly, use &mdash;. Also, remove the space after the em dash character.

### banner

The banner landmark is an area that has global, rather than page-specific, information or actionable elements.
For example, a website's logo and primary navigation would be expected child elements of a `banner` landmark. There should only be a single `banner` landmark per interface.
Copy link
Collaborator

Choose a reason for hiding this comment

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

It was my understanding, and it is also stated on w3schools.com, that it is ok to have multiple <header> elements on one page. For example, each significant section on a page may have a <header> element.

Copy link
Member

Choose a reason for hiding this comment

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

I'd follow MDN's doc and not w3schools (they have a bad reputation). That said, you can have more than one header/banner role on a page but if so, it should have a unique label. So that should be updated here (and for contentinfo)


The `complementary` landmark indicates an area that contains additional information that "complements" the main content. Though complementary, the content it represents should also be understandable on its own.

The `Banner`, `StatusBadge`, `Notification` , `Hero`, and `FeaturedContent` components could all be `complementary` landmarks.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Out of the box, Banner and Notification are <aside> elements, so they are inherently complementary landmarks. Would consuming apps need to explicitly add the role to the other components that are mentioned?


### contentinfo

`contentinfo` is another globally repeating landmark, like `banner`, with information about the parent document. If `banner` is usually the site's header, `contentinfo` is usually the footer. There should only be a single `contentinfo` landmark per interface.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Same thing here...it is generally accepted that more than one <footer> element can be added to a page.

Comment on lines +73 to +81
<Banner
content={
<>
<strong>IMPORTANT:</strong> Use the search landmark instead of the form
landmark when the form is used for search functionality.
</>
}
type="warning"
/>
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nice!


There should only be a single `main` landmark per interface. Since `main` represents the primary content of a page, it is the most important destination for [skip links](../?path=/docs/accessibility-guide-skip-navigation--docs), bypassing recurring elements like the header or navigation.

The `Template` [component](../?path=/docs/components-page-layout-template--docs) renders the `main` landmark (and the `header` and `footer`).
Copy link
Collaborator

Choose a reason for hiding this comment

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

This will need to be updated for v4, as the header and footer regions are not part of the updated Template component.

### navigation

The `navigation` landmark identifies groups (e.g. lists) of links that are intended to be used for website or page content navigation.
There can be multiple `navigation`s on a page, but if a `navigation` landmark has the same set of links as another `navigation` landmark on the page (think mobile versus desktop), use the same HTML `label` attribute for both.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nit: change "multiple navigations" to "multiple navigation elements"

The `navigation` landmark identifies groups (e.g. lists) of links that are intended to be used for website or page content navigation.
There can be multiple `navigation`s on a page, but if a `navigation` landmark has the same set of links as another `navigation` landmark on the page (think mobile versus desktop), use the same HTML `label` attribute for both.

Elements under [Navigation](../?path=/docs/components-navigation) should be wrapped by the `navigation` landmark.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Only two components in our Navigation category do not have a <nav> element baked in. In fact, one of the two that doe snot have it should be updated to have it added. So that would leave Link as the only component that needs to potentially be wrapped in a navigation landmark, and even that would depend on how it was being used.

This is a long winded way of saying this comment should be reworded.


Elements under [Navigation](../?path=/docs/components-navigation) should be wrapped by the `navigation` landmark.

### region
Copy link
Collaborator

Choose a reason for hiding this comment

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

Further, should region landmarks be nested inside the main landmark or do they typically sit outside main?


The `search` landmark contains the page's search and filter functionality, which will likely include form controls (such as an `input type="search"`).

Inspect below to see `<search>` in the DOM– notice that it wraps the `Heading`, the `TextInput`, the `Button`, and the `Checkbox`, not just the searchbar:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Replace the dash with an em dash and remove the trailing space.

If we are going to ask users to look for the DS components, let's tell them to click on the Show code button in the lower right corner. Conversely, if we are going to ask them to inspect the DOM, then let's ask them to look for the native HTML elements.

@bigfishdesign13 bigfishdesign13 added Changes Requested Pull requests where changes have been requested in peer review. and removed Needs Review Pull requests that are ready for peer review. labels May 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Changes Requested Pull requests where changes have been requested in peer review.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants