From 0741b2b3bee9483127f888d783ca35b22afa6985 Mon Sep 17 00:00:00 2001 From: Will Lopez Date: Wed, 14 Aug 2019 15:17:39 -0700 Subject: [PATCH 01/22] feat: add MultiSelect component Signed-off-by: Will Lopez --- package/package.json | 6 +- .../src/components/MultiSelect/MultiSelect.js | 193 ++++++++++++++++++ .../src/components/MultiSelect/MultiSelect.md | 53 +++++ .../components/MultiSelect/helpers/Control.js | 56 +++++ .../components/MultiSelect/helpers/Input.js | 21 ++ .../components/MultiSelect/helpers/Menu.js | 32 +++ .../MultiSelect/helpers/MultiValue.js | 33 +++ .../MultiSelect/helpers/NoOptionsMessage.js | 35 ++++ .../components/MultiSelect/helpers/Option.js | 60 ++++++ .../MultiSelect/helpers/Placeholder.js | 33 +++ .../MultiSelect/helpers/ValueContainer.js | 23 +++ .../components/MultiSelect/helpers/index.js | 17 ++ package/src/components/MultiSelect/index.js | 1 + package/yarn.lock | 180 +++++++++++++++- styleguide.config.js | 6 + 15 files changed, 743 insertions(+), 6 deletions(-) create mode 100644 package/src/components/MultiSelect/MultiSelect.js create mode 100644 package/src/components/MultiSelect/MultiSelect.md create mode 100644 package/src/components/MultiSelect/helpers/Control.js create mode 100644 package/src/components/MultiSelect/helpers/Input.js create mode 100644 package/src/components/MultiSelect/helpers/Menu.js create mode 100644 package/src/components/MultiSelect/helpers/MultiValue.js create mode 100644 package/src/components/MultiSelect/helpers/NoOptionsMessage.js create mode 100644 package/src/components/MultiSelect/helpers/Option.js create mode 100644 package/src/components/MultiSelect/helpers/Placeholder.js create mode 100644 package/src/components/MultiSelect/helpers/ValueContainer.js create mode 100644 package/src/components/MultiSelect/helpers/index.js create mode 100644 package/src/components/MultiSelect/index.js diff --git a/package/package.json b/package/package.json index 4af22793..c3eb272e 100644 --- a/package/package.json +++ b/package/package.json @@ -23,13 +23,15 @@ "dependencies": { "@babel/runtime": "~7.3.1", "accounting-js": "~1.1.1", + "clsx": "^1.0.4", "lodash.debounce": "~4.0.8", "lodash.get": "~4.4.2", "lodash.isempty": "~4.4.0", "lodash.isequal": "~4.5.0", "lodash.uniqueid": "~4.0.1", "mdi-material-ui": "~5.8.0", - "react-is": "~16.4.1" + "react-is": "~16.4.1", + "react-select": "^3.0.4" }, "devDependencies": { "@babel/cli": "~7.2.3", @@ -86,8 +88,8 @@ "access": "public" }, "peerDependencies": { - "@reactioncommerce/components-context": "~1.2.0", "@material-ui/core": ">=4.2.0 < 5", + "@reactioncommerce/components-context": "~1.2.0", "prop-types": "~15.6.2", "react-dom": "~16.8.6" } diff --git a/package/src/components/MultiSelect/MultiSelect.js b/package/src/components/MultiSelect/MultiSelect.js new file mode 100644 index 00000000..19a9edb2 --- /dev/null +++ b/package/src/components/MultiSelect/MultiSelect.js @@ -0,0 +1,193 @@ +import React, { useState } from "react"; +import PropTypes from "prop-types"; +import Select from "react-select"; +import AsyncSelect from "react-select/async"; +import { makeStyles, useTheme } from "@material-ui/core/styles"; +import { + Control, + Menu, + MultiValue, + NoOptionsMessage, + Option, + Placeholder, + ValueContainer +} from "./helpers"; + +const useStyles = makeStyles((theme) => ({ + root: { + flexGrow: 1, + height: 250, + minWidth: 290 + }, + input: { + display: "flex", + padding: 0, + height: "auto" + }, + valueContainer: { + display: "flex", + alignItems: "center", + flexWrap: "wrap", + flex: 1, + overflow: "hidden", + paddingLeft: theme.spacing(1), + paddingRight: theme.spacing(1) + }, + chip: { + margin: theme.spacing(0.5, 0.25) + }, + noOptionsMessage: { + padding: theme.spacing(1, 2) + }, + placeholder: { + position: "absolute", + left: theme.spacing(1), + fontSize: theme.typography.fontSize + }, + paper: { + position: "absolute", + zIndex: 1, + marginTop: theme.spacing(1), + left: 0, + right: 0 + }, + divider: { + height: theme.spacing(2) + } +})); + +// Rather than pass through all props to react-select, we'll keep a whitelist +// to better control the usage and appearance of this component. +const supportedPassthroughProps = [ + "async", + "cacheOptions", + "classes", + "defaultOptions", + "loadOptions", + "placeholder", + "onSelection", + "options" +]; + +// Custom components for various aspects of the select +const components = { + Control, + Menu, + MultiValue, + NoOptionsMessage, + Option, + Placeholder, + ValueContainer +}; + +/** + * @name MultiSelect + * @summary A Select component that supports selecting multiple options, and + * loading options asynchronously and synchronously. + * @param {Object} props - component props + * @returns {React.Component} A React component + */ +const MultiSelect = React.forwardRef(function MultiSelect(props, ref) { + const defaultClasses = useStyles(); + const theme = useTheme(); + const [value, setValue] = useState(null); + + const passThroughProps = {}; + supportedPassthroughProps.forEach((supportedProp) => { + passThroughProps[supportedProp] = props[supportedProp]; + }); + + const { classes, isAsync, onSelection } = props; + const SelectComponent = isAsync ? AsyncSelect : Select; + + /** + * + * @param {String} selectedValue The selected value + * @returns {undefined} nothing + */ + function handleChangeMulti(selectedValue) { + setValue(selectedValue); + onSelection(selectedValue); + } + + const selectStyles = { + input: (base) => ({ + ...base, + "color": theme.palette.text.primary, + "& input": { + font: "inherit" + } + }) + }; + + return ( +
+ +
+ ); +}); + +MultiSelect.defaultProps = { + placeholder: "Select options" +}; + +MultiSelect.propTypes = { + /** + * When provided options will be cached + */ + cacheOptions: PropTypes.bool, // eslint-disable-line react/boolean-prop-naming + /** + * Additional classes to customize the Select component + */ + classes: PropTypes.string, + /** + * The defaultOptions prop determines "when" your remote request is initially fired. + * There are two valid values for this property. + * Providing an option array to this prop will populate the initial set of options + * used when opening the select, at which point the remote load only occurs + * when filtering the options (typing in the control). + * Providing the prop by itself (or with 'true') tells the control to immediately + * fire the remote request, described by your loadOptions, + * to get those initial values for the Select. + */ + defaultOptions: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.bool]), + /** + * Set to true if options will be fetched asynchronously. + */ + isAsync: PropTypes.bool, + /** + * A function that returns a Promise which will load the options + */ + loadOptions: PropTypes.func, + /** + * Function to call when the selected value changes + */ + onSelection: PropTypes.func, + /** + * The select options + */ + options: PropTypes.arrayOf(PropTypes.object), + /** + * The placeholder string + */ + placeholder: PropTypes.string +}; + +export default MultiSelect; diff --git a/package/src/components/MultiSelect/MultiSelect.md b/package/src/components/MultiSelect/MultiSelect.md new file mode 100644 index 00000000..29ed819b --- /dev/null +++ b/package/src/components/MultiSelect/MultiSelect.md @@ -0,0 +1,53 @@ +Multi value select with options provided synchronously +```jsx +const options = [ + { value: "mens", label: "Mens" }, + { value: "womens", label: "Womens" }, + { value: "kids", label: "Kids" } +]; + +// Log selected value +function handleOnSelection(value) { + console.log("Selected value: ", value); +} + + +``` + +Multi value select with options provided asynchronously +```jsx +const options = [ + { value: "mens", label: "Mens" }, + { value: "womens", label: "Womens" }, + { value: "kids", label: "Kids" } +]; + +const filterOptions = (inputValue) => options.filter((i) => { + return i.label.toLowerCase().includes(inputValue.toLowerCase()); +}); + +const promiseOptions = (inputValue) => + new Promise((resolve) => { + setTimeout(() => { + resolve(filterOptions(inputValue)); + }, 1000); + }); + +// Log selected value +function handleOnSelection(value) { + console.log("Selected value: ", value); +} + + +``` diff --git a/package/src/components/MultiSelect/helpers/Control.js b/package/src/components/MultiSelect/helpers/Control.js new file mode 100644 index 00000000..1a9e32c8 --- /dev/null +++ b/package/src/components/MultiSelect/helpers/Control.js @@ -0,0 +1,56 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { TextField } from "@material-ui/core"; +import Input from "./Input"; + +/** + * @name Control + * @param {Object} props Component props + * @returns {React.Component} A React component + */ +export default function Control(props) { + const { + children, + innerProps, + innerRef, + selectProps: { classes, TextFieldProps } + } = props; + + return ( + + ); +} + +Control.propTypes = { + /** + * Children to render. + */ + children: PropTypes.node, + /** + * The mouse down event and the innerRef to pass down to the controller element. + */ + innerProps: PropTypes.shape({ + onMouseDown: PropTypes.func.isRequired + }).isRequired, + innerRef: PropTypes.oneOfType([ + PropTypes.oneOf([null]), + PropTypes.func, + PropTypes.shape({ + current: PropTypes.any.isRequired + }) + ]).isRequired, + selectProps: PropTypes.object.isRequired +}; diff --git a/package/src/components/MultiSelect/helpers/Input.js b/package/src/components/MultiSelect/helpers/Input.js new file mode 100644 index 00000000..fa2d84b5 --- /dev/null +++ b/package/src/components/MultiSelect/helpers/Input.js @@ -0,0 +1,21 @@ +import React from "react"; +import PropTypes from "prop-types"; + +/** + * @name Input + * @param {Function } inputRef Input reference + * @param {Object} props Component props + * @returns {React.Component} A React Component + */ +export default function Input({ inputRef, ...props }) { + return
; +} + +Input.propTypes = { + inputRef: PropTypes.oneOfType([ + PropTypes.func, + PropTypes.shape({ + current: PropTypes.any.isRequired + }) + ]) +}; diff --git a/package/src/components/MultiSelect/helpers/Menu.js b/package/src/components/MultiSelect/helpers/Menu.js new file mode 100644 index 00000000..f1c7a96f --- /dev/null +++ b/package/src/components/MultiSelect/helpers/Menu.js @@ -0,0 +1,32 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { Paper } from "@material-ui/core"; + +/** + * @name Menu + * @param {Object} props Component props + * @returns {React.Component} A React component + */ +export default function Menu(props) { + return ( + + {props.children} + + ); +} + +Menu.propTypes = { + /** + * The children to be rendered. + */ + children: PropTypes.element.isRequired, + /** + * Props to be passed to the menu wrapper. + */ + innerProps: PropTypes.object.isRequired, + selectProps: PropTypes.object.isRequired +}; diff --git a/package/src/components/MultiSelect/helpers/MultiValue.js b/package/src/components/MultiSelect/helpers/MultiValue.js new file mode 100644 index 00000000..0ed64d2e --- /dev/null +++ b/package/src/components/MultiSelect/helpers/MultiValue.js @@ -0,0 +1,33 @@ +import React from "react"; +import PropTypes from "prop-types"; +import clsx from "clsx"; +import Chip from "../../Chip"; + +/** + * @name MultiValue + * @param {Object} props Component props + * @returns {React.Component} A React Component + */ +export default function MultiValue(props) { + return ( + + ); +} + +MultiValue.propTypes = { + children: PropTypes.node, + isFocused: PropTypes.bool.isRequired, + removeProps: PropTypes.shape({ + onClick: PropTypes.func.isRequired, + onMouseDown: PropTypes.func.isRequired, + onTouchEnd: PropTypes.func.isRequired + }).isRequired, + selectProps: PropTypes.object.isRequired +}; diff --git a/package/src/components/MultiSelect/helpers/NoOptionsMessage.js b/package/src/components/MultiSelect/helpers/NoOptionsMessage.js new file mode 100644 index 00000000..df05a92c --- /dev/null +++ b/package/src/components/MultiSelect/helpers/NoOptionsMessage.js @@ -0,0 +1,35 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { Typography } from "@material-ui/core"; + +/** + * @name NoOptionsMessage + * @param {Object} props Component props + * @returns {React.Component} A React Component + */ +export default function NoOptionsMessage(props) { + return ( + + {props.children} + + ); +} + +NoOptionsMessage.propTypes = { + /** + * The children to be rendered. + */ + children: PropTypes.node, + /** + * Props to be passed on to the wrapper. + */ + innerProps: PropTypes.object, + /** + * Props passed to the select, which include classes for the no options message. + */ + selectProps: PropTypes.object.isRequired +}; diff --git a/package/src/components/MultiSelect/helpers/Option.js b/package/src/components/MultiSelect/helpers/Option.js new file mode 100644 index 00000000..b490c1c0 --- /dev/null +++ b/package/src/components/MultiSelect/helpers/Option.js @@ -0,0 +1,60 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { MenuItem } from "@material-ui/core"; + +/** + * @name Option + * @param {Object} props Component props + * @returns {React.Component} A React component + */ +export default function Option(props) { + return ( + + {props.children} + + ); +} + +Option.propTypes = { + /** + * The children to be rendered. + */ + children: PropTypes.node, + /** + * props passed to the wrapping element for the group. + */ + innerProps: PropTypes.shape({ + id: PropTypes.string.isRequired, + key: PropTypes.string, + onClick: PropTypes.func.isRequired, + onMouseMove: PropTypes.func.isRequired, + onMouseOver: PropTypes.func.isRequired, + tabIndex: PropTypes.number.isRequired + }).isRequired, + /** + * Inner ref to DOM Node + */ + innerRef: PropTypes.oneOfType([ + PropTypes.oneOf([null]), + PropTypes.func, + PropTypes.shape({ + current: PropTypes.any.isRequired + }) + ]), + /** + * Whether the option is focused. + */ + isFocused: PropTypes.bool.isRequired, + /** + * Whether the option is selected. + */ + isSelected: PropTypes.bool.isRequired +}; diff --git a/package/src/components/MultiSelect/helpers/Placeholder.js b/package/src/components/MultiSelect/helpers/Placeholder.js new file mode 100644 index 00000000..7a8ed89f --- /dev/null +++ b/package/src/components/MultiSelect/helpers/Placeholder.js @@ -0,0 +1,33 @@ +import React from "react"; +import PropTypes from "prop-types"; +import { Typography } from "@material-ui/core"; + +/** + * @name Placeholder + * @param {Object} props Component props + * @returns {React.Component} A React component + */ +export default function Placeholder(props) { + const { selectProps, innerProps = {}, children } = props; + return ( + + {children} + + ); +} + +Placeholder.propTypes = { + /** + * The children to be rendered. + */ + children: PropTypes.node, + /** + * props passed to the wrapping element for the group. + */ + innerProps: PropTypes.object, + selectProps: PropTypes.object.isRequired +}; diff --git a/package/src/components/MultiSelect/helpers/ValueContainer.js b/package/src/components/MultiSelect/helpers/ValueContainer.js new file mode 100644 index 00000000..f774e864 --- /dev/null +++ b/package/src/components/MultiSelect/helpers/ValueContainer.js @@ -0,0 +1,23 @@ +import React from "react"; +import PropTypes from "prop-types"; + +/** + * @name ValueContainer + * @param {Object} props Component props + * @returns {React.Component} A React component + */ +export default function ValueContainer(props) { + return ( +
+ {props.children} +
+ ); +} + +ValueContainer.propTypes = { + /** + * The children to be rendered. + */ + children: PropTypes.node, + selectProps: PropTypes.object.isRequired +}; diff --git a/package/src/components/MultiSelect/helpers/index.js b/package/src/components/MultiSelect/helpers/index.js new file mode 100644 index 00000000..9f84a51d --- /dev/null +++ b/package/src/components/MultiSelect/helpers/index.js @@ -0,0 +1,17 @@ +import Control from "./Control"; +import Menu from "./Menu"; +import MultiValue from "./MultiValue"; +import NoOptionsMessage from "./NoOptionsMessage"; +import Option from "./Option"; +import Placeholder from "./Placeholder"; +import ValueContainer from "./ValueContainer"; + +export { + Control, + Menu, + MultiValue, + NoOptionsMessage, + Option, + Placeholder, + ValueContainer +}; diff --git a/package/src/components/MultiSelect/index.js b/package/src/components/MultiSelect/index.js new file mode 100644 index 00000000..c728fbf2 --- /dev/null +++ b/package/src/components/MultiSelect/index.js @@ -0,0 +1 @@ +export { default } from "./MultiSelect"; diff --git a/package/yarn.lock b/package/yarn.lock index 67e6d41f..319646a7 100644 --- a/package/yarn.lock +++ b/package/yarn.lock @@ -725,7 +725,7 @@ pirates "^4.0.0" source-map-support "^0.5.9" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.4.5": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.4.2", "@babel/runtime@^7.4.3", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" dependencies: @@ -774,6 +774,83 @@ exec-sh "^0.3.2" minimist "^1.2.0" +"@emotion/cache@^10.0.15", "@emotion/cache@^10.0.9": + version "10.0.15" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.15.tgz#b81767b48015aae2689c60373992145c67b8de02" + integrity sha512-8VthgeKhlGeTXSW1JN7I14AnAaiFPbOrqNqg3dPoGCZ3bnMjkrmRU0zrx0BtBw9esBaPaQgDB9y0tVgAGT2Mrg== + dependencies: + "@emotion/sheet" "0.9.3" + "@emotion/stylis" "0.8.4" + "@emotion/utils" "0.11.2" + "@emotion/weak-memoize" "0.2.3" + +"@emotion/core@^10.0.9": + version "10.0.15" + resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.0.15.tgz#b8489d85d64b45bd03abdb8a3d9639ba8a0328d0" + integrity sha512-VHwwl3k/ddMfQOHYgOJryXOs2rGJ5AfKLQGm5AVolNonnr6tkmDI4nzIMNaPpveoXVs7sP0OrF24UunIPxveQw== + dependencies: + "@babel/runtime" "^7.4.3" + "@emotion/cache" "^10.0.15" + "@emotion/css" "^10.0.14" + "@emotion/serialize" "^0.11.9" + "@emotion/sheet" "0.9.3" + "@emotion/utils" "0.11.2" + +"@emotion/css@^10.0.14", "@emotion/css@^10.0.9": + version "10.0.14" + resolved "https://registry.yarnpkg.com/@emotion/css/-/css-10.0.14.tgz#95dacabdd0e22845d1a1b0b5968d9afa34011139" + integrity sha512-MozgPkBEWvorcdpqHZE5x1D/PLEHUitALQCQYt2wayf4UNhpgQs2tN0UwHYS4FMy5ROBH+0ALyCFVYJ/ywmwlg== + dependencies: + "@emotion/serialize" "^0.11.8" + "@emotion/utils" "0.11.2" + babel-plugin-emotion "^10.0.14" + +"@emotion/hash@0.7.2": + version "0.7.2" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.7.2.tgz#53211e564604beb9befa7a4400ebf8147473eeef" + integrity sha512-RMtr1i6E8MXaBWwhXL3yeOU8JXRnz8GNxHvaUfVvwxokvayUY0zoBeWbKw1S9XkufmGEEdQd228pSZXFkAln8Q== + +"@emotion/memoize@0.7.2": + version "0.7.2" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.2.tgz#7f4c71b7654068dfcccad29553520f984cc66b30" + integrity sha512-hnHhwQzvPCW1QjBWFyBtsETdllOM92BfrKWbUTmh9aeOlcVOiXvlPsK4104xH8NsaKfg86PTFsWkueQeUfMA/w== + +"@emotion/serialize@^0.11.8", "@emotion/serialize@^0.11.9": + version "0.11.9" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-0.11.9.tgz#123e0f51d2dee9693fae1057bd7fc27b021d6868" + integrity sha512-/Cn4V81z3ZyFiDQRw8nhGFaHkxHtmCSSBUit4vgTuLA1BqxfJUYiqSq97tq/vV8z9LfIoqs6a9v6QrUFWZpK7A== + dependencies: + "@emotion/hash" "0.7.2" + "@emotion/memoize" "0.7.2" + "@emotion/unitless" "0.7.4" + "@emotion/utils" "0.11.2" + csstype "^2.5.7" + +"@emotion/sheet@0.9.3": + version "0.9.3" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-0.9.3.tgz#689f135ecf87d3c650ed0c4f5ddcbe579883564a" + integrity sha512-c3Q6V7Df7jfwSq5AzQWbXHa5soeE4F5cbqi40xn0CzXxWW9/6Mxq48WJEtqfWzbZtW9odZdnRAkwCQwN12ob4A== + +"@emotion/stylis@0.8.4": + version "0.8.4" + resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.4.tgz#6c51afdf1dd0d73666ba09d2eb6c25c220d6fe4c" + integrity sha512-TLmkCVm8f8gH0oLv+HWKiu7e8xmBIaokhxcEKPh1m8pXiV/akCiq50FvYgOwY42rjejck8nsdQxZlXZ7pmyBUQ== + +"@emotion/unitless@0.7.4": + version "0.7.4" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.4.tgz#a87b4b04e5ae14a88d48ebef15015f6b7d1f5677" + integrity sha512-kBa+cDHOR9jpRJ+kcGMsysrls0leukrm68DmFQoMIWQcXdr2cZvyvypWuGYT7U+9kAExUE7+T7r6G3C3A6L8MQ== + +"@emotion/utils@0.11.2": + version "0.11.2" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-0.11.2.tgz#713056bfdffb396b0a14f1c8f18e7b4d0d200183" + integrity sha512-UHX2XklLl3sIaP6oiMmlVzT0J+2ATTVpf0dHQVyPJHTkOITvXfaSqnRk6mdDhV9pR8T/tHc3cex78IKXssmzrA== + +"@emotion/weak-memoize@0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.3.tgz#dfa0c92efe44a1d1a7974fb49ffeb40ef2da5a27" + integrity sha512-zVgvPwGK7c1aVdUVc9Qv7SqepOGRDrqCw7KZPSZziWGxSlbII3gmvGLPzLX4d0n0BMbamBacUrN22zOMyFFEkQ== + "@jest/console@^24.7.1": version "24.7.1" resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.7.1.tgz#32a9e42535a97aedfe037e725bd67e954b459545" @@ -1668,6 +1745,22 @@ babel-plugin-dynamic-import-node@^2.3.0: dependencies: object.assign "^4.1.0" +babel-plugin-emotion@^10.0.14: + version "10.0.15" + resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-10.0.15.tgz#2ce5bea191331ef65b3b9ae212a8f0e46ff97616" + integrity sha512-E3W68Zk8EcKpRUDW2tsFKi4gsavapMRjfr2/KKgG3l7l2zZpiKk0BxB59Ul9C0w0ekv6my/ylGOk2WroaqKXPw== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@emotion/hash" "0.7.2" + "@emotion/memoize" "0.7.2" + "@emotion/serialize" "^0.11.9" + babel-plugin-macros "^2.0.0" + babel-plugin-syntax-jsx "^6.18.0" + convert-source-map "^1.5.0" + escape-string-regexp "^1.0.5" + find-root "^1.1.0" + source-map "^0.5.7" + babel-plugin-istanbul@^4.1.6: version "4.1.6" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz#36c59b2192efce81c5b378321b74175add1c9a45" @@ -1695,6 +1788,15 @@ babel-plugin-jest-hoist@^24.6.0: dependencies: "@types/babel__traverse" "^7.0.6" +babel-plugin-macros@^2.0.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.6.1.tgz#41f7ead616fc36f6a93180e89697f69f51671181" + integrity sha512-6W2nwiXme6j1n2erPOnmRiWfObUhWH7Qw1LMi9XZy8cj+KtESu3T6asZvtk5bMQQjX8te35o7CFueiSdL/2NmQ== + dependencies: + "@babel/runtime" "^7.4.2" + cosmiconfig "^5.2.0" + resolve "^1.10.0" + babel-plugin-module-resolver@~3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-3.1.3.tgz#5a1c148bf528d20907ed508b70ae3c4762e78c8d" @@ -1711,6 +1813,11 @@ babel-plugin-rewire-exports@~1.0.1: dependencies: "@babel/template" "7" +babel-plugin-syntax-jsx@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" + integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= + babel-plugin-syntax-object-rest-spread@^6.13.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" @@ -2404,6 +2511,11 @@ clone@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" +clsx@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.0.4.tgz#0c0171f6d5cb2fe83848463c15fcc26b4df8c2ec" + integrity sha512-1mQ557MIZTrL/140j+JVdRM6e31/OA4vTYxXgqIIZlndyfjHpyawKZia1Im05Vp9BWmImkcNrNtFYQMyFcgJDg== + cmd-shim@^2.0.2, cmd-shim@~2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-2.0.2.tgz#6fcbda99483a8fd15d7d30a196ca69d688a2efdb" @@ -2662,7 +2774,7 @@ conventional-commits-parser@^3.0.0: through2 "^2.0.0" trim-off-newlines "^1.0.0" -convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.1: +convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.5.1: version "1.6.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" dependencies: @@ -2716,7 +2828,7 @@ core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" -cosmiconfig@^5.0.1: +cosmiconfig@^5.0.1, cosmiconfig@^5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" dependencies: @@ -2859,6 +2971,11 @@ cssstyle@^1.0.0: dependencies: cssom "0.3.x" +csstype@^2.5.7: + version "2.6.6" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.6.tgz#c34f8226a94bbb10c32cc0d714afdf942291fc41" + integrity sha512-RpFbQGUE74iyPgvr46U9t1xoQBM8T4BL8SxrN66Le2xYAPSaDJJKeztV3awugusb3g3G9iL8StmkBBXhcbbXhg== + currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" @@ -3119,6 +3236,13 @@ dom-converter@^0.2: dependencies: utila "~0.4" +dom-helpers@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8" + integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA== + dependencies: + "@babel/runtime" "^7.1.2" + dom-serializer@0, dom-serializer@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" @@ -3923,6 +4047,11 @@ find-npm-prefix@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/find-npm-prefix/-/find-npm-prefix-1.0.2.tgz#8d8ce2c78b3b4b9e66c8acc6a37c231eb841cfdf" +find-root@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== + find-up@3.0.0, find-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" @@ -6579,6 +6708,11 @@ mem@^4.0.0: mimic-fn "^2.0.0" p-is-promise "^2.0.0" +memoize-one@^5.0.0: + version "5.0.5" + resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.0.5.tgz#8cd3809555723a07684afafcd6f756072ac75d7e" + integrity sha512-ey6EpYv0tEaIbM/nTDOpHciXUvd+ackQrJgEzBwemhZZIWZjcyodqEcrmqDy2BKRTM3a65kKBV4WtLXJDt26SQ== + memory-fs@~0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" @@ -8203,7 +8337,7 @@ prop-types-exact@^1.2.0: object.assign "^4.1.0" reflect.ownkeys "^0.2.0" -prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" dependencies: @@ -8470,6 +8604,13 @@ react-icons@^2.2.7: dependencies: react-icon-base "2.1.0" +react-input-autosize@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.2.1.tgz#ec428fa15b1592994fb5f9aa15bb1eb6baf420f8" + integrity sha512-3+K4CD13iE4lQQ2WlF8PuV5htfmTRLH6MDnfndHM6LuBRszuXnuyIfE7nhSKt8AzRBZ50bu0sAhkNMeS5pxQQA== + dependencies: + prop-types "^15.5.8" + react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6: version "16.8.6" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16" @@ -8478,6 +8619,27 @@ react-is@~16.4.1: version "16.4.2" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.4.2.tgz#84891b56c2b6d9efdee577cc83501dfc5ecead88" +react-lifecycles-compat@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" + integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== + +react-select@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/react-select/-/react-select-3.0.4.tgz#16bde37c24fd4f6444914d4681e78f15ffbc86d3" + integrity sha512-fbVISKa/lSUlLsltuatfUiKcWCNvdLXxFFyrzVQCBUsjxJZH/m7UMPdw/ywmRixAmwXAP++MdbNNZypOsiDEfA== + dependencies: + "@babel/runtime" "^7.4.4" + "@emotion/cache" "^10.0.9" + "@emotion/core" "^10.0.9" + "@emotion/css" "^10.0.9" + classnames "^2.2.5" + memoize-one "^5.0.0" + prop-types "^15.6.0" + raf "^3.4.0" + react-input-autosize "^2.2.1" + react-transition-group "^2.2.1" + react-styleguidist@~6.5.3: version "6.5.3" resolved "https://registry.yarnpkg.com/react-styleguidist/-/react-styleguidist-6.5.3.tgz#17abbfd14cfc4e0eb8921bb03d7cbd74836b0b5b" @@ -8549,6 +8711,16 @@ react-test-renderer@^16.0.0-0, react-test-renderer@~16.8.6: react-is "^16.8.6" scheduler "^0.13.6" +react-transition-group@^2.2.1: + version "2.9.0" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d" + integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg== + dependencies: + dom-helpers "^3.4.0" + loose-envify "^1.4.0" + prop-types "^15.6.2" + react-lifecycles-compat "^3.0.4" + read-cmd-shim@^1.0.1, read-cmd-shim@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz#2d5d157786a37c055d22077c32c53f8329e91c7b" diff --git a/styleguide.config.js b/styleguide.config.js index 907cb830..761c494e 100644 --- a/styleguide.config.js +++ b/styleguide.config.js @@ -361,6 +361,12 @@ module.exports = { "DialogTitle" ], name: "Feedback" + }), + generateSection({ + componentNames: [ + "MultiSelect" + ], + name: "Inputs" }) ], sectionDepth: 2 From 983e1daab26818c4f3d3aba6f4f0540208881d0f Mon Sep 17 00:00:00 2001 From: Will Lopez Date: Wed, 14 Aug 2019 16:27:34 -0700 Subject: [PATCH 02/22] chore: add basic snapshot test for MultiSelect component Signed-off-by: Will Lopez --- .../ConfirmDialog/ConfirmDialog.test.js | 1 - .../MultiSelect/MultiSelect.test.js | 20 ++++ .../__snapshots__/MultiSelect.test.js.snap | 99 +++++++++++++++++++ 3 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 package/src/components/MultiSelect/MultiSelect.test.js create mode 100644 package/src/components/MultiSelect/__snapshots__/MultiSelect.test.js.snap diff --git a/package/src/components/ConfirmDialog/ConfirmDialog.test.js b/package/src/components/ConfirmDialog/ConfirmDialog.test.js index 72d06f92..7209be6d 100644 --- a/package/src/components/ConfirmDialog/ConfirmDialog.test.js +++ b/package/src/components/ConfirmDialog/ConfirmDialog.test.js @@ -1,6 +1,5 @@ import React from "react"; import { render, fireEvent } from "../../tests/"; -import "@testing-library/jest-dom/extend-expect"; import Button from "../Button"; import ConfirmDialog from "./ConfirmDialog"; diff --git a/package/src/components/MultiSelect/MultiSelect.test.js b/package/src/components/MultiSelect/MultiSelect.test.js new file mode 100644 index 00000000..a1fef286 --- /dev/null +++ b/package/src/components/MultiSelect/MultiSelect.test.js @@ -0,0 +1,20 @@ +import React from "react"; +import { render } from "../../tests"; +import MultiSelect from "./MultiSelect"; + +const options = [ + "Mens", + "Womens", + "Kids" +].map((option) => ({ + label: option.toLowerCase(), + value: option +})); + +test("basic snapshot test", () => { + const { asFragment } = render(( + + )); + + expect(asFragment()).toMatchSnapshot(); +}); diff --git a/package/src/components/MultiSelect/__snapshots__/MultiSelect.test.js.snap b/package/src/components/MultiSelect/__snapshots__/MultiSelect.test.js.snap new file mode 100644 index 00000000..53518155 --- /dev/null +++ b/package/src/components/MultiSelect/__snapshots__/MultiSelect.test.js.snap @@ -0,0 +1,99 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`basic snapshot test 1`] = ` + +
+
+
+
+ +
+
+

+ Select options +

+
+
+ +
+
+
+
+
+ + +
+
+
+
+
+
+ +`; From d3a75f7e423d8a0103ab65323eaceec997b89bb5 Mon Sep 17 00:00:00 2001 From: Will Lopez Date: Wed, 14 Aug 2019 16:54:38 -0700 Subject: [PATCH 03/22] docs: add better sample options data Signed-off-by: Will Lopez --- .../src/components/MultiSelect/MultiSelect.js | 2 +- .../src/components/MultiSelect/MultiSelect.md | 12 +++------ .../components/MultiSelect/helpers/tagData.js | 26 +++++++++++++++++++ 3 files changed, 31 insertions(+), 9 deletions(-) create mode 100644 package/src/components/MultiSelect/helpers/tagData.js diff --git a/package/src/components/MultiSelect/MultiSelect.js b/package/src/components/MultiSelect/MultiSelect.js index 19a9edb2..1d6a86ba 100644 --- a/package/src/components/MultiSelect/MultiSelect.js +++ b/package/src/components/MultiSelect/MultiSelect.js @@ -21,7 +21,7 @@ const useStyles = makeStyles((theme) => ({ }, input: { display: "flex", - padding: 0, + padding: theme.spacing(0.25), height: "auto" }, valueContainer: { diff --git a/package/src/components/MultiSelect/MultiSelect.md b/package/src/components/MultiSelect/MultiSelect.md index 29ed819b..2afb8d87 100644 --- a/package/src/components/MultiSelect/MultiSelect.md +++ b/package/src/components/MultiSelect/MultiSelect.md @@ -1,4 +1,4 @@ -Multi value select with options provided synchronously +##### Multi value select with options provided synchronously ```jsx const options = [ { value: "mens", label: "Mens" }, @@ -18,13 +18,9 @@ function handleOnSelection(value) { /> ``` -Multi value select with options provided asynchronously +##### Multi value select with options provided asynchronously ```jsx -const options = [ - { value: "mens", label: "Mens" }, - { value: "womens", label: "Womens" }, - { value: "kids", label: "Kids" } -]; +import options from "./helpers/tagData"; const filterOptions = (inputValue) => options.filter((i) => { return i.label.toLowerCase().includes(inputValue.toLowerCase()); @@ -48,6 +44,6 @@ function handleOnSelection(value) { defaultOptions loadOptions={promiseOptions} onSelection={handleOnSelection} - placeholder="Select tags" + placeholder="Search tags" /> ``` diff --git a/package/src/components/MultiSelect/helpers/tagData.js b/package/src/components/MultiSelect/helpers/tagData.js new file mode 100644 index 00000000..0d05f208 --- /dev/null +++ b/package/src/components/MultiSelect/helpers/tagData.js @@ -0,0 +1,26 @@ +export default [ + "Accessories", + "Active", + "Active", + "Casual", + "Dresses", + "Gifts", + "Jeans", + "Kids", + "Mens", + "New Arrivals", + "Nike", + "Outdoor", + "Pats", + "Running", + "Sales", + "Shoes", + "Shorts", + "Skirts", + "Socks", + "Womens", + "Workwear" +].map((tag) => ({ + label: tag, + value: tag.toLowerCase() +})); From aef47e03787a335bf17057c9c08978c059f4c3c1 Mon Sep 17 00:00:00 2001 From: Will Lopez Date: Thu, 15 Aug 2019 09:20:50 -0700 Subject: [PATCH 04/22] chore: fix typo Signed-off-by: Will Lopez --- package/src/components/MultiSelect/helpers/tagData.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/src/components/MultiSelect/helpers/tagData.js b/package/src/components/MultiSelect/helpers/tagData.js index 0d05f208..58082d49 100644 --- a/package/src/components/MultiSelect/helpers/tagData.js +++ b/package/src/components/MultiSelect/helpers/tagData.js @@ -11,7 +11,7 @@ export default [ "New Arrivals", "Nike", "Outdoor", - "Pats", + "Pants", "Running", "Sales", "Shoes", From 710f6b13eb131be4b236ddf5101358a2b1d510e6 Mon Sep 17 00:00:00 2001 From: Will Lopez Date: Thu, 15 Aug 2019 12:46:19 -0700 Subject: [PATCH 05/22] docs: add more detailed documentation Signed-off-by: Will Lopez --- package/src/components/MultiSelect/MultiSelect.js | 2 +- package/src/components/MultiSelect/MultiSelect.md | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/package/src/components/MultiSelect/MultiSelect.js b/package/src/components/MultiSelect/MultiSelect.js index 1d6a86ba..5b45e29f 100644 --- a/package/src/components/MultiSelect/MultiSelect.js +++ b/package/src/components/MultiSelect/MultiSelect.js @@ -107,7 +107,7 @@ const MultiSelect = React.forwardRef(function MultiSelect(props, ref) { */ function handleChangeMulti(selectedValue) { setValue(selectedValue); - onSelection(selectedValue); + onSelection && onSelection(selectedValue); } const selectStyles = { diff --git a/package/src/components/MultiSelect/MultiSelect.md b/package/src/components/MultiSelect/MultiSelect.md index 2afb8d87..dfa6338f 100644 --- a/package/src/components/MultiSelect/MultiSelect.md +++ b/package/src/components/MultiSelect/MultiSelect.md @@ -1,4 +1,11 @@ -##### Multi value select with options provided synchronously +### Overview +The `MultiSelect` component provides functionality to select multiple options with +autocompletion; options may be provided synchronously or asynchronously. Under the hood, it uses the [react-select](https://react-select.com) component. + +### Usage + +#### Basic +Multi value select with options provided synchronously: ```jsx const options = [ { value: "mens", label: "Mens" }, @@ -18,7 +25,8 @@ function handleOnSelection(value) { /> ``` -##### Multi value select with options provided asynchronously +#### Async options +Multi value select with options provided asynchronously: ```jsx import options from "./helpers/tagData"; From e2270b7603fcb3ed2710743dee70299a6385ed70 Mon Sep 17 00:00:00 2001 From: Will Lopez Date: Thu, 15 Aug 2019 15:05:28 -0700 Subject: [PATCH 06/22] refactor: pass all props through Signed-off-by: Will Lopez --- .../src/components/MultiSelect/MultiSelect.js | 23 ++----------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/package/src/components/MultiSelect/MultiSelect.js b/package/src/components/MultiSelect/MultiSelect.js index 5b45e29f..512243b4 100644 --- a/package/src/components/MultiSelect/MultiSelect.js +++ b/package/src/components/MultiSelect/MultiSelect.js @@ -56,19 +56,6 @@ const useStyles = makeStyles((theme) => ({ } })); -// Rather than pass through all props to react-select, we'll keep a whitelist -// to better control the usage and appearance of this component. -const supportedPassthroughProps = [ - "async", - "cacheOptions", - "classes", - "defaultOptions", - "loadOptions", - "placeholder", - "onSelection", - "options" -]; - // Custom components for various aspects of the select const components = { Control, @@ -91,13 +78,7 @@ const MultiSelect = React.forwardRef(function MultiSelect(props, ref) { const defaultClasses = useStyles(); const theme = useTheme(); const [value, setValue] = useState(null); - - const passThroughProps = {}; - supportedPassthroughProps.forEach((supportedProp) => { - passThroughProps[supportedProp] = props[supportedProp]; - }); - - const { classes, isAsync, onSelection } = props; + const { classes, isAsync, onSelection, ...otherProps } = props; const SelectComponent = isAsync ? AsyncSelect : Select; /** @@ -138,7 +119,7 @@ const MultiSelect = React.forwardRef(function MultiSelect(props, ref) { } }} value={value} - {...props} + {...otherProps} />
); From b5710109e21e950b8f47c26940d5248232500193 Mon Sep 17 00:00:00 2001 From: Will Lopez Date: Thu, 15 Aug 2019 15:09:06 -0700 Subject: [PATCH 07/22] refactor: minor styling change Signed-off-by: Will Lopez --- package/src/components/MultiSelect/MultiSelect.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package/src/components/MultiSelect/MultiSelect.js b/package/src/components/MultiSelect/MultiSelect.js index 512243b4..46a88b01 100644 --- a/package/src/components/MultiSelect/MultiSelect.js +++ b/package/src/components/MultiSelect/MultiSelect.js @@ -30,8 +30,7 @@ const useStyles = makeStyles((theme) => ({ flexWrap: "wrap", flex: 1, overflow: "hidden", - paddingLeft: theme.spacing(1), - paddingRight: theme.spacing(1) + paddingLeft: theme.spacing(0.5) }, chip: { margin: theme.spacing(0.5, 0.25) From 338f2ff05404977e0437aaa8aa99657a9cb1b3d6 Mon Sep 17 00:00:00 2001 From: Will Lopez Date: Thu, 15 Aug 2019 15:11:27 -0700 Subject: [PATCH 08/22] fix: update test snapshop Signed-off-by: Will Lopez --- .../__snapshots__/MultiSelect.test.js.snap | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/package/src/components/MultiSelect/__snapshots__/MultiSelect.test.js.snap b/package/src/components/MultiSelect/__snapshots__/MultiSelect.test.js.snap index 53518155..8e6743f1 100644 --- a/package/src/components/MultiSelect/__snapshots__/MultiSelect.test.js.snap +++ b/package/src/components/MultiSelect/__snapshots__/MultiSelect.test.js.snap @@ -14,20 +14,6 @@ exports[`basic snapshot test 1`] = `
-
+
From d1e13c3d64414f2e9c19aaceaa23a6e09d016928 Mon Sep 17 00:00:00 2001 From: Will Lopez Date: Thu, 15 Aug 2019 16:08:25 -0700 Subject: [PATCH 09/22] refactor: remove selected prop Signed-off-by: Will Lopez --- package/src/components/MultiSelect/helpers/Option.js | 1 - 1 file changed, 1 deletion(-) diff --git a/package/src/components/MultiSelect/helpers/Option.js b/package/src/components/MultiSelect/helpers/Option.js index b490c1c0..c3260ef6 100644 --- a/package/src/components/MultiSelect/helpers/Option.js +++ b/package/src/components/MultiSelect/helpers/Option.js @@ -11,7 +11,6 @@ export default function Option(props) { return ( Date: Fri, 16 Aug 2019 11:41:51 -0700 Subject: [PATCH 10/22] chore: renamed MultiSelect => Select Signed-off-by: Will Lopez --- package/src/components/MultiSelect/index.js | 1 - .../MultiSelect.js => Select/Select.js} | 19 +++++----- .../MultiSelect.md => Select/Select.md} | 35 ++++++++++++++++--- .../Select.test.js} | 4 +-- .../__snapshots__/MultiSelect.test.js.snap | 0 .../helpers/Control.js | 0 .../{MultiSelect => Select}/helpers/Input.js | 0 .../{MultiSelect => Select}/helpers/Menu.js | 0 .../helpers/MultiValue.js | 0 .../helpers/NoOptionsMessage.js | 0 .../{MultiSelect => Select}/helpers/Option.js | 0 .../helpers/Placeholder.js | 0 .../helpers/ValueContainer.js | 0 .../{MultiSelect => Select}/helpers/index.js | 0 .../helpers/tagData.js | 0 package/src/components/Select/index.js | 1 + styleguide.config.js | 6 ++-- 17 files changed, 45 insertions(+), 21 deletions(-) delete mode 100644 package/src/components/MultiSelect/index.js rename package/src/components/{MultiSelect/MultiSelect.js => Select/Select.js} (90%) rename package/src/components/{MultiSelect/MultiSelect.md => Select/Select.md} (57%) rename package/src/components/{MultiSelect/MultiSelect.test.js => Select/Select.test.js} (79%) rename package/src/components/{MultiSelect => Select}/__snapshots__/MultiSelect.test.js.snap (100%) rename package/src/components/{MultiSelect => Select}/helpers/Control.js (100%) rename package/src/components/{MultiSelect => Select}/helpers/Input.js (100%) rename package/src/components/{MultiSelect => Select}/helpers/Menu.js (100%) rename package/src/components/{MultiSelect => Select}/helpers/MultiValue.js (100%) rename package/src/components/{MultiSelect => Select}/helpers/NoOptionsMessage.js (100%) rename package/src/components/{MultiSelect => Select}/helpers/Option.js (100%) rename package/src/components/{MultiSelect => Select}/helpers/Placeholder.js (100%) rename package/src/components/{MultiSelect => Select}/helpers/ValueContainer.js (100%) rename package/src/components/{MultiSelect => Select}/helpers/index.js (100%) rename package/src/components/{MultiSelect => Select}/helpers/tagData.js (100%) create mode 100644 package/src/components/Select/index.js diff --git a/package/src/components/MultiSelect/index.js b/package/src/components/MultiSelect/index.js deleted file mode 100644 index c728fbf2..00000000 --- a/package/src/components/MultiSelect/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from "./MultiSelect"; diff --git a/package/src/components/MultiSelect/MultiSelect.js b/package/src/components/Select/Select.js similarity index 90% rename from package/src/components/MultiSelect/MultiSelect.js rename to package/src/components/Select/Select.js index 46a88b01..3b471825 100644 --- a/package/src/components/MultiSelect/MultiSelect.js +++ b/package/src/components/Select/Select.js @@ -1,6 +1,6 @@ import React, { useState } from "react"; import PropTypes from "prop-types"; -import Select from "react-select"; +import ReactSelect from "react-select"; import AsyncSelect from "react-select/async"; import { makeStyles, useTheme } from "@material-ui/core/styles"; import { @@ -67,18 +67,18 @@ const components = { }; /** - * @name MultiSelect - * @summary A Select component that supports selecting multiple options, and - * loading options asynchronously and synchronously. + * @name Select + * @summary A Select component that supports selecting single or multiple option(s), and + * loading options synchronously or asynchronously. * @param {Object} props - component props * @returns {React.Component} A React component */ -const MultiSelect = React.forwardRef(function MultiSelect(props, ref) { +const Select = React.forwardRef(function Select(props, ref) { const defaultClasses = useStyles(); const theme = useTheme(); const [value, setValue] = useState(null); const { classes, isAsync, onSelection, ...otherProps } = props; - const SelectComponent = isAsync ? AsyncSelect : Select; + const SelectComponent = isAsync ? AsyncSelect : ReactSelect; /** * @@ -105,7 +105,6 @@ const MultiSelect = React.forwardRef(function MultiSelect(props, ref) { +``` + +#### Basic Multi Select Multi value select with options provided synchronously: ```jsx const options = [ @@ -18,7 +41,8 @@ function handleOnSelection(value) { console.log("Selected value: ", value); } - { const { asFragment } = render(( - +