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

Commit

Permalink
Merge d4dd9d7 into f133ee0
Browse files Browse the repository at this point in the history
  • Loading branch information
Jon Quach committed Mar 1, 2019
2 parents f133ee0 + d4dd9d7 commit 2d8e2fa
Show file tree
Hide file tree
Showing 42 changed files with 892 additions and 261 deletions.
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
"react-router-dom": "4.0.0-4.3.1"
},
"dependencies": {
"@helpscout/fancy": "2.2.4",
"@helpscout/fancy": "2.2.5",
"@helpscout/react-utils": "1.0.6",
"@helpscout/wedux": "0.0.11",
"@seedcss/seed-button": "0.0.6",
Expand Down
2 changes: 1 addition & 1 deletion src/@types/helpscout__fancy/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
declare module '@helpscout/fancy' {
function styled(component: any): any
function styled(component: any, options?: any): any
export function ThemeProvider(component: any): any
export default styled
}
2 changes: 1 addition & 1 deletion src/components/Message/__tests__/Action.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,6 @@ describe('Context', () => {
let o = wrapper.find(ui.text).first()

expect(o.getDOMNode().classList.contains('is-12')).toBe(true)
expect(o.getDOMNode().classList.contains('is-faint')).toBe(true)
expect(o.getDOMNode().classList.contains('is-shade-faint')).toBe(true)
})
})
133 changes: 133 additions & 0 deletions src/components/Nav/Nav.Item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import * as React from 'react'
import propConnect from '../PropProvider/propConnect'
import getValidProps from '@helpscout/react-utils/dist/getValidProps'
import Flexy from '../Flexy'
import Icon from '../Icon'
import Tooltip from '../Tooltip'
import NavLink from '../NavLink'
import { classNames } from '../../utilities/classNames'
import { noop } from '../../utilities/other'
import {
ItemUI,
ContentUI,
GhostTitleUI,
TitleUI,
IndicatorUI,
ErrorWrapperUI,
} from './Nav.css'
import { ITEM_COMPONENT_KEY } from './Nav.utils'

export interface Props {
children?: any
className?: string
disabled: boolean
error: string
exact: boolean
href?: string
innerRef: (node: HTMLElement) => void
isActive?: any
location?: any
to?: string
strict?: boolean
}

export class Item extends React.Component<Props> {
static className = 'c-NavItem'
static contentClassName = 'c-NavItemContent'
static defaultProps = {
disabled: false,
error: '',
exact: true,
innerRef: noop,
}

getClassName() {
const { className, disabled } = this.props
return classNames(Item.className, disabled && 'is-disabled', className)
}

getLinkProps() {
const { disabled, exact, isActive, location, strict, to } = this.props

return {
disabled,
exact,
isActive,
location,
strict,
to,
}
}

renderError() {
const { error } = this.props
if (!error) return

return (
<ErrorWrapperUI>
<Tooltip title={error}>
<Icon name="alert" state="error" className="c-NavItemErrorIcon" />
</Tooltip>
</ErrorWrapperUI>
)
}

renderContent = ({ isActive }) => {
const { children } = this.props
const componentClassName = classNames(
Item.contentClassName,
isActive && 'is-active'
)

return (
<ContentUI className={componentClassName}>
<Flexy gap="xs">
<Flexy.Block>
<TitleUI
size="13"
lineHeightReset
isActive={isActive}
className="c-NavItemTitle"
>
{children}
</TitleUI>
<GhostTitleUI
size="13"
lineHeightReset
aria-hidden
className="c-NavItemTitleGhost"
>
{children}
</GhostTitleUI>
</Flexy.Block>
{this.renderError()}
</Flexy>
<IndicatorUI className="c-NavItemIndicator" isActive={isActive} />
</ContentUI>
)
}

render() {
const { children, href, innerRef, to, ...rest } = this.props

return (
<ItemUI
{...getValidProps(rest)}
className={this.getClassName()}
innerRef={innerRef}
>
<NavLink
{...this.getLinkProps()}
className="c-NavItemLink"
render={this.renderContent}
/>
</ItemUI>
)
}
}

const PropConnectedComponent = propConnect(ITEM_COMPONENT_KEY, { pure: false })(
Item
)

export default PropConnectedComponent
97 changes: 97 additions & 0 deletions src/components/Nav/Nav.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import styled from '../styled'
import Flexy from '../Flexy'
import Text from '../Text'
import { getColor } from '../../styles/utilities/color'
import baseStyles from '../../styles/resets/baseStyles.css'

export const config = {
indicatorTransition: 'opacity 100ms ease',
}

export const NavUI = styled('nav', { pure: false })`
--BlueConfigGlobalFontSize: 14px;
${baseStyles};
display: flex;
margin: 0 auto;
`

export const ListUI = styled('ul', { pure: false })`
${baseStyles};
display: flex;
list-style: none;
margin: 0 auto;
padding: 0;
`

export const ItemUI = styled('li', { pure: false })`
padding: 0 10px;
transform: translateZ(0);
&.is-disabled {
pointer-events: none;
opacity: 0.6;
}
.c-NavItemLink {
color: ${getColor('charcoal.200')};
display: block;
text-decoration: none !important;
&:hover {
color: ${getColor('charcoal.300')};
}
&.is-active {
color: ${getColor('charcoal.500')};
}
}
`

export const ContentUI = styled('div')`
padding: 20px 7px 20px 5px;
position: relative;
text-align: center;
`

export const TitleUI = styled(Text)`
display: block;
${({ isActive }) =>
isActive &&
`
font-weight: 500;
`};
`

export const GhostTitleUI = styled(Text)`
display: block;
font-weight: 500;
height: 0;
visibility: hidden;
`

export const ErrorWrapperUI = styled(Flexy.Item)`
height: 0;
position: relative;
top: -10px;
width: 20px;
`

export const IndicatorUI = styled('div')`
background: ${getColor('blue.500')};
border-radius: 9999px;
bottom: 0;
height: 2px;
opacity: 0;
left: 0;
position: absolute;
transition: ${config.indicatorTransition};
width: 100%;
will-change: opacity;
${({ isActive }) =>
isActive &&
`
opacity: 1;
`};
`
46 changes: 46 additions & 0 deletions src/components/Nav/Nav.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import * as React from 'react'
import propConnect from '../PropProvider/propConnect'
import getValidProps from '@helpscout/react-utils/dist/getValidProps'
import Item from './Nav.Item'
import { classNames } from '../../utilities/classNames'
import { noop } from '../../utilities/other'
import { NavUI, ListUI } from './Nav.css'
import { COMPONENT_KEY } from './Nav.utils'

export interface Props {
className?: string
children?: any
innerRef: (node: HTMLElement) => void
}

export class Nav extends React.Component<Props> {
static className = 'c-Nav'
static defaultProps = {
innerRef: noop,
}

static Item = Item

getClassName() {
const { className } = this.props
return classNames(Nav.className, className)
}

render() {
const { children, innerRef, ...rest } = this.props

return (
<NavUI
{...getValidProps(rest)}
className={this.getClassName()}
innerRef={innerRef}
>
<ListUI className="c-NavList">{children}</ListUI>
</NavUI>
)
}
}

const PropConnectedComponent = propConnect(COMPONENT_KEY, { pure: false })(Nav)

export default PropConnectedComponent
2 changes: 2 additions & 0 deletions src/components/Nav/Nav.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const COMPONENT_KEY = 'Nav'
export const ITEM_COMPONENT_KEY = 'NavItem'
10 changes: 10 additions & 0 deletions src/components/Nav/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Nav

This component is provides navigation interactions with support for [react-router](https://github.com/ReactTraining/react-router).

## Components

`Nav` is comprised of smaller sub-components:

* [Nav](./docs/Nav.md)
* [Item](./docs/Item.md)

0 comments on commit 2d8e2fa

Please sign in to comment.