gestalt
Advanced tools
Comparing version 0.19.1 to 0.19.2
{ | ||
"name": "gestalt", | ||
"version": "0.19.1", | ||
"version": "0.19.2", | ||
"license": "SEE LICENSE IN LICENSE", | ||
@@ -5,0 +5,0 @@ "homepage": "https://pinterest.github.io/gestalt", |
@@ -89,5 +89,5 @@ // @flow | ||
<Box xs={{ display: 'flex' }} justifyContent="between" alignItems="center" wrap> | ||
<PaddingSwatch padding={2} label="2" /> | ||
<PaddingSwatch padding={{ x: 2 }} label="{x: 2}" /> | ||
<PaddingSwatch padding={{ y: 2 }} label="{y: 2}" /> | ||
<PaddingSwatch padding={1} label="1" /> | ||
<PaddingSwatch padding={{ x: 1 }} label="{x: 1}" /> | ||
<PaddingSwatch padding={{ y: 1 }} label="{y: 1}" /> | ||
</Box> | ||
@@ -94,0 +94,0 @@ ); |
@@ -12,1 +12,49 @@ /* eslint-env jest */ | ||
}); | ||
test('Box has correct *-hide classes when display is false', () => { | ||
const tree = create( | ||
<Box | ||
xs={{ display: false }} | ||
sm={{ display: false }} | ||
md={{ display: false }} | ||
lg={{ display: false }} | ||
/> | ||
).toJSON(); | ||
expect(tree).toMatchSnapshot(); | ||
}); | ||
test('Box has correct *-flex classes when display is flex', () => { | ||
const tree = create( | ||
<Box | ||
xs={{ display: 'flex' }} | ||
sm={{ display: 'flex' }} | ||
md={{ display: 'flex' }} | ||
lg={{ display: 'flex' }} | ||
/> | ||
).toJSON(); | ||
expect(tree).toMatchSnapshot(); | ||
}); | ||
test('Box has correct *-flex-column classes when display is flexColumn', () => { | ||
const tree = create( | ||
<Box | ||
xs={{ display: 'flexColumn' }} | ||
sm={{ display: 'flexColumn' }} | ||
md={{ display: 'flexColumn' }} | ||
lg={{ display: 'flexColumn' }} | ||
/> | ||
).toJSON(); | ||
expect(tree).toMatchSnapshot(); | ||
}); | ||
test('Box has correct *-inline-block classes when display is inlineBlock', () => { | ||
const tree = create( | ||
<Box | ||
xs={{ display: 'inlineBlock' }} | ||
sm={{ display: 'inlineBlock' }} | ||
md={{ display: 'inlineBlock' }} | ||
lg={{ display: 'inlineBlock' }} | ||
/> | ||
).toJSON(); | ||
expect(tree).toMatchSnapshot(); | ||
}); |
@@ -86,3 +86,3 @@ // @flow | ||
value.column ? column(value.column) : identity(), | ||
value.display ? display(value.display) : identity() | ||
typeof value.display !== 'undefined' ? display(value.display) : identity() | ||
))); | ||
@@ -95,3 +95,3 @@ }; | ||
value.column ? column(value.column) : identity(), | ||
value.display ? display(value.display) : identity() | ||
typeof value.display !== 'undefined' ? display(value.display) : identity() | ||
))); | ||
@@ -104,3 +104,3 @@ }; | ||
value.column ? column(value.column) : identity(), | ||
value.display ? display(value.display) : identity() | ||
typeof value.display !== 'undefined' ? display(value.display) : identity() | ||
))); | ||
@@ -113,3 +113,3 @@ }; | ||
value.column ? column(value.column) : identity(), | ||
value.display ? display(value.display) : identity() | ||
typeof value.display !== 'undefined' ? display(value.display) : identity() | ||
))); | ||
@@ -400,8 +400,2 @@ }; | ||
type DisableFocusStyles = boolean; | ||
const disableFocusStyles = (value: DisableFocusStyles): Style => ( | ||
value ? fromClassName(styles.disableFocusStyles) : identity() | ||
); | ||
// -- | ||
@@ -424,3 +418,2 @@ | ||
fit?: Fit, | ||
disableFocusStyles?: DisableFocusStyles, | ||
grow?: Grow, | ||
@@ -452,3 +445,2 @@ justifyContent?: JustifyContent, | ||
fit, | ||
disableFocusStyles, | ||
grow, | ||
@@ -590,3 +582,2 @@ justifyContent, | ||
fit: PropTypes.bool, | ||
disableFocusStyles: PropTypes.bool, | ||
grow: PropTypes.bool, | ||
@@ -593,0 +584,0 @@ justifyContent: PropTypes.oneOf([ |
@@ -5,3 +5,2 @@ // @flow | ||
import Button from '../Button'; | ||
import GestaltProvider from '../../GestaltProvider/GestaltProvider'; | ||
import { ns } from '../../../.corkboard/cards'; | ||
@@ -52,3 +51,3 @@ | ||
`, | ||
<GestaltProvider> | ||
<div> | ||
<div className="p2"> | ||
@@ -72,3 +71,3 @@ <Button | ||
</div> | ||
</GestaltProvider>); | ||
</div>); | ||
@@ -99,3 +98,3 @@ card('Widths', | ||
`, | ||
<GestaltProvider> | ||
<div> | ||
<div className="p2"> | ||
@@ -118,3 +117,3 @@ <Button | ||
</div> | ||
</GestaltProvider>); | ||
</div>); | ||
@@ -140,3 +139,3 @@ card('Types', | ||
`, | ||
<GestaltProvider> | ||
<div> | ||
<div className="p2"> | ||
@@ -156,3 +155,3 @@ <Button | ||
</div> | ||
</GestaltProvider>); | ||
</div>); | ||
@@ -176,3 +175,3 @@ card('Disabled', | ||
`, | ||
<GestaltProvider> | ||
<div> | ||
<div className="p2"> | ||
@@ -191,2 +190,2 @@ <Button | ||
</div> | ||
</GestaltProvider>); | ||
</div>); |
@@ -18,7 +18,3 @@ // @flow | ||
type GestaltContext = { | ||
inputDevice: '' | 'key' | 'mouse' | 'touch' | ||
} | ||
export default function Button(props: Props, context: GestaltContext) { | ||
export default function Button(props: Props) { | ||
const { | ||
@@ -35,6 +31,3 @@ accessibilityExpanded, | ||
const { inputDevice = 'key' } = context; | ||
const classes = classnames(styles.button, { | ||
[styles.disableFocusOutline]: inputDevice !== 'key', | ||
[styles.disabled]: disabled, | ||
@@ -61,6 +54,2 @@ [styles.enabled]: !disabled, | ||
Button.contextTypes = { | ||
inputDevice: React.PropTypes.string | ||
}; | ||
Button.propTypes = { | ||
@@ -67,0 +56,0 @@ accessibilityExpanded: PropTypes.bool, |
@@ -8,3 +8,2 @@ // @flow | ||
import Card from '../Card'; | ||
import GestaltProvider from '../../GestaltProvider/GestaltProvider'; | ||
import Link from '../../Link/Link'; | ||
@@ -34,4 +33,4 @@ import Text from '../../Text/Text'; | ||
\`\`\`html | ||
<Card accessibilityLabel="Ben Silbermann - Pinterest CEO"> | ||
<Box> | ||
<Box padding={2} xs={{ column: 12 }}> | ||
<Card accessibilityLabel="Ben Silbermann - Pinterest CEO"> | ||
<Link color="darkGray" href="https://pinterest.com"> | ||
@@ -47,8 +46,8 @@ <Avatar | ||
</Link> | ||
<Button color="red" fullWidth text="Follow" /> | ||
</Box> | ||
</Card> | ||
<Button color="red" text="Follow" /> | ||
</Card> | ||
</Box> | ||
\`\`\` | ||
`, | ||
<GestaltProvider> | ||
<Box> | ||
<Box xs={{ display: 'flex' }} wrap> | ||
@@ -94,2 +93,2 @@ <Box | ||
</Box> | ||
</GestaltProvider>); | ||
</Box>); |
@@ -15,10 +15,2 @@ // @flow | ||
static contextTypes = { | ||
inputDevice: React.PropTypes.string | ||
} | ||
static context: { | ||
inputDevice: '' | 'key' | 'mouse' | 'touch' | ||
} | ||
static props: {| | ||
@@ -62,4 +54,2 @@ accessibilityLabel: String, | ||
const { inputDevice = 'key' } = this.context; | ||
const classes = classnames(styles.card, { | ||
@@ -73,3 +63,2 @@ [styles.hover]: hovered, | ||
aria-label={accessibilityLabel} | ||
disableFocusStyles={inputDevice !== 'key'} | ||
onBlur={this.handleBlur} | ||
@@ -76,0 +65,0 @@ onFocus={this.handleFocus} |
@@ -10,2 +10,3 @@ // @flow | ||
import IconButton from '../../IconButton/IconButton'; | ||
import Link from '../../Link/Link'; | ||
import Text from '../../Text/Text'; | ||
@@ -88,18 +89,18 @@ import { ns } from '../../../.corkboard/cards'; | ||
<li className="p2"> | ||
<Text bold><a href="http://pinterest.com">Access business tools</a></Text> | ||
<Text bold><Link color="darkGray" href="http://pinterest.com">Access business tools</Link></Text> | ||
</li> | ||
<li className="p2"> | ||
<Text bold><a href="http://pinterest.com">See order history</a></Text> | ||
<Text bold><Link color="darkGray" href="http://pinterest.com">See order history</Link></Text> | ||
</li> | ||
<li className="p2"> | ||
<Text bold><a href="http://pinterest.com">Find friends</a></Text> | ||
<Text bold><Link color="darkGray" href="http://pinterest.com">Find friends</Link></Text> | ||
</li> | ||
<li className="p2"> | ||
<Text bold><a href="http://pinterest.com">Make a widget</a></Text> | ||
<Text bold><Link color="darkGray" href="http://pinterest.com">Make a widget</Link></Text> | ||
</li> | ||
<li className="p2"> | ||
<Text bold><a href="http://pinterest.com">Get help</a></Text> | ||
<Text bold><Link color="darkGray" href="http://pinterest.com">Get help</Link></Text> | ||
</li> | ||
<li className="p2"> | ||
<Text bold><a href="http://pinterest.com">Logout</a></Text> | ||
<Text bold><Link color="darkGray" href="http://pinterest.com">Logout</Link></Text> | ||
</li> | ||
@@ -112,9 +113,9 @@ </ul> | ||
<li className="p2"> | ||
<Text bold><a href="http://pinterest.com">View profile</a></Text> | ||
<Text bold><Link color="darkGray" href="http://pinterest.com">View profile</Link></Text> | ||
</li> | ||
<li className="p2"> | ||
<Text bold><a href="http://pinterest.com">Get help</a></Text> | ||
<Text bold><Link color="darkGray" href="http://pinterest.com">Get help</Link></Text> | ||
</li> | ||
<li className="p2"> | ||
<Text bold><a href="http://pinterest.com">Logout</a></Text> | ||
<Text bold><Link color="darkGray" href="http://pinterest.com">Logout</Link></Text> | ||
</li> | ||
@@ -128,13 +129,13 @@ </ul> | ||
<Text color="gray" bold> | ||
<a href="http://pinterest.com">Get our browser button to save ideas even faster</a> | ||
<Link color="darkGray" href="http://pinterest.com">Get our browser button to save ideas even faster</Link> | ||
</Text> | ||
</li> | ||
<li className="p2"> | ||
<Text color="gray" bold><a href="http://pinterest.com">Upload a pin</a></Text> | ||
<Text color="gray" bold><Link color="darkGray" href="http://pinterest.com">Upload a pin</Link></Text> | ||
</li> | ||
<li className="p2"> | ||
<Text color="gray" bold><a href="http://pinterest.com">Save from a website</a></Text> | ||
<Text color="gray" bold><Link color="darkGray" href="http://pinterest.com">Save from a website</Link></Text> | ||
</li> | ||
<li className="p2"> | ||
<Text color="gray" bold><a href="http://pinterest.com">Report a bug</a></Text> | ||
<Text color="gray" bold><Link color="darkGray" href="http://pinterest.com">Report a bug</Link></Text> | ||
</li> | ||
@@ -141,0 +142,0 @@ </ul> |
@@ -322,3 +322,2 @@ // @flow | ||
props: Props; | ||
@@ -325,0 +324,0 @@ flyout: HTMLElement; |
@@ -6,3 +6,2 @@ // @flow | ||
import Box from '../../Box/Box'; | ||
import GestaltProvider from '../../GestaltProvider/GestaltProvider'; | ||
import IconButton from '../IconButton'; | ||
@@ -74,14 +73,12 @@ | ||
`, | ||
<GestaltProvider> | ||
<Box xs={{ display: 'flex' }} margin={{ left: -2, right: -2 }} wrap> | ||
{sizes.map((size, key) => | ||
<Box xs={{ display: 'flexColumn' }} alignItems="center" padding={{ x: 3 }} key={key}> | ||
<h5>{size}</h5> | ||
<Box xs={{ display: 'flex' }} justifyContent="center"> | ||
<IconButtonEx icon="heart" size={size} /> | ||
</Box> | ||
<Box xs={{ display: 'flex' }} margin={{ left: -2, right: -2 }} wrap> | ||
{sizes.map((size, key) => | ||
<Box xs={{ display: 'flexColumn' }} alignItems="center" padding={{ x: 3 }} key={key}> | ||
<h5>{size}</h5> | ||
<Box xs={{ display: 'flex' }} justifyContent="center"> | ||
<IconButtonEx icon="heart" size={size} /> | ||
</Box> | ||
)} | ||
</Box> | ||
</GestaltProvider> | ||
</Box> | ||
)} | ||
</Box> | ||
); | ||
@@ -115,15 +112,13 @@ | ||
`, | ||
<GestaltProvider> | ||
<Box margin={{ left: -2, right: -2 }} wrap xs={{ display: 'flex' }}> | ||
{icons.map((icon, i) => | ||
<Box key={i} margin={{ bottom: 1 }} padding={{ x: 2 }} xs={{ display: 'flex', column: 12 }}> | ||
{colors.map((color, idx) => | ||
<Box padding={{ x: 1 }} key={idx}> | ||
<IconButtonEx bgColor={color} icon={icon} size="md" /> | ||
</Box> | ||
)} | ||
</Box> | ||
)} | ||
</Box> | ||
</GestaltProvider> | ||
<Box margin={{ left: -2, right: -2 }} wrap xs={{ display: 'flex' }}> | ||
{icons.map((icon, i) => | ||
<Box key={i} margin={{ bottom: 1 }} padding={{ x: 2 }} xs={{ display: 'flex', column: 12 }}> | ||
{colors.map((color, idx) => | ||
<Box padding={{ x: 1 }} key={idx}> | ||
<IconButtonEx bgColor={color} icon={icon} size="md" /> | ||
</Box> | ||
)} | ||
</Box> | ||
)} | ||
</Box> | ||
); | ||
@@ -160,28 +155,26 @@ | ||
`, | ||
<GestaltProvider> | ||
<Box margin={{ left: -2, right: -2 }} wrap xs={{ display: 'flex' }}> | ||
<Box padding={{ x: 1 }}> | ||
<IconButton | ||
accessibilityLabel="heart" | ||
iconColor="red" | ||
icon="heart" | ||
/> | ||
</Box> | ||
<Box padding={{ x: 1 }}> | ||
<IconButton | ||
accessibilityLabel="pinterest" | ||
bgColor="lightGray" | ||
iconColor="red" | ||
icon="pinterest" | ||
/> | ||
</Box> | ||
<Box padding={{ x: 1 }}> | ||
<IconButton | ||
accessibilityLabel="globe" | ||
iconColor="blue" | ||
icon="globe" | ||
/> | ||
</Box> | ||
<Box margin={{ left: -2, right: -2 }} wrap xs={{ display: 'flex' }}> | ||
<Box padding={{ x: 1 }}> | ||
<IconButton | ||
accessibilityLabel="heart" | ||
iconColor="red" | ||
icon="heart" | ||
/> | ||
</Box> | ||
</GestaltProvider> | ||
<Box padding={{ x: 1 }}> | ||
<IconButton | ||
accessibilityLabel="pinterest" | ||
bgColor="lightGray" | ||
iconColor="red" | ||
icon="pinterest" | ||
/> | ||
</Box> | ||
<Box padding={{ x: 1 }}> | ||
<IconButton | ||
accessibilityLabel="globe" | ||
iconColor="blue" | ||
icon="globe" | ||
/> | ||
</Box> | ||
</Box> | ||
); |
// @flow | ||
/* eslint-disable react/no-unused-prop-types */ | ||
/* global $Keys */ | ||
import React, { PropTypes } from 'react'; | ||
import classnames from 'classnames'; | ||
import Box from '../Box/Box'; | ||
import Icon from '../Icon/Icon'; | ||
import React, { Component, PropTypes } from 'react'; | ||
import styles from './IconButton.css'; | ||
import icons from '../Icon/icons'; | ||
import Pog from '../Pog/Pog'; | ||
@@ -27,89 +25,85 @@ type Props = {| | ||
const defaultIconButtonIconColors = { | ||
transparent: 'gray', | ||
lightGray: 'gray', | ||
}; | ||
export default class IconButton extends Component { | ||
const buttonSize = { | ||
xs: 24, | ||
sm: 32, | ||
md: 40, | ||
lg: 48, | ||
xl: 56, | ||
}; | ||
static propTypes = { | ||
accessibilityExpanded: PropTypes.bool, | ||
accessibilityHaspopup: PropTypes.bool, | ||
accessibilityLabel: PropTypes.string.isRequired, | ||
bgColor: PropTypes.oneOf( | ||
['transparent', 'lightGray'] | ||
), | ||
icon: PropTypes.oneOf(Object.keys(icons)).isRequired, | ||
iconColor: PropTypes.oneOf( | ||
['gray', 'darkGray', 'red', 'blue'] | ||
), | ||
onClick: PropTypes.func, | ||
size: PropTypes.oneOf( | ||
['xs', 'sm', 'md', 'lg', 'xl'] | ||
), | ||
tabIndex: PropTypes.oneOf([-1, 0]), | ||
}; | ||
type GestaltContext = { | ||
inputDevice: '' | 'key' | 'mouse' | 'touch' | ||
} | ||
static props: Props; | ||
export default function IconButton(props: Props, context: GestaltContext) { | ||
const { | ||
accessibilityExpanded, | ||
accessibilityHaspopup, | ||
accessibilityLabel, | ||
bgColor = 'transparent', | ||
iconColor = defaultIconButtonIconColors[bgColor], | ||
icon, | ||
onClick, | ||
size = 'md', | ||
tabIndex, | ||
} = props; | ||
state = { | ||
active: false, | ||
focused: false, | ||
hovered: false, | ||
}; | ||
const { inputDevice = 'key' } = context; | ||
handleBlur = () => this.setState({ focused: false }); | ||
handleFocus = () => { this.setState({ focused: true }); }; | ||
handleMouseDown = () => { this.setState({ active: true }); }; | ||
handleMouseEnter = () => { this.setState({ hovered: true }); }; | ||
handleMouseLeave = () => { this.setState({ hovered: false }); }; | ||
handleMouseUp = () => { this.setState({ active: false }); }; | ||
const inlineStyle = { | ||
height: buttonSize[size], | ||
width: buttonSize[size], | ||
}; | ||
render() { | ||
const { | ||
accessibilityExpanded, | ||
accessibilityHaspopup, | ||
accessibilityLabel, | ||
bgColor, | ||
iconColor, | ||
icon, | ||
size, | ||
onClick, | ||
tabIndex, | ||
} = this.props; | ||
const iconSize = buttonSize[size] / 2; | ||
const { | ||
active, | ||
focused, | ||
hovered, | ||
} = this.state; | ||
return ( | ||
<button | ||
aria-expanded={accessibilityExpanded} | ||
aria-haspopup={accessibilityHaspopup} | ||
aria-label={accessibilityLabel} | ||
className={classnames( | ||
styles.button, | ||
styles[bgColor], { | ||
[styles.disableFocusOutline]: inputDevice !== 'key' | ||
} | ||
)} | ||
onClick={onClick} | ||
style={inlineStyle} | ||
tabIndex={tabIndex} | ||
> | ||
<Box xs={{ display: 'flex' }} alignItems="center" justifyContent="center"> | ||
{/* | ||
We're explicitly setting an empty string as a label on the Icon since we | ||
already have an aria-label on the button container. | ||
This is similar to having empty `alt` attributes: | ||
https://davidwalsh.name/accessibility-tip-empty-alt-attributes | ||
*/} | ||
<Icon color={iconColor} icon={icon} size={iconSize} accessibilityLabel="" /> | ||
</Box> | ||
</button> | ||
); | ||
const pogProps = { | ||
active, | ||
bgColor, | ||
focused, | ||
hovered, | ||
iconColor, | ||
icon, | ||
size, | ||
}; | ||
return ( | ||
<button | ||
aria-expanded={accessibilityExpanded} | ||
aria-haspopup={accessibilityHaspopup} | ||
aria-label={accessibilityLabel} | ||
className={styles.button} | ||
onBlur={this.handleBlur} | ||
onClick={onClick} | ||
onFocus={this.handleFocus} | ||
onMouseDown={this.handleMouseDown} | ||
onMouseEnter={this.handleMouseEnter} | ||
onMouseLeave={this.handleMouseLeave} | ||
onMouseUp={this.handleMouseUp} | ||
tabIndex={tabIndex} | ||
> | ||
<Pog {...pogProps} /> | ||
</button> | ||
); | ||
} | ||
} | ||
IconButton.contextTypes = { | ||
inputDevice: React.PropTypes.string | ||
}; | ||
IconButton.propTypes = { | ||
accessibilityExpanded: PropTypes.bool, | ||
accessibilityHaspopup: PropTypes.bool, | ||
accessibilityLabel: PropTypes.string.isRequired, | ||
bgColor: PropTypes.oneOf( | ||
['transparent', 'lightGray'] | ||
), | ||
icon: PropTypes.oneOf(Object.keys(icons)).isRequired, | ||
iconColor: PropTypes.oneOf( | ||
['gray', 'darkGray', 'red', 'blue'] | ||
), | ||
onClick: PropTypes.func, | ||
size: PropTypes.oneOf( | ||
['xs', 'sm', 'md', 'lg', 'xl'] | ||
), | ||
tabIndex: PropTypes.oneOf([-1, 0]), | ||
}; |
@@ -21,3 +21,2 @@ // @flow | ||
import Flyout from './Flyout/Flyout'; | ||
import GestaltProvider from './GestaltProvider/GestaltProvider'; | ||
import GroupAvatar from './GroupAvatar/GroupAvatar'; | ||
@@ -34,2 +33,3 @@ import Heading from './Heading/Heading'; | ||
import Modal from './Modal/Modal'; | ||
import Pog from './Pog/Pog'; | ||
import RadioButton from './RadioButton/RadioButton'; | ||
@@ -60,3 +60,2 @@ import ScrollFetch from './ScrollFetch/ScrollFetch'; | ||
Flyout, | ||
GestaltProvider, | ||
GroupAvatar, | ||
@@ -72,2 +71,3 @@ Heading, | ||
Modal, | ||
Pog, | ||
RadioButton, | ||
@@ -74,0 +74,0 @@ ScrollFetch, |
@@ -7,3 +7,2 @@ // @flow | ||
import { ns } from '../../../.corkboard/cards'; | ||
import GestaltProvider from '../../GestaltProvider/GestaltProvider'; | ||
import Icon from '../../Icon/Icon'; | ||
@@ -40,47 +39,37 @@ import Text from '../../Text/Text'; | ||
card( | ||
<GestaltProvider> | ||
<Box color="gray"> | ||
<Text> | ||
<Link color="white" href="https://pinterest.com"> | ||
<div className="p2">Pinterest.com</div> | ||
</Link> | ||
</Text> | ||
</Box> | ||
</GestaltProvider>, | ||
<Box color="gray"> | ||
<Text> | ||
<Link color="white" href="https://pinterest.com"> | ||
<div className="p2">Pinterest.com</div> | ||
</Link> | ||
</Text> | ||
</Box>, | ||
{ heading: false }, | ||
); | ||
card( | ||
<GestaltProvider> | ||
<Text> | ||
<Link color="gray" href="https://pinterest.com">Pinterest.com</Link> | ||
</Text> | ||
</GestaltProvider>, | ||
<Text> | ||
<Link color="gray" href="https://pinterest.com">Pinterest.com</Link> | ||
</Text>, | ||
{ heading: false }, | ||
); | ||
card( | ||
<GestaltProvider> | ||
<Text> | ||
<Link color="darkGray" href="https://pinterest.com">Pinterest.com</Link> | ||
</Text> | ||
</GestaltProvider>, | ||
<Text> | ||
<Link color="darkGray" href="https://pinterest.com">Pinterest.com</Link> | ||
</Text>, | ||
{ heading: false }, | ||
); | ||
card( | ||
<GestaltProvider> | ||
<Text> | ||
<Link color="red" href="https://pinterest.com">Pinterest.com</Link> | ||
</Text> | ||
</GestaltProvider>, | ||
<Text> | ||
<Link color="red" href="https://pinterest.com">Pinterest.com</Link> | ||
</Text>, | ||
{ heading: false }, | ||
); | ||
card( | ||
<GestaltProvider> | ||
<Text> | ||
<Link color="blue" href="https://pinterest.com"> | ||
<Icon icon="pin" color="blue" inline accessibilityLabel="pin" /> | ||
Pinterest.com | ||
</Link> | ||
</Text> | ||
</GestaltProvider>, | ||
<Text> | ||
<Link color="blue" href="https://pinterest.com"> | ||
<Icon icon="pin" color="blue" inline accessibilityLabel="pin" /> | ||
Pinterest.com | ||
</Link> | ||
</Text>, | ||
{ heading: false }, | ||
); |
@@ -35,8 +35,3 @@ // @flow | ||
type GestaltContext = { | ||
inputDevice: '' | 'key' | 'mouse' | 'touch' | ||
}; | ||
export default function Link(props: LinkProps, context: GestaltContext) { | ||
const { inputDevice = 'key' } = context; | ||
export default function Link(props: LinkProps) { | ||
const { color = 'darkGray', inline = false } = props; | ||
@@ -52,3 +47,2 @@ return ( | ||
(inline ? styles.inline : styles.block), | ||
(inputDevice !== 'key' ? styles.disableFocusOutline : '') | ||
) | ||
@@ -60,6 +54,2 @@ } | ||
Link.contextTypes = { | ||
inputDevice: React.PropTypes.string | ||
}; | ||
Link.propTypes = { | ||
@@ -66,0 +56,0 @@ // eslint-disable-next-line react/no-unused-prop-types |
@@ -114,2 +114,9 @@ // @flow | ||
componentDidMount() { | ||
// Append a node to measure items. | ||
this.measuringNode = document.createElement('div'); | ||
if (document.body) { | ||
document.body.appendChild(this.measuringNode); | ||
} | ||
this.props.scrollContainer.addEventListener('scroll', this.updateVirtualBounds); | ||
@@ -182,2 +189,6 @@ window.addEventListener('resize', this.handleResize); | ||
this.gridWrapper.removeEventListener('animationend', this.handleAnimationEnd); | ||
if (document.body) { | ||
document.body.removeChild(this.measuringNode); | ||
} | ||
} | ||
@@ -193,3 +204,2 @@ | ||
getItemsRelatedTo(colIdx: number, iIdx: number, noItems: number = 5) { | ||
@@ -241,11 +251,2 @@ const { gridItems } = this.state; | ||
/** | ||
* Returns the scroll position of the scroll container. | ||
*/ | ||
getScrollPos = () => { | ||
// Try accessing scrollY, as the grid will generally be scrolled by the window. | ||
const el = this.props.scrollContainer; | ||
return el.scrollY !== undefined ? el.scrollY : el.scrollTop; | ||
} | ||
/** | ||
* Sets all grid items in the grid. | ||
@@ -310,2 +311,3 @@ */ | ||
itemKeyCounter: number; | ||
measuringNode: HTMLElement; | ||
resizeTimeout: ?number; | ||
@@ -435,15 +437,8 @@ serverRefs: Array<HTMLElement>; | ||
if (pendingDomMeasurements.length > 0) { | ||
// Append a temporary node to the dom to measure it. | ||
const measuringNode = document.createElement('div'); | ||
if (document.body) { | ||
document.body.appendChild(measuringNode); | ||
} | ||
ReactDOM.unstable_renderSubtreeIntoContainer( | ||
this, <div> { pendingDomMeasurements.map(({ component }, idx) => | ||
<div key={`el-${idx}`} style={{ width: `${this.itemWidth}px` }}>{ component }</div> | ||
)} </div>, measuringNode); | ||
)} </div>, this.measuringNode); | ||
const wrapperNodes = measuringNode.children[0].children; | ||
const wrapperNodes = this.measuringNode.children[0].children; | ||
for (let i = 0; i < wrapperNodes.length; i += 1) { | ||
@@ -456,7 +451,3 @@ const { itemInfo } = pendingDomMeasurements[i]; | ||
ReactDOM.unmountComponentAtNode(measuringNode); | ||
if (document.body) { | ||
document.body.removeChild(measuringNode); | ||
} | ||
ReactDOM.unmountComponentAtNode(this.measuringNode); | ||
} | ||
@@ -463,0 +454,0 @@ |
@@ -16,2 +16,6 @@ // @flow | ||
state = { | ||
focused: false | ||
}; | ||
props: {| | ||
@@ -30,2 +34,5 @@ checked?: boolean, | ||
handleBlur = () => this.setState({ focused: false }); | ||
handleFocus = () => { this.setState({ focused: true }); }; | ||
render() { | ||
@@ -35,2 +42,3 @@ const { checked, id, name, value } = this.props; | ||
const customRadioButton = classnames(styles.radioButton, { | ||
[styles.focused]: this.state.focused, | ||
[styles.checked]: checked, | ||
@@ -47,3 +55,5 @@ [styles.unchecked]: !checked | ||
name={name} | ||
onBlur={this.handleBlur} | ||
onChange={this.handleChange} | ||
onFocus={this.handleFocus} | ||
type="radio" | ||
@@ -50,0 +60,0 @@ value={value} |
@@ -13,2 +13,4 @@ // @flow | ||
this.props.container.addEventListener('scroll', this.check); | ||
this.scrollBuffer = this.scrollBuffer || this.getContainerHeight() * 2; | ||
setTimeout(() => this.check()); | ||
} | ||
@@ -20,3 +22,2 @@ | ||
componentDidUpdate() { | ||
this.scrollBuffer = this.scrollBuffer || this.getContainerHeight() * 2; | ||
// setTimeout so the parent component can calculate renderHeight(). | ||
@@ -23,0 +24,0 @@ setTimeout(() => this.check()); |
// @flow | ||
import React, { PropTypes } from 'react'; | ||
import React, { Component, PropTypes } from 'react'; | ||
import classnames from 'classnames'; | ||
@@ -15,39 +15,53 @@ import styles from './Switch.css'; | ||
export default function Switch(props: Props) { | ||
const { id, name, onChange, switched = false } = props; | ||
export default class Switch extends Component { | ||
static propTypes = { | ||
id: PropTypes.string.isRequired, | ||
onChange: PropTypes.func.isRequired, | ||
switched: PropTypes.bool, | ||
}; | ||
const switchStyles = classnames(styles.switch, { | ||
[styles.switchOn]: switched, | ||
[styles.switchOff]: !switched, | ||
}); | ||
state = { | ||
focused: false | ||
}; | ||
const sliderStyles = cx(styles.slider, { | ||
[styles.sliderOn]: switched, | ||
[styles.sliderOff]: !switched, | ||
}); | ||
props: Props; | ||
return ( | ||
<div className={switchStyles} > | ||
<input | ||
checked={switched} | ||
className={styles.checkbox} | ||
name={name} | ||
id={id} | ||
onChange={ | ||
(e: { nativeEvent: { target: { checked: boolean}}}) => { | ||
const checked = e.nativeEvent.target.checked; | ||
return onChange(checked); | ||
handleBlur = () => this.setState({ focused: false }); | ||
handleFocus = () => { this.setState({ focused: true }); }; | ||
render() { | ||
const { id, name, onChange, switched = false } = this.props; | ||
const switchStyles = classnames(styles.switch, { | ||
[styles.focused]: this.state.focused, | ||
[styles.switchOn]: switched, | ||
[styles.switchOff]: !switched, | ||
}); | ||
const sliderStyles = cx(styles.slider, { | ||
[styles.sliderOn]: switched, | ||
[styles.sliderOff]: !switched, | ||
}); | ||
return ( | ||
<div className={switchStyles} > | ||
<input | ||
checked={switched} | ||
className={styles.checkbox} | ||
name={name} | ||
id={id} | ||
onBlur={this.handleBlur} | ||
onChange={ | ||
(e: { nativeEvent: { target: { checked: boolean}}}) => { | ||
const checked = e.nativeEvent.target.checked; | ||
return onChange(checked); | ||
} | ||
} | ||
} | ||
type="checkbox" | ||
/> | ||
<div className={sliderStyles} /> | ||
</div> | ||
); | ||
onFocus={this.handleFocus} | ||
type="checkbox" | ||
/> | ||
<div className={sliderStyles} /> | ||
</div> | ||
); | ||
} | ||
} | ||
Switch.propTypes = { | ||
id: PropTypes.string.isRequired, | ||
onChange: PropTypes.func.isRequired, | ||
switched: PropTypes.bool, | ||
}; |
@@ -5,2 +5,3 @@ // @flow | ||
import { card, md } from 'corkboard'; | ||
import Box from '../../Box/Box'; | ||
import TextArea from '../TextArea'; | ||
@@ -46,3 +47,5 @@ import { ns } from '../../../.corkboard/cards'; | ||
<div className="py2"> | ||
<label htmlFor="aboutme">With a placeholder</label> | ||
<Box margin={{ bottom: 2 }}> | ||
<label htmlFor="aboutme">With a placeholder</label> | ||
</Box> | ||
<TextArea | ||
@@ -73,3 +76,5 @@ id="aboutme" | ||
<div className="py2"> | ||
<label htmlFor="comment">With error message </label> | ||
<Box margin={{ bottom: 2 }}> | ||
<label htmlFor="comment">With error message</label> | ||
</Box> | ||
<TextArea | ||
@@ -76,0 +81,0 @@ errorMessage="This field can't be blank!" |
@@ -5,2 +5,3 @@ // @flow | ||
import { card, md } from 'corkboard'; | ||
import Box from '../../Box/Box'; | ||
import TextField from '../TextField'; | ||
@@ -47,3 +48,5 @@ import { ns } from '../../../.corkboard/cards'; | ||
<div className="py2"> | ||
<label htmlFor="email">With a placeholder</label> | ||
<Box margin={{ bottom: 2 }}> | ||
<label htmlFor="email">With a placeholder</label> | ||
</Box> | ||
<TextField | ||
@@ -58,3 +61,5 @@ id="email" | ||
<div className="py2"> | ||
<label htmlFor="password">With a password</label> | ||
<Box margin={{ bottom: 2 }}> | ||
<label htmlFor="password">With a password</label> | ||
</Box> | ||
<TextField | ||
@@ -90,3 +95,5 @@ id="password" | ||
<div className="py2"> | ||
<label htmlFor="firstName">With error message</label> | ||
<Box margin={{ bottom: 2 }}> | ||
<label htmlFor="firstName">With error message</label> | ||
</Box> | ||
<TextField | ||
@@ -93,0 +100,0 @@ errorMessage="This field can't be blank!" |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
1571571
244
26201