Introduce Avatar component for displaying profile pictures

pull/10616/head
Alex P 2018-09-25 15:06:58 -07:00
parent e0c252c845
commit 9817d76f9a
6 changed files with 119 additions and 25 deletions

View File

@ -47,6 +47,15 @@ $nav--bg-accent: $c-comet;
}
}
.nav--avatar {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
transition:
box-shadow 0.4s ease;
}
.nav--item-menu {
position: absolute;
top: 0;
@ -86,6 +95,12 @@ $nav--bg-accent: $c-comet;
// Active State
.nav--item.active {
.nav--avatar {
box-shadow:
0 0 9px $c-laser,
0 0 15px $c-ocean,
0 0 20px $c-amethyst;
}
.nav--item-icon {
color: $g20-white;
background-color: $g4-onyx;
@ -98,6 +113,12 @@ $nav--bg-accent: $c-comet;
// Active Hover State
.nav--item.active:hover {
.nav--avatar {
box-shadow:
0 0 9px $c-yeti,
0 0 15px $c-hydrogen,
0 0 20px $c-laser;
}
.nav--item-icon {
background-color: $nav--bg;
text-shadow:

View File

@ -4,21 +4,17 @@ import _ from 'lodash'
// Components
import NavMenuItem from 'src/page_layout/components/NavMenuItem'
import Avatar from 'src/shared/components/avatar/Avatar'
// Types
import {NavItem, NavItemType} from 'src/page_layout/containers/Nav'
import {ErrorHandling} from 'src/shared/decorators/errors'
import {IconFont} from 'src/clockface'
interface Props {
navItems: NavItem[]
}
interface NavItem {
title: string
link: string
icon: string
location: string
highlightWhen: string[]
}
@ErrorHandling
class NavMenu extends PureComponent<Props> {
constructor(props) {
@ -30,20 +26,40 @@ class NavMenu extends PureComponent<Props> {
return (
<nav className="nav">
{navItems.map(({title, highlightWhen, icon, link, location}) => (
<NavMenuItem
key={`navigation--${title}`}
title={title}
highlightWhen={highlightWhen}
link={link}
location={location}
>
<span className={`icon sidebar--icon ${icon}`} />
</NavMenuItem>
))}
{navItems.map(
({title, highlightWhen, icon, link, location, type, image}) => (
<NavMenuItem
key={`navigation--${title}`}
title={title}
highlightWhen={highlightWhen}
link={link}
location={location}
>
{this.renderIconOrGraphic(type, icon, image)}
</NavMenuItem>
)
)}
</nav>
)
}
private renderIconOrGraphic = (
type: NavItemType,
icon?: IconFont,
image?: string
): JSX.Element => {
if (type === NavItemType.Avatar) {
return (
<Avatar
imageURI={image}
diameterPixels={30}
customClass="nav--avatar"
/>
)
} else if (type === NavItemType.Icon) {
return <span className={`icon sidebar--icon ${icon}`} />
}
}
}
export default NavMenu

View File

@ -9,6 +9,10 @@ import NavMenu from 'src/page_layout/components/NavMenu'
// Types
import {Source} from 'src/types/v2'
import {IconFont} from 'src/clockface'
// MOCK DATA
import {LeroyJenkins} from 'src/user/mockUserData'
import {ErrorHandling} from 'src/shared/decorators/errors'
@ -17,10 +21,17 @@ interface Props extends WithRouterProps {
isHidden: boolean
}
interface NavItem {
export enum NavItemType {
Icon = 'icon',
Avatar = 'avatar',
}
export interface NavItem {
title: string
link: string
icon: string
type: NavItemType
icon?: IconFont
image?: string
location: string
highlightWhen: string[]
}
@ -46,33 +57,45 @@ class SideNav extends PureComponent<Props> {
return [
{
type: NavItemType.Icon,
title: 'Status',
link: `/${this.sourceParam}`,
icon: 'cubo-uniform',
icon: IconFont.Cubouniform,
location: location.pathname,
highlightWhen: ['status'],
},
{
type: NavItemType.Icon,
title: 'Flux Builder',
link: `/delorean/${this.sourceParam}`,
icon: 'capacitor2',
icon: IconFont.Capacitor,
location: location.pathname,
highlightWhen: ['delorean'],
},
{
type: NavItemType.Icon,
title: 'Dashboards',
link: `/dashboards/${this.sourceParam}`,
icon: 'dash-j',
icon: IconFont.DashJ,
location: location.pathname,
highlightWhen: ['dashboards'],
},
{
type: NavItemType.Icon,
title: 'Configuration',
link: `/manage-sources/${this.sourceParam}`,
icon: 'wrench',
icon: IconFont.Wrench,
location: location.pathname,
highlightWhen: ['manage-sources'],
},
{
type: NavItemType.Avatar,
title: 'My Profile',
link: `/user`,
image: LeroyJenkins.avatar,
location: location.pathname,
highlightWhen: ['user'],
},
]
}

View File

@ -0,0 +1,11 @@
/*
Avatar Styles
------------------------------------------------------------------------------
Used to represent organizations or users
*/
.avatar {
border-radius: 50%;
background-position: center center;
background-size: 100% 100%;
}

View File

@ -0,0 +1,22 @@
// Libraries
import React, {SFC} from 'react'
import classnames from 'classnames'
interface Props {
imageURI: string
diameterPixels: number
customClass?: string
}
const Avatar: SFC<Props> = ({imageURI, diameterPixels, customClass}) => (
<div
className={classnames('avatar', {[customClass]: customClass})}
style={{
width: `${diameterPixels}px`,
height: `${diameterPixels}px`,
backgroundImage: `url(${imageURI})`,
}}
/>
)
export default Avatar

View File

@ -22,6 +22,7 @@
// Components
// TODO: Import these styles into their respective components instead of this stylesheet
@import 'src/page_layout/PageLayout';
@import 'src/shared/components/avatar/Avatar';
@import 'src/shared/components/fancy_scrollbar/FancyScrollbar';
@import 'src/shared/components/notifications/Notifications';
@import 'src/shared/components/threesizer/Threesizer';