Skip to content

NavList API #2027

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

Merged
merged 8 commits into from
Apr 28, 2022
Merged

NavList API #2027

merged 8 commits into from
Apr 28, 2022

Conversation

colebemis
Copy link
Contributor

@colebemis colebemis commented Apr 18, 2022

In the spirit of documentation-driven development (DDD), I've drafted the documentation for the NavList (previously NavigationList) component. I'm looking for feedback on the component API before I begin implementation.

Direct link to the docs preview

Code review notes

  • We renamed NavigationList to NavList to save characters and align with UnderlineNav and the <nav> element (Slack discussion). The NavigationList ViewComponent will be renamed to NavList when it's moved from dotcom into the primer/view_components repo.
  • I'd love to have an accessibility expert verify that the "Rendered HTML" sections look correct.
  • I'm not confident in the sub-item API yet. Extra consideration for that section would be appreciated.
  • Should title be a required prop on the NavList.Group component?

Part of https://github.com/github/primer/issues/637

@changeset-bot
Copy link

changeset-bot bot commented Apr 18, 2022

⚠️ No Changeset found

Latest commit: dc26139

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions
Copy link
Contributor

github-actions bot commented Apr 18, 2022

size-limit report 📦

Path Size
dist/browser.esm.js 65.64 KB (0%)
dist/browser.umd.js 65.98 KB (0%)

@colebemis colebemis added the skip changeset This change does not need a changelog label Apr 19, 2022
@colebemis colebemis changed the title [WIP] NavigationList API NavList API Apr 19, 2022
@colebemis colebemis marked this pull request as ready for review April 19, 2022 23:37
@colebemis colebemis requested review from a team and rezrah April 19, 2022 23:37
<NavList>
<NavList.Item href="/branches">Branches</NavList.Item>
<NavList.Item href="/tags">Tags</NavList.Item>
<NavList.Item>
Copy link
Member

@siddharthkp siddharthkp Apr 20, 2022

Choose a reason for hiding this comment

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

(weakly held opinions) Let's talk subnav,

1.1 Making sub item work: Should we give this expandable item a special name?

like NavList.CollapsableItem, NavList.ExpandableItem, NavList.Section, NavList.Accordion, NavList.Details

<NavList>
  <NavList.Item href="/branches">Branches</NavList.Item>
  <NavList.Item href="/tags">Tags</NavList.Item>
  <NavList.ExpandableItem>
    Actions
    <NavList.LeadingVisual></ActionIcon/></NavList.LeadingVisual>
    <NavList.SubItem href="/actions">General</NavList.SubItem>
    <NavList.SubItem href="/actions/runners">Runners</NavList.SubItem>
  </NavList.ExpandableItem />
</NavList>

➕ explicit over implicit leads to more predictable API / readable application code?
➖ subItems and item text/visual as siblings feels off
➖ verbose name

1.2 Making sub item work: Should we give this expandable item a special prop instead?

like <NavList.Item expandable>

<NavList>
  <NavList.Item href="/branches">Branches</NavList.Item>
  <NavList.Item href="/tags">Tags</NavList.Item>
  <NavList.Item expandable>
    Actions
    <NavList.LeadingVisual></ActionIcon/></NavList.LeadingVisual>
    <NavList.SubItem href="/actions">General</NavList.SubItem>
    <NavList.SubItem href="/actions/runners">Runners</NavList.SubItem>
  </NavList.Item/>
</NavList>

➕ explicit over implicit leads to more predictable API / readable application code?
➕ minimal API
➖ the extra prop doesn't really do anything other than make the intent clear
➖ subItems and item text/visual as siblings feels off

2. Forget SubItem, wrap items in NavList.SubNav

<NavList>
  <NavList.Item href="/branches">Branches</NavList.Item>
  <NavList.Item href="/tags">Tags</NavList.Item>
  <NavList.Item>
      Actions
      <NavList.LeadingVisual></ActionIcon/></NavList.LeadingVisual>
      <NavList.SubNav>
        <NavList.Item href="/actions">General</NavList.Item>
        <NavList.Item href="/actions/runners">Runners</NavList.Item>
      </NavList.SubNav>
  </NavList.Item/>
</NavList>

➕ items wrapped in SubNav feels slightly better than direct siblings to item text/visual
➕ the same NavList.Item which accepts the same props*
➕ explicit over implicit leads to more predictable API / readable application code?
➖ verbose API
➖ does not match view-components API
Proir art: auth0/cosmos; API | Visual

/* assuming that's good, and subitem does not need to restricted to just text

Copy link
Member

@siddharthkp siddharthkp Apr 20, 2022

Choose a reason for hiding this comment

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

Looking at other primer implementations for inspiration,

As the view-components implementation is marked as experimental, I think it's okay to diverge from it at this point if we can find an API that works for both

Copy link
Contributor

Choose a reason for hiding this comment

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

As the view-components implementation is marked as experimental, I think it's okay to diverge from it at this point if we can find an API that works for both

Agree!

Making sub item work: Should we give this expandable item a special name?

Initially I kept Item as generic in PCSS, but eventually ended up creating ItemCollapsible as a separate entity. It felt easier to work with as its own component, but I don't have a strong preference over any of the options @siddharthkp listed above 😄

Copy link
Contributor Author

@colebemis colebemis Apr 20, 2022

Choose a reason for hiding this comment

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

This is amazing feedback. Thank you @siddharthkp! I've scheduled some time to discuss the nuances of these API options. Feel free to move the calendar event if another time is more convenient :)

Another API consideration: TreeView/TreeGrid will need to support similar expand/collapse functionality. I would love to pick an API that we can use across all three components

Copy link
Contributor Author

Choose a reason for hiding this comment

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

/* assuming that's good, and subitem does not need to restricted to just text

Good question! @vdepizzol @langermank Should subitem support all the same functionality as item or is it more restrictive?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@siddharthkp and I tentatively decided to move forward with option 2:

<NavList>
  <NavList.Item href="/branches">Branches</NavList.Item>
  <NavList.Item href="/tags">Tags</NavList.Item>
  <NavList.Item>
      Actions
      <NavList.LeadingVisual></ActionIcon/></NavList.LeadingVisual>
      <NavList.SubNav>
        <NavList.Item href="/actions">General</NavList.Item>
        <NavList.Item href="/actions/runners">Runners</NavList.Item>
      </NavList.SubNav>
  </NavList.Item/>
</NavList>

If anyone has strong opinions against this API, please let me know

Copy link
Contributor

Choose a reason for hiding this comment

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

As @siddharthkp mentioned, the PVC NavigationList infers whether or not it should expand/collapse by determining if it has any sub-items, i.e. any item that has sub-items can be expanded/collapsed. That seemed like a reasonable assumption at the time. Will there ever be a need for a list of non-collapsible sub-items?

The API you've chosen makes sense, but I do wonder if simply using <NavList.SubItem ...> would be closer to the PVC API. For example:

<NavList>
  <NavList.Item href="/branches">
    Branches
    <NavList.SubItem href="/actions">General</NavList.SubItem>
    <NavList.SubItem href="/actions/runners">Runners</NavList.SubItem>
  </NavList.Item/>
</NavList>

My understanding is navigation lists only ever have one nesting level.

Copy link
Contributor

Choose a reason for hiding this comment

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

My understanding is navigation lists only ever have one nesting level.

I think you're correct. We're working on a TreeView component to support more levels of nesting.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I do wonder if simply using <NavList.SubItem ...> would be closer to the PVC API

@siddharthkp and I are leaning towards the <NavList.SubNav> component because it will allow us to create a predictable and consistent API across NavList, TreeView, and TreeGrid. Would a similar API work for ViewComponents?

Copy link
Contributor

@camertron camertron Apr 26, 2022

Choose a reason for hiding this comment

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

@colebemis yeah that works for me 😄 Just as long as it's not expected that SubNavs are a whole nav unto themselves, i.e. can themselves have sub navs, etc.

Copy link
Contributor

@langermank langermank left a comment

Choose a reason for hiding this comment

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

Looking good!

<NavList>
<NavList.Item href="/branches">Branches</NavList.Item>
<NavList.Item href="/tags">Tags</NavList.Item>
<NavList.Item>
Copy link
Contributor

Choose a reason for hiding this comment

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

As the view-components implementation is marked as experimental, I think it's okay to diverge from it at this point if we can find an API that works for both

Agree!

Making sub item work: Should we give this expandable item a special name?

Initially I kept Item as generic in PCSS, but eventually ended up creating ItemCollapsible as a separate entity. It felt easier to work with as its own component, but I don't have a strong preference over any of the options @siddharthkp listed above 😄

<li><a href="/">Dashboard</a></li>
<li><a href="/pulls">Pull requests</a></li>
<li><a href="/issues">Issues</a></li>
<div role="separator"></div>
Copy link
Contributor

Choose a reason for hiding this comment

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

I think you need aria-hidden="true" here as well

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm curious what purpose role would serve if aria-hidden is set to true cc @ichelsea

Copy link
Contributor

Choose a reason for hiding this comment

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

Good question, I think I added that based on the a11y audit but didn't research it myself.

Choose a reason for hiding this comment

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

cc: @alliethu I'm not entirely sure the nuances on this one


```jsx
<NavList>
<NavList.Group title="Overview">
Copy link
Contributor

Choose a reason for hiding this comment

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

I assume groups in NavList are analogous to the concept of sections in NavigationList? If so, why not call them sections in NavList as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I called it Group because that what it's called inActionList: https://primer.style/react/ActionList#with-groups

It looks like "section" and "group" are used interchangeably in some of our docs. I propose that we standardize on "group" in Primer React and ViewComponents because it aligns with the ARIA role (group). Here's some more context

Copy link
Contributor

@camertron camertron left a comment

Choose a reason for hiding this comment

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

Looks good to me, just left a few non-blocking comments. One remaining question: why is the component called NavList instead of NavigationList?

Copy link
Member

@siddharthkp siddharthkp left a comment

Choose a reason for hiding this comment

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

:shipit:

Comment on lines +25 to +26
<details>
<summary>Rendered HTML</summary>
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the <details> and <summary> content meant to be inside the html codefence?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No. These were a temporary way to get review on the rendered HTML without cluttering the document too much. I'll remove these <details> sections when I implement the component.


```html
<nav>
<ul role="list">
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to render role="list" if we're using a <ul>?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There's a bug in some browsers that removes the list semantics from ul if the element has list-style: none (article). role="list" restores the list semantics so it's properly announced by screenreaders. @alliethu or @ichelsea please correct me if I'm wrong 🙏

Choose a reason for hiding this comment

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

Yes @colebemis! That's correct 🙂 . It's a failsafe for the browsers that remove it.

@colebemis
Copy link
Contributor Author

why is the component called NavList instead of NavigationList?

@camertron we had a conversation about "NavigationList" vs "NavList" in Slack. The consensus was to rename NavigationList to NavList in both React and ViewComponents to save characters and align with UnderlineNav and the <nav> element

@colebemis colebemis temporarily deployed to github-pages April 26, 2022 00:55 Inactive
@colebemis colebemis merged commit 1f6f8f7 into main Apr 28, 2022
@colebemis colebemis deleted the navigationlist-api branch April 28, 2022 17:10
@colebemis colebemis mentioned this pull request May 5, 2022
10 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
react skip changeset This change does not need a changelog
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants