React/JS/TS - Adding prop to component by location

Viewed 138

So I have a custom component for my sidebar navigation that isn't completely functional. I'm trying to figure out how to dynamically add isSelected to the CustomItem component by location.

Edit: I'm assuming that useLocation from react-router-dom is my best bet for the first part.

Here's the code for the Dashboard:

/** @jsx jsx */
import React, { forwardRef } from 'react';

import { 
  Main,
  Content, 
  LeftSidebar, 
} from '@atlaskit/page-layout';

import { 
  Link, 
  Route, 
  Switch, 
  useParams, 
  useRouteMatch } from 'react-router-dom';
import { css, jsx } from '@emotion/core';
import { Section } from '@atlaskit/menu';
 
import {
  Header,
  NavigationHeader,
  NestableNavigationContent,
  SideNavigation,
  CustomItem,
  CustomItemComponentProps
} from '@atlaskit/side-navigation';

type CustomProps = CustomItemComponentProps & { 
  href: string;
};

const CustomLink = forwardRef<HTMLAnchorElement, CustomProps>(
  (props: CustomProps, ref) => {
    const { href, children, ...rest } = props;
    return (
      <Link to={href} ref={ref} {...rest}>
        {children}
      </Link>
    );
  },
);

function SideNavigationWrapper(props: { children: React.ReactNode }) {
  return (
    <div
      css={css`
        height: 100%;
        & nav {
          min-width: 20px;
          overflow-x: hidden;
        }
      `}
    >
      {props.children}
    </div>
  );
}

function Components() {
  let { component } = useParams();
  
  if (component === 'assets') {
    return (
      <Assets />
    );
  }
  if (component === 'orders') {
    return (
      <Orders />
    );
  }
  return (
    <div></div>
  );
}

export default function Dashboard() {
  let { path } = useRouteMatch();
  return (
    <Content>
      <LeftSidebar
        isFixed={true}
        id="dash-navigation"
      >
        <SideNavigationWrapper>
          <SideNavigationContent />
        </SideNavigationWrapper>
      </LeftSidebar>
      <Main>
        <div
          style={{
            marginLeft: 40, 
            marginRight: 40,
            marginTop: 20,
          }}
        > 
          <Switch>

            <Route exact path={path}>
              <Overview />
            </Route>

            <Route path={`${path}/:component`}>
              <Components />
            </Route>

          </Switch>
        </div>
      </Main>
    </Content>
  );
}

const SideNavigationContent = () => {
  return (
    <SideNavigation label="DashboardNav">
      <NavigationHeader>
        <Header>Dashboard</Header>
      </NavigationHeader>
      <NestableNavigationContent initialStack={[]}>
        <Section>
          <CustomItem 
            isSelected 
            component={CustomLink}
            href="/dashboard" 
            iconBefore={<PortfolioIcon label="" />}
          >
            Portfolio
          </CustomItem>
          <CustomItem 
            component={CustomLink}
            href="/dashboard/assets"                 
            iconBefore={<SuitcaseIcon label="" />}
          >
            Assets
          </CustomItem>
          <CustomItem 
            component={CustomLink}
            href="/dashboard/orders" 
            iconBefore={<RoadmapIcon label="" />}
          >
            Orders
          </CustomItem>
        </Section>
      </NestableNavigationContent>
    </SideNavigation>
  );
};

It's also worth nothing that my approach has slightly messed up the styling as shown below:

enter image description here

Which should appear like this naturally without me having to hover over it.

enter image description here

Edit: I'm also assuming that I would have to override the styling with cssFn as per the documentation.

Any guidance on either two issues would be helpful. I've gave myself a headache trying to redo the entire apps routing. Figured I'd try my best to wrap this up tonight so I can move onto greater issues

1 Answers

You should assign boolean instead of putting props

const SideNavigationContent = props => {
  //Add logic to control variable 
  //isPortfolioSelected, isAssetsSelect, isOrdersSelected, then assign to each item, 
  //Ex: isPortfolioSelected = props.selected['Portfolio']

  return (
    <SideNavigation label="DashboardNav">
      <NavigationHeader>
        <Header>Dashboard</Header>
      </NavigationHeader>
      <NestableNavigationContent initialStack={[]}>
        <Section>
          <CustomItem 
            isSelected={isPortfolioSelected}
            component={CustomLink}
            href="/dashboard" 
            iconBefore={<PortfolioIcon label="" />}
          >
            Portfolio
          </CustomItem>
          <CustomItem 
            isSelected={isAssetsSelect}
            component={CustomLink}
            href="/dashboard/assets"                 
            iconBefore={<SuitcaseIcon label="" />}
          >
            Assets
          </CustomItem>
          <CustomItem 
            isSelecled={isOrdersSelected}
            component={CustomLink}
            href="/dashboard/orders" 
            iconBefore={<RoadmapIcon label="" />}
          >
            Orders
          </CustomItem>
        </Section>
      </NestableNavigationContent>
    </SideNavigation>
  );
};
Related