diff --git a/.storybook/addons.js b/.storybook/addons.js index 402ccc13e..0eb390b19 100644 --- a/.storybook/addons.js +++ b/.storybook/addons.js @@ -1,2 +1,3 @@ +import '@storybook/addon-options/register' import '@storybook/addon-actions/register' import '@storybook/addon-links/register' diff --git a/.storybook/config.js b/.storybook/config.js index d9210e7ea..34525332e 100644 --- a/.storybook/config.js +++ b/.storybook/config.js @@ -67,10 +67,8 @@ setOptions({ selectedAddonPanel: undefined, // The order of addons in the "Addons Panel" is the same as you import them in 'addons.js'. The first panel will be opened by default as you run Storybook }) -const req = require.context('../packages', true, /.stories.js$/) - function loadStories() { - req.keys().forEach(filename => req(filename)) + require('./requireStories!./empty') } configure(loadStories, module) diff --git a/.storybook/empty.js b/.storybook/empty.js new file mode 100644 index 000000000..34fca4c1b --- /dev/null +++ b/.storybook/empty.js @@ -0,0 +1,2 @@ +// This file exists to satisfy the `require('./requireStories!…')` call in +// `config.js`. It doesn't need to contain anything, it just has to exist. diff --git a/.storybook/requireStories.js b/.storybook/requireStories.js new file mode 100644 index 000000000..84d28a460 --- /dev/null +++ b/.storybook/requireStories.js @@ -0,0 +1,34 @@ +const glob = require('glob') + +module.exports = function noop() {} +module.exports.pitch = function pitch() { + // This is a temp fix for storybooks. If we are running static builds we'll have the PACKAGE var + // and we need to work from within that package. Otherwise we are running the server and we know + // we are inside the packages directory already + const packagesRoot = process.env.PACKAGE + ? `${__dirname}/../../packages/${process.env.PACKAGE}` + : process.cwd() + + // Prevent node_modules from being loaded + const storiesPattern = `${packagesRoot}/packages/*/stories/**/*.stories.js` + const storybookFiles = glob.sync(storiesPattern, { cwd: __dirname }) + + console.log('require the following stories:') + + // Pretty print the stories that are being loaded for testing + console.log( + JSON.stringify( + storybookFiles.map(x => x.substr(x.indexOf('evergreen/packages'))), + null, + 2, + ), + ) + + console.log(`Loading ${storybookFiles.length} storybook files`) + + const storyRequireStatements = storybookFiles + .map(storyPath => `require(${JSON.stringify(storyPath)});`) + .join('\n') + + return storyRequireStatements +} diff --git a/packages/evergreen-autocomplete/src/components/Autocomplete.js b/packages/evergreen-autocomplete/src/components/Autocomplete.js index a3b192c0b..e5df16d6e 100644 --- a/packages/evergreen-autocomplete/src/components/Autocomplete.js +++ b/packages/evergreen-autocomplete/src/components/Autocomplete.js @@ -2,32 +2,34 @@ import React, { PureComponent } from 'react' import PropTypes from 'prop-types' import fuzzaldrin from 'fuzzaldrin-plus' import Downshift from 'downshift' -import VirtualList from 'react-tiny-virtual-list' -import AutocompleteItem from './AutocompleteItem' import { Pane } from 'evergreen-layers' -import { Text } from 'evergreen-typography' import { Popover } from 'evergreen-popover' +import VirtualList from 'react-tiny-virtual-list' +import AutocompleteItem from './AutocompleteItem' const fuzzyFilter = (items, input) => fuzzaldrin.filter(items, input) const autocompleteItemRenderer = props => +// https://github.com/paypal/downshift/issues/164 export default class Autocomplete extends PureComponent { static propTypes = { children: PropTypes.func, itemSize: PropTypes.number, renderItem: PropTypes.func, itemsFilter: PropTypes.func, + isFilterDisabled: PropTypes.bool, popoverMaxHeight: PropTypes.number, useSmartPositioning: PropTypes.bool, ...Downshift.propTypes, } static defaultProps = { - itemsFilter: fuzzyFilter, - useSmartPositioning: false, itemSize: 32, + itemsFilter: fuzzyFilter, + isFilterDisabled: false, popoverMaxHeight: 240, + useSmartPositioning: false, renderItem: autocompleteItemRenderer, } @@ -40,14 +42,16 @@ export default class Autocomplete extends PureComponent { getItemProps, }) => { const { - itemsFilter, itemSize, + itemsFilter, items: originalItems, - popoverMaxHeight, renderItem, + popoverMaxHeight, + isFilterDisabled, } = this.props + const items = - inputValue.trim() === '' + isFilterDisabled || inputValue.trim() === '' ? originalItems : itemsFilter(originalItems, inputValue) @@ -56,12 +60,12 @@ export default class Autocomplete extends PureComponent { {items.length > 0 && ( { const item = items[index] return renderItem( @@ -70,11 +74,13 @@ export default class Autocomplete extends PureComponent { key: item, index, style, - onClick: () => selectItemAtIndex(index), - isHighlighted: highlightedIndex === index, isEven: index % 2 === 1, - isSelected: selectedItem === item, children: item, + onMouseUp: () => { + selectItemAtIndex(index) + }, + isSelected: selectedItem === item, + isHighlighted: highlightedIndex === index, }), ) }} @@ -108,7 +114,8 @@ export default class Autocomplete extends PureComponent { }) => (
this.renderResults({ width: targetRect.width, @@ -118,8 +125,8 @@ export default class Autocomplete extends PureComponent { highlightedIndex, selectItemAtIndex, })} - display="inline-block" - isOpen={isOpen} + animationDuration={0} + useSmartPositioning={useSmartPositioning} > {({ isOpen: isOpenPopover, toggle, getRef, key }) => children({ diff --git a/packages/evergreen-autocomplete/src/components/AutocompleteItem.js b/packages/evergreen-autocomplete/src/components/AutocompleteItem.js index e0f0990e2..3b8f4bcbf 100644 --- a/packages/evergreen-autocomplete/src/components/AutocompleteItem.js +++ b/packages/evergreen-autocomplete/src/components/AutocompleteItem.js @@ -22,6 +22,7 @@ export default class AutocompleteItem extends PureComponent { children, ...props } = this.props + return ( - + {children} diff --git a/packages/evergreen-buttons/package.json b/packages/evergreen-buttons/package.json index db69927e7..9d02630a4 100644 --- a/packages/evergreen-buttons/package.json +++ b/packages/evergreen-buttons/package.json @@ -19,6 +19,7 @@ }, "dependencies": { "evergreen-colors": "^2.2.6", + "evergreen-shared-styles": "^2.2.6", "evergreen-typography": "^2.2.6", "ui-box": "^0.4.1" } diff --git a/packages/evergreen-buttons/src/components/Button.js b/packages/evergreen-buttons/src/components/Button.js index 3fd1585de..9b321a8fb 100644 --- a/packages/evergreen-buttons/src/components/Button.js +++ b/packages/evergreen-buttons/src/components/Button.js @@ -1,20 +1,12 @@ import React, { PureComponent } from 'react' import PropTypes from 'prop-types' -import { Text, TextStyles } from 'evergreen-typography' +import { Text } from 'evergreen-typography' +import { + getBorderRadiusForControlHeight, + getTextStyleForControlHeight, +} from 'evergreen-shared-styles' import ButtonAppearances from '../styles/button-appearances' -const getTextStyleForButton = ({ height }) => { - // HACK: add padding top to visually align in center - if (height <= 24) return { ...TextStyles['200'], paddingTop: 1 } - if (height <= 28) return TextStyles['300'] - if (height <= 32) return TextStyles['300'] - if (height <= 36) return TextStyles['400'] - if (height <= 40) return TextStyles['400'] - if (height <= 48) return TextStyles['500'] - if (height <= 56) return TextStyles['700'] - return TextStyles['800'] -} - export default class Button extends PureComponent { static propTypes = { ...Text.propTypes, @@ -24,6 +16,7 @@ export default class Button extends PureComponent { static defaultProps = { is: 'button', + position: 'relative', appearance: 'default', paddingTop: 0, paddingBottom: 0, @@ -47,10 +40,15 @@ export default class Button extends PureComponent { ...props } = this.props const appearanceStyle = ButtonAppearances[appearance] - const textStyle = getTextStyleForButton({ height }) + const textStyle = getTextStyleForControlHeight({ height }) + const borderRadius = getBorderRadiusForControlHeight({ height }) return ( +``` + +## Prop types and default props + +```js +static propTypes = { + ...Box.propTypes, + items: PropTypes.array, + width: PropTypes.oneOf(PropTypes.string, PropTypes.number), + height: PropTypes.number, + onChange: PropTypes.func, + inputProps: PropTypes.objectOf(TextInput.propTypes), + buttonProps: PropTypes.objectOf(Button.propTypes), +} +``` + + +## Complete Story +```jsx +import { storiesOf } from '@storybook/react' +import React from 'react' +import Box from 'ui-box' +import starWarsNames from 'starwars-names' +import { Combobox } from '../src/' + +// Generate a big list of items +const items = [ + ...starWarsNames.all, + ...starWarsNames.all.map(x => `${x} 2`), + ...starWarsNames.all.map(x => `${x} 3`), +].sort((a, b) => { + const nameA = a.toUpperCase() + const nameB = b.toUpperCase() + if (nameA < nameB) { + return -1 + } + if (nameA > nameB) { + return 1 + } + + return 0 +}) + +const handleChange = selectedItem => { + // eslint-disable-next-line no-console + console.log(selectedItem) +} + +storiesOf('combobox', module).add('Combobox', () => ( + + {(() => { + document.body.style.margin = '0' + document.body.style.height = '100vh' + })()} + + +)) +``` diff --git a/packages/evergreen-combobox/package.json b/packages/evergreen-combobox/package.json new file mode 100644 index 000000000..1b3908435 --- /dev/null +++ b/packages/evergreen-combobox/package.json @@ -0,0 +1,29 @@ +{ + "name": "evergreen-combobox", + "version": "1.0.0", + "description": "React components: Combobox", + "main": "lib/index.js", + "keywords": [ + "evergreen", + "segment", + "ui", + "react", + "Combobox" + ], + "author": "Segment", + "license": "MIT", + "dependencies": { + "evergreen-autocomplete": "^2.4.0", + "evergreen-buttons": "^2.2.6", + "evergreen-icons": "^2.2.7", + "evergreen-text-input": "^2.2.8", + "prop-types": "^15.0.0", + "ui-box": "^0.4.0" + }, + "peerDependencies": { + "react": "^16.0.0" + }, + "devDependencies": { + "starwars-names": "^1.6.0" + } +} diff --git a/packages/evergreen-combobox/src/components/Combobox.js b/packages/evergreen-combobox/src/components/Combobox.js new file mode 100644 index 000000000..9133d4d8d --- /dev/null +++ b/packages/evergreen-combobox/src/components/Combobox.js @@ -0,0 +1,102 @@ +import React, { PureComponent } from 'react' +import { Autocomplete } from 'evergreen-autocomplete' +import { TextInput } from 'evergreen-text-input' +import { Button } from 'evergreen-buttons' +import { TriangleIcon } from 'evergreen-icons' +import PropTypes from 'prop-types' +import Box from 'ui-box' + +export default class Combobox extends PureComponent { + static propTypes = { + ...Box.propTypes, + items: PropTypes.array, + width: PropTypes.oneOf(PropTypes.string, PropTypes.number), + height: PropTypes.number, + onChange: PropTypes.func, + inputProps: PropTypes.objectOf(TextInput.propTypes), + buttonProps: PropTypes.objectOf(Button.propTypes), + } + + constructor(props, context) { + super(props, context) + this.state = { + isOpenedByButton: false, + } + } + + handleStateChange = changes => { + if (Object.prototype.hasOwnProperty.call(changes, 'isOpen')) { + if (!changes.isOpen) { + this.setState({ isOpenedByButton: false }) + } + } + } + + render() { + const { + items, + onChange, + height, + width, + inputProps, + buttonProps, + ...props + } = this.props + + return ( + + {({ + key, + getRef, + isOpen, + inputValue, + getInputProps, + getButtonProps, + }) => ( + getRef(ref)} + display="inline-flex" + key={key} + width={width} + {...props} + > + + + + )} + + ) + } +} diff --git a/packages/evergreen-combobox/src/index.js b/packages/evergreen-combobox/src/index.js new file mode 100644 index 000000000..7e387a273 --- /dev/null +++ b/packages/evergreen-combobox/src/index.js @@ -0,0 +1,4 @@ +import Combobox from './components/Combobox' + +export default Combobox +export { Combobox } diff --git a/packages/evergreen-combobox/stories/index.stories.js b/packages/evergreen-combobox/stories/index.stories.js new file mode 100644 index 000000000..e856b2868 --- /dev/null +++ b/packages/evergreen-combobox/stories/index.stories.js @@ -0,0 +1,38 @@ +import { storiesOf } from '@storybook/react' +import React from 'react' +import Box from 'ui-box' +import starWarsNames from 'starwars-names' +import { Combobox } from '../src/' + +// Generate a big list of items +const items = [ + ...starWarsNames.all, + ...starWarsNames.all.map(x => `${x} 2`), + ...starWarsNames.all.map(x => `${x} 3`), +].sort((a, b) => { + const nameA = a.toUpperCase() + const nameB = b.toUpperCase() + if (nameA < nameB) { + return -1 + } + if (nameA > nameB) { + return 1 + } + + return 0 +}) + +const handleChange = selectedItem => { + // eslint-disable-next-line no-console + console.log(selectedItem) +} + +storiesOf('combobox', module).add('Combobox', () => ( + + {(() => { + document.body.style.margin = '0' + document.body.style.height = '100vh' + })()} + + +)) diff --git a/packages/evergreen-combobox/yarn.lock b/packages/evergreen-combobox/yarn.lock new file mode 100644 index 000000000..47b879e74 --- /dev/null +++ b/packages/evergreen-combobox/yarn.lock @@ -0,0 +1,275 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +asap@~2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + +bowser@^1.7.3: + version "1.8.1" + resolved "https://registry.yarnpkg.com/bowser/-/bowser-1.8.1.tgz#49785777e7302febadb1a5b71d9a646520ed310d" + +chain-function@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/chain-function/-/chain-function-1.0.0.tgz#0d4ab37e7e18ead0bdc47b920764118ce58733dc" + +classnames@^2.2.5: + version "2.2.5" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.2.5.tgz#fb3801d453467649ef3603c7d61a02bd129bde6d" + +core-js@^1.0.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + +css-in-js-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-2.0.0.tgz#5af1dd70f4b06b331f48d22a3d86e0786c0b9435" + dependencies: + hyphenate-style-name "^1.0.2" + +dom-helpers@^3.2.0, dom-helpers@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.2.1.tgz#3203e07fed217bd1f424b019735582fc37b2825a" + +downshift@^1.16.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/downshift/-/downshift-1.16.1.tgz#c8c12e1fc2d053b6d926882d257a88c3e57c1982" + +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + dependencies: + iconv-lite "~0.4.13" + +evergreen-autocomplete@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/evergreen-autocomplete/-/evergreen-autocomplete-2.4.0.tgz#26ce45c6be2096e6ccae263ff2a0953953944d14" + dependencies: + downshift "^1.16.0" + evergreen-layers "^2.2.6" + evergreen-popover "^2.3.0" + evergreen-typography "^2.2.6" + fuzzaldrin-plus "^0.5.0" + prop-types "^15.0.0" + react-tiny-virtual-list "^2.1.4" + ui-box "^0.4.0" + +evergreen-buttons@^2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/evergreen-buttons/-/evergreen-buttons-2.2.6.tgz#76fecde2633263c0554291b8735a9a064806545f" + dependencies: + evergreen-colors "^2.2.6" + evergreen-typography "^2.2.6" + ui-box "^0.4.1" + +evergreen-colors@^2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/evergreen-colors/-/evergreen-colors-2.2.6.tgz#229277e934eab18de8ac67d4fedf565f59502497" + +evergreen-icons@^2.2.7: + version "2.2.7" + resolved "https://registry.yarnpkg.com/evergreen-icons/-/evergreen-icons-2.2.7.tgz#1edd3c9c2140724da48ce86122758ecee2294237" + dependencies: + ui-box "^0.4.1" + +evergreen-layers@^2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/evergreen-layers/-/evergreen-layers-2.2.6.tgz#d65e9056ae2fc4eb41e0a73577fb7d41d4a8d672" + dependencies: + evergreen-colors "^2.2.6" + ui-box "^0.4.1" + +evergreen-popover@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/evergreen-popover/-/evergreen-popover-2.3.0.tgz#26bf65dcee76a9d308b2a3c070c12d2e9b75ee4a" + dependencies: + evergreen-layers "^2.2.6" + evergreen-portal "^2.2.6" + object-values "^1.0.0" + react-transition-group "^2.2.1" + ui-box "^0.4.1" + +evergreen-portal@^2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/evergreen-portal/-/evergreen-portal-2.2.6.tgz#2bb507bf01c95dd3ce428888fe533b4d9b94df14" + dependencies: + dom-helpers "^3.2.1" + ui-box "^0.4.1" + +evergreen-shared-styles@^2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/evergreen-shared-styles/-/evergreen-shared-styles-2.2.6.tgz#0acb2263c06f1ad648e975e95b42d96f13361e39" + dependencies: + evergreen-colors "^2.2.6" + evergreen-typography "^2.2.6" + ui-box "^0.4.1" + +evergreen-text-input@^2.2.8: + version "2.2.8" + resolved "https://registry.yarnpkg.com/evergreen-text-input/-/evergreen-text-input-2.2.8.tgz#d895a686bd3628622d34ff884b97d3e072a92d35" + dependencies: + evergreen-colors "^2.2.6" + evergreen-shared-styles "^2.2.6" + evergreen-typography "^2.2.6" + ui-box "^0.4.1" + +evergreen-typography@^2.2.6: + version "2.2.6" + resolved "https://registry.yarnpkg.com/evergreen-typography/-/evergreen-typography-2.2.6.tgz#9d7fa8a2892e353069c6f6d37eddf6843bd1f765" + dependencies: + evergreen-colors "^2.2.6" + ui-box "^0.4.1" + +fbjs@^0.8.12, fbjs@^0.8.16: + version "0.8.16" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db" + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.9" + +fuzzaldrin-plus@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/fuzzaldrin-plus/-/fuzzaldrin-plus-0.5.0.tgz#ef5f26f0c2fc7e9e9a16ea149a802d6cb4804b1e" + +glamor@^2.20.22: + version "2.20.40" + resolved "https://registry.yarnpkg.com/glamor/-/glamor-2.20.40.tgz#f606660357b7cf18dface731ad1a2cfa93817f05" + dependencies: + fbjs "^0.8.12" + inline-style-prefixer "^3.0.6" + object-assign "^4.1.1" + prop-types "^15.5.10" + through "^2.3.8" + +hyphenate-style-name@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.2.tgz#31160a36930adaf1fc04c6074f7eb41465d4ec4b" + +iconv-lite@~0.4.13: + version "0.4.19" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" + +inline-style-prefixer@^3.0.6: + version "3.0.8" + resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-3.0.8.tgz#8551b8e5b4d573244e66a34b04f7d32076a2b534" + dependencies: + bowser "^1.7.3" + css-in-js-utils "^2.0.0" + +is-stream@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +isomorphic-fetch@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + +js-tokens@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + +loose-envify@^1.0.0, loose-envify@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + dependencies: + js-tokens "^3.0.0" + +node-fetch@^1.0.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +object-assign@^4.1.0, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +object-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/object-values/-/object-values-1.0.0.tgz#72af839630119e5b98c3b02bb8c27e3237158105" + +promise@^7.1.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + dependencies: + asap "~2.0.3" + +prop-types@^15.0.0, prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.5.8: + version "15.6.0" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856" + dependencies: + fbjs "^0.8.16" + loose-envify "^1.3.1" + object-assign "^4.1.1" + +react-tiny-virtual-list@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/react-tiny-virtual-list/-/react-tiny-virtual-list-2.1.4.tgz#a574c4dfd8ccf462e3a335f665cffbfd08ce6e7d" + dependencies: + prop-types "^15.5.7" + +react-transition-group@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.2.1.tgz#e9fb677b79e6455fd391b03823afe84849df4a10" + dependencies: + chain-function "^1.0.0" + classnames "^2.2.5" + dom-helpers "^3.2.0" + loose-envify "^1.3.1" + prop-types "^15.5.8" + warning "^3.0.0" + +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + +starwars-names@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/starwars-names/-/starwars-names-1.6.0.tgz#5f984b5a954714eb383b4d6c19234efea6398335" + dependencies: + unique-random-array "1.0.0" + +through@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +ua-parser-js@^0.7.9: + version "0.7.17" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac" + +ui-box@^0.4.0, ui-box@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/ui-box/-/ui-box-0.4.1.tgz#410f7b14ef9abdfac10973e21ba6fc1e1d0fa072" + dependencies: + classnames "^2.2.5" + glamor "^2.20.22" + +unique-random-array@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-random-array/-/unique-random-array-1.0.0.tgz#42b3721c579388d8b667c93c2dbde3d5d81a9136" + dependencies: + unique-random "^1.0.0" + +unique-random@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-random/-/unique-random-1.0.0.tgz#ce3e224c8242cd33a0e77b0d7180d77e6b62d0c4" + +warning@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c" + dependencies: + loose-envify "^1.0.0" + +whatwg-fetch@>=0.10.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" diff --git a/packages/evergreen-icons/src/components/Icon.js b/packages/evergreen-icons/src/components/Icon.js index 67b4bf531..ead81f522 100644 --- a/packages/evergreen-icons/src/components/Icon.js +++ b/packages/evergreen-icons/src/components/Icon.js @@ -17,6 +17,7 @@ export default class Icon extends PureComponent { ...Box.propTypes, aim: PropTypes.oneOf(Object.keys(IconAim)).isRequired, size: PropTypes.number, + iconSize: PropTypes.number, } static defaultProps = { @@ -26,10 +27,11 @@ export default class Icon extends PureComponent { alignItems: 'center', justifyContent: 'center', size: 32, + iconSize: 16, } render() { - const { aim, transform, size, ...props } = this.props + const { aim, transform, size, iconSize, children, ...props } = this.props let totalTransform = transform || '' if (aim) { @@ -37,7 +39,18 @@ export default class Icon extends PureComponent { } return ( - + + + {children} + + ) } } diff --git a/packages/evergreen-popover/src/components/Popover.js b/packages/evergreen-popover/src/components/Popover.js index e95d77177..98dc18fdb 100644 --- a/packages/evergreen-popover/src/components/Popover.js +++ b/packages/evergreen-popover/src/components/Popover.js @@ -10,29 +10,31 @@ export default class Popover extends Component { onOpen: PropTypes.func.isRequired, // Use isOpen to manually control the Popover isOpen: PropTypes.bool, + zIndex: PropTypes.number, onClose: PropTypes.func.isRequired, content: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired, children: PropTypes.oneOfType([PropTypes.element, PropTypes.func]) .isRequired, - useSmartPositioning: PropTypes.bool, + display: PropTypes.string, minWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), minHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), - zIndex: PropTypes.number, - display: PropTypes.string, bodyOffset: PropTypes.number, targetOffset: PropTypes.number, + animationDuration: PropTypes.number, + useSmartPositioning: PropTypes.bool, } static defaultProps = { side: PopoverSides.BOTTOM, - useSmartPositioning: true, + zIndex: 50, onOpen: () => {}, onClose: () => {}, minWidth: 200, minHeight: 40, - zIndex: 50, bodyOffset: 8, targetOffset: 4, + useSmartPositioning: true, + animationDuration: 300, } constructor() { @@ -132,17 +134,18 @@ export default class Popover extends Component { render() { const { - children, - content, side, - useSmartPositioning, + zIndex, + isOpen, + content, + display, + children, minWidth, minHeight, - display, - zIndex, bodyOffset, targetOffset, - isOpen, + animationDuration, + useSmartPositioning, } = this.props const { isOpen: stateIsOpen, targetRect } = this.state @@ -170,16 +173,17 @@ export default class Popover extends Component { innerRef={ref => { this.popoverNode = ref }} - isOpen={open} - targetRect={targetRect} side={side} - useSmartPositioning={useSmartPositioning} + isOpen={open} + zIndex={zIndex} + display={display} minWidth={minWidth} minHeight={minHeight} - display={display} - zIndex={zIndex} + targetRect={targetRect} bodyOffset={bodyOffset} targetOffset={targetOffset} + animationDuration={animationDuration} + useSmartPositioning={useSmartPositioning} > {typeof content === 'function' ? content({ targetRect, close: this.close }) diff --git a/packages/evergreen-popover/src/components/PopoverContentCard.js b/packages/evergreen-popover/src/components/PopoverContentCard.js index dbbeb28fd..ecfc51462 100644 --- a/packages/evergreen-popover/src/components/PopoverContentCard.js +++ b/packages/evergreen-popover/src/components/PopoverContentCard.js @@ -6,7 +6,6 @@ import { Card } from 'evergreen-layers' import { Portal } from 'evergreen-portal' import PopoverSides from '../popover-sides' -const ANIMATION_DURATION = 300 const INITIAL_SCALE = 0.9 const animationEasing = { @@ -17,10 +16,10 @@ const animationEasing = { spring: `cubic-bezier(0.175, 0.885, 0.320, 1.175)`, } -const styles = ({ targetOffset }) => ({ +const styles = ({ targetOffset, animationDuration }) => ({ position: 'absolute', opacity: 0, - transition: `all ${ANIMATION_DURATION}ms ${animationEasing.spring}`, + transition: `all ${animationDuration}ms ${animationEasing.spring}`, transform: `scale(${INITIAL_SCALE}) translateY(-4px)`, '&[data-state="entering"][data-position="bottom"], &[data-state="entered"][data-position="bottom"]': { opacity: 1, @@ -48,14 +47,19 @@ const initialState = () => ({ export default class PopoverContentCard extends Component { static propTypes = { ...Card.propTypes, - children: PropTypes.node, side: PropTypes.oneOf(objectValues(PopoverSides)), isOpen: PropTypes.bool.isRequired, - useSmartPositioning: PropTypes.bool, zIndex: PropTypes.number, + children: PropTypes.node, innerRef: PropTypes.func, bodyOffset: PropTypes.number, targetOffset: PropTypes.number, + animationDuration: PropTypes.number, + useSmartPositioning: PropTypes.bool, + } + + static defaultProps = { + animationDuration: 300, } constructor() { @@ -117,7 +121,14 @@ export default class PopoverContentCard extends Component { } render() { - const { children, isOpen, zIndex, innerRef, targetOffset } = this.props + const { + children, + isOpen, + zIndex, + innerRef, + targetOffset, + animationDuration, + } = this.props const { left, top, side, transformOriginX } = this.state @@ -130,7 +141,7 @@ export default class PopoverContentCard extends Component { { template.push(` .add('${componentName}', () =>`) - template.push(`
`) + template.push(` `) + template.push(` {(() => {`) + template.push(` document.body.style.margin = '0'`) + template.push(` document.body.style.height = '100vh'`) + template.push(` })()}`) template.push(` <${componentName}>${componentName}`) - template.push(`
,`) + template.push(`
,`) template.push(` )`) }) return template.join('\n')