Skip to content

Commit

Permalink
feat: ComboBox component (trussworks#694)
Browse files Browse the repository at this point in the history
  • Loading branch information
haworku authored Dec 18, 2020
1 parent d1f85f1 commit 824028a
Show file tree
Hide file tree
Showing 10 changed files with 1,964 additions and 19 deletions.
48 changes: 43 additions & 5 deletions example/src/pages/Forms.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React, { useState } from 'react'
import React from 'react'
import { Field, Formik } from 'formik'
import * as Yup from 'yup'
import {
Alert,
Button,
ComboBox,
Form,
Label,
TextInput,
Expand All @@ -14,21 +15,40 @@ import {
type FormValues = {
email?: string
password?: string
fruit?: string
}

const FormSchema = Yup.object().shape({
email: Yup.string().email().required(),
password: Yup.string().min(8).max(20).required(),
fruit: Yup.string().nullable(),
})

const fruits = {
apple: 'Apple',
apricot: 'Apricot',
avocado: 'Avocado',
banana: 'Banana',
blackberry: 'Blackberry',
'blood orange': 'Blood orange',
blueberry: 'Blueberry',
boysenberry: 'Boysenberry',
breadfruit: 'Breadfruit',
}

const fruitOptions = Object.entries(fruits).map(([value, key]) => ({
value: value,
label: key,
}))

const FormsPage = (): React.ReactElement => {
return (
<>
<h1>Forms Examples</h1>
<section>
<h2>Formik</h2>
<Formik
initialValues={{ email: '', password: '' }}
initialValues={{ email: '', password: '', fruit: 'avocado' }}
validationSchema={FormSchema}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
Expand All @@ -37,8 +57,20 @@ const FormsPage = (): React.ReactElement => {
setSubmitting(false)
}, 400)
}}>
{({ values, errors, touched, handleSubmit, isSubmitting }) => (
{({
values,
errors,
touched,
handleSubmit,
isSubmitting,
setFieldValue,
}) => (
<Form onSubmit={handleSubmit}>
<div>
<span>Form data</span>
<pre>{JSON.stringify(values)}</pre>
</div>

{touched.email && errors.email && (
<Alert type="info" validation heading="Email Requirements">
<ValidationChecklist id="validate-email">
Expand All @@ -62,7 +94,6 @@ const FormsPage = (): React.ReactElement => {
id="email"
value={values.email}
/>

{touched.password && errors.password && (
<Alert type="info" validation heading="Password Requirements">
<ValidationChecklist id="validate-password">
Expand All @@ -85,7 +116,14 @@ const FormsPage = (): React.ReactElement => {
id="password"
value={values.password}
/>

<Label htmlFor="fruit">My Favorite Fruit</Label>
<Field
as={ComboBox}
name="fruit"
id="fruit"
options={fruitOptions}
onChange={(val: string) => setFieldValue('fruit', val, true)}
defaultValue="avocado"></Field>
<Button type="submit" disabled={isSubmitting}>
Submit
</Button>
Expand Down
43 changes: 36 additions & 7 deletions example/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1582,7 +1582,7 @@
happo-plugin-storybook "^2.5.3"
react "^16.10.0"
react-dom "^16.10.0"
uswds "^2.7.0"
uswds "2.7.1"

"@types/aria-query@^4.2.0":
version "4.2.0"
Expand Down Expand Up @@ -3187,6 +3187,15 @@ cliui@^5.0.0:
strip-ansi "^5.2.0"
wrap-ansi "^5.1.0"

cliui@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1"
integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==
dependencies:
string-width "^4.2.0"
strip-ansi "^6.0.0"
wrap-ansi "^6.2.0"

clone-deep@^0.2.4:
version "0.2.4"
resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-0.2.4.tgz#4e73dd09e9fb971cc38670c5dced9c1896481cc6"
Expand Down Expand Up @@ -4952,7 +4961,7 @@ find-cache-dir@^3.3.1:
make-dir "^3.0.2"
pkg-dir "^4.1.0"

[email protected], find-up@^4.0.0:
[email protected], find-up@^4.0.0, find-up@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
Expand Down Expand Up @@ -10369,7 +10378,7 @@ string-width@^3.0.0, string-width@^3.1.0:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^5.1.0"

string-width@^4.1.0:
string-width@^4.1.0, string-width@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5"
integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==
Expand Down Expand Up @@ -10990,11 +10999,12 @@ use@^3.1.0:
resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"
integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==

uswds@^2.7.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/uswds/-/uswds-2.8.0.tgz#635e829555a359562f28ab51e1b6c983f149f739"
integrity sha512-LI7ZNbh823ehtThvebwQ5eHNKGY791vcT5d3T9gJ+RY511HgstWLRSEEso7YO/ifjoV/FwuTAtDwQqt7zsXRvA==
[email protected].1:
version "2.7.1"
resolved "https://registry.yarnpkg.com/uswds/-/uswds-2.7.1.tgz#43f719fb3ef450e3faef722d336b29a39f6eee3b"
integrity sha512-RzczCK4TfnJud6WFj7pV6er5BQ0qQviM/GZgyDkYT6ZvOIXR0khbk7WZR72a+vy75fEiAzJut4N/x5/UZq0ZrA==
dependencies:
"@types/node" "^13.13.12"
classlist-polyfill "^1.0.3"
del "^5.1.0"
domready "^1.0.8"
Expand All @@ -11003,6 +11013,8 @@ uswds@^2.7.0:
object-assign "^4.1.1"
receptor "^1.0.0"
resolve-id-refs "^0.1.0"
typescript "^2.4.1"
yargs "^15.3.1"

util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
version "1.0.2"
Expand Down Expand Up @@ -11494,6 +11506,15 @@ wrap-ansi@^5.1.0:
string-width "^3.0.0"
strip-ansi "^5.0.0"

wrap-ansi@^6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53"
integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"

wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
Expand Down Expand Up @@ -11579,6 +11600,14 @@ yargs-parser@^13.1.2:
camelcase "^5.0.0"
decamelize "^1.2.0"

yargs-parser@^18.1.2:
version "18.1.3"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0"
integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==
dependencies:
camelcase "^5.0.0"
decamelize "^1.2.0"

yargs@^13.3.0, yargs@^13.3.2:
version "13.3.2"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd"
Expand Down
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
},
"scripts": {
"test": "jest",
"test:debug": "node --inspect node_modules/.bin/jest --runInBand",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"storybook": "start-storybook -p 9009",
Expand Down Expand Up @@ -64,7 +65,7 @@
"happo-plugin-storybook": "^2.5.3",
"react": "^16.10.0",
"react-dom": "^16.10.0",
"uswds": "^2.7.0"
"uswds": "2.7.1"
},
"devDependencies": {
"@babel/core": "^7.10.5",
Expand All @@ -73,9 +74,11 @@
"@storybook/addon-viewport": "^6.0.21",
"@storybook/react": "^6.0.21",
"@storybook/storybook-deployer": "^2.8.6",
"@testing-library/dom": "^7.22.3",
"@testing-library/jest-dom": "^5.3.0",
"@testing-library/react": "^11.0.2",
"@testing-library/react-hooks": "^3.2.1",
"@testing-library/user-event": "^12.1.1",
"@types/classnames": "^2.2.9",
"@types/jest": "^26.0.0",
"@types/react": "^17.0.0",
Expand Down
94 changes: 94 additions & 0 deletions src/components/forms/ComboBox/ComboBox.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import React from 'react'

import { ComboBox } from './ComboBox'
import { Form } from '../Form/Form'
import { Label } from '../Label/Label'

import { fruits } from './fruits'

export default {
title: 'Forms/ComboBox',
component: ComboBox,
parameters: {
info: `
USWDS 2.0 ComboBox component
Source: https://designsystem.digital.gov/components/form-controls/#ComboBox
`,
},
}

const noop = (): void => {
return
}

export const defaultComboBoxWithPropOptions = (): React.ReactElement => {
const fruitList = Object.entries(fruits).map(([key, value]) => ({
value: key,
label: value,
}))

return (
<Form onSubmit={noop}>
<ComboBox
id="input-ComboBox"
name="input-ComboBox"
options={fruitList}
onChange={noop}
/>
</Form>
)
}

export const withDefaultValue = (): React.ReactElement => {
const fruitList = Object.entries(fruits).map(([value, key]) => ({
value: value,
label: key,
}))

return (
<Form onSubmit={noop}>
<ComboBox
id="input-ComboBox"
name="input-ComboBox"
options={fruitList}
onChange={noop}
defaultValue="avocado"
/>
</Form>
)
}

export const withLabel = (): React.ReactElement => {
const fruitList = Object.entries(fruits).map(([value, key]) => ({
value: value,
label: key,
}))

return (
<Form onSubmit={noop}>
<Label htmlFor="fruit">Select A Fruit</Label>
<ComboBox id="fruit" name="fruit" options={fruitList} onChange={noop} />
</Form>
)
}

export const disabled = (): React.ReactElement => {
const fruitList = Object.entries(fruits).map(([value, key]) => ({
value: value,
label: key,
}))

return (
<Form onSubmit={noop}>
<Label htmlFor="fruit">Select a Fruit</Label>
<ComboBox
id="fruit"
name="fruit"
options={fruitList}
onChange={noop}
disabled
/>
</Form>
)
}
Loading

0 comments on commit 824028a

Please sign in to comment.