uswds-site
uswds-site copied to clipboard
PR for early version of the In-page navigation component
Thanks for taking a look at this early version of the In-page navigation component. It's a WIP, but we wanted to get eyes on it early and often.
Here is a link to the latest build and the early In-page navigation component page: https://federalist-ead78f8d-8948-417c-a957-c21ec5617a57.app.cloud.gov/preview/uswds/uswds-site/mm-inclusive-patterns-in-page-navigation/components/in-page-navigation/
The in-page navigation appears on all component pages (click any to view): https://federalist-ead78f8d-8948-417c-a957-c21ec5617a57.app.cloud.gov/preview/uswds/uswds-site/mm-inclusive-patterns-in-page-navigation/components/overview/
Approach:
- integrate a working in-page navigation component inside uswds-site first
- implement it only on component pages for now
- create a new layout template called in-page-nav.html
- for the component layout, we changed the frontmatter layout to in-page-nav and created a new layout page _layouts/in-page-nav.html
- this file contains the updated grid row and columns, plus the sticky nav code
- add section wrappers around all the component sections
- the stick nav current/active behavior is calculated on scroll with the height from the top and the height of each section container
- the class usa-current is added or removed while scrolling to match the hash from the link and the id of each section
- the sticky nav JS is currently at the bottom of /js/sidenav.js
- the sticky nav CSS is currently inline which of course will be updated to live in a scss file in the future
There was an interesting aspect with regards to the calculated heights of the various sections.
Due to "collapsing margins", section heights were not being calculated to their full height... https://stackoverflow.com/questions/27829250/why-doesnt-a-childs-margin-affect-a-parents-height https://www.w3.org/TR/CSS2/box.html#collapsing-margins
...this was causing the current state of a sticky nav link to turn off briefly while scrolling between sections.
We had to add "overflow: auto" to each one of the sections. This allowed for the height calculation to include any margins that were previously not being accounted for by offsetHeight.
Really looking forward to any and all feedback on the progress and early implementation of this new feature, thank you!! Mitch
@mitchmoccia one thing I noticed interacting with the internal nav - depending on which item is clicked in the nav element and subsequent scroll position it will give an active class to the wrong item - when clicking on "Component Code" (if it's not expanded) "Guidance" will get the active class.
@mitchmoccia one thing I noticed interacting with the internal nav - depending on which item is clicked in the nav element and subsequent scroll position it will give an active class to the wrong item - when clicking on "Component Code" (if it's not expanded) "Guidance" will get the active class.
@jonathanbobel The click to issue should be resolved with this commit... Also implemented smooth scrolling but also put in some code to remove smooth scrolling if the user has the "minimize the amount of motion" setting on their device (see prefers-reduced-motion)
@mejiaj Thanks for the awesome feedback, working on these issues now.
Here are some details on the latest updates to this PR:
The in-page navigation items are now dynamically coming from each component's markdown files, and specifically the subnav key/value pairs section.
This originally controlled the left side subnav (which has now been removed).
- Expanded upon the existing subnav items in listed in the component markdown files for guidance.
For example, link.md had the following key/value pairs in markdown:
subnav:
- text: Preview
href: '#link-preview'
- text: Code
href: '#link-code'
- text: Guidance
href: '#link-guidance'
- text: Package
href: '#link-package'
- text: Research findings
href: '#research-findings'
These were the items that would show on the left side nav under the currently active, top level page.
In essence, I shifted this logic to the in-page navigation component on the right. The result is the in-page navigation is now completely dynamic and built from the subnav key/value pairs inside each component's guidance markdown file.
This also allowed for the target ids to exist in the markdown rather than hardcoding them in the html.
So by adding the following inside the in-page navigation markdown, you can get a way more granular in-page navigation (which can be as high-level or as detailed as we want, all controlled through the markdown):
subnav:
- text: In-page navigation
href: '#in-page-navigation'
- text: Preview
href: '#in-page-navigation-preview'
- text: Code
href: '#in-page-navigation-code'
- text: Guidance
href: '#in-page-navigation-guidance'
- text: When to use the in-page navigation component
href: '#when-to-use-the-in-page-navigation'
- text: When to consider something else
href: '#when-to-consider-something-else-in-page-navigation'
- text: Usability guidance
href: '#usability-guidance-in-page-navigation'
- text: Accessibility
href: '#accessibility-in-page-navigation'
- text: Using the in-page navigation component
href: '#using-the-in-page-navigation-component'
- text: Package
href: '#in-page-navigation-package'
Note: I discovered that the content section ids are automatically generated by the guidance > heading key/value pairs in the markdown files.
So for this:
guidance:
- heading: Additional information
... the id ends up as additional-information
This means that any items added to the subnav key/value pairs should match those resulting ids.
Where this really shines is in pages that have non-standard guidance like Link that includes sections like: What you must do What you should do What you shouldn't do and Research findings
Special cases
There are several components that don't use the standard component layout template to display guidance. It turns out, this was due to those component pages using a different layout template than the rest of the components. The following components use the "styleguide" template:
- Button Group
- Data Visualizations
- Form
- Header
- Table
- Typography
These all used the template "styleguide.html" so styleguide was altered to inlcude the in-page-navigation HTML layout and code found in the template in-page-nav.html
UPDATE: The component overview page was using styleguide as well, so what I did was changed the layout template of the items above to use the in-page-nav template as well, and reverted styleguide to its original state.
One component "Link" had some non-standard guidance but was still using the in-page-nav template.
To Do
- Continue working on the styling of in-page navigation (active state vertical bar, indented sub-sections etc.)
- Update all markdown files to include more key/value pairs in the subnav section
- Prevent focus from moving to the content sections when an in-page nav item is clicked
- Make focus work for when the Enter key is pressed on an in-page item [DONE]
- Make the component overview page not use the styleguide template
- Add a header to the in-page navigation like "On this page"
- Make in-page navigation a minimum width
@mejiaj the in-page nav has evolved quite a bit and is now coming from the component site. Also created JS to dynamically generate the ToC based on h2s and h3s in the page... I'm going to create a PR from the components site and tag you. Thanks for taking a look whenever you have the time.
Yeah maybe the h3s should not be auto-added to the ToC if they are inside the Code preview section? I'll work on some logic for this, thanks
I'm having trouble getting this to work for me locally. Can you give me a hand @mitchmoccia?
Sorry — added that comment to the wrong PR! Meant to put it in https://github.com/uswds/uswds/pull/4918
This is all good pending a new image for the preview
Awesome! Adding it now