diff --git a/CHANGELOG.md b/CHANGELOG.md index 73fbc2519e5..75b53f1b2a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ ## [`master`](https://github.com/elastic/eui/tree/master) -No public interface changes since `0.0.41`. +- Added `euiDatePicker` component for date/time input ([#644](https://github.com/elastic/eui/pull/644)) ## [`0.0.41`](https://github.com/elastic/eui/tree/v0.0.41) diff --git a/package.json b/package.json index 2c96b4566b6..45d3e395773 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "prop-types": "^15.6.0", "react-ace": "^5.5.0", "react-color": "^2.13.8", + "react-datepicker": "v1.4.1", "react-input-autosize": "^2.2.1", "serve": "^6.3.1", "tabbable": "^1.1.0", diff --git a/src-docs/src/components/guide_components.scss b/src-docs/src/components/guide_components.scss index 4c0f8ee2d55..c70766030ac 100644 --- a/src-docs/src/components/guide_components.scss +++ b/src-docs/src/components/guide_components.scss @@ -158,6 +158,22 @@ $guideZLevelHighest: $euiZLevel9 + 1000; } } +.dpTest__purpleCal { + background: purple; +} + +.dpTest__purpleInput { + outline: solid 2px purple; +} + +.dpTest__purpleDay { + background: purple; +} + +.dpTest__purplePopper { + outline: solid 2px purple; +} + @import "../views/guidelines/index"; @import "guide_section/index"; diff --git a/src-docs/src/routes.js b/src-docs/src/routes.js index f6428226b12..0d693e40825 100644 --- a/src-docs/src/routes.js +++ b/src-docs/src/routes.js @@ -80,6 +80,9 @@ import { ComboBoxExample } import { ContextMenuExample } from './views/context_menu/context_menu_example'; +import { DatePickerExample } + from './views/date_picker/date_picker_example'; + import { DelayHideExample } from './views/delay_hide/delay_hide_example'; @@ -314,6 +317,7 @@ const navigation = [{ ComboBoxExample, ColorPickerExample, CodeEditorExample, + DatePickerExample, ExpressionExample, FilterGroupExample, SearchBarExample, diff --git a/src-docs/src/views/date_picker/classes.js b/src-docs/src/views/date_picker/classes.js new file mode 100644 index 00000000000..835acc86d90 --- /dev/null +++ b/src-docs/src/views/date_picker/classes.js @@ -0,0 +1,79 @@ +import React, { + Component, +} from 'react'; + +import moment from 'moment'; + +import { + EuiDatePicker, + EuiFormRow, + EuiSpacer, +} from '../../../../src/components'; + +export default class extends Component { + + constructor(props) { + super(props); + + this.state = { + startDate: moment() + }; + + this.handleChange = this.handleChange.bind(this); + } + + handleChange(date) { + this.setState({ + startDate: date + }); + } + + render() { + return ( +
+ + + + + + + + + + + + + + date.date() < Math.random() * 31 ? 'dpTest__purpleDay' : undefined} + /> + + + + + + + + +
+ ); + } +} diff --git a/src-docs/src/views/date_picker/custom_input.js b/src-docs/src/views/date_picker/custom_input.js new file mode 100644 index 00000000000..5d6f5ee313b --- /dev/null +++ b/src-docs/src/views/date_picker/custom_input.js @@ -0,0 +1,63 @@ +import React, { + Component, +} from 'react'; + +import PropTypes from 'prop-types'; + +import moment from 'moment'; + +import { + EuiDatePicker, + EuiButton, +} from '../../../../src/components'; + +// Should be a component because the datepicker does some ref stuff behind the scenes +// eslint-disable-next-line react/prefer-stateless-function +class ExampleCustomInput extends React.Component { + + render () { + return ( + + {this.props.value} + + ) + } +} + +ExampleCustomInput.propTypes = { + onClick: PropTypes.func, + value: PropTypes.string +}; + +// eslint-disable-next-line react/no-multi-comp +export default class extends Component { + + constructor(props) { + super(props); + + this.state = { + startDate: moment() + }; + + this.handleChange = this.handleChange.bind(this); + } + + handleChange(date) { + this.setState({ + startDate: date + }); + } + + render() { + return ( + } + /> + ); + } +} diff --git a/src-docs/src/views/date_picker/date_picker.js b/src-docs/src/views/date_picker/date_picker.js new file mode 100644 index 00000000000..460116ecd8b --- /dev/null +++ b/src-docs/src/views/date_picker/date_picker.js @@ -0,0 +1,40 @@ +import React, { + Component, +} from 'react'; + +import moment from 'moment'; + +import { + EuiDatePicker, + EuiFormRow, +} from '../../../../src/components'; + +export default class extends Component { + + constructor(props) { + super(props); + + this.state = { + startDate: moment() + }; + + this.handleChange = this.handleChange.bind(this); + } + + handleChange(date) { + this.setState({ + startDate: date + }); + } + + render() { + return ( + + + + ); + } +} diff --git a/src-docs/src/views/date_picker/date_picker_example.js b/src-docs/src/views/date_picker/date_picker_example.js new file mode 100644 index 00000000000..4bd9ca9ecd2 --- /dev/null +++ b/src-docs/src/views/date_picker/date_picker_example.js @@ -0,0 +1,259 @@ +import React from 'react'; + +import { renderToHtml } from '../../services'; + +import { + GuideSectionTypes, +} from '../../components'; + +import { + EuiCode, + EuiLink, + EuiDatePicker, +} from '../../../../src/components'; + +import DatePicker from './date_picker'; +const datePickerSource = require('!!raw-loader!./date_picker'); +const datePickerHtml = renderToHtml(DatePicker); + +import States from './states'; +const statesSource = require('!!raw-loader!./states'); +const statesHtml = renderToHtml(States); + +import Locale from './locale'; +const localeSource = require('!!raw-loader!./locale'); +const localeHtml = renderToHtml(Locale); + +import Time from './time_select'; +const timeSource = require('!!raw-loader!./time_select'); +const timeHtml = renderToHtml(Time); + +import Inline from './inline'; +const inlineSource = require('!!raw-loader!./inline'); +const inlineHtml = renderToHtml(Inline); + +import Range from './range'; +const rangeSource = require('!!raw-loader!./range'); +const rangeHtml = renderToHtml(Range); + +import MinMax from './min_max'; +const minMaxSource = require('!!raw-loader!./min_max'); +const minMaxHtml = renderToHtml(MinMax); + +import Classes from './classes'; +const classesSource = require('!!raw-loader!./classes'); +const classesHtml = renderToHtml(Classes); + +import OpenToDate from './open_to_date'; +const openToDateSource = require('!!raw-loader!./open_to_date'); +const openToDateHtml = renderToHtml(OpenToDate); + +import CustomInput from './custom_input'; +const customInputSource = require('!!raw-loader!./custom_input'); +const customInputHtml = renderToHtml(CustomInput); + +import Utc from './utc'; +const utcSource = require('!!raw-loader!./utc'); +const utcHtml = renderToHtml(Utc); + +export const DatePickerExample = { + title: 'DatePicker', + sections: [{ + source: [{ + type: GuideSectionTypes.JS, + code: datePickerSource, + }, { + type: GuideSectionTypes.HTML, + code: datePickerHtml, + }], + text: ( +

+ At its most bare the EuiDatePicker only requires + props for selected and onChange. + It depends on moment for + all of its formatting. +

+ ), + components: { EuiDatePicker }, + demo: , + props: { EuiDatePicker }, + }, { + title: 'Datepicker states', + source: [{ + type: GuideSectionTypes.JS, + code: statesSource, + }, { + type: GuideSectionTypes.HTML, + code: statesHtml, + }], + text: ( +

+ Examples of how the input can appear within a form. This should match our + other form styles. +

+ ), + demo: , + }, { + title: 'Time selection', + source: [{ + type: GuideSectionTypes.JS, + code: timeSource, + }, { + type: GuideSectionTypes.HTML, + code: timeHtml, + }], + text: ( +

+ Two props control time selction. showTimeSelect will make + time selection appear next to the calendar + and showTimeSelectOnly will exclude the calendar and + make the time selection the only thing you see. Make sure to adjust + your dateFormat and timeFormat values + to match. +

+ ), + demo: