Skip to content
This repository has been archived by the owner on Jan 9, 2023. It is now read-only.

Commit

Permalink
feat(navbar): support navbar items horizontal position w array order
Browse files Browse the repository at this point in the history
fix #225
  • Loading branch information
ocBruno committed Jan 18, 2020
1 parent 64bbb29 commit f80382f
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 103 deletions.
116 changes: 63 additions & 53 deletions src/components/Navbar/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,78 +5,88 @@ import Form from 'react-bootstrap/Form'
import FormControl from 'react-bootstrap/FormControl'
import NavDropdown from 'react-bootstrap/NavDropdown'
import { Button } from '../Button'
import { NavLink, Brand, NavLinkElement, Search } from './interfaces'
import { NavLink, NavBrand, NavLinkList, NavSearch } from './interfaces'

interface Props extends React.Props<any> {
/** Determines the navbar background color */
bg?: string
/** Determines the letters color. It should be combined with the background color (bg) */
variant?: 'light' | 'dark'
/** Determines the links names, theirs onClick methods and paths. It has children array which contain links to be used on a dropdown. */
navLinks: NavLink[]
/** Determines the hospital/clinic name to be shown at the navbar */
brand: Brand
/** Defines the properties of the search element */
search: Search
navItems: (NavBrand | NavLink | NavLinkList | NavSearch)[]
}

/**
* Used to redirect users to the main topics.
*/
const Navbar = (props: Props) => {
const { bg, variant, navLinks, brand, search } = props
const { bg, variant, navItems } = props

const getNavItems = (subLink: NavLinkElement, index: number) => (
<NavDropdown.Item href={subLink.href ? subLink.href : ''} key={index} onClick={subLink.onClick}>
{subLink.label}
const getNavListLinks = (link: NavLink, index: number) => (
<NavDropdown.Item href={link.href ? link.href : ''} key={index} onClick={link.onClick}>
{link.label}
</NavDropdown.Item>
)

const getNavLinks = (link: NavLink, index: number) => {
if (link.children.length === 0) {
return (
<Nav.Link onClick={link.onClick} key={index}>
{link.label}
</Nav.Link>
)
}

return (
<NavDropdown title={link.label} id="collasible-nav-dropdown" key={index}>
{link.children.map((subLink, i) => getNavItems(subLink, i))}
</NavDropdown>
)
}
const getNavSearch = (search: NavSearch) => (
<Nav>
<Form inline>
<FormControl
type="text"
placeholder={search.placeholderText || 'Search'}
className="mr-sm-2"
onChange={search.onChangeInput}
/>
<Button color={search.buttonColor || 'primary'} onClick={search.onClickButton}>
{search.buttonText || 'Search'}
</Button>
</Form>
</Nav>
)
const getNavList = (list: NavLinkList, index: number) => (
<NavDropdown title={list.label} id="collasible-nav-dropdown" key={index}>
{list.children.map((subLink, i) => getNavListLinks(subLink, i))}
</NavDropdown>
)
const getNavBrand = (brand: NavBrand) => (
<NavbarRB.Brand onClick={brand.onClick} style={{ cursor: 'pointer' }}>
{brand.src ? (
<img
alt={brand.label}
src={brand.src}
width="28"
height="28"
className="d-inline-block align-top mr-3"
/>
) : (
''
)}
<span style={{ color: brand.color }}>{`${brand.label}`}</span>
</NavbarRB.Brand>
)
const getNavLink = (link: NavLink, index: number) => (
<Nav.Link onClick={link.onClick} key={index}>
{link.label}
</Nav.Link>
)
return (
<NavbarRB bg={bg} variant={variant}>
<NavbarRB.Brand onClick={brand.onClick} style={{ cursor: 'pointer' }}>
{brand.src ? (
<img
alt={brand.label}
src={brand.src}
width="28"
height="28"
className="d-inline-block align-top mr-3"
/>
) : (
''
)}
<span style={{ color: brand.color }}>{`${brand.label}`}</span>
</NavbarRB.Brand>
<NavbarRB.Collapse id="responsive-navbar-nav">
<Nav className="mr-auto">{navLinks.map((link, index) => getNavLinks(link, index))}</Nav>
<Nav>
<Form inline>
<FormControl
type="text"
placeholder={search.placeholderText || 'Search'}
className="mr-sm-2"
onChange={search.onChangeInput}
/>
<Button color={search.buttonColor || 'primary'} onClick={search.onClickButton}>
{search.buttonText || 'Search'}
</Button>
</Form>
<Nav className="mr-auto">
{navItems.map((item, index) => {
if ((item as NavBrand).type === 'brand') {
return getNavBrand(item as NavBrand)
}
if ((item as NavLink).type === 'link') {
return getNavLink(item as NavLink, index)
}
if ((item as NavSearch).type === 'search') {
return getNavSearch(item as NavSearch)
}
if ((item as NavLinkList).type === 'link-list') {
return getNavList(item as NavLinkList, index)
}
return null
})}
</Nav>
</NavbarRB.Collapse>
</NavbarRB>
Expand Down
14 changes: 9 additions & 5 deletions src/components/Navbar/interfaces.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export interface Brand {
export interface NavBrand extends NavItem {
/** Clinic/Hospital name */
label: string
/** Label color */
Expand All @@ -9,7 +9,11 @@ export interface Brand {
onClick?: (event: React.MouseEvent<any>) => void
}

export interface NavLinkElement {
export interface NavItem {
type: string
}

export interface NavLink extends NavItem {
/** The link name */
label: string
/** A click handle which will redirect the user to whenever it is clicked */
Expand All @@ -18,12 +22,12 @@ export interface NavLinkElement {
href?: string
}

export interface NavLink extends NavLinkElement {
export interface NavLinkList extends NavLink {
/** An array to hold a dropdown Links */
children: NavLinkElement[]
children: Array<NavLink>
}

export interface Search {
export interface NavSearch extends NavItem {
/** Defines the placeholder text. */
placeholderText?: string
/** Defines the button text. */
Expand Down
97 changes: 52 additions & 45 deletions stories/navbar.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,69 +14,37 @@ storiesOf('Navbar', module)
.add('Navbar', () => (
<div>
<Navbar
brand={{
label: 'Hospital',
onClick: () => {
Toast('success', 'Brand button clicked!!', 'Success')
},
}}
search={{
placeholderText: 'Custom',
buttonText: 'Text',
buttonColor: 'secondary',
onClickButton: () => {
Toast('success', 'Button clicked!!', 'Success')
},
onChangeInput: () => {
Toast('success', 'Search box changed!!', 'Success')
navItems={[
{
type: 'brand',
label: 'Hospital',
onClick: () => {
Toast('success', 'Brand button clicked!!', 'Success')
},
},
}}
navLinks={[
{
type: 'link',
label: 'Link',
onClick: () => {
Toast('success', 'NavLink clicked!!', 'Success')
},
children: [],
},
]}
/>

<br />

<Navbar
brand={{
label: 'HospitalRun',
src:
'https://raw.githubusercontent.com/HospitalRun/hospitalrun.github.io/master/favicon.png',
onClick: () => {
Toast('success', 'Brand button clicked!!', 'Success')
},
}}
search={{
onClickButton: () => {
Toast('success', 'Button clicked!!', 'Success')
},
onChangeInput: () => {
Toast('success', 'Search box changed!!', 'Success')
},
}}
bg="light"
variant="light"
navLinks={[
{
label: 'Dropdown',
type: 'link-list',
label: 'Link',
onClick: () => {
Toast('success', 'NavLink clicked!!', 'Success')
},
children: [
{
type: 'link',
label: 'Sublink1',
onClick: () => {
Toast('success', 'Sublink1 clicked!!', 'Success')
},
},
{
type: 'link',
label: 'Sublink2',
onClick: () => {
Toast('success', 'Sublink2 clicked!!', 'Success')
Expand All @@ -85,11 +53,50 @@ storiesOf('Navbar', module)
],
},
{
type: 'search',
placeholderText: 'Custom',
buttonText: 'Text',
buttonColor: 'secondary',
onClickButton: () => {
Toast('success', 'Button clicked!!', 'Success')
},
onChangeInput: () => {
Toast('success', 'Search box changed!!', 'Success')
},
},
]}
/>

<br />

<Navbar
bg="light"
variant="light"
navItems={[
{
type: 'brand',
label: 'HospitalRun',
src:
'https://raw.githubusercontent.com/HospitalRun/hospitalrun.github.io/master/favicon.png',
onClick: () => {
Toast('success', 'Brand button clicked!!', 'Success')
},
},
{
type: 'link',
label: 'Link',
onClick: () => {
Toast('success', 'NavLink clicked!!', 'Success')
},
children: [],
},
{
type: 'search',
onClickButton: () => {
Toast('success', 'Button clicked!!', 'Success')
},
onChangeInput: () => {
Toast('success', 'Search box changed!!', 'Success')
},
},
]}
/>
Expand Down

0 comments on commit f80382f

Please sign in to comment.