Skip to content
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

SideNav component - Porting of advanced features from HcNav #1304

Merged
merged 12 commits into from
Apr 20, 2023

Conversation

didoo
Copy link
Contributor

@didoo didoo commented Apr 13, 2023

πŸ“Œ Summary

This is a large PR that takes the existing Hds::SideNav implementation and extends it to include advanced features like responsiveness (animation/transition) and content "portaling", by adopting (and adapting) the implementation in Cloud UI (then extracted and refactored by @meirish as reusable/standalone component in https://github.com/hashicorp/ember-shared-components).

πŸ› οΈ Detailed description

Unfortunately, it's not been possible to break down the PR in smaller commits: some of the work has been done in other PRs (see related PRs below) and ported in this PR all together, other work involved large renaming/refactoring of the main component (SideNav) as well as its children/sub-components. I'll try to give an overview of what the code changes are, and why they've been done.

  • added new dependencies
    • ember-a11y-refocus - used to add a navigator narrator to the SideNav (it's optionally controlled by the consumers)
    • ember-stargate - used for content "portaling" (see the Cloud UI implementation to understand how this works
  • updated SideNav component porting advanced features from HcNav (responsiveness/animation/portaling)
    • SideNav
      • "merged" the layout provided by the SideNav::Wrapper container, with the high-level functionalities provided by the HcNav implementation:
        • accessibility improvements
          • added support for a11y-refocus <NavigatorNarrator> element
            • it's added by default but can be disabled via hasA11yRefocus argument
            • we expose a set of arguments to customise its behaviour
          • added focus trapping for the navigation (when is "responsive", is in "mobile" mode and is "expanded")
        • responsiveness
          • made the "responsive" behaviour optional (true by default)
            • it adds a button that toggles the minimized/expanded states when in "mobile" viewport (the button itself changes visual state)
          • exposed the header/body/footer containers of the "sidenav" as named blocks and exposed the isMinimized tracked property so it can be used for custom behaviours if necessary
          • the consumers can "override" some of the default properties (eg. breaking point between "mobile" and "desktop" views) using CSS custom props (eg. --hds-app-desktop-breakpoint)
          • when in "mobile" + "expanded" mode
            • an overlay is shown (if clicked it minimizes the sidenav)
            • a keyboard event listener for esc is added (if triggered it minimizes the sidenav)
          • two callbacks are exposed: onDesktopViewportChange and onToggleMinimizedStatus so consumers can hook on these if they need
          • a special hds-side-nav-hide-when-minimized class name is provided so consumers can use it with custom element, to control how they respond to changes in the "minimised" state
    • SideNav::Wrapper
      • removed this component because it's not needed anymore as standalone element, now it's possible to use directly the SideNav top-level component (with/without responsiveness)
    • SideNav::Header
      • renamed a couple of classes and added a specific class used to fade-in/out the action on "minimize" toggle
      • moved SideNav::HomeLink and SideNav::IconButton under the "header" folder for better file organization
    • SideNav::List
      • added "extra" generic containers before/after the
          list to account for potential future use cases
      • SideNav::PortalTarget + SideNav::Portal
        • added these two new components to allow users to inject content in the navigation via "portals"
        • this were an almost direct porting of the existing implementation, I've just removed some extra stuff that was not needed anymore
    • updated (and added) integration tests
    • updated the website documentation
      • temporarily hidden the "how to use" section and replaced it with a banner explaining that the docs are being updated
      • updated the "component API" section to align it with the latest changes introduced in this refactoring

    πŸ‘€ Previews

    🚧 Todo

    • add JSON design tokens for the CSS variables
      • will be done in a separate PR - HDS-1696
    • update the "how to use" section of the documentation
      • will be done in a separate PR - HDS-1826
    • standardize z-index values and expose them as design tokens (JSON + CSS variables)

    πŸ”— External links

    Jira tickets:

    Related PRs:


    πŸ‘€ Reviewer's checklist:

    • +1 Percy if applicable
    • Confirm that PR has a changelog update via Changesets if needed

    πŸ’¬ Please consider using conventional comments when reviewing this PR.

@vercel
Copy link

vercel bot commented Apr 13, 2023

The latest updates on your projects. Learn more about Vercel for Git β†—οΈŽ

Name Status Preview Updated (UTC)
hds-showcase βœ… Ready (Inspect) Visit Preview Apr 20, 2023 9:26am
hds-website βœ… Ready (Inspect) Visit Preview Apr 20, 2023 9:26am

@didoo didoo changed the base branch from main to app-frame-component April 13, 2023 14:22
@didoo didoo mentioned this pull request Apr 13, 2023
2 tasks
Base automatically changed from app-frame-component to main April 13, 2023 15:06
Copy link
Member

@alex-ju alex-ju left a comment

Choose a reason for hiding this comment

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

Impressive work! πŸ‘

I couldn't spot anything off in my tests so far. Thanks for setting up a preview in Cloud UI, helped a lot to test it in context!

}

addEventListeners() {
document.addEventListener('keydown', this.escapePress, true);
Copy link
Member

Choose a reason for hiding this comment

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

not sure if there's a non-convoluted way to add this listener to sidenav's outermost element instead of document

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@meirish I think you wrote this code (according to this commit: https://github.com/hashicorp/cloud-ui/commit/f8a3e3a9387a967654742fde2512cae816a1b79d#diff-571b3895fafd8c25954e1f6a914ed1b575c8a7211246259004b521459d5d2e4b)

any ideas/suggestion? specific reasons for attaching the listener to the document ?


{{#if this.isResponsive}}
{{! template-lint-disable no-invalid-interactive}}
<div class="hds-side-nav__overlay" {{on "click" this.toggleMinimizedStatus}} />
Copy link
Contributor

Choose a reason for hiding this comment

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

Just curious why this needs to be a div vs. a button?

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 strong reasons, apart from:

  • I've ported as is from the existing Cloud UI implementation
  • it would be weird to have a huge button covering the entire page (I know it's silly, but the idea makes me nervous)

Copy link
Contributor

@KristinLBradley KristinLBradley left a comment

Choose a reason for hiding this comment

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

Looks great to me! I just added a few very minor comments, questions, and suggested edits.

Co-authored-by: Kristin Bradley <kristin.bradley@hashicorp.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants