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
82 changes: 82 additions & 0 deletions src/components/forms/DateInput/DateInput.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import React from 'react'
import { DateInput } from './DateInput'
import { DateInputGroup } from '../DateInputGroup/DateInputGroup'
import { Fieldset } from '../Fieldset/Fieldset'

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

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

export const monthDateInput = (): React.ReactElement => (
<DateInput
id="testDateInput"
name="testName"
label="Month"
unit="month"
maxLength={2}
minLength={2}
/>
)

export const dayDateInput = (): React.ReactElement => (
<DateInput
id="testDateInput"
name="testName"
label="Day"
unit="day"
maxLength={2}
minLength={1}
/>
)

export const yearDateInput = (): React.ReactElement => (
<DateInput
id="testDateInput"
name="testName"
label="Year"
unit="year"
maxLength={4}
minLength={4}
/>
)

export const dateOfBirthExample = (): React.ReactElement => (
<Fieldset legend="Date of birth">
<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.InputHTMLAttributes<HTMLInputElement>
): React.ReactElement => {
const {
id,
name,
label,
unit,
maxLength,
minLength,
className,
...inputProps
} = props

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

const inputClasses = classnames('usa-input--inline', className)

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

export default DateInput
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'
import classnames from 'classnames'

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

const classes = classnames('usa-memorable-date', className)

return (
<div className={classes} {...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