Comparing version 0.16.3 to 0.17.0
{ | ||
"name": "gestalt", | ||
"version": "0.16.3", | ||
"version": "0.17.0", | ||
"license": "SEE LICENSE IN LICENSE", | ||
@@ -5,0 +5,0 @@ "homepage": "https://pinterest.github.io/gestalt", |
@@ -6,3 +6,3 @@ /* eslint-env jest */ | ||
import React from 'react'; | ||
import { mount, shallow } from 'enzyme'; | ||
import { shallow } from 'enzyme'; | ||
import Controller from '../Controller'; | ||
@@ -13,8 +13,2 @@ import Contents from '../Contents'; | ||
describe('Flyout', () => { | ||
const mockTrigger = (extras = {}) => ({ | ||
getBoundingClientRect: jest.fn(), | ||
contains: jest.fn(), | ||
...extras, | ||
}); | ||
it('does not render Contents when isOpen is false', () => { | ||
@@ -31,17 +25,2 @@ const wrapper = shallow( | ||
}); | ||
it('renders Contents when isOpen is true', () => { | ||
const wrapper = mount( | ||
<Controller | ||
closeLabel="close" | ||
isOpen | ||
onDismiss={() => null} | ||
trigger={<button onClick={() => null}> test </button>} | ||
/> | ||
); | ||
wrapper.instance().triggerButton = mockTrigger(); | ||
expect(wrapper.find(Contents).length).toEqual(1); | ||
}); | ||
}); |
@@ -267,5 +267,2 @@ // @flow | ||
this.setFlyoutPosition(); | ||
if (document.activeElement && this.props.shouldFocus) { | ||
this.priorFocus = document.activeElement; | ||
} | ||
setTimeout(() => { | ||
@@ -279,6 +276,2 @@ if (this.props.shouldFocus) { | ||
window.addEventListener('keydown', this.props.onKeyDown); | ||
if (this.props.shouldFocus) { | ||
// not needed for errors and tooltips which don't receive immediate focus | ||
document.addEventListener('focus', this.restrictFocus, true); | ||
} | ||
} | ||
@@ -291,13 +284,5 @@ | ||
componentWillUnmount() { | ||
setTimeout(() => { | ||
if (this.priorFocus) { | ||
this.priorFocus.focus(); | ||
} | ||
}); | ||
document.removeEventListener('click', this.props.onClick); | ||
window.removeEventListener('resize', this.props.onResize); | ||
window.removeEventListener('keydown', this.props.onKeyDown); | ||
if (this.props.shouldFocus) { | ||
document.removeEventListener('focus', this.restrictFocus); | ||
} | ||
} | ||
@@ -339,12 +324,5 @@ | ||
restrictFocus = (e: Event) => { | ||
if (this.flyout && e.target instanceof Node && !this.flyout.contains(e.target)) { | ||
e.stopPropagation(); | ||
this.flyout.focus(); | ||
} | ||
} | ||
props: Props; | ||
flyout: HTMLElement; | ||
priorFocus: HTMLElement; | ||
@@ -368,3 +346,3 @@ render() { | ||
> | ||
<div className={classnames('overflow-auto', styles.dimensions)} style={{ width }}> | ||
<div className={classnames('items-center', 'flex', 'overflow-auto', styles.dimensions)} style={{ width }}> | ||
{children} | ||
@@ -371,0 +349,0 @@ </div> |
// @flow | ||
import React, { Component, PropTypes } from 'react'; | ||
import React, { PropTypes } from 'react'; | ||
import classnames from 'classnames'; | ||
@@ -48,6 +48,2 @@ import Masonry from '../Masonry/Masonry'; | ||
type GridRefType = { | ||
reflow: () => void, | ||
}; | ||
type GridItemPropsType = { | ||
@@ -189,46 +185,29 @@ data: ModifiedAvatarProps, | ||
export default class GroupAvatar extends Component { | ||
gridRef: GridRefType; | ||
props: GroupAvatarProps; | ||
export default function GroupAvatar(props: GroupAvatarProps) { | ||
const { collaborators, size } = props; | ||
const collabs = addPositionDataToCollabs(collaborators, size).slice(0, 3); | ||
const MAX_AVATAR_DIM = AVATAR_SIZES[size]; | ||
const HALF_AVATAR_DIM = (MAX_AVATAR_DIM - GUTTER_WIDTH) / 2; | ||
const borderBoxStyle = { | ||
border: '2px solid #ffffff', | ||
height: MAX_AVATAR_DIM, | ||
width: MAX_AVATAR_DIM, | ||
}; | ||
/** | ||
* Do not use this unless you know what you are doing. | ||
* This is a private method and is intended to be removed in the future. | ||
* This manually reflows the grid and clears the grid item cache. | ||
*/ | ||
reflowGrid() { | ||
if (this.gridRef) { | ||
this.gridRef.reflow(); | ||
} | ||
} | ||
render() { | ||
const { collaborators, size } = this.props; | ||
const collabs = addPositionDataToCollabs(collaborators, size).slice(0, 3); | ||
const MAX_AVATAR_DIM = AVATAR_SIZES[this.props.size]; | ||
const HALF_AVATAR_DIM = (MAX_AVATAR_DIM - GUTTER_WIDTH) / 2; | ||
const borderBoxStyle = { | ||
border: '2px solid #ffffff', | ||
height: MAX_AVATAR_DIM, | ||
width: MAX_AVATAR_DIM, | ||
}; | ||
return ( | ||
<div | ||
className={classnames('bg-white', 'circle', 'overflow-hidden')} | ||
style={borderBoxStyle} | ||
> | ||
<div style={{ margin: GUTTER_WIDTH / -2 }}> | ||
<Masonry | ||
comp={Avatar} | ||
flexible | ||
items={collabs} | ||
minCols={1} | ||
columnWidth={collabs.length === 1 ? MAX_AVATAR_DIM : HALF_AVATAR_DIM} | ||
ref={(ref) => { this.gridRef = ref; }} | ||
/> | ||
</div> | ||
return ( | ||
<div | ||
className={classnames('bg-white', 'circle', 'overflow-hidden')} | ||
style={borderBoxStyle} | ||
> | ||
<div style={{ margin: GUTTER_WIDTH / -2 }}> | ||
<Masonry | ||
comp={Avatar} | ||
flexible | ||
items={collabs} | ||
minCols={1} | ||
columnWidth={collabs.length === 1 ? MAX_AVATAR_DIM : HALF_AVATAR_DIM} | ||
/> | ||
</div> | ||
); | ||
} | ||
</div> | ||
); | ||
} | ||
@@ -235,0 +214,0 @@ |
@@ -15,3 +15,3 @@ // @flow | ||
children?: any, | ||
color?: 'blue' | 'dark-gray' | 'gray' | 'red' | 'white', /* default: dark-gray */ | ||
color?: 'blue' | 'darkGray' | 'gray' | 'red' | 'white', /* default: darkGray */ | ||
overflow?: 'normal' | 'breakWord' /* default: normal */ | ||
@@ -18,0 +18,0 @@ size: 'xs' | 'sm' | 'md' | 'lg' | 'xl', |
@@ -13,6 +13,16 @@ // @flow | ||
type Color = 'blue' | 'darkGray' | 'gray' | 'red' | 'white'; | ||
const headingColor = (color: Color) => { | ||
switch (color) { | ||
case 'darkGray': | ||
return 'dark-gray'; | ||
default: | ||
return color; | ||
} | ||
}; | ||
type Props = { | ||
accessibilityLevel?: 1 | 2 | 3 | 4 | 5 | 6, | ||
children?: any, | ||
color?: 'blue' | 'dark-gray' | 'gray' | 'red' | 'white', | ||
color?: Color, | ||
overflow?: 'normal' | 'breakWord', | ||
@@ -27,3 +37,3 @@ size: 'xs' | 'sm' | 'md' | 'lg' | 'xl', | ||
children, | ||
color = 'dark-gray', | ||
color = 'darkGray', | ||
size, | ||
@@ -41,3 +51,3 @@ overflow = 'normal', | ||
`display-${size}`, | ||
color, | ||
headingColor(color), | ||
{ | ||
@@ -56,3 +66,3 @@ 'break-word': overflow === 'breakWord', | ||
children: PropTypes.node, | ||
color: PropTypes.oneOf(['blue', 'dark-gray', 'gray', 'red', 'white']), | ||
color: PropTypes.oneOf(['blue', 'darkGray', 'gray', 'red', 'white']), | ||
overflow: PropTypes.oneOf(['normal', 'breakWord']), | ||
@@ -59,0 +69,0 @@ size: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']).isRequired, |
@@ -17,3 +17,3 @@ // @flow | ||
ariaLabel: string, | ||
color?: 'white' | 'gray' | 'dark-gray' | 'blue' | 'red', /* default: gray */ | ||
color?: 'white' | 'gray' | 'darkGray' | 'blue' | 'red', /* default: gray */ | ||
/* $Keys is an undocumented feature of Flow that helps with creating enums dynamically. | ||
@@ -32,3 +32,3 @@ * This allows us to type check for a valid icon name based on the keys from the list of | ||
gray: 'gray (default)', | ||
'dark-gray': 'dark-gray', | ||
darkGray: 'darkGray', | ||
white: 'white', | ||
@@ -54,3 +54,3 @@ blue: 'blue', | ||
<Icon icon="pin" ariaLabel="Pin" /> | ||
<Icon icon="pin" ariaLabel="Pin" color="dark-gray" /> | ||
<Icon icon="pin" ariaLabel="Pin" color="darkGray" /> | ||
\`\`\` | ||
@@ -62,3 +62,3 @@ `, | ||
<Box padding={{ y: 3 }}> | ||
<Text align="center" bold color="dark-gray">{colorMap[color]}</Text> | ||
<Text align="center" bold color="darkGray">{colorMap[color]}</Text> | ||
</Box> | ||
@@ -87,3 +87,3 @@ {colorItem(color)} | ||
<Box padding={{ y: 3 }}> | ||
<Text align="center" bold color="dark-gray">{size}</Text> | ||
<Text align="center" bold color="darkGray">{size}</Text> | ||
</Box> | ||
@@ -100,3 +100,3 @@ <Icon icon="pin" ariaLabel="Pin" size={size} /> | ||
<Box padding={{ y: 3 }}> | ||
<Text align="center" bold color="dark-gray">{iconName}</Text> | ||
<Text align="center" bold color="darkGray">{iconName}</Text> | ||
</Box> | ||
@@ -103,0 +103,0 @@ <Icon icon={iconName} ariaLabel={iconName.replace(/-/g, ' ')} color="gray" /> |
@@ -8,4 +8,14 @@ // @flow | ||
type Color = 'blue' | 'darkGray' | 'gray' | 'red' | 'white'; | ||
const iconColor = (color: Color) => { | ||
switch (color) { | ||
case 'darkGray': | ||
return 'dark-gray'; | ||
default: | ||
return color; | ||
} | ||
}; | ||
type IconProps = { | ||
color?: 'white' | 'gray' | 'dark-gray' | 'blue' | 'red', | ||
color?: Color, | ||
/* $Keys is an undocumented feature of Flow that helps with creating enums dynamically. | ||
@@ -32,3 +42,3 @@ * This allows us to type check for a valid icon name based on the keys from the list of | ||
styles.icon, | ||
color, | ||
iconColor(color), | ||
(!inline && 'block'), | ||
@@ -49,3 +59,3 @@ ); | ||
ariaLabel: PropTypes.string.isRequired, | ||
color: PropTypes.oneOf(['white', 'gray', 'dark-gray', 'blue', 'red']), | ||
color: PropTypes.oneOf(['white', 'gray', 'darkGray', 'blue', 'red']), | ||
icon: PropTypes.oneOf(Object.keys(icons)).isRequired, | ||
@@ -52,0 +62,0 @@ inline: PropTypes.bool, |
@@ -9,2 +9,3 @@ // @flow | ||
import arrowForward from './arrow-forward.svg'; | ||
import arrowUp from './arrow-up.svg'; | ||
import camera from './camera.svg'; | ||
@@ -29,2 +30,3 @@ import cancel from './cancel.svg'; | ||
import globe from './globe.svg'; | ||
import graphBar from './graph-bar.svg'; | ||
import knoop from './knoop.svg'; | ||
@@ -60,2 +62,3 @@ import lightbulb from './lightbulb.svg'; | ||
'arrow-forward': arrowForward, | ||
'arrow-up': arrowUp, | ||
camera, | ||
@@ -80,2 +83,3 @@ cancel, | ||
globe, | ||
'graph-bar': graphBar, | ||
heart, | ||
@@ -82,0 +86,0 @@ 'heart-broken': heartBroken, |
@@ -17,4 +17,4 @@ // @flow | ||
ariaHaspopup?: boolean, /* accessibility */ | ||
bgColor?: 'transparent' | 'light-gray', /* default: transparent */ | ||
iconColor?: 'gray' | 'dark-gray' | 'red' | 'blue', /* default: gray */ | ||
bgColor?: 'transparent' | 'lightGray', /* default: transparent */ | ||
iconColor?: 'gray' | 'darkGray' | 'red' | 'blue', /* default: gray */ | ||
/* $Keys is an undocumented feature of Flow that helps with creating enums dynamically. | ||
@@ -42,6 +42,6 @@ * This allows us to type check for a valid icon name based on the keys from the list of | ||
const sizes = ['xs', 'sm', 'md', 'lg', 'xl']; | ||
const colors = ['transparent', 'light-gray']; | ||
const colors = ['transparent', 'lightGray']; | ||
function IconButtonEx(props: *) { | ||
const { bgColor = 'light-gray', icon, size } = props; | ||
const { bgColor = 'lightGray', icon, size } = props; | ||
return ( | ||
@@ -66,3 +66,3 @@ <IconButton | ||
<IconButton | ||
bgColor="light-gray" | ||
bgColor="lightGray" | ||
icon="cancel" | ||
@@ -89,3 +89,3 @@ label="cancel" | ||
\`bgColor\` is \`transparent\` and \`iconColor\` is \`gray\`. For a provided \`bgColor\` | ||
of \`light-gray\`, the default \`iconColor\` associated is \`gray\` if none is specified. | ||
of \`lightGray\`, the default \`iconColor\` associated is \`gray\` if none is specified. | ||
This occurs so that a button's \`iconColor\` will be set to coordinate correctly with the | ||
@@ -104,3 +104,3 @@ \`bgColor\` you provided (as shown) without having to explicitly define it. | ||
<IconButton | ||
bgColor="light-gray" | ||
bgColor="lightGray" | ||
icon="cancel" | ||
@@ -142,3 +142,3 @@ label="cancel" | ||
<IconButton | ||
bgColor="light-gray" | ||
bgColor="lightGray" | ||
iconColor="red" | ||
@@ -167,3 +167,3 @@ icon="pinterest" | ||
<IconButton | ||
bgColor="light-gray" | ||
bgColor="lightGray" | ||
iconColor="red" | ||
@@ -170,0 +170,0 @@ icon="pinterest" |
@@ -14,4 +14,4 @@ // @flow | ||
ariaHaspopup?: boolean, | ||
bgColor?: 'transparent' | 'light-gray', | ||
iconColor?: 'gray' | 'dark-gray' | 'red' | 'blue', | ||
bgColor?: 'transparent' | 'lightGray', | ||
iconColor?: 'gray' | 'darkGray' | 'red' | 'blue', | ||
/* $Keys is an undocumented feature of Flow that helps with creating enums dynamically. | ||
@@ -30,3 +30,3 @@ * This allows us to type check for a valid icon name based on the keys from the list of | ||
transparent: 'gray', | ||
'light-gray': 'gray', | ||
lightGray: 'gray', | ||
}; | ||
@@ -89,7 +89,7 @@ | ||
bgColor: PropTypes.oneOf( | ||
['transparent', 'light-gray'] | ||
['transparent', 'lightGray'] | ||
), | ||
icon: PropTypes.oneOf(Object.keys(icons)).isRequired, | ||
iconColor: PropTypes.oneOf( | ||
['gray', 'dark-gray', 'red', 'blue'] | ||
['gray', 'darkGray', 'red', 'blue'] | ||
), | ||
@@ -96,0 +96,0 @@ label: PropTypes.string.isRequired, |
@@ -20,3 +20,2 @@ // @flow | ||
import ErrorFlyout from './ErrorFlyout/ErrorFlyout'; | ||
import FlexibleGrid from './FlexibleGrid/FlexibleGrid'; | ||
import Flyout from './Flyout/Flyout'; | ||
@@ -57,3 +56,2 @@ import GroupAvatar from './GroupAvatar/GroupAvatar'; | ||
ErrorFlyout, | ||
FlexibleGrid, | ||
Flyout, | ||
@@ -60,0 +58,0 @@ GroupAvatar, |
@@ -16,3 +16,3 @@ /* global describe */ | ||
describe('Masonry > virtual bounds visibility', () => { | ||
it('Reflows the grid after a resize', async () => { | ||
it('Calculates correct virtual bounds when masonry is offset', async () => { | ||
// This test cares about page size, so close the previous instance to ensure | ||
@@ -19,0 +19,0 @@ // we open a new window with the correct dimensions. |
@@ -500,8 +500,11 @@ // @flow | ||
measureContainer() { | ||
const { scrollContainer } = this.props; | ||
this.containerHeight = this.getContainerHeight(); | ||
if (typeof window !== 'undefined' && this.props.scrollContainer === window) { | ||
if (typeof window !== 'undefined' && scrollContainer === window) { | ||
this.containerOffset = ReactDOM.findDOMNode(this).getBoundingClientRect().top | ||
+ window.scrollY; | ||
} else { | ||
this.containerOffset = 0; | ||
this.containerOffset = (ReactDOM.findDOMNode(this).getBoundingClientRect().top | ||
+ scrollContainer.scrollTop) | ||
- scrollContainer.getBoundingClientRect().top; | ||
} | ||
@@ -508,0 +511,0 @@ this.scrollBuffer = this.containerHeight * 2; |
@@ -57,3 +57,3 @@ // @flow | ||
window.removeEventListener('resize', this.updateBreakpoint); | ||
document.removeEventListener('focus', this.restrictFocus); | ||
document.removeEventListener('focus', this.restrictFocus, true); | ||
@@ -60,0 +60,0 @@ if (document.body) { |
@@ -38,3 +38,3 @@ // @flow | ||
bold | ||
color={isSelected ? 'dark-gray' : 'gray'} | ||
color={isSelected ? 'darkGray' : 'gray'} | ||
align="center" | ||
@@ -41,0 +41,0 @@ truncate |
@@ -68,3 +68,3 @@ // @flow | ||
> | ||
<Icon icon="arrow-down" size={14} color="dark-gray" ariaLabel="" /> | ||
<Icon icon="arrow-down" size={14} color="darkGray" ariaLabel="" /> | ||
</Box> | ||
@@ -71,0 +71,0 @@ <select |
@@ -21,3 +21,3 @@ // @flow | ||
children?: any, | ||
color?: 'blue' | 'dark-gray' | 'gray' | 'red' | 'white', /* default: dark-gray */ | ||
color?: 'blue' | 'darkGray' | 'gray' | 'red' | 'white', /* default: darkGray */ | ||
inline?: bool, /* default: false */ | ||
@@ -95,3 +95,3 @@ italic?: bool, /* default: false */ | ||
</Text> | ||
<Text color="dark-gray"> | ||
<Text color="darkGray"> | ||
Dark Gray (default) | ||
@@ -115,3 +115,3 @@ </Text> | ||
<div className="mb2"> | ||
<Text color="dark-gray">Dark Gray (default)</Text> | ||
<Text color="darkGray">Dark Gray (default)</Text> | ||
</div> | ||
@@ -118,0 +118,0 @@ <div className="mb2"> |
@@ -6,2 +6,12 @@ // @flow | ||
type Color = 'blue' | 'darkGray' | 'gray' | 'red' | 'white'; | ||
const textColor = (color: Color) => { | ||
switch (color) { | ||
case 'darkGray': | ||
return 'dark-gray'; | ||
default: | ||
return color; | ||
} | ||
}; | ||
type Props = { | ||
@@ -11,3 +21,3 @@ align?: 'left' | 'right' | 'center' | 'justify', | ||
children?: any, | ||
color?: 'blue' | 'dark-gray' | 'gray' | 'red' | 'white', | ||
color?: Color, | ||
inline?: bool, | ||
@@ -25,3 +35,3 @@ italic?: bool, | ||
children, | ||
color = 'dark-gray', | ||
color = 'darkGray', | ||
inline = false, | ||
@@ -34,2 +44,3 @@ italic = false, | ||
const cs = cx( | ||
@@ -39,3 +50,3 @@ 'antialiased', | ||
`text-${size}`, | ||
color, | ||
textColor(color), | ||
`text-${align}`, | ||
@@ -57,3 +68,3 @@ { | ||
children: PropTypes.node, | ||
color: PropTypes.oneOf(['blue', 'dark-gray', 'gray', 'red', 'white']), | ||
color: PropTypes.oneOf(['blue', 'darkGray', 'gray', 'red', 'white']), | ||
inline: PropTypes.bool, | ||
@@ -60,0 +71,0 @@ italic: PropTypes.bool, |
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1491112
225
25056