@simpozio/nav-menu

Package for nav-menu component

Usage no npm install needed!

<script type="module">
  import simpozioNavMenu from 'https://cdn.skypack.dev/@simpozio/nav-menu';
</script>

README

Nav Menu Component

React component for navigation menu.

Installation

npm i @simpozio/terminal-text

Usage

Basic

import {Menu, Logo, Nav, Action, Social} from '@simpozio/nav-menu';
import {Link} from 'react-router-dom';
import LogoImg from './logo.svg';

const Component = () => {
  return (
    <Menu>
      <Logo>
        {/* you can pass your own children */} 
        <LogoImg />
      </Logo>

      <Nav>
        {/* you can pass your own children */} 
        <Link to="/">Home</Link>
        <Link to="/about">About</Link>
        <Link to="/products">Products</Link>
        <Link to="/contacts">Contacts</Link>
      </Nav>

      <Social>
        {/* you can pass your own children */} 
        <a href="https://facebook.com" rel="noreferrer,nofollow" target="_blank">Facebook</a>
        <a href="https://instagram.com" rel="noreferrer,nofollow" target="_blank">Instagram</a>
      </Social>

      <Action>
        {/* you can pass your own children */} 
        <button>Some Action</button>
      </Action>
    </Menu>
  )
}

Control Menu from outside

import React, {useRef} from 'react';
import {Menu, Logo, Nav, Action, Social} from '@simpozio/nav-menu';

const Component = () => {
  const menuRef = useRef();

  const handleClick = () => {
    const {isOpen, setOpen} = menuRef.current;

    setOpen(!isOpen);
  }

  return (
    <>
      <button onClick={handleClick}>

      <Menu ref={menuRef} >
        {/* ... */} 
      </Menu>
    </>
  )
}

Passed Props

  • isMobile: boolean - applying mobile state to menu
  • isNarrow: boolean - applying narrow state to menu
import React, {useEffect, useState} from 'react';
import {Menu, Logo, Nav, Action, Social} from '@simpozio/nav-menu';

const Component = () => {
  const [isMobile, setMobile] = useState(window.innerWidth < 768);
  const [isScrolling, setScrolling] = useState(window.pageYOffset > 0);

  useEffect(() => {
    const handleResize = () => setMobile(window.innerWidth < 768);

    window.addEventListener('resize', handleResize);
    window.addEventListener('orientationchange', handleResize);

    return () => {
      window.removeEventListener('resize', handleResize);
      window.removeEventListener('orientationchange', handleResize);
    }
  }, [isMobile])

  useEffect(() => {
    const handleScroll = () => setScrolling(window.pageYOffset > 0);

    window.addEventListener('scroll', handleScroll);
    return () => window.removeEventListener('scroll', handleScroll);
  }, [isScrolling])

  return (
    <>
      <button onClick={handleClick}>

      <Menu 
        isMobile={isMobile}
        isNarrow={isScrolling}
      >
        {/* ... */} 
      </Menu>
    </>
  )
}

Styling

You can pass all styles as styles prop to Menu component. In your mixin you can use props, passed to Menu styled component: isOpen: boolean - is menu open isNarrow: boolean - is menu in narrow state isMobile: boolean - is menu in mobile state Toggle - reference to Toggle component Mobile - reference to Mobile wrapper Logo - reference to Logo component Nav - reference to Nav component Social - reference to Social component Action - reference to Action component

import {Menu, Logo, Nav, Action, Social} from '@simpozio/nav-menu';
import {css} from 'styled-components';

const styles = {
  // menu styles
  height: 2rem;

  // used Logo reference
  ${props => props.Logo} {
    width: 3rem;
    height: 1rem;
  }

  // used isMobile prop
  ${props => props.isMobile
    ? `padding: 5px;`
    : `padding: 10px;`}
}

const Component = () => {
  return (
    <Menu styles={styles}>
      <Logo>
        {/* ... */} 
      </Logo>

      <Nav>
        {/* ... */} 
      </Nav>

      <Social>
        {/* ... */} 
      </Social>

      <Action>
        {/* ... */}
      </Action>
    </Menu>
  )
}

or you can pass styles to all components separately

import {Menu, Logo, Nav, Action, Social} from '@simpozio/nav-menu';
import {css} from 'styled-components';

const menuStyles = css`
  height: 2rem;

  ${props => props.isMobile
    ? `padding: 5px;`
    : `padding: 10px;`}
`;

const logoStyles = css`
  margin-right: 20px;
`;

const navStyles = css`
  margin-left: 20px;
`;

const actionStyles = css`
  color: red;
`;

const socialStyles = css`
  text-decoration: underline;
`;

const Component = () => {
  return (
    <Menu styles={menuStyles}>
      <Logo styles={logoStyles}>
        {/* ... */} 
      </Logo>

      <Nav styles={navStyles}>
        {/* ... */} 
      </Nav>

      <Social styles={socialStyles}>
        {/* ... */} 
      </Social>

      <Action styles={actionStyles}>
        {/* ... */}
      </Action>
    </Menu>
  )
}

Development

Look simpozio-frontend-common library