Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DateInput Component for Forms #144

Merged
merged 14 commits into from
May 20, 2020
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## UNRELEASED

- Added form dateInput and dateInputGroup components
eamahanna marked this conversation as resolved.
Show resolved Hide resolved
- Added yarn audit check to dangerfile (on package change)
- Added search component
- Added Grid, GridContainer components
Expand Down
60 changes: 60 additions & 0 deletions src/components/forms/DateInput/DateInput.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React from 'react'
import { DateInput } from './DateInput'
import { DateInputGroup } from '../DateInputGroup/DateInputGroup'
import { Fieldset } from '../Fieldset/Fieldset'

export default {
title: 'Form/DateInput',
eamahanna marked this conversation as resolved.
Show resolved Hide resolved
parameters: {
info: `
USWDS 2.0 DateInput component

Source: https://designsystem.digital.gov/components/form-controls/#date-input
`,
},
}

export const defaultDateInput = (): React.ReactElement => (
eamahanna marked this conversation as resolved.
Show resolved Hide resolved
<DateInput
id="testDateInput"
name="testName"
label="Month"
unit="month"
maxLength={2}
minLength={2}
/>
)

export const dateOfBirthExample = (): React.ReactElement => (
<Fieldset legend={'Date of birth'}>
eamahanna marked this conversation as resolved.
Show resolved Hide resolved
<span className="usa-hint" id="dateOfBirthHint">
For example: 4 28 1986
</span>
<DateInputGroup>
<DateInput
id="testDateInput"
name="testName"
label="Month"
unit="month"
maxLength={2}
minLength={2}
/>
<DateInput
id="testDateInput"
name="testName"
label="Day"
unit="day"
maxLength={2}
minLength={2}
/>
<DateInput
id="testDateInput"
name="testName"
label="Year"
unit="year"
maxLength={4}
minLength={4}
/>
</DateInputGroup>
</Fieldset>
)
68 changes: 68 additions & 0 deletions src/components/forms/DateInput/DateInput.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React from 'react'
import { render } from '@testing-library/react'

import { DateInput } from './DateInput'

describe('DateInput component', () => {
it('renders without errors', () => {
const { getByText } = render(
<DateInput
id="testDateInput"
name="testName"
label="Day"
unit="day"
maxLength={2}
minLength={2}
/>
)
expect(getByText('Day')).toBeInTheDocument()
})

it('renders the month, day and year inputs', () => {
const { getByText } = render(
<>
<DateInput
id="testDateInput"
name="testName"
label="Day"
unit="day"
maxLength={2}
minLength={2}
/>
<DateInput
id="testDateInput"
name="testName"
label="Month"
unit="month"
maxLength={2}
minLength={2}
/>
<DateInput
id="testDateInput"
name="testName"
label="Year"
unit="year"
maxLength={4}
minLength={4}
/>
</>
)
expect(getByText('Month')).toBeInTheDocument()
expect(getByText('Day')).toBeInTheDocument()
expect(getByText('Year')).toBeInTheDocument()
})

it('renders the correct class based on unit', () => {
const { getByTestId } = render(
<DateInput
id="testDateInput"
name="testName"
label="Day"
unit="day"
maxLength={2}
minLength={2}
/>
)
expect(getByTestId('formGroup')).toHaveClass('usa-form-group--day')
})
})
57 changes: 57 additions & 0 deletions src/components/forms/DateInput/DateInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from 'react'
import classnames from 'classnames'

import { TextInput } from '../TextInput/TextInput'
import { Label } from '../Label/Label'
import { FormGroup } from '../FormGroup/FormGroup'

interface DateInputElementProps {
id: string
name: string
label: string
unit: 'month' | 'day' | 'year'
maxLength: number
minLength?: number
}

export const DateInput = (
props: DateInputElementProps & React.HTMLAttributes<HTMLElement>
): React.ReactElement => {
const {
id,
name,
label,
unit,
maxLength,
minLength,
className,
...divProps
} = props

const classes = classnames(
{
'usa-form-group--month': unit == 'month',
'usa-form-group--day': unit == 'day',
'usa-form-group--year': unit == 'year',
},
className
)

return (
<FormGroup className={classes} {...divProps}>
<Label htmlFor={id}>{label}</Label>
<TextInput
className="usa-input--inline"
id={id}
name={name}
type="text"
maxLength={maxLength}
minLength={minLength}
pattern="[0-9]*"
inputMode="numeric"
/>
</FormGroup>
)
}

export default DateInput
18 changes: 18 additions & 0 deletions src/components/forms/DateInputGroup/DateInputGroup.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react'
import { DateInputGroup } from './DateInputGroup'

export default {
title: 'Form/DateInputGroup',
parameters: {
info: `
USWDS 2.0 DateInput component

Source: https://designsystem.digital.gov/components/form-controls/#date-input
`,
},
}

// TODO Determine if this is the way to display this component
export const defaultDateInputGroup = (): React.ReactElement => (
eamahanna marked this conversation as resolved.
Show resolved Hide resolved
<DateInputGroup>Test Date: 12-31-1999</DateInputGroup>
)
17 changes: 17 additions & 0 deletions src/components/forms/DateInputGroup/DateInputGroup.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react'
import { render } from '@testing-library/react'

import { DateInputGroup } from './DateInputGroup'

describe('DateInputGroup component', () => {
it('renders without errors', () => {
const { getByTestId } = render(<DateInputGroup />)
expect(getByTestId('dateInputGroup')).toBeInTheDocument()
})

it('renders children', () => {
const { getByText } = render(<DateInputGroup>DATES</DateInputGroup>)

expect(getByText('DATES')).toBeInTheDocument()
})
})
18 changes: 18 additions & 0 deletions src/components/forms/DateInputGroup/DateInputGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react'

export const DateInputGroup = (
props: React.HTMLAttributes<HTMLElement>
): React.ReactElement => {
const { children, ...divAttributes } = props

return (
<div
className="usa-memorable-date"
eamahanna marked this conversation as resolved.
Show resolved Hide resolved
{...divAttributes}
data-testid="dateInputGroup">
{children}
</div>
)
}

export default DateInputGroup
2 changes: 2 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export { Grid } from './components/grid/Grid/Grid'

/** Form components */
export { Checkbox } from './components/forms/Checkbox/Checkbox'
export { DateInput } from './components/forms/DateInput/DateInput'
export { DateInputGroup } from './components/forms/DateInputGroup/DateInputGroup'
export { Dropdown } from './components/forms/Dropdown/Dropdown'
export { ErrorMessage } from './components/forms/ErrorMessage/ErrorMessage'
export { Fieldset } from './components/forms/Fieldset/Fieldset'
Expand Down