Navbar

Note: Based on this advice from Nielsen Norman Group, on narrow viewports (eg. mobile devices) a hamburger menu will be used if there are more than four nav items and a stacked list (no hamburger menu) will be used if there are four or less nav items.

Note: In the examples below the horizontal padding is a little off. This won't happen in practice though if you do something like this:

export default () => {
  return (
    <>
      <Navbar />
      <Container size="xl">
        {children}
      </Container>
      <Footer />
    </>
  );
}
Source code
import { 
  Navbar,
  NavbarLeft,
  NavbarRight,
  NavbarItem,
  NavbarDropdown,
  NavbarMegamenu
} from "rfui-package";

#Basic

<Navbar size="xl">
  <NavbarLeft>
    <NavbarItem href="https://one.com">One</NavbarItem>
    <NavbarItem href="https://two.com">Two</NavbarItem>
  </NavbarLeft>
</Navbar>

#NavbarLeft and NavbarRight

<Navbar size="xl">
  <NavbarLeft>
    <NavbarItem href="https://one.com">One</NavbarItem>
    <NavbarItem href="https://two.com">Two</NavbarItem>
  </NavbarLeft>
  <NavbarRight>
    <NavbarItem href="https://three.com">Three</NavbarItem>
    <NavbarItem href="https://four.com">Four</NavbarItem>
  </NavbarRight>
</Navbar>

#Background

Set background to "neutral" or "none". Defaults to "neutral".
<Stack className="w-full gap-5">
  <Navbar size="xl" background="neutral">
    <NavbarLeft>
      <NavbarItem href="https://one.com">One</NavbarItem>
      <NavbarItem href="https://two.com">Two</NavbarItem>
    </NavbarLeft>
    <NavbarRight>
      <NavbarItem href="https://three.com">Three</NavbarItem>
      <NavbarItem href="https://four.com">Four</NavbarItem>
    </NavbarRight>
  </Navbar>
  <Navbar size="xl" background="none">
    <NavbarLeft>
      <NavbarItem href="https://one.com">One</NavbarItem>
      <NavbarItem href="https://two.com">Two</NavbarItem>
    </NavbarLeft>
    <NavbarRight>
      <NavbarItem href="https://three.com">Three</NavbarItem>
      <NavbarItem href="https://four.com">Four</NavbarItem>
    </NavbarRight>
  </Navbar>
</Stack>
If you pass onClick without passing href the navbar item will be displayed like a link, won't be rendered as an <a> tag, and will call onClick when clicked.
<Navbar size="xl">
  <NavbarLeft>
    <NavbarItem href="https://one.com">One</NavbarItem>
    <NavbarItem href="https://two.com">Two</NavbarItem>
    <NavbarItem
      type="button"
      onClick={() => {
        alert("Clicked");
      }}
    >
      Click me
    </NavbarItem>
  </NavbarLeft>
</Navbar>

#Form button

If you pass formProps without passing href the navbar item will be displayed like a link and will be rendered as something like:

<form {...formProps}>
  <button>{children}</button>
</form>

rather than an <a> tag. This is useful for things like log out functionality, where it is generally desirable to use POST instead of GET.

<Navbar size="xl">
  <NavbarLeft>
    <NavbarItem href="https://one.com">One</NavbarItem>
    <NavbarItem href="https://two.com">Two</NavbarItem>
    <NavbarItem type="form" formProps={{ method: "post" }}>
      Log out
    </NavbarItem>
  </NavbarLeft>
</Navbar>

#Custom content

If you omit href, onClick, and formProps, what you pass to children will be rendered.
<Navbar size="xl">
  <NavbarLeft>
    <NavbarItem href="https://one.com">One</NavbarItem>
    <NavbarItem href="https://two.com">Two</NavbarItem>
    <NavbarItem type="custom">
      <div>Text</div>
    </NavbarItem>
    <NavbarItem type="button" onClick={() => {}}>
      <Button>Button</Button>
    </NavbarItem>
  </NavbarLeft>
</Navbar>

#Dropdown

Dropdowns work well when there are few menu items. Prefer using a megamenu when there are many menu items.
<Navbar size="xl">
  <NavbarLeft>
    <NavbarItem href="https://one.com">One</NavbarItem>
    <NavbarItem href="https://two.com">Two</NavbarItem>
    <NavbarDropdown
      title="Dropdown"
      items={[
        { label: "Link", href: "/example" },
        {
          label: "Link (new tab)",
          href: "/example",
          shouldOpenInNewTab: true,
        },
        {
          label: "onClick",
          onClick: () => {
            alert("clicked");
          },
        },
        { label: "Link with icon", href: "/icon", icon: <IconOne /> },
        {
          label: "onClick with icon",
          onClick: () => {
            alert("clicked");
          },
          icon: <IconOne />,
        },
      ]}
    />
  </NavbarLeft>
</Navbar>

#Megamenu

While dropdowns work well when there are few menu items, megamenus work well when there are many menu items.
To control the submenu on desktop views, desktopRest will be passed in a manner similar to other rest parameters. For the mobile submenu, use mobileRest instead of desktopRest.
Note: this demo is sorta broken. You need to scroll to the top of the page to see the desktop submenu. In practice, if your navbar is at the top of the page, you won't have this problem. If you need to position the submenu you can set the left and top css properties.
<Navbar size="xl">
  <NavbarLeft>
    <NavbarItem href="https://one.com">One</NavbarItem>
    <NavbarItem href="https://two.com">Two</NavbarItem>
    <NavbarMegamenu
      title="Megamenu"
      desktopSubmenu={{
        class: "left-0 w-full p-6 bg-neutral-900 text-neutral-100",
      }}
      mobileSubmenu={{
        class: "bg-neutral-900 text-neutral-100 p-6",
      }}
    >
      <div>Example</div>
    </NavbarMegamenu>
  </NavbarLeft>
</Navbar>

#Props

PropRequiredDefaultType and notes
size-"md"
"sm" | "md" | "lg" | "xl"
Set this to the same value as the Container.
background-"neutral"
"neutral" | "none"
sticky-false
boolean
Doesn't apply to the stacked UI that appears on small viewports.
children-
ComponentChild
...rest--
Omit<ComponentProps<"nav">, "size">
See the docs for rest parameters. For Navbar, you could pass anything you normally would pass to <nav> because the return value looks something like this:
<nav className={containerClass} {...restWithoutClass}>
  ...
</nav>

NavbarLeft

PropRequiredDefaultType and notes
children-
ComponentChild

NavbarRight

PropRequiredDefaultType and notes
children-
ComponentChild

NavbarItem

PropRequiredDefaultType and notes
type-"link"
"link" | "button" | "form" | "custom"
href--
string
isActive-false
boolean
onClick--
() => void
formProps--
ComponentProps<"form">
children-
ComponentChild
...rest--
ComponentProps<"li">

NavbarDropdown

PropRequiredDefaultType and notes
title-
string
items-
DropdownItemType[]

NavbarMegamenu

PropRequiredDefaultType and notes
title-
string
children-
ComponentChild
desktopSubmenu--
ComponentProps<"div">
This will be passed to the desktop submenu in a manner similar to other rest parameters.
mobileSubmenu--
ComponentProps<"div">
This will be passed to the mobile submenu in a manner similar to other rest parameters.
...rest--
ComponentProps<"li">