Skip to content

Commit

Permalink
feat(ui,ui-date-input): add new DateInput2 component
Browse files Browse the repository at this point in the history
  • Loading branch information
balzss committed Jul 8, 2024
1 parent bcfcb84 commit 4b5ad11
Show file tree
Hide file tree
Showing 12 changed files with 658 additions and 11 deletions.
7 changes: 5 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 2 additions & 5 deletions packages/__docs__/components.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export { Expandable } from '@instructure/ui-expandable'
export { Focusable } from '@instructure/ui-focusable'
export { Img } from '@instructure/ui-img'
export { NumberInput } from '@instructure/ui-number-input'
export { DateInput } from '@instructure/ui-date-input'
export { DateInput, DateInput2 } from '@instructure/ui-date-input'
export { DateTimeInput } from '@instructure/ui-date-time-input'
export { Pill } from '@instructure/ui-pill'
export { TextInput } from '@instructure/ui-text-input'
Expand All @@ -69,10 +69,7 @@ export {
} from '@instructure/ui-form-field'
export { Table } from '@instructure/ui-table'
export { TruncateText } from '@instructure/ui-truncate-text'
export {
ApplyLocale,
TextDirectionContext
} from '@instructure/ui-i18n'
export { ApplyLocale, TextDirectionContext } from '@instructure/ui-i18n'
export { MetricGroup, Metric } from '@instructure/ui-metric'
export { Modal } from '@instructure/ui-modal'
export { Transition } from '@instructure/ui-motion'
Expand Down
2 changes: 2 additions & 0 deletions packages/ui-date-input/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"devDependencies": {
"@instructure/ui-axe-check": "9.1.0",
"@instructure/ui-babel-preset": "9.1.0",
"@instructure/ui-buttons": "9.1.0",
"@instructure/ui-scripts": "9.1.0",
"@instructure/ui-test-utils": "9.1.0",
"@testing-library/jest-dom": "^6.4.5",
Expand All @@ -47,6 +48,7 @@
"@instructure/ui-testable": "9.1.0",
"@instructure/ui-text-input": "9.1.0",
"@instructure/ui-utils": "9.1.0",
"moment-timezone": "^0.5.45",
"prop-types": "^15.8.1"
},
"peerDependencies": {
Expand Down
2 changes: 2 additions & 0 deletions packages/ui-date-input/src/DateInput/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
describes: DateInput
---

> **Important:** You can now use are updated version [`DateInput2`](/#DateInput2) which is easier to configure for devs, has a better UX for end users, better accessibility features and a year picker. In our next major update (v10) this component will be deprecated and renamed.
The `DateInput` component provides a visual interface for inputting date data.

### Default config
Expand Down
2 changes: 0 additions & 2 deletions packages/ui-date-input/src/DateInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ import type { FormMessage } from '@instructure/ui-form-field'
---
category: components
---
The `DateInput` component provides a visual interface for inputting date data.
See <https://instructure.design/#DateInput/>
**/
@withStyle(generateStyle, null)
@testable()
Expand Down
21 changes: 20 additions & 1 deletion packages/ui-date-input/src/DateInput/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,24 @@ type DateInputOwnProps = {
* property or a context property.
**/
timezone?: string

/**
* If set, years can be picked from a dropdown.
* It accepts an object.
* screenReaderLabel: string // e.g.: i18n("pick a year")
*
* onRequestYearChange?:(e: React.MouseEvent,requestedYear: number): void // if set, on year change, only this will be called and no internal change will take place
*
* startYear: number // e.g.: 2001, sets the start year of the selectable list
*
* endYear: number // e.g.: 2030, sets the end year of the selectable list
*/
withYearPicker?: {
screenReaderLabel: string
onRequestYearChange?: (e: any, requestedYear: number) => void
startYear: number
endYear: number
}
}

type PropKeys = keyof DateInputOwnProps
Expand Down Expand Up @@ -308,7 +326,8 @@ const propTypes: PropValidators<PropKeys> = {
PropTypes.string
]),
locale: PropTypes.string,
timezone: PropTypes.string
timezone: PropTypes.string,
withYearPicker: PropTypes.object
}

const allowedProps: AllowedPropKeys = [
Expand Down
205 changes: 205 additions & 0 deletions packages/ui-date-input/src/DateInput2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
---
describes: DateInput
---

This component is an updated version of [`DateInput`](/#DateInput) that's easier to configure for developers and use for end users. It has better accessibility and a year picker option. We recommend using this one instead and in our next major release (v10) it will replace `DateInput`.

### Minimal config

- ```js
class Example extends React.Component {
state = { value: '' }

render() {
return (
<DateInput2
renderLabel="Choose a date"
screenReaderLabels={{
calendarIcon: 'Calendar',
nextMonthButton: 'Next month',
prevMonthButton: 'Previous month'
}}
value={this.state.value}
width="20rem"
onChange={(e, value) => this.setState({ value })}
invalidDateErrorMessage="Invalid date"
/>
)
}
}

render(<Example />)
```

- ```js
const Example = () => {
const [value, setValue] = useState('')
return (
<DateInput2
renderLabel="Choose a date"
screenReaderLabels={{
calendarIcon: 'Calendar',
nextMonthButton: 'Next month',
prevMonthButton: 'Previous month'
}}
value={value}
width="20rem"
onChange={(e, value) => setValue(value)}
invalidDateErrorMessage="Invalid date"
/>
)
}

render(<Example />)
```

### With year picker

- ```js
class Example extends React.Component {
state = { value: '' }

render() {
return (
<DateInput2
renderLabel="Choose a date"
screenReaderLabels={{
calendarIcon: 'Calendar',
nextMonthButton: 'Next month',
prevMonthButton: 'Previous month'
}}
width="20rem"
value={this.state.value}
onChange={(e, value) => this.setState({ value })}
invalidDateErrorMessage="Invalid date"
withYearPicker={{
screenReaderLabel: 'Year picker',
startYear: 1999,
endYear: 2024
}}
/>
)
}
}

render(<Example />)
```

- ```js
const Example = () => {
const [value, setValue] = useState('')

return (
<DateInput2
renderLabel="Choose a date"
screenReaderLabels={{
calendarIcon: 'Calendar',
nextMonthButton: 'Next month',
prevMonthButton: 'Previous month'
}}
width="20rem"
value={value}
onChange={(e, value) => setValue(value)}
invalidDateErrorMessage="Invalid date"
withYearPicker={{
screenReaderLabel: 'Year picker',
startYear: 1999,
endYear: 2024
}}
/>
)
}

render(<Example />)
```

### Inside modal

```js
---
type: example
---

class Example extends React.Component {
constructor (props) {
super(props)

this.state = {
open: false,
value: '',
}
}

handleButtonClick = () => {
this.setState(function (state) {
return { open: !state.open }
})
};

handleFormSubmit = e => {
e.preventDefault()
console.log('form submitted')
this.setState(state => ({ open: false }))
}

renderCloseButton () {
return (
<CloseButton
placement="end"
offset="small"
onClick={this.handleButtonClick}
screenReaderLabel="Close"
/>
)
}

render () {
return (
<div style={{ padding: '0 0 11rem 0', margin: '0 auto' }}>
<Button onClick={this.handleButtonClick}>
{this.state.open ? 'Close' : 'Open'} the Modal
</Button>
<Modal
as="form"
open={this.state.open}
onDismiss={() => { this.setState({ open: false }) }}
onSubmit={this.handleFormSubmit}
size="auto"
label="Modal Dialog: Hello World"
shouldCloseOnDocumentClick
>
<Modal.Header>
{this.renderCloseButton()}
<Heading>Hello World</Heading>
</Modal.Header>
<Modal.Body>
<DateInput2
renderLabel="Choose a date"
screenReaderLabels={{
calendarIcon: 'Calendar',
nextMonthButton: 'Next month',
prevMonthButton: 'Previous month',
}}
width="20rem"
value={this.state.value}
onChange={(e, value) => this.setState({ value })}
invalidDateErrorMessage="Invalid date"
withYearPicker={{
screenReaderLabel: 'Year picker',
startYear: 1999,
endYear: 2024
}}
/>
</Modal.Body>
<Modal.Footer>
<Button onClick={this.handleButtonClick} margin="0 x-small 0 0">Close</Button>
<Button color="primary" type="submit">Submit</Button>
</Modal.Footer>
</Modal>
</div>
)
}
}

render(<Example />)
```
Loading

0 comments on commit 4b5ad11

Please sign in to comment.