From c6e4ab3d8b92979e86f9b549a5ee8036ebe0453c Mon Sep 17 00:00:00 2001 From: Bob Saris Date: Wed, 1 Apr 2020 16:33:11 -0400 Subject: [PATCH] UIDS 18 react select wrappers (#19) UIDS-18 Add a wrapper to the ReactSelect and colors This adds a wrapper to the Async component from React Select. This adds React Select as a dependency of this library as well as brings over some styling we had on it from the main repo. Also add a SingleSelect component to hold logic for that style of component. This is largely meant to help us standardize styles for these components which use CSS in JS. In adding input colors separated out the color palette from other semantic color variables. This led to moving the palette to be colors in js and scss and added separate files for the palette (which defines the base colors we should use) as well as other files for input colors which are joined in a common color output. Additionally brought some ESLint rules to the top level instead of just living in src. --- .eslintrc | 15 +- package.json | 1 + scss/buttons.scss | 2 +- scss/colors.scss | 2 + scss/colors/inputs.scss | 4 + scss/{ => colors}/palette.scss | 2 +- scss/theme.scss | 2 +- spec/__snapshots__/Storyshots.test.js.snap | 569 ++++++++++++++++++ src/Popper/Popper.scss | 2 +- src/Select/AsyncSelect.jsx | 108 ++++ src/Select/SingleSelect.jsx | 90 +++ src/Select/index.js | 7 + src/Select/styles.js | 57 ++ src/Styles/colors/index.js | 7 + src/Styles/colors/inputs.js | 6 + src/Styles/{ => colors}/palette.js | 19 +- src/Styles/index.js | 4 +- src/index.js | 6 + stories/AsyncSelect.stories.jsx | 48 ++ stories/Form Elements/RadioButton.stories.jsx | 4 +- stories/SingleSelect.stories.jsx | 42 ++ stories/Styles/Palette.stories.jsx | 4 +- 22 files changed, 978 insertions(+), 23 deletions(-) create mode 100644 scss/colors.scss create mode 100644 scss/colors/inputs.scss rename scss/{ => colors}/palette.scss (98%) create mode 100644 src/Select/AsyncSelect.jsx create mode 100644 src/Select/SingleSelect.jsx create mode 100644 src/Select/index.js create mode 100644 src/Select/styles.js create mode 100644 src/Styles/colors/index.js create mode 100644 src/Styles/colors/inputs.js rename src/Styles/{ => colors}/palette.js (83%) create mode 100644 stories/AsyncSelect.stories.jsx create mode 100644 stories/SingleSelect.stories.jsx diff --git a/.eslintrc b/.eslintrc index e76cfa93..50d22761 100644 --- a/.eslintrc +++ b/.eslintrc @@ -22,13 +22,6 @@ "babel/semi": 2, "import/prefer-default-export": 0, "jsx-a11y/anchor-is-valid": 1, - "jsx-a11y/label-has-associated-control": [ 2, { - "assert": "either", - "controlComponents": [], - "depth": 25, - "labelAttributes": ["label"], - "labelComponents": [] - }], "jsx-a11y/label-has-for": 0, "no-alert": 0, "react/destructuring-assignment": 0, @@ -118,6 +111,13 @@ "function-paren-newline": ["error", "consistent"], "func-names": ["error", "never"], "implicit-arrow-linebreak": 0, + "jsx-a11y/label-has-associated-control": [ 2, { + "assert": "either", + "controlComponents": ["AsyncSelect", "SingleSelect"], + "depth": 25, + "labelAttributes": ["label"], + "labelComponents": [] + }], "linebreak-style": 0, "no-case-declarations": "warn", "no-confusing-arrow": 0, @@ -131,6 +131,7 @@ "prefer-destructuring": "warn", "quotes": ["error", "single", { "allowTemplateLiterals" : true }], "radix": 0, + "react/jsx-fragments": 0, "symbol-description": 0, "template-curly-spacing": "off", "indent": "off" diff --git a/package.json b/package.json index f3685baf..0bdbec04 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "react-transition-group": "^4.3.0", "react-copy-to-clipboard": "^5.0.2", "react-popper": "^1.3.7", + "react-select": "^3.0.8", "react-tracking": "^7.3.0", "uuid": "^7.0.2" }, diff --git a/scss/buttons.scss b/scss/buttons.scss index 7a39c97d..97cbcc98 100644 --- a/scss/buttons.scss +++ b/scss/buttons.scss @@ -1,4 +1,4 @@ -@import './palette'; +@import './colors'; .btn-link--neutral { color: $ux-gray-500; diff --git a/scss/colors.scss b/scss/colors.scss new file mode 100644 index 00000000..336cbe8b --- /dev/null +++ b/scss/colors.scss @@ -0,0 +1,2 @@ +@import './colors/inputs'; +@import './colors/palette'; diff --git a/scss/colors/inputs.scss b/scss/colors/inputs.scss new file mode 100644 index 00000000..a9088909 --- /dev/null +++ b/scss/colors/inputs.scss @@ -0,0 +1,4 @@ +@import './palette'; + +$input-border-color: $ux-gray-400; // Override bootstrap default +$input-disabled-bg: $ux-gray-300; // Override bootstrap default diff --git a/scss/palette.scss b/scss/colors/palette.scss similarity index 98% rename from scss/palette.scss rename to scss/colors/palette.scss index cb963f11..b0022f15 100644 --- a/scss/palette.scss +++ b/scss/colors/palette.scss @@ -1,7 +1,7 @@ // When updating this file, please consider the values in src/Styles/palette.js $ux-black: #000000; -$ux-blue: #337ab7; +$ux-blue: #337AB7; $ux-gray: #A1A1A1; $ux-green: #6DBD63; $ux-light-blue: #7CCBF2; diff --git a/scss/theme.scss b/scss/theme.scss index ccff0a2f..b403c5f7 100644 --- a/scss/theme.scss +++ b/scss/theme.scss @@ -1,7 +1,7 @@ @import './box_shadow'; @import './buttons'; +@import './colors'; @import './lists'; @import './navbar'; -@import './palette'; @import './typography'; @import './z_stack'; diff --git a/spec/__snapshots__/Storyshots.test.js.snap b/spec/__snapshots__/Storyshots.test.js.snap index 771d1913..7fc8d0d7 100644 --- a/spec/__snapshots__/Storyshots.test.js.snap +++ b/spec/__snapshots__/Storyshots.test.js.snap @@ -720,6 +720,575 @@ exports[`Storyshots Design System/Popper Default 1`] = ` `; +exports[`Storyshots Design System/Selects/Async Default 1`] = ` +
+
+
+
+
+ Select... +
+
+
+ +
+ +
+
+
+
+
+ + +
+
+
+
+`; + +exports[`Storyshots Design System/Selects/Async Labeled 1`] = ` +
+ +
+
+
+
+ Select... +
+
+
+ +
+ +
+
+
+
+
+ + +
+
+
+
+`; + +exports[`Storyshots Design System/Selects/Single Default 1`] = ` +
+
+
+
+
+ Select... +
+ +
+
+ + +
+
+
+
+`; + +exports[`Storyshots Design System/Selects/Single Labeled 1`] = ` +
+ +
+
+
+
+ Select... +
+ +
+
+ + +
+
+
+
+`; + +exports[`Storyshots Design System/Selects/Single Loading 1`] = ` +
+
+
+
+
+ Select... +
+ +
+
+ + +
+
+
+
+`; + +exports[`Storyshots Design System/Selects/Single Searchable 1`] = ` +
+
+
+
+
+ Select... +
+
+
+ +
+ +
+
+
+
+
+ + +
+
+
+
+`; + exports[`Storyshots Design System/Styles/Color Palette Blue 1`] = `
( + ( + modal ? + base : + { ...base, zIndex: zStack.zIndexModalBackdrop + 1 } + ), + }} + theme={defaultTheme} + value={value} + + onBlurResetsInput={false} + onChange={onChange} + onSelectResetsInput={false} + /> +); + +AsyncSelect.propTypes = { + 'aria-label': propTypes.string, + 'aria-labelledby': propTypes.string, + className: propTypes.string, + defaultOptions: propTypes.oneOfType([propTypes.bool, propTypes.array]), + disabled: propTypes.bool, + getOptionLabel: propTypes.func, + getOptionValue: propTypes.func, + id: propTypes.string, + ignoreCase: propTypes.bool, + isClearable: propTypes.bool, + isLoading: propTypes.bool, + loadOptions: propTypes.func.isRequired, + modal: propTypes.bool, + name: propTypes.string, + noOptionsMessage: propTypes.func, + placeholder: propTypes.string, + value: propTypes.object, + + onChange: propTypes.func, +}; + +AsyncSelect.defaultProps = { + 'aria-label': undefined, + 'aria-labelledby': undefined, + className: undefined, + defaultOptions: false, + disabled: false, + getOptionLabel: undefined, + getOptionValue: undefined, + id: undefined, + ignoreCase: undefined, + isClearable: false, + isLoading: false, + modal: false, + name: undefined, + noOptionsMessage: undefined, + placeholder: undefined, + value: undefined, + + onChange: undefined, +}; + +export default AsyncSelect; diff --git a/src/Select/SingleSelect.jsx b/src/Select/SingleSelect.jsx new file mode 100644 index 00000000..dcf6092b --- /dev/null +++ b/src/Select/SingleSelect.jsx @@ -0,0 +1,90 @@ +import React from 'react'; +import Select from 'react-select'; +import propTypes from 'prop-types'; + +import zStack from 'src/Styles/zStack'; + +import { defaultTheme, defaultStyles } from './styles'; + +const SingleSelect = ({ + 'aria-label': ariaLabel, + 'aria-labelledby': ariaLabelledBy, + className, + defaultValue, + disabled, + isClearable, + id, + isLoading, + isSearchable, + modal, + name, + options, + placeholder, + value, + + onChange, +}) => ( +