feat(navbar): controlled example added, data atrrs addded

This commit is contained in:
Junior Garcia 2023-07-11 19:57:57 -03:00
parent 9cae2d2625
commit a822eddc11
6 changed files with 255 additions and 11 deletions

View File

@ -0,0 +1,104 @@
"use client";
import {
Navbar,
NavbarBrand,
NavbarContent,
NavbarItem,
Link,
NavbarMenu,
NavbarMenuItem,
NavbarMenuToggle,
Avatar,
} from "@nextui-org/react";
import React from "react";
const AcmeLogo = () => (
<svg fill="none" height="36" viewBox="0 0 32 32" width="36">
<path
clipRule="evenodd"
d="M17.6482 10.1305L15.8785 7.02583L7.02979 22.5499H10.5278L17.6482 10.1305ZM19.8798 14.0457L18.11 17.1983L19.394 19.4511H16.8453L15.1056 22.5499H24.7272L19.8798 14.0457Z"
fill="currentColor"
fillRule="evenodd"
/>
</svg>
);
export default function Page() {
const [isMenuOpen, setIsMenuOpen] = React.useState<boolean | undefined>(false);
const menuItems = [
"Profile",
"Dashboard",
"Activity",
"Analytics",
"System",
"Deployments",
"My Settings",
"Team Settings",
"Help & Feedback",
"Log Out",
];
return (
<Navbar isBordered onMenuOpenChange={setIsMenuOpen}>
<NavbarContent className="sm:hidden" justify="start">
<NavbarMenuToggle aria-label={isMenuOpen ? "Close menu" : "Open menu"} />
</NavbarContent>
<NavbarContent className="sm:hidden pr-3" justify="center">
<NavbarBrand>
<AcmeLogo />
<p className="font-bold text-inherit">ACME</p>
</NavbarBrand>
</NavbarContent>
<NavbarContent className="hidden sm:flex gap-4" justify="center">
<NavbarBrand>
<AcmeLogo />
<p className="font-bold text-inherit">ACME</p>
</NavbarBrand>
<NavbarItem as={Link} color="foreground" href="#">
Features
</NavbarItem>
<NavbarItem isActive as={Link} color="warning" href="#">
Customers
</NavbarItem>
<NavbarItem as={Link} color="foreground" href="#">
Integrations
</NavbarItem>
</NavbarContent>
<NavbarContent justify="end">
<NavbarItem>
<Avatar
isBordered
as="button"
className="transition-transform"
color="warning"
name="Jane Lee"
size="sm"
src="https://i.pravatar.cc/150?u=a042581f4e29026704d"
/>
</NavbarItem>
</NavbarContent>
<NavbarMenu>
{menuItems.map((item, index) => (
<NavbarMenuItem key={`${item}-${index}`}>
<Link
className="w-full"
color={
index === 2 ? "warning" : index === menuItems.length - 1 ? "danger" : "foreground"
}
href="#"
size="lg"
>
{item}
</Link>
</NavbarMenuItem>
))}
</NavbarMenu>
</Navbar>
);
}

View File

@ -25,8 +25,6 @@ const AcmeLogo = () => (
); );
export default function Page() { export default function Page() {
const [isMenuOpen, setIsMenuOpen] = React.useState<boolean | undefined>(false);
const menuItems = [ const menuItems = [
"Profile", "Profile",
"Dashboard", "Dashboard",
@ -41,12 +39,12 @@ export default function Page() {
]; ];
return ( return (
<Navbar disableAnimation isBordered onMenuOpenChange={setIsMenuOpen}> <Navbar disableAnimation isBordered>
<NavbarContent className="sm:hidden" justify="start"> <NavbarContent className="sm:hidden" justify="start">
<NavbarMenuToggle aria-label={isMenuOpen ? "Close menu" : "Open menu"} /> <NavbarMenuToggle />
</NavbarContent> </NavbarContent>
<NavbarContent className="sm:hidden" justify="center"> <NavbarContent className="sm:hidden pr-3" justify="center">
<NavbarBrand> <NavbarBrand>
<AcmeLogo /> <AcmeLogo />
<p className="font-bold text-inherit">ACME</p> <p className="font-bold text-inherit">ACME</p>

View File

@ -0,0 +1,102 @@
const AcmeLogo = `export const AcmeLogo = () => (
<svg fill="none" height="36" viewBox="0 0 32 32" width="36">
<path
clipRule="evenodd"
d="M17.6482 10.1305L15.8785 7.02583L7.02979 22.5499H10.5278L17.6482 10.1305ZM19.8798 14.0457L18.11 17.1983L19.394 19.4511H16.8453L15.1056 22.5499H24.7272L19.8798 14.0457Z"
fill="currentColor"
fillRule="evenodd"
/>
</svg>
);`;
const App = `import {Navbar, NavbarBrand, NavbarContent, NavbarItem, Link, Button} from "@nextui-org/react";
import {AcmeLogo} from "./AcmeLogo.jsx";
export default function App() {
const [isMenuOpen, setIsMenuOpen] = React.useState(false);
const menuItems = [
"Profile",
"Dashboard",
"Activity",
"Analytics",
"System",
"Deployments",
"My Settings",
"Team Settings",
"Help & Feedback",
"Log Out",
];
return (
<Navbar
isBordered
isMenuOpen={isMenuOpen}
onMenuOpenChange={setIsMenuOpen}
>
<NavbarContent className="sm:hidden" justify="start">
<NavbarMenuToggle aria-label={isMenuOpen ? "Close menu" : "Open menu"} />
</NavbarContent>
<NavbarContent className="sm:hidden pr-3" justify="center">
<NavbarBrand>
<AcmeLogo />
<p className="font-bold text-inherit">ACME</p>
</NavbarBrand>
</NavbarContent>
<NavbarContent className="hidden sm:flex gap-4" justify="center">
<NavbarBrand>
<AcmeLogo />
<p className="font-bold text-inherit">ACME</p>
</NavbarBrand>
<NavbarItem as={Link} color="foreground" href="#">
Features
</NavbarItem>
<NavbarItem isActive as={Link} color="warning" href="#">
Customers
</NavbarItem>
<NavbarItem as={Link} color="foreground" href="#">
Integrations
</NavbarItem>
</NavbarContent>
<NavbarContent justify="end">
<NavbarItem as={Link} className="hidden md:flex" href="#">
Login
</NavbarItem>
<NavbarItem>
<Button as={Link} color="warning" href="#" variant="flat">
Sign Up
</Button>
</NavbarItem>
</NavbarContent>
<NavbarMenu>
{menuItems.map((item, index) => (
<NavbarMenuItem key={\`\${item}-\${index}\`}>
<Link
className="w-full"
color={
index === 2 ? "warning" : index === menuItems.length - 1 ? "danger" : "foreground"
}
href="#"
size="lg"
>
{item}
</Link>
</NavbarMenuItem>
))}
</NavbarMenu>
</Navbar>
);
}`;
const react = {
"/App.jsx": App,
"/AcmeLogo.jsx": AcmeLogo,
};
export default {
...react,
};

View File

@ -13,8 +13,6 @@ const App = `import {Navbar, NavbarBrand, NavbarContent, NavbarItem, Link, Butto
import {AcmeLogo} from "./AcmeLogo.jsx"; import {AcmeLogo} from "./AcmeLogo.jsx";
export default function App() { export default function App() {
const [isMenuOpen, setIsMenuOpen] = React.useState(false);
const menuItems = [ const menuItems = [
"Profile", "Profile",
"Dashboard", "Dashboard",
@ -29,12 +27,12 @@ export default function App() {
]; ];
return ( return (
<Navbar disableAnimation isBordered onMenuOpenChange={setIsMenuOpen}> <Navbar disableAnimation isBordered>
<NavbarContent className="sm:hidden" justify="start"> <NavbarContent className="sm:hidden" justify="start">
<NavbarMenuToggle aria-label={isMenuOpen ? "Close menu" : "Open menu"} /> <NavbarMenuToggle />
</NavbarContent> </NavbarContent>
<NavbarContent className="sm:hidden" justify="center"> <NavbarContent className="sm:hidden pr-3" justify="center">
<NavbarBrand> <NavbarBrand>
<AcmeLogo /> <AcmeLogo />
<p className="font-bold text-inherit">ACME</p> <p className="font-bold text-inherit">ACME</p>

View File

@ -4,6 +4,7 @@ import disabledBlur from "./disabled-blur";
import staticPosition from "./static"; import staticPosition from "./static";
import hideOnScroll from "./hide-on-scroll"; import hideOnScroll from "./hide-on-scroll";
import withMenu from "./with-menu"; import withMenu from "./with-menu";
import controlledMenu from "./controlled-menu";
import disableMenuAnimation from "./disable-menu-animation"; import disableMenuAnimation from "./disable-menu-animation";
import withAvatar from "./with-avatar"; import withAvatar from "./with-avatar";
import withDropdownMenu from "./with-dropdown-menu"; import withDropdownMenu from "./with-dropdown-menu";
@ -17,6 +18,7 @@ export const navbarContent = {
hideOnScroll, hideOnScroll,
disabledBlur, disabledBlur,
withMenu, withMenu,
controlledMenu,
disableMenuAnimation, disableMenuAnimation,
withAvatar, withAvatar,
withDropdownMenu, withDropdownMenu,

View File

@ -108,6 +108,20 @@ If you want to remove the `open` / `close` animation, you can pass the `disableA
files={navbarContent.disableMenuAnimation} files={navbarContent.disableMenuAnimation}
/> />
### Controlled Menu
You can use the `isMenuOpen` and `onMenuOpenChange` props to control the navbar menu state.
<CodeDemo
asIframe
title="Controlled Menu"
iframeInitialWidth={420}
previewHeight="600px"
highlightedLines="5,23-24"
iframeSrc="/examples/navbar/controlled-menu"
files={navbarContent.controlledMenu}
/>
### With Border ### With Border
You can use the `isBordered` prop to add a bottom border to the navbar. You can use the `isBordered` prop to add a bottom border to the navbar.
@ -170,7 +184,7 @@ Example of a navbar with search input.
/> />
### Active Item Customization ### Customizing the active item
When the `NavbarItem` is active, it will have a `data-active` attribute. You can use this attribute to customize it. When the `NavbarItem` is active, it will have a `data-active` attribute. You can use this attribute to customize it.
@ -182,3 +196,29 @@ When the `NavbarItem` is active, it will have a `data-active` attribute. You can
highlightedLines="9-20" highlightedLines="9-20"
files={navbarContent.customActiveItem} files={navbarContent.customActiveItem}
/> />
## Data Attributes
`Navbar` has the following attributes on the `root` element:
- **data-menu-open**:
Indicates if the navbar menu is open.
- **data-hidden**:
Indicates if the navbar is hidden. It is used when the `shouldHideOnScroll` prop is `true`.
`NavbarItem` has the following attributes on the `root` element:
- **data-active**:
Indicates if the navbar item is active. It is used when the `isActive` prop is `true`.
`NavbarMenuToggle` has the following attributes on the `root` element:
- **data-open**:
Indicates if the navbar menu is open. It is used when the `isMenuOpen` prop is `true`.
- **data-pressed**:
When the navbar menu toggle is pressed. Based on [usePress](https://react-spectrum.adobe.com/react-aria/usePress.html)
- **data-hover**:
When the navbar menu toggle is being hovered. Based on [useHover](https://react-spectrum.adobe.com/react-aria/useHover.html)
- **data-focus-visible**:
When the navbar menu toggle is being focused with the keyboard. Based on [useFocusRing](https://react-spectrum.adobe.com/react-aria/useFocusRing.html).