import { StoryObj, Meta } from "@storybook/react-vite"; import { within, expect } from "storybook/test"; import React from "react"; import Nav from "./nav"; import Link from "../link/link"; import Button from "../buttons/button"; const meta: Meta = { title: "FP.React Components/Nav", component: Nav, tags: ["stable"], parameters: { docs: { description: { component: `Navigation component with accessible markup and customizable styling via CSS variables. ## CSS Variables ### Layout & Sizing - \`--nav-display\`: Display mode (default: flex) - \`--nav-width\`: Nav width (default: auto) - \`--nav-height\`: Minimum height (default: fit-content) - \`--nav-direction\`: Flex direction (default: row) - \`--nav-align\`: Vertical alignment (default: center) - \`--nav-justify\`: Horizontal justification (default: space-between) ### Spacing - \`--nav-padding-inline\`: Horizontal padding (default: 1rem) - \`--nav-padding-block\`: Vertical padding (default: 0) - \`--nav-margin-inline\`: Horizontal margin (default: 0) - \`--nav-margin-block-end\`: Bottom margin (default: 0) - \`--nav-gap\`: Gap between nav items (default: 0) ### Typography & Color - \`--nav-fs\`: Font size (default: 0.9rem) - \`--nav-color\`: Text color - \`--nav-bg\`: Background color (default: initial) - \`--nav-hover-bg\`: Background color on hover (default: #e8e8e8) ### Focus Indicators (WCAG 2.4.7) - \`--nav-focus-color\`: Focus outline color (default: currentColor) - \`--nav-focus-width\`: Focus outline width (default: 0.125rem / 2px) - \`--nav-focus-offset\`: Focus outline offset (default: 0.125rem / 2px) - \`--nav-focus-style\`: Focus outline style (default: solid) ### Image Elements - \`--nav-img-padding-inline\`: Image padding (default: 0 var(--s1)) - \`--nav-img-width\`: Image width (default: var(--brand-w, 3.6rem)) `, }, }, }, args: { children: ( Link 1 Link 2 ), id: "nav", classes: "nav", }, } as Story; export default meta; type Story = StoryObj; export const NavComponent: Story = { args: {}, play: async ({ canvasElement }) => { const canvas = within(canvasElement); expect(canvas.getAllByRole("link")).toHaveLength(2); expect(canvas.getByText(/link 1/i)).toBeInTheDocument(); }, }; export const NavSection: Story = { args: { children: ( <> Link 1 Link 2 ), }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); expect(canvas.getByText("Link 1")).toBeInTheDocument(); expect(canvas.getByText("Link 2")).toBeInTheDocument(); }, } as Story; export const NavBlock: Story = { args: { ...NavSection.args, children: ( <> Link 1 Link 2 ), }, } as Story; export const MultipleNavs: Story = { args: { ...NavSection.args, classes: "navbar", "aria-label": "Main navigation", children: ( <> Home Products Login Sign Up ), }, } as Story; export const WithCurrentPage: Story = { args: { "aria-label": "Main navigation", children: ( Home About Products Contact ), }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); const homeLink = canvas.getByText(/home/i); expect(homeLink).toHaveAttribute("aria-current", "page"); }, } as Story;