diff --git a/apps/www/src/content/docs/components/navbar/index.mdx b/apps/www/src/content/docs/components/navbar/index.mdx
index ad04488c5..f3fe11496 100644
--- a/apps/www/src/content/docs/components/navbar/index.mdx
+++ b/apps/www/src/content/docs/components/navbar/index.mdx
@@ -23,6 +23,7 @@ import { Navbar } from "@raystack/apsara";
+
```
@@ -41,6 +42,12 @@ The start section is a container component that accepts all `div` props. It's co
+### Center
+
+The center section sits between Start and End and centers its content. It accepts all `div` props.
+
+
+
### End
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.
@@ -73,7 +80,7 @@ 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
+ - `role="group"` for Start, Center, and End sections when `aria-label` is provided
- Customizable `aria-label` and `aria-labelledby` support
- Semantic HTML
diff --git a/apps/www/src/content/docs/components/navbar/props.ts b/apps/www/src/content/docs/components/navbar/props.ts
index cca5b6f97..d71584c08 100644
--- a/apps/www/src/content/docs/components/navbar/props.ts
+++ b/apps/www/src/content/docs/components/navbar/props.ts
@@ -5,6 +5,12 @@ export interface NavbarRootProps {
*/
sticky?: boolean;
+ /**
+ * Show the bottom shadow.
+ * @default true
+ */
+ shadow?: boolean;
+
/**
* Accessible label for the navigation.
* Use this to provide a description of the navbar's purpose.
@@ -27,6 +33,13 @@ export interface NavbarStartProps {
'aria-label'?: string;
}
+export interface NavbarCenterProps {
+ /**
+ * Accessible label for the center section. 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
diff --git a/packages/raystack/components/navbar/__tests__/navbar.test.tsx b/packages/raystack/components/navbar/__tests__/navbar.test.tsx
index 394504123..c4ff2c86c 100644
--- a/packages/raystack/components/navbar/__tests__/navbar.test.tsx
+++ b/packages/raystack/components/navbar/__tests__/navbar.test.tsx
@@ -1,8 +1,8 @@
import { render, screen } from '@testing-library/react';
import { describe, expect, it, vi } from 'vitest';
import { Navbar } from '../navbar';
-import { NavbarRootProps } from '../navbar-root';
import styles from '../navbar.module.css';
+import { NavbarRootProps } from '../navbar-root';
const START_TEXT = 'Explore';
const END_BUTTON_TEXT = 'Action';
@@ -118,6 +118,22 @@ describe('Navbar', () => {
});
});
+ describe('Shadow', () => {
+ it('shows shadow by default', () => {
+ render();
+
+ const nav = screen.getByRole('navigation');
+ expect(nav).toHaveAttribute('data-shadow', 'true');
+ });
+
+ it('hides shadow when shadow is false', () => {
+ render();
+
+ const nav = screen.getByRole('navigation');
+ expect(nav).toHaveAttribute('data-shadow', 'false');
+ });
+ });
+
describe('Navbar.Start', () => {
it('renders start section content', () => {
render(
@@ -204,6 +220,31 @@ describe('Navbar', () => {
});
});
+ describe('Navbar.Center', () => {
+ it('renders center section content', () => {
+ render(
+
+
+ Center
+
+
+ );
+
+ expect(screen.getByText('Center')).toBeInTheDocument();
+ });
+
+ it('applies center styles', () => {
+ const { container } = render(
+
+
+
+ );
+
+ const center = container.querySelector(`.${styles.center}`);
+ expect(center).toBeInTheDocument();
+ });
+ });
+
describe('Navbar.End', () => {
it('renders end section content', () => {
render(
@@ -369,18 +410,21 @@ describe('Navbar', () => {
expect(containerEl).toBeInTheDocument();
});
- it('positions Start and End correctly', () => {
+ it('positions Start, Center, and End correctly', () => {
const { container } = render(
Start
+ Center
End
);
const start = container.querySelector(`.${styles.start}`);
+ const center = container.querySelector(`.${styles.center}`);
const end = container.querySelector(`.${styles.end}`);
expect(start).toBeInTheDocument();
+ expect(center).toBeInTheDocument();
expect(end).toBeInTheDocument();
});
});
diff --git a/packages/raystack/components/navbar/navbar-root.tsx b/packages/raystack/components/navbar/navbar-root.tsx
index 6700cd388..84c13a3d4 100644
--- a/packages/raystack/components/navbar/navbar-root.tsx
+++ b/packages/raystack/components/navbar/navbar-root.tsx
@@ -7,15 +7,17 @@ import styles from './navbar.module.css';
export interface NavbarRootProps extends ComponentPropsWithoutRef<'nav'> {
sticky?: boolean;
+ shadow?: boolean;
}
export const NavbarRoot = forwardRef, NavbarRootProps>(
- ({ className, sticky = false, children, ...props }, ref) => {
+ ({ className, sticky = false, shadow = true, children, ...props }, ref) => {
return (