Skip to content

[EPIC] Stacked Navigation: Milestone 1 (navigation components) #84018

@malwilley

Description

@malwilley

At present, items in the side nav are defined in a central location by a config object (see code here). These config items are quite rigid, only allowing for a label and a pathname. In order to support issue and other saved views with custom behavior, it would be beneficial to move the rendering of these items into the product areas themselves so that product teams can easily access and share state with the main content.

The system should be flexible enough to support all present feature in issue views (overflow menus, custom selection behavior based on variables other than the URL, drag and drop, etc), as well as future features that we cannot yet anticipate. Each individual product team should be able to render custom components without needing to modify any internal side nav components. In order to keep things looking consistent, there should be a suite of composable components to build the UI from.

Another requirement is that we need this solution to handle a collapsible sidebar. When collapsed (either by user action or because the screen is too small), the sidebar items should instead be rendered in a flyout. When the screen is even smaller, nav items will be rendered in a

Component Design

Proposed Structure

  • <SecondaryNav />
    • This component can be rendered anywhere in the component tree, but will use a portal so that it appears beside the main nav.
    • This portal will use a top-level NavContext to determine the portal target. The NavContext will contain a reference to the element, which may change based on screen size or collapsed state.
    • Props:
      • id: NavId - A unique identifier, like issues. Should match the id given to the top-level
      • children: ReactNode - Custom content
  • <SecondaryNav.Body />
    • Simple container component for the main sub nav content
    • Props:
      • children: ReactNode
  • <SecondaryNav.Footer />
    • Simple container component for content that should be displayed at the bottom of the sub nav (in the designs, this contains “Alerts” and “Crons”)
    • Props:
      • children: ReactNode
  • <SecondaryNav.BodySection />
    • Designates a section of secondary nav items (in the designs, this is used to separate issue views from the “All” and “Feedback” items).
    • Props:
      • title?: ReactNode
      • children: ReactNode
  • <SecondaryNav.Item />
    • This component provides the styling for a secondary nav item, such as an issue view. This component must change appearance based on where it is being rendered (expanded secondary nav, collapsed secondary nav flyout, or mobile secondary nav).
    • Props:
      • isActive?: boolean - Optionally control the active state of the item, if it is not as simple as a matching URL
      • to: To
      • children: ReactNode
  • <SecondaryNav.ItemProjectIcon />
    • Props:
      • projects: string[]

Example usage

// Top-level /issues component

return (
    <Fragment>
        <IssuesSecondaryNav />
        <IssueListOverview />
    </Fragment>
)

// IssuesSecondaryNav
// Located inside /views/issues/

function IssuesSecondaryNav() {
    const views = useApiQuery(...); // Custom data fetching
    const activeViewId = useActiveViewId(); // Custom selection logic

    return (
        <SecondaryNav>
            <SecondaryNav.Body>
                <SecondaryNav.BodySection>
                    <SecondaryNav.Item to="/issues/all/">
                        All
                    </SecondaryNav.Item>
                    <SecondaryNav.Item to="/issues/feedback/">
                        Feedback
                    </SecondaryNav.Item>
                </SecondaryNav.BodySection>
                <SecondaryNav.BodySection title="Views">
                    {views.map(view => (
                        <SecondaryNav.Item key={view.id} to={`/issues/views/${view.id}/`} isActive={view.id === activeViewId}>
                            <SecondaryNav.ItemProjectIcon projects={view.projects} />
                            {view.name}
                        </SecondaryNav.Item>
                    ))}
                </SecondaryNav.BodySection>
            </SecondaryNav.Body>
            <SecondaryNav.Footer>
                <SecondaryNav.Item to="/issues/alerts/">
                    Alerts
                </SecondaryNav.Item>
                <SecondaryNav.Item to="/issues/crons/">
                    Crons
                </SecondaryNav.Item>
            </SecondaryNav.Footer>
        </SecondaryNav>
    )
}
Designs

Image

Task list

  • Create framework and components for customizing navigation items
  • Add collapse/expand button to navigation
  • Support onboarding tooltips in new navigation component
  • Render navigation items in mobile view
  • Fix misc navigation bugs
  • Modify navigation structure to fit into Issues/Explore/Boards/Insights
  • Modify URL structure for /explore/ and /insights/ routes
  • Add redirects for /explore/ and /insights/ routes
  • Add ability to toggle the stacked nav on/off
  • Replace old onboarding panels
  • Create Storybook entries for navigation components

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions