Skip to content

Commit

Permalink
Merge pull request #72 from brainstormforce/organism/top-navbar
Browse files Browse the repository at this point in the history
SUR-280 Organism: Implement Top navbar
  • Loading branch information
vrundakansara authored Sep 26, 2024
2 parents f998a7e + 34aecdb commit 0060bf1
Show file tree
Hide file tree
Showing 10 changed files with 333 additions and 4 deletions.
2 changes: 1 addition & 1 deletion dist/force-ui-rtl.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/force-ui.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array('react', 'react-dom'), 'version' => '38ce5b3d1b5c65ab2fac');
<?php return array('dependencies' => array('react', 'react-dom'), 'version' => 'db1bc2308688800294fc');
2 changes: 1 addition & 1 deletion dist/force-ui.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/force-ui.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ export { default as EditorInput } from './editor-input/index';
export { default as ProgressSteps } from './progress-steps/index';
export { default as Skeleton } from './skeleton/index';
export { default as Menu } from './menu-item/index';
export { default as Topbar } from './topbar/index';
1 change: 1 addition & 0 deletions src/components/topbar/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './topbar.jsx';
139 changes: 139 additions & 0 deletions src/components/topbar/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# Topbar Component Documentation

## Description

The `Topbar` is a flexible navigation bar component that provides three sections: `Left`, `Middle`, and `Right`. It allows easy alignment and placement of items within each section.

## `Topbar` Props

### `children`
- **Type:** `ReactNode`
- **Description:** Elements to render inside the Topbar container, typically the `Topbar.Left`, `Topbar.Middle`, and `Topbar.Right` components.

### gap
- **Type:** `string`
- **Default:** `"lg"`
- **Description:** Defines the gap between Topbar sections.
- `"0"`
- `"xxs"`
- `"xs"`
- `"sm"`
- `"md"`
- `"lg"`
- `"xl"`
- `"2xl"`

### `className`
- **Type:** `string`
- **Description:** Additional classes to customize the Topbar container's styles.

## `Topbar.Left` Props

### `children`
- **Type:** `ReactNode`
- **Description:** Elements to render inside the `Topbar.Left` container, usually icons, logos, or navigation items.

### gap
- **Type:** `string`
- **Default:** `"sm"`
- **Description:** Defines the gap between Topbar.Left items.
- `"0"`
- `"xxs"`
- `"xs"`
- `"sm"`
- `"md"`
- `"lg"`
- `"xl"`
- `"2xl"`

## `Topbar.Middle` Props

### `align`
- **Type:** `string`
- **Default:** `"center"`
- **Description:** Defines how the content inside the Middle section is aligned. Options include:
- `"left"`
- `"center"`
- `"right"`

### `children`
- **Type:** `ReactNode`
- **Description:** Elements to render inside the `Topbar.Middle` container, usually navigation links, buttons, or other interactive elements.

### gap
- **Type:** `string`
- **Default:** `"md"`
- **Description:** Defines the gap between Topbar.Middle items.
- `"0"`
- `"xxs"`
- `"xs"`
- `"sm"`
- `"md"`
- `"lg"`
- `"xl"`
- `"2xl"`

## `Topbar.Right` Props

### `children`
- **Type:** `ReactNode`
- **Description:** Elements to render inside the `Topbar.Right` container, typically icons, user profile, badges, or help buttons.

### gap
- **Type:** `string`
- **Default:** `"sm"`
- **Description:** Defines the gap between Topbar.Right items.
- `"0"`
- `"xxs"`
- `"xs"`
- `"sm"`
- `"md"`
- `"lg"`
- `"xl"`
- `"2xl"`

## `Topbar.Item` Props

### `children`
- **Type:** `ReactNode`
- **Description:** Content or components to render inside the `Topbar.Item`.

### `className`
- **Type:** `string`
- **Description:** Additional classes to customize the Item styling.

```jsx
<Topbar>
<Topbar.Left>
<Topbar.Item>
<Logo />
</Topbar.Item>
</Topbar.Left>

<Topbar.Middle align="left">
<Topbar.Item>
<div className='flex gap-2'>
<div>Nav Item 1</div>
<div>Nav item 2</div>
<div>Nav Item 3</div>
</div>
</Topbar.Item>
<Topbar.Item>
<Button>Upgrade to Pro</Button>
</Topbar.Item>
</Topbar.Middle>

<Topbar.Right>
<Topbar.Item>
<Badge />
</Topbar.Item>
<Topbar.Item className='flex gap-2'>
<CircleHelp />
<Megaphone />
</Topbar.Item>
<Topbar.Item>
<Avatar />
</Topbar.Item>
</Topbar.Right>
</Topbar>
```
39 changes: 39 additions & 0 deletions src/components/topbar/topbar.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react';
import { cn, getGapClass } from '@/utilities/functions';

const Topbar = ( { children, gap = 'lg', className, ...props } ) => {
return (
<div className={ cn( 'w-full flex items-center justify-between bg-background-primary p-5 min-h-16', getGapClass( gap ), className ) } { ...props }>
{ children }
</div>
);
};

const Left = ( { gap = 'sm', children, className } ) => {
return <div className={ cn( 'flex items-center', getGapClass( gap ), className ) }>{ children }</div>;
};

const Middle = ( { gap = 'md', children, align = 'center', className } ) => {
const alignmentClass = {
left: 'justify-start',
center: 'justify-center',
right: 'justify-end',
}?.[ align ];

return <div className={ cn( 'flex items-center grow', getGapClass( gap ), alignmentClass, className ) }>{ children }</div>;
};

const Right = ( { gap = 'sm', children, className } ) => {
return <div className={ cn( 'flex items-center', getGapClass( gap ), className ) }>{ children }</div>;
};

const Item = ( { children, className } ) => {
return <div className={ cn( 'flex items-center [&>svg]:block h-full', className ) }>{ children }</div>;
};

Topbar.Left = Left;
Topbar.Middle = Middle;
Topbar.Right = Right;
Topbar.Item = Item;

export default Topbar;
134 changes: 134 additions & 0 deletions src/components/topbar/topbar.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import React from 'react';
import Topbar from './topbar.jsx';
import Button from '../button/button.jsx';
import { ArrowUpRight, CircleHelp, Megaphone, User } from 'lucide-react';
import Badge from '../badge/badge.jsx';
import Avatar from '../avatar/avatar.jsx';

export default {
title: 'Organisms/Topbar',
component: Topbar,
tags: [ 'autodocs' ],
argTypes: {
gap: {
description: 'Defines the gap between Topbar sections.',
control: { type: 'select' },
options: [ '0', 'xxs', 'xs', 'sm', 'md', 'lg', 'xl', '2xl' ],
table: {
type: { summary: 'string' },
},
},
},
};

export const WithLeftAlignment = ( args ) => (
<Topbar gap={ args.gap }>
<Topbar.Left>
<Topbar.Item>
<svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fillRule="evenodd" clipRule="evenodd" d="M12.5 24C19.1275 24 24.5 18.6273 24.5 11.9999C24.5 5.37255 19.1275 0 12.5 0C5.87259 0 0.5 5.37255 0.5 11.9999C0.5 18.6273 5.87259 24 12.5 24ZM12.5517 5.99996C11.5882 5.99996 10.2547 6.55101 9.5734 7.23073L7.7229 9.07688H16.9465L20.0307 5.99996H12.5517ZM15.4111 16.7692C14.7298 17.4489 13.3964 17.9999 12.4328 17.9999H4.95388L8.03804 14.923H17.2616L15.4111 16.7692ZM18.4089 10.6153H6.18418L5.60673 11.1923C4.23941 12.423 4.64495 13.3846 6.5598 13.3846H18.8176L19.3952 12.8076C20.7492 11.5841 20.3237 10.6153 18.4089 10.6153Z" fill="#0D7EE8" />
</svg>
</Topbar.Item>
</Topbar.Left>

<Topbar.Middle align="left">
<Topbar.Item>
<div className="flex gap-2">
<div>Nav Item 1</div>
<div>Nav Item 2</div>
<div>Nav Item 3</div>
</div>
</Topbar.Item>
<Topbar.Item>
<Button
variant="ghost"
icon={ <ArrowUpRight /> }
iconPosition="right"
>
Upgrade to Pro
</Button>
</Topbar.Item>
</Topbar.Middle>

<Topbar.Right>
<Topbar.Item>
<Badge label="V 0.0 2" size="xs" variant="neutral" closable={ false } />
</Topbar.Item>
<Topbar.Item className="gap-2">
<CircleHelp />
<Megaphone />
</Topbar.Item>
<Topbar.Item>
<Avatar size="sm" border="ring">
<User />
</Avatar>
</Topbar.Item>
</Topbar.Right>
</Topbar>
);

WithLeftAlignment.storyName = 'Topbar with Left-Aligned Middle Section';

export const WithCenterAlignment = ( args ) => (
<Topbar gap={ args.gap }>
<Topbar.Left>
<Topbar.Item>
<svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fillRule="evenodd" clipRule="evenodd" d="M12.5 24C19.1275 24 24.5 18.6273 24.5 11.9999C24.5 5.37255 19.1275 0 12.5 0C5.87259 0 0.5 5.37255 0.5 11.9999C0.5 18.6273 5.87259 24 12.5 24ZM12.5517 5.99996C11.5882 5.99996 10.2547 6.55101 9.5734 7.23073L7.7229 9.07688H16.9465L20.0307 5.99996H12.5517ZM15.4111 16.7692C14.7298 17.4489 13.3964 17.9999 12.4328 17.9999H4.95388L8.03804 14.923H17.2616L15.4111 16.7692ZM18.4089 10.6153H6.18418L5.60673 11.1923C4.23941 12.423 4.64495 13.3846 6.5598 13.3846H18.8176L19.3952 12.8076C20.7492 11.5841 20.3237 10.6153 18.4089 10.6153Z" fill="#0D7EE8" />
</svg>
</Topbar.Item>
</Topbar.Left>

<Topbar.Middle align="center">
<Topbar.Item>
<div className="flex gap-2">
<div>Nav Item 1</div>
<div>Nav Item 2</div>
<div>Nav Item 3</div>
</div>
</Topbar.Item>
</Topbar.Middle>

<Topbar.Right>
<Topbar.Item>
<Avatar size="sm" border="ring">
<User />
</Avatar>
</Topbar.Item>
</Topbar.Right>
</Topbar>
);

WithCenterAlignment.storyName = 'Topbar with Center-Aligned Middle Section';

export const WithRightAlignment = ( args ) => (
<Topbar gap={ args.gap }>
<Topbar.Left>
<Topbar.Item>
<svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fillRule="evenodd" clipRule="evenodd" d="M12.5 24C19.1275 24 24.5 18.6273 24.5 11.9999C24.5 5.37255 19.1275 0 12.5 0C5.87259 0 0.5 5.37255 0.5 11.9999C0.5 18.6273 5.87259 24 12.5 24ZM12.5517 5.99996C11.5882 5.99996 10.2547 6.55101 9.5734 7.23073L7.7229 9.07688H16.9465L20.0307 5.99996H12.5517ZM15.4111 16.7692C14.7298 17.4489 13.3964 17.9999 12.4328 17.9999H4.95388L8.03804 14.923H17.2616L15.4111 16.7692ZM18.4089 10.6153H6.18418L5.60673 11.1923C4.23941 12.423 4.64495 13.3846 6.5598 13.3846H18.8176L19.3952 12.8076C20.7492 11.5841 20.3237 10.6153 18.4089 10.6153Z" fill="#0D7EE8" />
</svg>
</Topbar.Item>
</Topbar.Left>

<Topbar.Middle align="right">
<Topbar.Item>
<div className="flex gap-2">
<div>Nav Item 1</div>
<div>Nav Item 2</div>
<div>Nav Item 3</div>
</div>
</Topbar.Item>
</Topbar.Middle>

<Topbar.Right>
<Topbar.Item>
<Avatar size="sm" border="ring">
<User />
</Avatar>
</Topbar.Item>
</Topbar.Right>
</Topbar>
);

WithRightAlignment.storyName = 'Topbar with Right-Aligned Middle Section';
15 changes: 15 additions & 0 deletions src/utilities/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,18 @@ export function prefix() {
* @return {string} - Merged TailwindCSS classes.
*/
export const cn = ( ...classNames ) => twMerge( clsx( ...classNames ) );

export const getGapClass = ( gap ) => {
const gapClasses = {
0: 'gap-0',
xxs: 'gap-1',
xs: 'gap-2',
sm: 'gap-3',
md: 'gap-4',
lg: 'gap-5',
xl: 'gap-6',
'2xl': 'gap-8',
};

return gapClasses[ gap ] || gapClasses.md;
};

0 comments on commit 0060bf1

Please sign in to comment.