-
Notifications
You must be signed in to change notification settings - Fork 13
feat: add navbar component #551
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
285f32b
feat: add navbar
paanSinghCoder ceaf3f5
style: update style
paanSinghCoder ebbae36
feat: add accessibility
paanSinghCoder 07337d9
feat: add accessibility
paanSinghCoder aa0d7fb
chore: remove unused file
paanSinghCoder 86dacdc
fix: css changes
paanSinghCoder File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,137 @@ | ||
| 'use client'; | ||
|
|
||
| export const preview = { | ||
| type: 'code', | ||
| code: ` | ||
| <Navbar> | ||
| <Navbar.Start> | ||
| <Text size="regular" weight="medium">Explore</Text> | ||
| </Navbar.Start> | ||
| <Navbar.End> | ||
| <Search placeholder="Search an AOI" size="small" style={{ width: '200px' }} /> | ||
| <Button variant="outline" size="small" color="neutral" leadingIcon={<FilterIcon />}> | ||
| Draw AOI | ||
| </Button> | ||
| <Button variant="outline" size="small" color="neutral" leadingIcon={<OrganizationIcon />}> | ||
| Upload AOI | ||
| </Button> | ||
| </Navbar.End> | ||
| </Navbar>` | ||
| }; | ||
|
|
||
| export const stickyDemo = { | ||
| type: 'code', | ||
| tabs: [ | ||
| { | ||
| name: 'Default', | ||
| code: ` | ||
| <Navbar> | ||
| <Navbar.Start> | ||
| <Text size="regular" weight="medium">Navigation</Text> | ||
| </Navbar.Start> | ||
| <Navbar.End> | ||
| <Button variant="ghost" size="small">Home</Button> | ||
| <Button variant="ghost" size="small">About</Button> | ||
| <Button variant="ghost" size="small">Contact</Button> | ||
| </Navbar.End> | ||
| </Navbar>` | ||
| }, | ||
| { | ||
| name: 'Sticky', | ||
| code: ` | ||
| <Navbar sticky> | ||
| <Navbar.Start> | ||
| <Text size="regular" weight="medium">Navigation</Text> | ||
| </Navbar.Start> | ||
| <Navbar.End> | ||
| <Button variant="ghost" size="small">Home</Button> | ||
| <Button variant="ghost" size="small">About</Button> | ||
| <Button variant="ghost" size="small">Contact</Button> | ||
| </Navbar.End> | ||
| </Navbar>` | ||
| } | ||
| ] | ||
| }; | ||
|
|
||
| export const sectionsDemo = { | ||
| type: 'code', | ||
| tabs: [ | ||
| { | ||
| name: 'Start Only', | ||
| code: ` | ||
| <Navbar> | ||
| <Navbar.Start> | ||
| <Text size="regular" weight="medium">Brand Name</Text> | ||
| </Navbar.Start> | ||
| </Navbar>` | ||
| }, | ||
| { | ||
| name: 'End Only', | ||
| code: ` | ||
| <Navbar> | ||
| <Navbar.End> | ||
| <Button variant="outline" size="small">Login</Button> | ||
| <Button size="small">Sign Up</Button> | ||
| </Navbar.End> | ||
| </Navbar>` | ||
| }, | ||
| { | ||
| name: 'Both Sections', | ||
| code: ` | ||
| <Navbar> | ||
| <Navbar.Start> | ||
| <Text size="regular" weight="medium">Explore</Text> | ||
| </Navbar.Start> | ||
| <Navbar.End> | ||
| <Search placeholder="Search..." size="small" style={{ width: '200px' }} /> | ||
| <Button variant="outline" size="small">Action</Button> | ||
| </Navbar.End> | ||
| </Navbar>` | ||
| } | ||
| ] | ||
| }; | ||
|
|
||
| export const accessibilityDemo = { | ||
| type: 'code', | ||
| tabs: [ | ||
| { | ||
| name: 'Custom aria-label', | ||
| code: ` | ||
| <Navbar aria-label="Primary navigation"> | ||
| <Navbar.Start> | ||
| <Text size="regular" weight="medium">Brand</Text> | ||
| </Navbar.Start> | ||
| <Navbar.End> | ||
| <Button size="small">Menu</Button> | ||
| </Navbar.End> | ||
| </Navbar>` | ||
| }, | ||
| { | ||
| name: 'With aria-labelledby', | ||
| code: ` | ||
| <> | ||
| <Navbar aria-labelledby="nav-heading"> | ||
| <Navbar.Start> | ||
| <Text size="regular" weight="medium">Brand</Text> | ||
| </Navbar.Start> | ||
| <Navbar.End> | ||
| <Button size="small">Menu</Button> | ||
| </Navbar.End> | ||
| </Navbar> | ||
| </>` | ||
| }, | ||
| { | ||
| name: 'Section Labels', | ||
| code: ` | ||
| <Navbar> | ||
| <Navbar.Start aria-label="Brand and navigation links"> | ||
| <Text size="regular" weight="medium">Brand</Text> | ||
| </Navbar.Start> | ||
| <Navbar.End aria-label="User actions and settings"> | ||
| <Button size="small">Settings</Button> | ||
| <Button size="small">Profile</Button> | ||
| </Navbar.End> | ||
| </Navbar>` | ||
| } | ||
| ] | ||
| }; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| --- | ||
| title: Navbar | ||
| description: A horizontal navigation bar component with flexible left and right sections for building site headers and navigation. | ||
| --- | ||
|
|
||
| import { | ||
| preview, | ||
| stickyDemo, | ||
| sectionsDemo, | ||
| accessibilityDemo, | ||
| } from "./demo.ts"; | ||
|
|
||
| <Demo data={preview} /> | ||
|
|
||
| ## Usage | ||
|
|
||
| ```tsx | ||
| import { Navbar } from "@raystack/apsara"; | ||
| ``` | ||
|
|
||
| ## Component Structure | ||
|
|
||
| The Navbar component uses a composite pattern, providing modular sub-components for flexible navigation layouts: | ||
|
|
||
| - `Navbar` - Root container that wraps the navigation bar | ||
| - `Navbar.Start` - Left section container for brand, logo, or primary navigation | ||
| - `Navbar.End` - Right section container for actions, search, or secondary navigation | ||
|
|
||
| ## Navbar Props | ||
|
|
||
| <auto-type-table path="./props.ts" name="NavbarRootProps" /> | ||
|
|
||
| ### Navbar.Start Props | ||
|
|
||
| The start section is a container component that accepts all `div` props. It's commonly used for brand logos, primary navigation links, or page titles. | ||
|
|
||
| <auto-type-table path="./props.ts" name="NavbarStartProps" /> | ||
|
|
||
| ### Navbar.End Props | ||
|
|
||
| The end section is a container component that accepts all `div` props. It's commonly used for search inputs, action buttons, user menus, or secondary navigation. | ||
|
|
||
| <auto-type-table path="./props.ts" name="NavbarEndProps" /> | ||
|
|
||
| ## Examples | ||
|
|
||
| ### Sticky Navigation | ||
|
|
||
| The Navbar can be made sticky to remain visible at the top of the viewport when scrolling. | ||
|
|
||
| <Demo data={stickyDemo} /> | ||
|
|
||
| ### Section Layouts | ||
|
|
||
| You can use either or both sections depending on your needs. The sections automatically position themselves with proper spacing. | ||
|
|
||
| <Demo data={sectionsDemo} /> | ||
|
|
||
| ### Accessibility | ||
|
|
||
| The Navbar supports custom ARIA labels for better screen reader support. You can provide descriptive labels for the entire navbar or individual sections. | ||
|
|
||
| <Demo data={accessibilityDemo} /> | ||
|
|
||
| ## Accessibility | ||
|
|
||
| The Navbar implements the following accessibility features: | ||
|
|
||
| - Proper ARIA roles and attributes | ||
| - `role="navigation"` for the main navbar | ||
| - `role="group"` for Start and End sections when `aria-label` is provided | ||
| - Customizable `aria-label` and `aria-labelledby` support | ||
|
|
||
| - Semantic HTML | ||
| - Uses `<nav>` element for proper navigation landmark | ||
| - Maintains proper heading hierarchy when using `aria-labelledby` | ||
|
|
||
| - Screen reader support | ||
| - Meaningful labels for all sections | ||
| - Clear structure for assistive technologies | ||
| - Support for linking to visible headings via `aria-labelledby` | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| export interface NavbarRootProps { | ||
| /** | ||
| * Makes the navbar stick to the top of the viewport when scrolling. | ||
| * @default false | ||
| */ | ||
| sticky?: boolean; | ||
|
|
||
| /** | ||
| * Accessible label for the navigation. | ||
| * Use this to provide a description of the navbar's purpose. | ||
| */ | ||
| 'aria-label'?: string; | ||
|
|
||
| /** | ||
| * ID of an element that labels the navigation. Use this when you have a visible heading | ||
| * that describes the navbar. | ||
| */ | ||
| 'aria-labelledby'?: string; | ||
| } | ||
|
|
||
| export interface NavbarStartProps { | ||
| /** | ||
| * Accessible label for the start section. Use this to describe the purpose | ||
| * of the content in the start section (e.g., "Brand and navigation links"). | ||
| * When provided, the section will have `role="group"`. | ||
| */ | ||
| 'aria-label'?: string; | ||
| } | ||
|
|
||
| export interface NavbarEndProps { | ||
| /** | ||
| * Accessible label for the end section. Use this to describe the purpose | ||
| * of the content in the end section (e.g., "User actions and settings"). | ||
| * When provided, the section will have `role="group"`. | ||
| */ | ||
| 'aria-label'?: string; | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.