Search code examples
javascriptreactjstypescriptstyled-components

How to pass props into style styled components file from component?


I'm using styled components and have the following code

TopNav.tsx

import {
  Container,
  SearchContainer,
  SearchBox,
  NotificationsContainer,
  NotificationsDetails,
  NotificationsSummary,
  NotificationsCounter,
  NotificationsItems,
  NotificationsHeader,
  NotificationsMarkReadText,
  Notification,
  NotificationTopper,
  NotificationContent,
  NotificationUnread,
  NotificationUnreadDot,
  NotificationsShowAll
} from '@/components/Layout/TopNav.style';
import Link from 'next/link';
import { MagnifyingGlassIcon, BellIcon } from '@heroicons/react/24/outline';
import { NOTIFICATIONS } from '@/constants/Notifications';
import { ThemeSwitch } from '@/components/ThemeSwitch/ThemeSwitch';

interface TopNavProps {
  fullWidth: Boolean;
}

export const TopNav = ({ fullWidth }: TopNavProps) => {
  return (
    <Container>
      <SearchContainer>
        <SearchBox>
          <form>
            <button type="submit">
              <MagnifyingGlassIcon />
            </button>
            <input type="text" placeholder="The everything search..." />
          </form>
        </SearchBox>
      </SearchContainer>

      <NotificationsContainer>
        <NotificationsDetails>
          <NotificationsSummary>
            <BellIcon />
            <NotificationsCounter>10</NotificationsCounter>
          </NotificationsSummary>
          <NotificationsItems>
            <NotificationsHeader>
              <NotificationsMarkReadText>
                Mark all as read
              </NotificationsMarkReadText>
              <NotificationsShowAll>
                <Link href="/notifications">Show all</Link>
              </NotificationsShowAll>
            </NotificationsHeader>

            {NOTIFICATIONS.map(({ date, message, url }, index) => {
              return (
                <Notification key={`notify_${index}`}>
                  <NotificationContent>
                    <Link href={url} target="_blank">
                      <NotificationTopper>
                        <strong>{date}</strong>

                        <NotificationUnread>
                          <NotificationUnreadDot />
                        </NotificationUnread>
                      </NotificationTopper>

                      <p>{message}</p>
                    </Link>
                  </NotificationContent>
                </Notification>
              );
            })}
          </NotificationsItems>
        </NotificationsDetails>
      </NotificationsContainer>

      <ThemeSwitch />
    </Container>
  );
};

TopNav.style.ts

import styled from 'styled-components';
import mq from '@/styles/mq';

export const Container = styled.nav`
  border-bottom: var(--border2px) solid var(--gray500);
  background-color: var(--gray100);
  width: ${(props) => props.fullWidth}? '100%' : calc(100% - 5rem);
  padding: 1.06rem 0.5rem;
  align-items: center;
  position: fixed;
  display: flex;
  z-index: 999;
  gap: 2rem;
  right: 0;
  top: 0;

  @media screen and ${mq.minMedium} {
    width: calc(100% - 15rem);
    padding: 1.25rem 0.5rem;
  }
`;

export const SearchContainer = styled.div`
  flex: 12;
`;

...

As my styles are in a separate file to keep the code clean, how do I go about passing fullWidth into my style file? So I can dynamically set the width of my navigation.

I have took a look at the docs, and it seems all the examples are will all the code in the same file.


Solution

  • how do I go about passing fullWidth into my style file? So I can dynamically set the width of my navigation.

    If only I have understood you correctly, you need to pass the fullWidth to the Container component.

    <Container fullWidth={fullWidth}>
    

    However there's also a syntax error in your style file, since

    width: ${(props) => props.fullWidth}? '100%' : calc(100% - 5rem);
    

    will obviously fail, because the ternary operator is outside the string literal. Just change it to:

    width: ${({ fullWidth }: { fullWidth: boolean }) => fullWidth ? '100%' : 'calc(100% - 5rem)'};