From 00495775f7f0fd30bd105993b2d16a6ad65e9bfc Mon Sep 17 00:00:00 2001 From: Dave Snider Date: Wed, 28 Mar 2018 19:33:18 -0700 Subject: [PATCH 01/42] start of datepicker --- package.json | 1 + src-docs/src/routes.js | 4 ++ src-docs/src/views/date_picker/date_picker.js | 9 +++ .../views/date_picker/date_picker_example.js | 37 +++++++++++++ src/components/date_picker/_date_picker.scss | 22 ++++++++ src/components/date_picker/_index.scss | 1 + src/components/date_picker/date_picker.js | 55 +++++++++++++++++++ .../date_picker/date_picker.test.js | 16 ++++++ src/components/date_picker/index.js | 3 + src/components/index.js | 4 ++ src/components/index.scss | 3 + yarn.lock | 23 ++++++++ 12 files changed, 178 insertions(+) create mode 100644 src-docs/src/views/date_picker/date_picker.js create mode 100644 src-docs/src/views/date_picker/date_picker_example.js create mode 100644 src/components/date_picker/_date_picker.scss create mode 100644 src/components/date_picker/_index.scss create mode 100644 src/components/date_picker/date_picker.js create mode 100644 src/components/date_picker/date_picker.test.js create mode 100644 src/components/date_picker/index.js diff --git a/package.json b/package.json index 2c96b4566b6..e6a7bd4182a 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "react-ace": "^5.5.0", "react-color": "^2.13.8", "react-input-autosize": "^2.2.1", + "react-datepicker": "^1.3.0", "serve": "^6.3.1", "tabbable": "^1.1.0", "uuid": "^3.1.0" 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/date_picker.js b/src-docs/src/views/date_picker/date_picker.js new file mode 100644 index 00000000000..136feebfb19 --- /dev/null +++ b/src-docs/src/views/date_picker/date_picker.js @@ -0,0 +1,9 @@ +import React from 'react'; + +import { + EuiDatePicker, +} from '../../../../src/components'; + +export default () => ( + +); 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..25853fcfddb --- /dev/null +++ b/src-docs/src/views/date_picker/date_picker_example.js @@ -0,0 +1,37 @@ +import React from 'react'; + +import { renderToHtml } from '../../services'; + +import { + GuideSectionTypes, +} from '../../components'; + +import { + EuiCode, + EuiDatePicker, +} from '../../../../src/components'; + +import DatePicker from './date_picker'; +const datePickerSource = require('!!raw-loader!./date_picker'); +const datePickerHtml = renderToHtml(DatePicker); + +export const DatePickerExample = { + title: 'DatePicker', + sections: [{ + title: 'DatePicker', + source: [{ + type: GuideSectionTypes.JS, + code: datePickerSource, + }, { + type: GuideSectionTypes.HTML, + code: datePickerHtml, + }], + text: ( +

+ Description needed: how to use the EuiDatePicker component. +

+ ), + components: { EuiDatePicker }, + demo: , + }], +}; diff --git a/src/components/date_picker/_date_picker.scss b/src/components/date_picker/_date_picker.scss new file mode 100644 index 00000000000..ee1b1d00046 --- /dev/null +++ b/src/components/date_picker/_date_picker.scss @@ -0,0 +1,22 @@ +$datepicker__background-color: $euiColorEmptyShade !default; +$datepicker__border-color: $euiBorderColor !default; +$datepicker__highlighted-color: #3dcc4a !default; +$datepicker__muted-color: $euiColorLightestShade !default; +$datepicker__selected-color: $euiColorPrimary !default; +$datepicker__text-color: $euiTextColor !default; +$datepicker__header-color: $euiColorFullShade !default; +$datepicker__navigation-disabled-color: lighten($datepicker__muted-color, 10%) + !default; + +$datepicker__border-radius: $euiBorderRadius !default; +$datepicker__day-margin: $euiSizeXS !default; +$datepicker__font-size: $euiSizeM !default; +$datepicker__font-family: $euiFontFamily !default; +$datepicker__item-size: $euiSizeL !default; +$datepicker__margin: $euiSize !default; +$datepicker__navigation-size: $euiSize !default; +$datepicker__triangle-size: 0 !default; + +.euiDatePicker { + +} diff --git a/src/components/date_picker/_index.scss b/src/components/date_picker/_index.scss new file mode 100644 index 00000000000..653a85c6211 --- /dev/null +++ b/src/components/date_picker/_index.scss @@ -0,0 +1 @@ +@import 'date_picker'; diff --git a/src/components/date_picker/date_picker.js b/src/components/date_picker/date_picker.js new file mode 100644 index 00000000000..cf8b6941787 --- /dev/null +++ b/src/components/date_picker/date_picker.js @@ -0,0 +1,55 @@ +import React, { + Component, +} from 'react'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; + +import moment from 'moment'; +import DatePicker from 'react-datepicker'; + +export class EuiDatePicker extends Component { + static propTypes = { + children: PropTypes.node, + className: PropTypes.string, + } + + constructor(props) { + super(props); + + this.state = { + startDate: moment() + }; + + this.handleChange = this.handleChange.bind(this); + } + + handleChange(date) { + this.setState({ + startDate: date + }); + } + + render() { + const { + className, + ...rest + } = this.props; + + const classes = classNames( + 'euiDatePicker', + 'euiFieldText', + className + ); + + return ( + + ); + } +} diff --git a/src/components/date_picker/date_picker.test.js b/src/components/date_picker/date_picker.test.js new file mode 100644 index 00000000000..be5692d8195 --- /dev/null +++ b/src/components/date_picker/date_picker.test.js @@ -0,0 +1,16 @@ +import React from 'react'; +import { render } from 'enzyme'; +import { requiredProps } from '../../test'; + +import { EuiDatePicker } from './date_picker'; + +describe('EuiDatePicker', () => { + test('is rendered', () => { + const component = render( + + ); + + expect(component) + .toMatchSnapshot(); + }); +}); diff --git a/src/components/date_picker/index.js b/src/components/date_picker/index.js new file mode 100644 index 00000000000..a50b7176468 --- /dev/null +++ b/src/components/date_picker/index.js @@ -0,0 +1,3 @@ +export { + EuiDatePicker, +} from './date_picker'; diff --git a/src/components/index.js b/src/components/index.js index 0777c546f5c..a1f1c7c02c7 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -57,6 +57,10 @@ export { EuiContextMenuItem, } from './context_menu'; +export { + EuiDatePicker, +} from './date_picker'; + export { EuiDelayHide } from './delay_hide'; diff --git a/src/components/index.scss b/src/components/index.scss index 75d2c6c3779..08d3a871ad2 100644 --- a/src/components/index.scss +++ b/src/components/index.scss @@ -48,3 +48,6 @@ @import 'toast/index'; @import 'tool_tip/index'; @import 'text/index'; + +@import 'date_picker/index'; +@import '../../node_modules/react-datepicker/src/stylesheets/datepicker' diff --git a/yarn.lock b/yarn.lock index 375bc03be51..086f94b0efb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6606,6 +6606,10 @@ pn@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" +popper.js@^1.12.9: + version "1.14.1" + resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.14.1.tgz#b8815e5cda6f62fc2042e47618649f75866e6753" + portfinder@^1.0.9: version "1.0.13" resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9" @@ -7182,6 +7186,15 @@ react-color@^2.13.8: reactcss "^1.2.0" tinycolor2 "^1.4.1" +react-datepicker@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/react-datepicker/-/react-datepicker-1.3.0.tgz#200978cf25c4736f97df4ccab9693e167466bf3a" + dependencies: + classnames "^2.2.5" + prop-types "^15.6.0" + react-onclickoutside "^6.7.1" + react-popper "^0.8.3" + react-docgen@^2.20.0: version "2.20.0" resolved "https://registry.yarnpkg.com/react-docgen/-/react-docgen-2.20.0.tgz#41a6da483a34a4aaed041a9909f5e61864d681cb" @@ -7208,6 +7221,16 @@ react-input-autosize@^2.2.1: resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.2.1.tgz#ec428fa15b1592994fb5f9aa15bb1eb6baf420f8" dependencies: prop-types "^15.5.8" +react-onclickoutside@^6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/react-onclickoutside/-/react-onclickoutside-6.7.1.tgz#6a5b5b8b4eae6b776259712c89c8a2b36b17be93" + +react-popper@^0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-0.8.3.tgz#0f73333137c9fb0af6ec4074d2d0585a0a0461e1" + dependencies: + popper.js "^1.12.9" + prop-types "^15.6.0" react-reconciler@^0.7.0: version "0.7.0" From 85602b39ab06929d768d8676d34fb46223d4bc07 Mon Sep 17 00:00:00 2001 From: Dave Snider Date: Thu, 5 Apr 2018 15:01:47 -0700 Subject: [PATCH 02/42] update datepicker, now works with form controls --- package.json | 2 +- src-docs/src/views/date_picker/date_picker.js | 13 +- src/components/date_picker/_date_picker.scss | 637 +++++++++++++++++- src/components/date_picker/_index.scss | 4 + src/components/date_picker/date_picker.js | 56 +- src/components/index.scss | 4 +- yarn.lock | 33 +- 7 files changed, 720 insertions(+), 29 deletions(-) diff --git a/package.json b/package.json index e6a7bd4182a..6f01218eed1 100644 --- a/package.json +++ b/package.json @@ -42,8 +42,8 @@ "prop-types": "^15.6.0", "react-ace": "^5.5.0", "react-color": "^2.13.8", + "react-datepicker": "v1.4.0", "react-input-autosize": "^2.2.1", - "react-datepicker": "^1.3.0", "serve": "^6.3.1", "tabbable": "^1.1.0", "uuid": "^3.1.0" diff --git a/src-docs/src/views/date_picker/date_picker.js b/src-docs/src/views/date_picker/date_picker.js index 136feebfb19..be55ef8a1f2 100644 --- a/src-docs/src/views/date_picker/date_picker.js +++ b/src-docs/src/views/date_picker/date_picker.js @@ -1,9 +1,20 @@ import React from 'react'; +import moment from 'moment'; + import { EuiDatePicker, + EuiFormRow, } from '../../../../src/components'; export default () => ( - + + + ); diff --git a/src/components/date_picker/_date_picker.scss b/src/components/date_picker/_date_picker.scss index ee1b1d00046..d8f2f664cbe 100644 --- a/src/components/date_picker/_date_picker.scss +++ b/src/components/date_picker/_date_picker.scss @@ -1,22 +1,651 @@ +// This file is a heavy retheme of react-datepicker's Sass as of v1.4.0 +// https://github.com/Hacker0x01/react-datepicker + $datepicker__background-color: $euiColorEmptyShade !default; $datepicker__border-color: $euiBorderColor !default; $datepicker__highlighted-color: #3dcc4a !default; $datepicker__muted-color: $euiColorLightestShade !default; $datepicker__selected-color: $euiColorPrimary !default; -$datepicker__text-color: $euiTextColor !default; +$datepicker__text-color: $euiColorFullShade !default; $datepicker__header-color: $euiColorFullShade !default; $datepicker__navigation-disabled-color: lighten($datepicker__muted-color, 10%) !default; $datepicker__border-radius: $euiBorderRadius !default; -$datepicker__day-margin: $euiSizeXS !default; +$datepicker__day-margin: $euiSizeXS / 2 !default; $datepicker__font-size: $euiSizeM !default; $datepicker__font-family: $euiFontFamily !default; -$datepicker__item-size: $euiSizeL !default; +$datepicker__item-size: $euiSizeXL !default; $datepicker__margin: $euiSize !default; $datepicker__navigation-size: $euiSize !default; $datepicker__triangle-size: 0 !default; +$datepicker__time-width: auto !default; + +%triangle-arrow { + margin-left: -$datepicker__triangle-size; + position: absolute; + + &, + &::before { + box-sizing: content-box; + position: absolute; + border: $datepicker__triangle-size solid transparent; + + height: 0; + width: 1px; + } + + &::before { + content: ""; + z-index: -1; + border-width: $datepicker__triangle-size; + + left: -$datepicker__triangle-size; + border-bottom-color: $datepicker__border-color; + } +} + +%triangle-arrow-up { + @extend %triangle-arrow; + + top: 0; + margin-top: -$datepicker__triangle-size; + + &, + &::before { + border-top: none; + border-bottom-color: $datepicker__background-color; + } + + &::before { + top: -1px; + border-bottom-color: $datepicker__border-color; + } +} + +%triangle-arrow-down { + @extend %triangle-arrow; + + bottom: 0; + margin-bottom: -$datepicker__triangle-size; + + &, + &::before { + border-bottom: none; + border-top-color: #fff; + } + + &::before { + bottom: -1px; + border-top-color: $datepicker__border-color; + } +} + +.react-datepicker-wrapper { + display: inline-block; +} + +.react-datepicker { + font-family: $datepicker__font-family; + font-size: $datepicker__font-size; + background-color: #fff; + color: $datepicker__text-color; + border: 1px solid $datepicker__border-color; + border-radius: $datepicker__border-radius; + display: inline-block; + position: relative; +} + +.react-datepicker--time-only { + .react-datepicker__triangle { + left: 35px; + } + + .react-datepicker__time-container { + border-left: 0; + } + + .react-datepicker__time { + border-radius: 0.3rem; + } + + .react-datepicker__time-box { + border-radius: 0.3rem; + } +} + +.react-datepicker__triangle { + position: absolute; + left: 50px; +} + +.react-datepicker-popper { + z-index: 1; + + &[data-placement^="bottom"] { + margin-top: $datepicker__triangle-size + 2px; + + .react-datepicker__triangle { + @extend %triangle-arrow-up; + } + } + + &[data-placement^="top"] { + margin-bottom: $datepicker__triangle-size + 2px; + + .react-datepicker__triangle { + @extend %triangle-arrow-down; + } + } + + &[data-placement^="right"] { + margin-left: $datepicker__triangle-size; + + .react-datepicker__triangle { + left: auto; + right: 42px; + } + } + + &[data-placement^="left"] { + margin-right: $datepicker__triangle-size; + + .react-datepicker__triangle { + left: 42px; + right: auto; + } + } +} + +.react-datepicker__header { + text-align: center; + border-top-left-radius: $datepicker__border-radius; + border-top-right-radius: $datepicker__border-radius; + position: relative; + + &--time { + display: none; + } +} + +.react-datepicker__year-dropdown-container--select, +.react-datepicker__month-dropdown-container--select, +.react-datepicker__month-year-dropdown-container--select, +.react-datepicker__year-dropdown-container--scroll, +.react-datepicker__month-dropdown-container--scroll, +.react-datepicker__month-year-dropdown-container--scroll { + display: inline-block; + margin: 0 2px; +} + +.react-datepicker__current-month, +.react-datepicker-time__header { + margin-top: 0; + color: $datepicker__header-color; + font-weight: bold; + font-size: $datepicker__font-size * 1.18; +} + +.react-datepicker-time__header { + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; +} + +.react-datepicker__navigation { + background: none; + line-height: $datepicker__item-size; + text-align: center; + cursor: pointer; + position: absolute; + top: 10px; + width: 0; + padding: 0; + border: $datepicker__navigation-size solid transparent; + z-index: 1; + + &--previous { + left: 10px; + border-right-color: $datepicker__muted-color; + + &:hover { + border-right-color: darken($datepicker__muted-color, 10%); + } + + &--disabled, + &--disabled:hover { + border-right-color: $datepicker__navigation-disabled-color; + cursor: default; + } + } + + &--next { + right: 10px; + border-left-color: $datepicker__muted-color; + &--with-time:not(&--with-today-button) { + right: 80px; + } + + &:hover { + border-left-color: darken($datepicker__muted-color, 10%); + } + + &--disabled, + &--disabled:hover { + border-left-color: $datepicker__navigation-disabled-color; + cursor: default; + } + } + + &--years { + position: relative; + top: 0; + display: block; + margin-left: auto; + margin-right: auto; + + &-previous { + top: 4px; + border-top-color: $datepicker__muted-color; + + &:hover { + border-top-color: darken($datepicker__muted-color, 10%); + } + } + + &-upcoming { + top: -4px; + border-bottom-color: $datepicker__muted-color; + + &:hover { + border-bottom-color: darken($datepicker__muted-color, 10%); + } + } + } +} + +.react-datepicker__month-container { +} + +.react-datepicker__month { + margin: $datepicker__margin; + text-align: center; +} + +.react-datepicker__time-container { + border-left: 1px solid $datepicker__border-color; + width: $datepicker__time-width; + + &--with-today-button { + display: inline; + border: 1px solid #aeaeae; + border-radius: 0.3rem; + position: absolute; + right: $datepicker__time-width; + top: 0; + } + + .react-datepicker__time { + position: relative; + background: white; + + .react-datepicker__time-box { + width: $datepicker__time-width; + overflow-x: hidden; + margin: 0 auto; + text-align: center; + ul.react-datepicker__time-list { + list-style: none; + margin: 0; + height: calc(195px + (#{$datepicker__item-size} / 2)); + overflow-y: scroll; + padding-right: 30px; + width: 100%; + box-sizing: content-box; + + li.react-datepicker__time-list-item { + padding: 5px 10px; + &:hover { + cursor: pointer; + background-color: $datepicker__background-color; + } + &--selected { + background-color: $datepicker__selected-color; + color: white; + font-weight: bold; + &:hover { + background-color: $datepicker__selected-color; + } + } + &--disabled { + color: $datepicker__muted-color; + + &:hover { + cursor: default; + background-color: transparent; + } + } + } + } + } + } +} + +.react-datepicker__week-number { + color: $datepicker__muted-color; + display: inline-block; + width: $datepicker__item-size; + line-height: $datepicker__item-size - 4px; + text-align: center; + margin: 0 $datepicker__day-margin; + &.react-datepicker__week-number--clickable { + cursor: pointer; + &:hover { + border-radius: $datepicker__border-radius; + background-color: $datepicker__background-color; + } + } +} + +.react-datepicker__day-names, +.react-datepicker__week { + white-space: nowrap; +} + +.react-datepicker__day-name, +.react-datepicker__day, +.react-datepicker__time-name { + color: $datepicker__text-color; + display: inline-block; + width: $datepicker__item-size; + line-height: $datepicker__item-size - 4px; + text-align: center; + margin: 0 $datepicker__day-margin; +} + +.react-datepicker__day-name { + color: $euiColorDarkShade; + text-transform: uppercase; +} + +.react-datepicker__day { + cursor: pointer; + border: solid 2px transparent; + + &:hover { + border-radius: $datepicker__border-radius; + background-color: $datepicker__background-color; + } + + &--today { + font-weight: bold; + color: $euiColorPrimary; + } + &--outside-month { + color: $euiColorMediumShade; + } + + &--highlighted { + border-radius: $datepicker__border-radius; + background-color: $datepicker__highlighted-color; + color: #fff; + + &:hover { + background-color: darken($datepicker__highlighted-color, 5%); + } + + &-custom-1 { + color: magenta; + } + + &-custom-2 { + color: green; + } + + } + + &--selected, + &--in-selecting-range, + &--in-range { + border-radius: $datepicker__border-radius; + background-color: $datepicker__selected-color; + color: #fff; + + &:hover { + background-color: darken($datepicker__selected-color, 5%); + } + } + + &--keyboard-selected { + border-radius: $datepicker__border-radius; + border: solid 2px $euiColorPrimary; + font-weight: $euiFontWeightBold; + + &:hover { + background-color: darken($datepicker__selected-color, 5%); + } + } + + &--in-selecting-range:not(&--in-range) { + background-color: rgba($datepicker__selected-color, 0.5); + } + + &--in-range:not(&--in-selecting-range) { + .react-datepicker__month--selecting-range & { + background-color: $datepicker__background-color; + color: $datepicker__text-color; + } + } + + &--disabled { + cursor: default; + color: $datepicker__muted-color; + + &:hover { + background-color: transparent; + } + } +} + +.react-datepicker__input-container { + position: relative; + display: inline-block; +} + +.react-datepicker__year-read-view, +.react-datepicker__month-read-view, +.react-datepicker__month-year-read-view { + border: 1px solid transparent; + border-radius: $datepicker__border-radius; + + &:hover { + cursor: pointer; + + .react-datepicker__year-read-view--down-arrow, + .react-datepicker__month-read-view--down-arrow { + border-top-color: darken($datepicker__muted-color, 10%); + } + } + + &--down-arrow { + @extend %triangle-arrow-down; + border-top-color: $datepicker__muted-color; + float: right; + margin-left: 20px; + top: 8px; + position: relative; + border-width: $datepicker__navigation-size; + } +} + +.react-datepicker__year-dropdown, +.react-datepicker__month-dropdown, +.react-datepicker__month-year-dropdown { + background-color: $datepicker__background-color; + position: absolute; + width: 50%; + left: 25%; + top: 30px; + z-index: 1; + text-align: center; + border-radius: $datepicker__border-radius; + border: 1px solid $datepicker__border-color; + + &:hover { + cursor: pointer; + } + + &--scrollable { + height: 150px; + overflow-y: scroll; + } +} + +.react-datepicker__year-option, +.react-datepicker__month-option, +.react-datepicker__month-year-option { + line-height: 20px; + width: 100%; + display: block; + margin-left: auto; + margin-right: auto; + + &:first-of-type { + border-top-left-radius: $datepicker__border-radius; + border-top-right-radius: $datepicker__border-radius; + } + + &:last-of-type { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + border-bottom-left-radius: $datepicker__border-radius; + border-bottom-right-radius: $datepicker__border-radius; + } + + &:hover { + background-color: $datepicker__muted-color; + + .react-datepicker__navigation--years-upcoming { + border-bottom-color: darken($datepicker__muted-color, 10%); + } + + .react-datepicker__navigation--years-previous { + border-top-color: darken($datepicker__muted-color, 10%); + } + } + + &--selected { + position: absolute; + left: 15px; + } +} + +.react-datepicker__close-icon { + background-color: transparent; + border: 0; + cursor: pointer; + display: inline-block; + height: 0; + outline: 0; + padding: 0; + vertical-align: middle; + + &::after { + background-color: $datepicker__selected-color; + border-radius: 50%; + bottom: 0; + box-sizing: border-box; + color: #fff; + content: "\00d7"; + cursor: pointer; + font-size: 12px; + height: 16px; + width: 16px; + line-height: 1; + margin: -8px auto 0; + padding: 2px; + position: absolute; + right: 7px; + text-align: center; + top: 50%; + } +} + +.react-datepicker__today-button { + background: $datepicker__background-color; + border-top: 1px solid $datepicker__border-color; + cursor: pointer; + text-align: center; + font-weight: bold; + padding: 5px 0; + clear: left; +} + +.react-datepicker__portal { + position: fixed; + width: 100vw; + height: 100vh; + background-color: rgba(0, 0, 0, 0.8); + left: 0; + top: 0; + justify-content: center; + align-items: center; + display: flex; + z-index: 2147483647; + + .react-datepicker__day-name, + .react-datepicker__day, + .react-datepicker__time-name { + width: 3rem; + line-height: 3rem; + } + + // Resize for small screens + @media (max-width: 400px), (max-height: 550px) { + .react-datepicker__day-name, + .react-datepicker__day, + .react-datepicker__time-name { + width: 2rem; + line-height: 2rem; + } + } + + .react-datepicker__current-month, + .react-datepicker-time__header { + font-size: $datepicker__font-size * 1.8; + } + + .react-datepicker__navigation { + border: 1.8 * $datepicker__navigation-size solid transparent; + } + + .react-datepicker__navigation--previous { + border-right-color: $datepicker__muted-color; + + &:hover { + border-right-color: darken($datepicker__muted-color, 10%); + } + + &--disabled, + &--disabled:hover { + border-right-color: $datepicker__navigation-disabled-color; + cursor: default; + } + } + + .react-datepicker__navigation--next { + border-left-color: $datepicker__muted-color; -.euiDatePicker { + &:hover { + border-left-color: darken($datepicker__muted-color, 10%); + } + &--disabled, + &--disabled:hover { + border-left-color: $datepicker__navigation-disabled-color; + cursor: default; + } + } } diff --git a/src/components/date_picker/_index.scss b/src/components/date_picker/_index.scss index 653a85c6211..e3e05110e32 100644 --- a/src/components/date_picker/_index.scss +++ b/src/components/date_picker/_index.scss @@ -1 +1,5 @@ +// Uses some form mixins +@import '../form/_variables'; +@import '../form/_mixins'; + @import 'date_picker'; diff --git a/src/components/date_picker/date_picker.js b/src/components/date_picker/date_picker.js index cf8b6941787..45b5d1e650b 100644 --- a/src/components/date_picker/date_picker.js +++ b/src/components/date_picker/date_picker.js @@ -7,6 +7,14 @@ import classNames from 'classnames'; import moment from 'moment'; import DatePicker from 'react-datepicker'; +import { + EuiFormControlLayout, +} from '../form/form_control_layout'; + +import { + EuiValidatableControl, +} from '../form/validatable_control'; + export class EuiDatePicker extends Component { static propTypes = { children: PropTypes.node, @@ -32,24 +40,56 @@ export class EuiDatePicker extends Component { render() { const { className, + isInvalid, + inputRef, + fullWidth, + isLoading, + placeholder, ...rest } = this.props; const classes = classNames( 'euiDatePicker', 'euiFieldText', + 'euiFieldText--fullWidth': fullWidth, + 'euiFieldText-isLoading': isLoading, + 'euiFieldText--withIcon', className ); return ( - + + + + + ); } } + +EuiDatePicker.propTypes = { + placeholder: PropTypes.string, + icon: PropTypes.string, + isInvalid: PropTypes.bool, + inputRef: PropTypes.func, + fullWidth: PropTypes.bool, + isLoading: PropTypes.bool, +}; + +EuiDatePicker.defaultProps = { + fullWidth: false, + isLoading: false, +}; diff --git a/src/components/index.scss b/src/components/index.scss index 08d3a871ad2..12007c37949 100644 --- a/src/components/index.scss +++ b/src/components/index.scss @@ -15,6 +15,7 @@ @import 'color_picker/index'; @import 'combo_box/index'; @import 'context_menu/index'; +@import 'date_picker/index'; @import 'description_list/index'; @import 'error_boundary/index'; @import 'expression/index'; @@ -48,6 +49,3 @@ @import 'toast/index'; @import 'tool_tip/index'; @import 'text/index'; - -@import 'date_picker/index'; -@import '../../node_modules/react-datepicker/src/stylesheets/datepicker' diff --git a/yarn.lock b/yarn.lock index 086f94b0efb..bee4c7e29a7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6606,9 +6606,9 @@ pn@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" -popper.js@^1.12.9: - version "1.14.1" - resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.14.1.tgz#b8815e5cda6f62fc2042e47618649f75866e6753" +popper.js@^1.14.1: + version "1.14.3" + resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.14.3.tgz#1438f98d046acf7b4d78cd502bf418ac64d4f095" portfinder@^1.0.9: version "1.0.13" @@ -7013,6 +7013,14 @@ prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.5.8, prop-types@^15.6.0: loose-envify "^1.3.1" object-assign "^4.1.1" +prop-types@^15.6.1: + version "15.6.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca" + dependencies: + fbjs "^0.8.16" + loose-envify "^1.3.1" + object-assign "^4.1.1" + protochain@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/protochain/-/protochain-1.0.5.tgz#991c407e99de264aadf8f81504b5e7faf7bfa260" @@ -7186,14 +7194,14 @@ react-color@^2.13.8: reactcss "^1.2.0" tinycolor2 "^1.4.1" -react-datepicker@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/react-datepicker/-/react-datepicker-1.3.0.tgz#200978cf25c4736f97df4ccab9693e167466bf3a" +react-datepicker@v1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/react-datepicker/-/react-datepicker-1.4.0.tgz#3043afe7c1b65640e75c86d67fe3d5fbe844e413" dependencies: classnames "^2.2.5" prop-types "^15.6.0" react-onclickoutside "^6.7.1" - react-popper "^0.8.3" + react-popper "^0.9.1" react-docgen@^2.20.0: version "2.20.0" @@ -7221,16 +7229,17 @@ react-input-autosize@^2.2.1: resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.2.1.tgz#ec428fa15b1592994fb5f9aa15bb1eb6baf420f8" dependencies: prop-types "^15.5.8" + react-onclickoutside@^6.7.1: version "6.7.1" resolved "https://registry.yarnpkg.com/react-onclickoutside/-/react-onclickoutside-6.7.1.tgz#6a5b5b8b4eae6b776259712c89c8a2b36b17be93" -react-popper@^0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-0.8.3.tgz#0f73333137c9fb0af6ec4074d2d0585a0a0461e1" +react-popper@^0.9.1: + version "0.9.5" + resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-0.9.5.tgz#02a24ef3eec33af9e54e8358ab70eb0e331edd05" dependencies: - popper.js "^1.12.9" - prop-types "^15.6.0" + popper.js "^1.14.1" + prop-types "^15.6.1" react-reconciler@^0.7.0: version "0.7.0" From f2e06028adeb1a097cbe55fecb55a8d820566304 Mon Sep 17 00:00:00 2001 From: Dave Snider Date: Thu, 5 Apr 2018 16:22:01 -0700 Subject: [PATCH 03/42] more styling --- src/components/date_picker/_date_picker.scss | 42 ++++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/components/date_picker/_date_picker.scss b/src/components/date_picker/_date_picker.scss index d8f2f664cbe..efa2eb49c11 100644 --- a/src/components/date_picker/_date_picker.scss +++ b/src/components/date_picker/_date_picker.scss @@ -82,7 +82,6 @@ $datepicker__time-width: auto !default; } .react-datepicker-wrapper { - display: inline-block; } .react-datepicker { @@ -92,8 +91,9 @@ $datepicker__time-width: auto !default; color: $datepicker__text-color; border: 1px solid $datepicker__border-color; border-radius: $datepicker__border-radius; - display: inline-block; + display: flex; position: relative; + @include euiBottomShadowMedium; } .react-datepicker--time-only { @@ -121,9 +121,9 @@ $datepicker__time-width: auto !default; .react-datepicker-popper { z-index: 1; + animation: euiAnimFadeIn $euiAnimSpeedFast ease-in; &[data-placement^="bottom"] { - margin-top: $datepicker__triangle-size + 2px; .react-datepicker__triangle { @extend %triangle-arrow-up; @@ -131,7 +131,6 @@ $datepicker__time-width: auto !default; } &[data-placement^="top"] { - margin-bottom: $datepicker__triangle-size + 2px; .react-datepicker__triangle { @extend %triangle-arrow-down; @@ -268,7 +267,7 @@ $datepicker__time-width: auto !default; } .react-datepicker__month { - margin: $datepicker__margin; + margin: 0 $datepicker__margin $datepicker__margin $datepicker__margin; text-align: center; } @@ -287,32 +286,32 @@ $datepicker__time-width: auto !default; .react-datepicker__time { position: relative; - background: white; + background: $euiColorLightestShade; + border-radius: 0 $euiBorderRadius $euiBorderRadius 0; .react-datepicker__time-box { width: $datepicker__time-width; - overflow-x: hidden; - margin: 0 auto; - text-align: center; + padding: $euiSize 0 $euiSize $euiSizeXS; ul.react-datepicker__time-list { - list-style: none; - margin: 0; - height: calc(195px + (#{$datepicker__item-size} / 2)); + height: 204px !important; overflow-y: scroll; - padding-right: 30px; - width: 100%; - box-sizing: content-box; + @include euiScrollBar; li.react-datepicker__time-list-item { - padding: 5px 10px; + padding: $euiSizeXS $euiSizeS; + margin-bottom: $euiSizeXS; + text-align: right; + font-family: $euiCodeFontFamily; + color: $euiColorDarkShade; + &:hover { cursor: pointer; - background-color: $datepicker__background-color; + text-decoration: underline; } &--selected { background-color: $datepicker__selected-color; color: white; - font-weight: bold; + border-radius: $euiBorderRadius / 2; &:hover { background-color: $datepicker__selected-color; } @@ -371,10 +370,12 @@ $datepicker__time-width: auto !default; .react-datepicker__day { cursor: pointer; border: solid 2px transparent; + transition: transform $euiAnimSpeedExtraFast ease-in-out; &:hover { - border-radius: $datepicker__border-radius; - background-color: $datepicker__background-color; + text-decoration: underline; + font-weight: $euiFontWeightBold; + transform: scale(1.2); } &--today { @@ -449,7 +450,6 @@ $datepicker__time-width: auto !default; .react-datepicker__input-container { position: relative; - display: inline-block; } .react-datepicker__year-read-view, From ee791175a0f1315746f3896cd88f86dc984ac6c2 Mon Sep 17 00:00:00 2001 From: Dave Snider Date: Fri, 6 Apr 2018 13:50:24 -0700 Subject: [PATCH 04/42] better timebox --- src-docs/src/views/date_picker/date_picker.js | 2 +- src/components/date_picker/_date_picker.scss | 126 ++++++++++++------ 2 files changed, 83 insertions(+), 45 deletions(-) diff --git a/src-docs/src/views/date_picker/date_picker.js b/src-docs/src/views/date_picker/date_picker.js index be55ef8a1f2..06b48685f31 100644 --- a/src-docs/src/views/date_picker/date_picker.js +++ b/src-docs/src/views/date_picker/date_picker.js @@ -14,7 +14,7 @@ export default () => ( dateFormat="LLL" showYearDropdown showMonthDropdown - yearDropdownItemNumber={10} + yearDropdownItemNumber={9} /> ); diff --git a/src/components/date_picker/_date_picker.scss b/src/components/date_picker/_date_picker.scss index efa2eb49c11..c1cacc8e275 100644 --- a/src/components/date_picker/_date_picker.scss +++ b/src/components/date_picker/_date_picker.scss @@ -8,8 +8,7 @@ $datepicker__muted-color: $euiColorLightestShade !default; $datepicker__selected-color: $euiColorPrimary !default; $datepicker__text-color: $euiColorFullShade !default; $datepicker__header-color: $euiColorFullShade !default; -$datepicker__navigation-disabled-color: lighten($datepicker__muted-color, 10%) - !default; +$datepicker__navigation-disabled-color: lighten($datepicker__muted-color, 10%) !default; $datepicker__border-radius: $euiBorderRadius !default; $datepicker__day-margin: $euiSizeXS / 2 !default; @@ -21,6 +20,10 @@ $datepicker__navigation-size: $euiSize !default; $datepicker__triangle-size: 0 !default; $datepicker__time-width: auto !default; +@mixin datePicker__arrow { + background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiI+ICA8ZGVmcz4gICAgPHBhdGggaWQ9ImFycm93X2Rvd24tYSIgZD0iTTEzLjA2ODg1MDgsNS4xNTcyNTAzOCBMOC4zODQyMzk3NSw5Ljc2ODI3NDI4IEM4LjE3MDU0NDE1LDkuOTc4NjEzMDggNy44Mjk5OTIxNCw5Ljk3OTE0MDk1IDcuNjE1NzYwMjUsOS43NjgyNzQyOCBMMi45MzExNDkxNSw1LjE1NzI1MDM4IEMyLjcxODEzNTksNC45NDc1ODMyMSAyLjM3Mjc3MzE5LDQuOTQ3NTgzMjEgMi4xNTk3NTk5NCw1LjE1NzI1MDM4IEMxLjk0Njc0NjY5LDUuMzY2OTE3NTYgMS45NDY3NDY2OSw1LjcwNjg1NTIyIDIuMTU5NzU5OTQsNS45MTY1MjI0IEw2Ljg0NDM3MTA0LDEwLjUyNzU0NjMgQzcuNDg1MTc0MjQsMTEuMTU4MjgzNiA4LjUxNjQ0OTc5LDExLjE1NjY4NTEgOS4xNTU2Mjg5NiwxMC41Mjc1NDYzIEwxMy44NDAyNDAxLDUuOTE2NTIyNCBDMTQuMDUzMjUzMyw1LjcwNjg1NTIyIDE0LjA1MzI1MzMsNS4zNjY5MTc1NiAxMy44NDAyNDAxLDUuMTU3MjUwMzggQzEzLjYyNzIyNjgsNC45NDc1ODMyMSAxMy4yODE4NjQxLDQuOTQ3NTgzMjEgMTMuMDY4ODUwOCw1LjE1NzI1MDM4IFoiLz4gIDwvZGVmcz4gIDxnIGZpbGwtcnVsZT0iZXZlbm9kZCI+ICAgIDx1c2UgZmlsbC1ydWxlPSJub256ZXJvIiB4bGluazpocmVmPSIjYXJyb3dfZG93bi1hIi8+ICA8L2c+PC9zdmc+); +} + %triangle-arrow { margin-left: -$datepicker__triangle-size; position: absolute; @@ -160,13 +163,15 @@ $datepicker__time-width: auto !default; text-align: center; border-top-left-radius: $datepicker__border-radius; border-top-right-radius: $datepicker__border-radius; - position: relative; - &--time { display: none; } } +.react-datepicker__header__dropdown { + padding: $euiSizeS 0; +} + .react-datepicker__year-dropdown-container--select, .react-datepicker__month-dropdown-container--select, .react-datepicker__month-year-dropdown-container--select, @@ -174,15 +179,12 @@ $datepicker__time-width: auto !default; .react-datepicker__month-dropdown-container--scroll, .react-datepicker__month-year-dropdown-container--scroll { display: inline-block; - margin: 0 2px; + margin: 0 $euiSizeXS; } .react-datepicker__current-month, .react-datepicker-time__header { - margin-top: 0; - color: $datepicker__header-color; - font-weight: bold; - font-size: $datepicker__font-size * 1.18; + display: none; } .react-datepicker-time__header { @@ -192,20 +194,19 @@ $datepicker__time-width: auto !default; } .react-datepicker__navigation { - background: none; - line-height: $datepicker__item-size; - text-align: center; cursor: pointer; position: absolute; - top: 10px; + top: $euiSizeS + $euiSizeXS; width: 0; padding: 0; - border: $datepicker__navigation-size solid transparent; z-index: 1; &--previous { - left: 10px; - border-right-color: $datepicker__muted-color; + @include datePicker__arrow; + left: $euiSize + $euiSizeXS; + height: 16px; + width: 16px; + transform: rotate(90deg); &:hover { border-right-color: darken($datepicker__muted-color, 10%); @@ -219,14 +220,17 @@ $datepicker__time-width: auto !default; } &--next { + @include datePicker__arrow; right: 10px; - border-left-color: $datepicker__muted-color; + height: 16px; + width: 16px; + transform: rotate(-90deg); + &--with-time:not(&--with-today-button) { - right: 80px; + left: 248px; } &:hover { - border-left-color: darken($datepicker__muted-color, 10%); } &--disabled, @@ -274,6 +278,10 @@ $datepicker__time-width: auto !default; .react-datepicker__time-container { border-left: 1px solid $datepicker__border-color; width: $datepicker__time-width; + display: flex; + padding: $euiSize 0; + background: $euiColorLightestShade; + border-radius: 0 $euiBorderRadius $euiBorderRadius 0; &--with-today-button { display: inline; @@ -286,16 +294,16 @@ $datepicker__time-width: auto !default; .react-datepicker__time { position: relative; - background: $euiColorLightestShade; - border-radius: 0 $euiBorderRadius $euiBorderRadius 0; + flex-grow: 1; + display: flex; + padding-right: $euiSizeXS; + overflow-y: scroll; + @include euiScrollBar; .react-datepicker__time-box { width: $datepicker__time-width; - padding: $euiSize 0 $euiSize $euiSizeXS; ul.react-datepicker__time-list { height: 204px !important; - overflow-y: scroll; - @include euiScrollBar; li.react-datepicker__time-list-item { padding: $euiSizeXS $euiSizeS; @@ -452,14 +460,23 @@ $datepicker__time-width: auto !default; position: relative; } +.react-datepicker__year-read-view { + font-weight: $euiFontWeightLight; + color: $euiColorMediumShade; +} + +.react-datepicker__month-read-view { + font-weight: $euiFontWeightMedium; +} + .react-datepicker__year-read-view, .react-datepicker__month-read-view, .react-datepicker__month-year-read-view { - border: 1px solid transparent; - border-radius: $datepicker__border-radius; + font-size: $euiFontSizeL; &:hover { cursor: pointer; + color: $euiColorPrimary; .react-datepicker__year-read-view--down-arrow, .react-datepicker__month-read-view--down-arrow { @@ -468,13 +485,13 @@ $datepicker__time-width: auto !default; } &--down-arrow { - @extend %triangle-arrow-down; - border-top-color: $datepicker__muted-color; - float: right; - margin-left: 20px; - top: 8px; - position: relative; - border-width: $datepicker__navigation-size; + display: none; + // display: inline-block; + // float: right; + // height: 8px; + // width: 8px; + // background-size: 8px 8px; + // @include datePicker__arrow; } } @@ -483,13 +500,22 @@ $datepicker__time-width: auto !default; .react-datepicker__month-year-dropdown { background-color: $datepicker__background-color; position: absolute; - width: 50%; - left: 25%; - top: 30px; + width: 100%; + height: 100%; + left: 0; + top: 0; + bottom: 0; + right: 0; z-index: 1; text-align: center; border-radius: $datepicker__border-radius; - border: 1px solid $datepicker__border-color; + display: flex; + flex-wrap: wrap; + animation: euiAnimFadeIn $euiAnimSpeedFast ease-in; + align-content: space-around; + align-items: center; + padding: $euiSizeS; + &:hover { cursor: pointer; @@ -501,14 +527,20 @@ $datepicker__time-width: auto !default; } } +.react-datepicker__year-option { + &:first-of-type, + &:last-of-type { + display: none; + } +} + .react-datepicker__year-option, .react-datepicker__month-option, .react-datepicker__month-year-option { - line-height: 20px; - width: 100%; - display: block; - margin-left: auto; - margin-right: auto; + flex-basis: 25%; + font-size: $euiSizeM; + padding: $euiSizeS; + color: $euiColorDarkestShade; &:first-of-type { border-top-left-radius: $datepicker__border-radius; @@ -524,6 +556,13 @@ $datepicker__time-width: auto !default; border-bottom-right-radius: $datepicker__border-radius; } + &.--selected_year, &.--selected_month { + background: $euiColorPrimary; + color: $euiColorEmptyShade; + font-weight: $euiFontWeightBold; + border-radius: $euiBorderRadius; + } + &:hover { background-color: $datepicker__muted-color; @@ -537,8 +576,7 @@ $datepicker__time-width: auto !default; } &--selected { - position: absolute; - left: 15px; + display: none; } } From f17a9303efdc8ddadefef6cfef93734dedfcced4 Mon Sep 17 00:00:00 2001 From: Dave Snider Date: Mon, 9 Apr 2018 12:57:01 -0700 Subject: [PATCH 05/42] shadows are optional, inline works --- src-docs/src/views/date_picker/date_picker.js | 2 +- .../views/date_picker/date_picker_example.js | 21 +++++++ src-docs/src/views/date_picker/inline.js | 24 ++++++++ src/components/date_picker/_date_picker.scss | 50 +++++++++++++---- src/components/date_picker/date_picker.js | 56 ++++++++++++------- 5 files changed, 122 insertions(+), 31 deletions(-) create mode 100644 src-docs/src/views/date_picker/inline.js diff --git a/src-docs/src/views/date_picker/date_picker.js b/src-docs/src/views/date_picker/date_picker.js index 06b48685f31..26063c39796 100644 --- a/src-docs/src/views/date_picker/date_picker.js +++ b/src-docs/src/views/date_picker/date_picker.js @@ -14,7 +14,7 @@ export default () => ( dateFormat="LLL" showYearDropdown showMonthDropdown - yearDropdownItemNumber={9} + yearDropdownItemNumber={7} /> ); diff --git a/src-docs/src/views/date_picker/date_picker_example.js b/src-docs/src/views/date_picker/date_picker_example.js index 25853fcfddb..78b26ce7961 100644 --- a/src-docs/src/views/date_picker/date_picker_example.js +++ b/src-docs/src/views/date_picker/date_picker_example.js @@ -15,6 +15,10 @@ import DatePicker from './date_picker'; const datePickerSource = require('!!raw-loader!./date_picker'); const datePickerHtml = renderToHtml(DatePicker); +import Inline from './inline'; +const inlineSource = require('!!raw-loader!./inline'); +const inlineHtml = renderToHtml(Inline); + export const DatePickerExample = { title: 'DatePicker', sections: [{ @@ -33,5 +37,22 @@ export const DatePickerExample = { ), components: { EuiDatePicker }, demo: , + }, { + title: 'Datepicker inline', + source: [{ + type: GuideSectionTypes.JS, + code: inlineSource, + }, { + type: GuideSectionTypes.HTML, + code: inlineHtml, + }], + text: ( +

+ The passed icon needs to come from our list of svg icons. Can be flipped { + // eslint-disable-next-line react/no-unescaped-entities + } to the other side by passing iconSide="right". +

+ ), + demo: , }], }; diff --git a/src-docs/src/views/date_picker/inline.js b/src-docs/src/views/date_picker/inline.js new file mode 100644 index 00000000000..fca1cccd473 --- /dev/null +++ b/src-docs/src/views/date_picker/inline.js @@ -0,0 +1,24 @@ +import React from 'react'; + +import moment from 'moment'; + +import { + EuiDatePicker, + EuiFormRow, +} from '../../../../src/components'; + +export default () => ( +
+ + +
+); diff --git a/src/components/date_picker/_date_picker.scss b/src/components/date_picker/_date_picker.scss index c1cacc8e275..1c1dbbf6d6f 100644 --- a/src/components/date_picker/_date_picker.scss +++ b/src/components/date_picker/_date_picker.scss @@ -21,7 +21,11 @@ $datepicker__triangle-size: 0 !default; $datepicker__time-width: auto !default; @mixin datePicker__arrow { - background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiI+ICA8ZGVmcz4gICAgPHBhdGggaWQ9ImFycm93X2Rvd24tYSIgZD0iTTEzLjA2ODg1MDgsNS4xNTcyNTAzOCBMOC4zODQyMzk3NSw5Ljc2ODI3NDI4IEM4LjE3MDU0NDE1LDkuOTc4NjEzMDggNy44Mjk5OTIxNCw5Ljk3OTE0MDk1IDcuNjE1NzYwMjUsOS43NjgyNzQyOCBMMi45MzExNDkxNSw1LjE1NzI1MDM4IEMyLjcxODEzNTksNC45NDc1ODMyMSAyLjM3Mjc3MzE5LDQuOTQ3NTgzMjEgMi4xNTk3NTk5NCw1LjE1NzI1MDM4IEMxLjk0Njc0NjY5LDUuMzY2OTE3NTYgMS45NDY3NDY2OSw1LjcwNjg1NTIyIDIuMTU5NzU5OTQsNS45MTY1MjI0IEw2Ljg0NDM3MTA0LDEwLjUyNzU0NjMgQzcuNDg1MTc0MjQsMTEuMTU4MjgzNiA4LjUxNjQ0OTc5LDExLjE1NjY4NTEgOS4xNTU2Mjg5NiwxMC41Mjc1NDYzIEwxMy44NDAyNDAxLDUuOTE2NTIyNCBDMTQuMDUzMjUzMyw1LjcwNjg1NTIyIDE0LjA1MzI1MzMsNS4zNjY5MTc1NiAxMy44NDAyNDAxLDUuMTU3MjUwMzggQzEzLjYyNzIyNjgsNC45NDc1ODMyMSAxMy4yODE4NjQxLDQuOTQ3NTgzMjEgMTMuMDY4ODUwOCw1LjE1NzI1MDM4IFoiLz4gIDwvZGVmcz4gIDxnIGZpbGwtcnVsZT0iZXZlbm9kZCI+ICAgIDx1c2UgZmlsbC1ydWxlPSJub256ZXJvIiB4bGluazpocmVmPSIjYXJyb3dfZG93bi1hIi8+ICA8L2c+PC9zdmc+); + @if (lightness($euiColorEmptyShade) > 50) { + background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiI+ICA8ZGVmcz4gICAgPHBhdGggaWQ9ImFycm93X2Rvd24tYSIgZD0iTTEzLjA2ODg1MDgsNS4xNTcyNTAzOCBMOC4zODQyMzk3NSw5Ljc2ODI3NDI4IEM4LjE3MDU0NDE1LDkuOTc4NjEzMDggNy44Mjk5OTIxNCw5Ljk3OTE0MDk1IDcuNjE1NzYwMjUsOS43NjgyNzQyOCBMMi45MzExNDkxNSw1LjE1NzI1MDM4IEMyLjcxODEzNTksNC45NDc1ODMyMSAyLjM3Mjc3MzE5LDQuOTQ3NTgzMjEgMi4xNTk3NTk5NCw1LjE1NzI1MDM4IEMxLjk0Njc0NjY5LDUuMzY2OTE3NTYgMS45NDY3NDY2OSw1LjcwNjg1NTIyIDIuMTU5NzU5OTQsNS45MTY1MjI0IEw2Ljg0NDM3MTA0LDEwLjUyNzU0NjMgQzcuNDg1MTc0MjQsMTEuMTU4MjgzNiA4LjUxNjQ0OTc5LDExLjE1NjY4NTEgOS4xNTU2Mjg5NiwxMC41Mjc1NDYzIEwxMy44NDAyNDAxLDUuOTE2NTIyNCBDMTQuMDUzMjUzMyw1LjcwNjg1NTIyIDE0LjA1MzI1MzMsNS4zNjY5MTc1NiAxMy44NDAyNDAxLDUuMTU3MjUwMzggQzEzLjYyNzIyNjgsNC45NDc1ODMyMSAxMy4yODE4NjQxLDQuOTQ3NTgzMjEgMTMuMDY4ODUwOCw1LjE1NzI1MDM4IFoiLz4gIDwvZGVmcz4gIDxnIGZpbGwtcnVsZT0iZXZlbm9kZCI+ICAgIDx1c2UgZmlsbC1ydWxlPSJub256ZXJvIiB4bGluazpocmVmPSIjYXJyb3dfZG93bi1hIi8+ICA8L2c+PC9zdmc+); + } @else { + background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiI+ICA8ZGVmcz4gICAgPHBhdGggaWQ9ImRvd25hcnJvd3doaXRlLWEiIGQ9Ik0xMy4wNjg4NTA4LDUuMTU3MjUwMzggTDguMzg0MjM5NzUsOS43NjgyNzQyOCBDOC4xNzA1NDQxNSw5Ljk3ODYxMzA4IDcuODI5OTkyMTQsOS45NzkxNDA5NSA3LjYxNTc2MDI1LDkuNzY4Mjc0MjggTDIuOTMxMTQ5MTUsNS4xNTcyNTAzOCBDMi43MTgxMzU5LDQuOTQ3NTgzMjEgMi4zNzI3NzMxOSw0Ljk0NzU4MzIxIDIuMTU5NzU5OTQsNS4xNTcyNTAzOCBDMS45NDY3NDY2OSw1LjM2NjkxNzU2IDEuOTQ2NzQ2NjksNS43MDY4NTUyMiAyLjE1OTc1OTk0LDUuOTE2NTIyNCBMNi44NDQzNzEwNCwxMC41Mjc1NDYzIEM3LjQ4NTE3NDI0LDExLjE1ODI4MzYgOC41MTY0NDk3OSwxMS4xNTY2ODUxIDkuMTU1NjI4OTYsMTAuNTI3NTQ2MyBMMTMuODQwMjQwMSw1LjkxNjUyMjQgQzE0LjA1MzI1MzMsNS43MDY4NTUyMiAxNC4wNTMyNTMzLDUuMzY2OTE3NTYgMTMuODQwMjQwMSw1LjE1NzI1MDM4IEMxMy42MjcyMjY4LDQuOTQ3NTgzMjEgMTMuMjgxODY0MSw0Ljk0NzU4MzIxIDEzLjA2ODg1MDgsNS4xNTcyNTAzOCBaIi8+ICA8L2RlZnM+ICA8ZyBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPiAgICA8dXNlIGZpbGw9IiNGRkYiIGZpbGwtcnVsZT0ibm9uemVybyIgeGxpbms6aHJlZj0iI2Rvd25hcnJvd3doaXRlLWEiLz4gIDwvZz48L3N2Zz4=); + } } %triangle-arrow { @@ -84,19 +88,27 @@ $datepicker__time-width: auto !default; } } +.euiDatePicker { + &.euiDatePicker--shadow { + .react-datepicker { + border: 1px solid $datepicker__border-color; + border-radius: $datepicker__border-radius; + @include euiBottomShadowMedium; + } + } +} + .react-datepicker-wrapper { } .react-datepicker { font-family: $datepicker__font-family; font-size: $datepicker__font-size; - background-color: #fff; + background-color: $euiColorEmptyShade; color: $datepicker__text-color; - border: 1px solid $datepicker__border-color; - border-radius: $datepicker__border-radius; display: flex; position: relative; - @include euiBottomShadowMedium; + } .react-datepicker--time-only { @@ -207,9 +219,13 @@ $datepicker__time-width: auto !default; height: 16px; width: 16px; transform: rotate(90deg); + transition: transform $euiAnimSpeedExtraFast ease-in-out; &:hover { - border-right-color: darken($datepicker__muted-color, 10%); + background-color: $euiColorLightestShade; + border-radius: $euiBorderRadius; + outline: solid 2px $euiColorLightestShade; + transform: scale(1.2) rotate(90deg); } &--disabled, @@ -231,6 +247,10 @@ $datepicker__time-width: auto !default; } &:hover { + transform: scale(1.2) rotate(-90deg); + background-color: $euiColorLightestShade; + border-radius: $euiBorderRadius; + outline: solid 2px $euiColorLightestShade; } &--disabled, @@ -282,6 +302,7 @@ $datepicker__time-width: auto !default; padding: $euiSize 0; background: $euiColorLightestShade; border-radius: 0 $euiBorderRadius $euiBorderRadius 0; + flex-grow: 1; &--with-today-button { display: inline; @@ -296,7 +317,7 @@ $datepicker__time-width: auto !default; position: relative; flex-grow: 1; display: flex; - padding-right: $euiSizeXS; + padding-left: $euiSizeXS; overflow-y: scroll; @include euiScrollBar; @@ -391,7 +412,7 @@ $datepicker__time-width: auto !default; color: $euiColorPrimary; } &--outside-month { - color: $euiColorMediumShade; + color: $euiColorDarkShade; } &--highlighted { @@ -462,7 +483,7 @@ $datepicker__time-width: auto !default; .react-datepicker__year-read-view { font-weight: $euiFontWeightLight; - color: $euiColorMediumShade; + color: $euiColorDarkShade; } .react-datepicker__month-read-view { @@ -527,6 +548,13 @@ $datepicker__time-width: auto !default; } } +// Strike that, reverse it Willy Wonka style +.react-datepicker__year-dropdown { + flex-wrap: wrap-reverse; + flex-direction: row-reverse; + justify-content: flex-end; +} + .react-datepicker__year-option { &:first-of-type, &:last-of-type { @@ -537,10 +565,10 @@ $datepicker__time-width: auto !default; .react-datepicker__year-option, .react-datepicker__month-option, .react-datepicker__month-year-option { - flex-basis: 25%; - font-size: $euiSizeM; + font-size: $euiFontSizeS; padding: $euiSizeS; color: $euiColorDarkestShade; + flex-basis: 33.3%; &:first-of-type { border-top-left-radius: $datepicker__border-radius; diff --git a/src/components/date_picker/date_picker.js b/src/components/date_picker/date_picker.js index 45b5d1e650b..eb3501f98ac 100644 --- a/src/components/date_picker/date_picker.js +++ b/src/components/date_picker/date_picker.js @@ -45,37 +45,54 @@ export class EuiDatePicker extends Component { fullWidth, isLoading, placeholder, + inline, + shadow, ...rest } = this.props; const classes = classNames( + 'euiDatePicker', + { + 'euiDatePicker--shadow': shadow, + }, + className + ); + + const datePickerClasses = classNames( 'euiDatePicker', 'euiFieldText', 'euiFieldText--fullWidth': fullWidth, 'euiFieldText-isLoading': isLoading, - 'euiFieldText--withIcon', - className + { + 'euiFieldText--withIcon': !inline, + }, ); return ( - - + - - - + + + + + ); } } @@ -92,4 +109,5 @@ EuiDatePicker.propTypes = { EuiDatePicker.defaultProps = { fullWidth: false, isLoading: false, + shadow: true, }; From 307f523e27782a7474b6a7632c4cf4c42a84ba5f Mon Sep 17 00:00:00 2001 From: Dave Snider Date: Mon, 9 Apr 2018 14:39:23 -0700 Subject: [PATCH 06/42] ranges work --- src-docs/src/views/date_picker/date_picker.js | 47 +++++++++++---- .../views/date_picker/date_picker_example.js | 21 +++++++ src-docs/src/views/date_picker/inline.js | 60 +++++++++++++------ src-docs/src/views/date_picker/range.js | 59 ++++++++++++++++++ src/components/date_picker/_date_picker.scss | 28 ++++++++- src/components/date_picker/date_picker.js | 7 --- 6 files changed, 183 insertions(+), 39 deletions(-) create mode 100644 src-docs/src/views/date_picker/range.js diff --git a/src-docs/src/views/date_picker/date_picker.js b/src-docs/src/views/date_picker/date_picker.js index 26063c39796..1e0c7c6745f 100644 --- a/src-docs/src/views/date_picker/date_picker.js +++ b/src-docs/src/views/date_picker/date_picker.js @@ -1,4 +1,6 @@ -import React from 'react'; +import React, { + Component, +} from 'react'; import moment from 'moment'; @@ -7,14 +9,35 @@ import { EuiFormRow, } from '../../../../src/components'; -export default () => ( - - - -); +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 index 78b26ce7961..39f016ec351 100644 --- a/src-docs/src/views/date_picker/date_picker_example.js +++ b/src-docs/src/views/date_picker/date_picker_example.js @@ -19,6 +19,10 @@ 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); + export const DatePickerExample = { title: 'DatePicker', sections: [{ @@ -37,6 +41,23 @@ export const DatePickerExample = { ), components: { EuiDatePicker }, demo: , + }, { + title: 'Datepicker range', + source: [{ + type: GuideSectionTypes.JS, + code: rangeSource, + }, { + type: GuideSectionTypes.HTML, + code: rangeHtml, + }], + text: ( +

+ The passed icon needs to come from our list of svg icons. Can be flipped { + // eslint-disable-next-line react/no-unescaped-entities + } to the other side by passing iconSide="right". +

+ ), + demo: , }, { title: 'Datepicker inline', source: [{ diff --git a/src-docs/src/views/date_picker/inline.js b/src-docs/src/views/date_picker/inline.js index fca1cccd473..3aed41b7c87 100644 --- a/src-docs/src/views/date_picker/inline.js +++ b/src-docs/src/views/date_picker/inline.js @@ -1,24 +1,50 @@ -import React from 'react'; + +import React, { + Component, +} from 'react'; import moment from 'moment'; import { EuiDatePicker, - EuiFormRow, } from '../../../../src/components'; -export default () => ( -
- - -
-); +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/range.js b/src-docs/src/views/date_picker/range.js new file mode 100644 index 00000000000..db756cece0d --- /dev/null +++ b/src-docs/src/views/date_picker/range.js @@ -0,0 +1,59 @@ + +import React, { + Component, +} from 'react'; + +import moment from 'moment'; + +import { + EuiDatePicker, +} from '../../../../src/components'; + +export default class extends Component { + constructor(props) { + super(props); + + this.state = { + startDate: moment(), + endDate: moment(), + }; + + this.handleChangeStart = this.handleChangeStart.bind(this); + this.handleChangeEnd = this.handleChangeEnd.bind(this); + } + + handleChangeStart(date) { + this.setState({ + startDate: date + }); + } + + handleChangeEnd(date) { + this.setState({ + endDate: date + }); + } + + render() { + return ( +
+ + +
+ ); + } +} diff --git a/src/components/date_picker/_date_picker.scss b/src/components/date_picker/_date_picker.scss index 1c1dbbf6d6f..cf6b89d92ce 100644 --- a/src/components/date_picker/_date_picker.scss +++ b/src/components/date_picker/_date_picker.scss @@ -88,6 +88,9 @@ $datepicker__time-width: auto !default; } } +// Some wrapping cascade is needed in a couple rare cases. This is the only +// "new" selectors added to this sass. + .euiDatePicker { &.euiDatePicker--shadow { .react-datepicker { @@ -95,6 +98,10 @@ $datepicker__time-width: auto !default; border-radius: $datepicker__border-radius; @include euiBottomShadowMedium; } + + .react-datepicker__time-container { + background: $euiColorLightestShade; + } } } @@ -300,7 +307,6 @@ $datepicker__time-width: auto !default; width: $datepicker__time-width; display: flex; padding: $euiSize 0; - background: $euiColorLightestShade; border-radius: 0 $euiBorderRadius $euiBorderRadius 0; flex-grow: 1; @@ -434,11 +440,27 @@ $datepicker__time-width: auto !default; } - &--selected, - &--in-selecting-range, &--in-range { + background-color: transparentize($datepicker__selected-color, .9); + color: $euiColorFullShade; + border-radius: 0; + border-top: solid 6px $euiColorEmptyShade; + border-bottom: solid 6px $euiColorEmptyShade; + border-right: none; + border-left: none; + line-height: 20px; + } + + &--selected, + &--range-start, + &--range-end, + &--in-selecting-range { + height: $euiSizeXL; + margin: 0 $euiSizeXS / 2; border-radius: $datepicker__border-radius; background-color: $datepicker__selected-color; + line-height: 28px; + border: solid 2px $euiColorPrimary; color: #fff; &:hover { diff --git a/src/components/date_picker/date_picker.js b/src/components/date_picker/date_picker.js index eb3501f98ac..78fb2663c13 100644 --- a/src/components/date_picker/date_picker.js +++ b/src/components/date_picker/date_picker.js @@ -16,11 +16,6 @@ import { } from '../form/validatable_control'; export class EuiDatePicker extends Component { - static propTypes = { - children: PropTypes.node, - className: PropTypes.string, - } - constructor(props) { super(props); @@ -79,8 +74,6 @@ export class EuiDatePicker extends Component { isInvalid={isInvalid} > Date: Mon, 9 Apr 2018 20:53:16 -0700 Subject: [PATCH 07/42] blacklist certain react-datepicker props, set defaults for others --- src-docs/src/views/date_picker/date_picker.js | 8 +- src-docs/src/views/date_picker/inline.js | 2 - src-docs/src/views/date_picker/range.js | 4 +- .../__snapshots__/date_picker.test.js.snap | 41 +++++++++ src/components/date_picker/_date_picker.scss | 33 +++---- src/components/date_picker/date_picker.js | 88 ++++++++++++++++++- 6 files changed, 150 insertions(+), 26 deletions(-) create mode 100644 src/components/date_picker/__snapshots__/date_picker.test.js.snap diff --git a/src-docs/src/views/date_picker/date_picker.js b/src-docs/src/views/date_picker/date_picker.js index 1e0c7c6745f..3a1fa05a8f3 100644 --- a/src-docs/src/views/date_picker/date_picker.js +++ b/src-docs/src/views/date_picker/date_picker.js @@ -32,10 +32,10 @@ export default class extends Component { ); diff --git a/src-docs/src/views/date_picker/inline.js b/src-docs/src/views/date_picker/inline.js index 3aed41b7c87..9312bee13d9 100644 --- a/src-docs/src/views/date_picker/inline.js +++ b/src-docs/src/views/date_picker/inline.js @@ -34,14 +34,12 @@ export default class extends Component { onChange={this.handleChange} inline showTimeSelect - dateFormat="LLL" /> diff --git a/src-docs/src/views/date_picker/range.js b/src-docs/src/views/date_picker/range.js index db756cece0d..fa2b6ee40ae 100644 --- a/src-docs/src/views/date_picker/range.js +++ b/src-docs/src/views/date_picker/range.js @@ -15,7 +15,7 @@ export default class extends Component { this.state = { startDate: moment(), - endDate: moment(), + endDate: moment().add(11, 'd'), }; this.handleChangeStart = this.handleChangeStart.bind(this); @@ -43,7 +43,6 @@ export default class extends Component { startDate={this.state.startDate} endDate={this.state.endDate} showTimeSelect - dateFormat="LLL" /> ); diff --git a/src/components/date_picker/__snapshots__/date_picker.test.js.snap b/src/components/date_picker/__snapshots__/date_picker.test.js.snap new file mode 100644 index 00000000000..925636c2b83 --- /dev/null +++ b/src/components/date_picker/__snapshots__/date_picker.test.js.snap @@ -0,0 +1,41 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`EuiDatePicker is rendered 1`] = ` + + +
+
+
+
+ +
+
+
+ + + +
+
+
+`; diff --git a/src/components/date_picker/_date_picker.scss b/src/components/date_picker/_date_picker.scss index cf6b89d92ce..3363bb25a64 100644 --- a/src/components/date_picker/_date_picker.scss +++ b/src/components/date_picker/_date_picker.scss @@ -237,8 +237,8 @@ $datepicker__time-width: auto !default; &--disabled, &--disabled:hover { - border-right-color: $datepicker__navigation-disabled-color; - cursor: default; + cursor: not-allowed ; + opacity: .2; } } @@ -262,8 +262,8 @@ $datepicker__time-width: auto !default; &--disabled, &--disabled:hover { - border-left-color: $datepicker__navigation-disabled-color; - cursor: default; + cursor: not-allowed ; + opacity: .2; } } @@ -352,10 +352,11 @@ $datepicker__time-width: auto !default; } } &--disabled { - color: $datepicker__muted-color; + color: $euiColorLightShade; &:hover { - cursor: default; + cursor: not-allowed; + text-decoration: none; background-color: transparent; } } @@ -407,7 +408,7 @@ $datepicker__time-width: auto !default; border: solid 2px transparent; transition: transform $euiAnimSpeedExtraFast ease-in-out; - &:hover { + &:hover:not(&--disabled) { text-decoration: underline; font-weight: $euiFontWeightBold; transform: scale(1.2); @@ -490,8 +491,8 @@ $datepicker__time-width: auto !default; } &--disabled { - cursor: default; - color: $datepicker__muted-color; + cursor: not-allowed; + color: $euiColorLightShade; &:hover { background-color: transparent; @@ -606,13 +607,6 @@ $datepicker__time-width: auto !default; border-bottom-right-radius: $datepicker__border-radius; } - &.--selected_year, &.--selected_month { - background: $euiColorPrimary; - color: $euiColorEmptyShade; - font-weight: $euiFontWeightBold; - border-radius: $euiBorderRadius; - } - &:hover { background-color: $datepicker__muted-color; @@ -625,6 +619,13 @@ $datepicker__time-width: auto !default; } } + &.--selected_year, &.--selected_month { + background: $euiColorPrimary; + color: $euiColorEmptyShade; + font-weight: $euiFontWeightBold; + border-radius: $euiBorderRadius; + } + &--selected { display: none; } diff --git a/src/components/date_picker/date_picker.js b/src/components/date_picker/date_picker.js index 78fb2663c13..99b541bf019 100644 --- a/src/components/date_picker/date_picker.js +++ b/src/components/date_picker/date_picker.js @@ -15,6 +15,10 @@ import { EuiValidatableControl, } from '../form/validatable_control'; +import { + EuiErrorBoundary, +} from '../error_boundary'; + export class EuiDatePicker extends Component { constructor(props) { super(props); @@ -42,6 +46,22 @@ export class EuiDatePicker extends Component { placeholder, inline, shadow, + dateFormat, + excludeDates, + locale, + minDate, + maxDate, + minTime, + maxTime, + timeFormat, + showTimeSelect, + showTimeSelectOnly, + onChange, + selected, + injectTimes, + calendarClassName, + dayClassName, + shouldCloseOnSelect, ...rest } = this.props; @@ -63,7 +83,7 @@ export class EuiDatePicker extends Component { }, ); - return ( + let datePickerOrError = ( ); + + // EuiDatePicker only supports a subset of props from react-datepicker. Using any of + // the unsupported props below will spit out an error. + const PropNotSupported = () => { + throw new Error(`You are using a prop from react-datepicker that EuiDatePicker + does not support. Please check the EUI documentation for more information.`); + }; + + if ( + this.props.monthsShown || + this.props.showWeekNumbers || + this.props.fixedHeight || + this.props.dropdownMode || + this.props.useShortMonthInDropdown || + this.props.todayButton || + this.props.timeCaption || + this.props.withPortal + ) { + datePickerOrError = ( + + + + ); + } + + return ( + + {datePickerOrError} + + ); } } + // if (props.monthsShown || props.showWeekNumbers || props.fixedHeight || props.dropdownMode || props.useShortMonthInDropdown || props.withPortal) { + EuiDatePicker.propTypes = { + className: PropTypes.string, + calendarClassName: PropTypes.string, + dayClassName: PropTypes.string, placeholder: PropTypes.string, icon: PropTypes.string, + local: PropTypes.string, isInvalid: PropTypes.bool, inputRef: PropTypes.func, fullWidth: PropTypes.bool, isLoading: PropTypes.bool, + onChange: PropTypes.func, + showTimeSelect: PropTypes.bool, + showTimeSelectOnly: PropTypes.bool, + timeFormat: PropTypes.string, + dateFormat: PropTypes.string, + injectTimes: PropTypes.array, + selected: PropTypes.instanceOf(moment), + minDate: PropTypes.instanceOf(moment), + maxDate: PropTypes.instanceOf(moment), + minTime: PropTypes.instanceOf(moment), + maxTime: PropTypes.instanceOf(moment), }; EuiDatePicker.defaultProps = { fullWidth: false, isLoading: false, + shouldCloseOnSelect: true, shadow: true, + dateFormat:"MM/DD/YYY hh:mm A", + timeFormat:"hh:mm A", }; From e4b27d052680394dbb5fa6b11de86014c080c6e2 Mon Sep 17 00:00:00 2001 From: Dave Snider Date: Mon, 9 Apr 2018 21:05:56 -0700 Subject: [PATCH 08/42] more props alignment --- src/components/date_picker/date_picker.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/components/date_picker/date_picker.js b/src/components/date_picker/date_picker.js index 99b541bf019..18baff97077 100644 --- a/src/components/date_picker/date_picker.js +++ b/src/components/date_picker/date_picker.js @@ -62,6 +62,7 @@ export class EuiDatePicker extends Component { calendarClassName, dayClassName, shouldCloseOnSelect, + openToDate, ...rest } = this.props; @@ -117,6 +118,7 @@ export class EuiDatePicker extends Component { locale={locale} excludeDates={excludeDates} shouldCloseOnSelect={shouldCloseOnSelect} + openToDate={openToDate} {...rest} /> @@ -132,13 +134,25 @@ export class EuiDatePicker extends Component { }; if ( + // We don't want to show multiple months next to each other this.props.monthsShown || + // There is no need to show week numbers this.props.showWeekNumbers || + // Our css adapts to height, no need to fix it this.props.fixedHeight || + // We force the month / year selection UI. No need to configure it this.props.dropdownMode || + // Short month is uncessary. Our UI has plenty of room for full months this.props.useShortMonthInDropdown || + // The today button is not needed. This should always be external to the calendar this.props.todayButton || + // We hide the time caption, so there is no need to overwrite its text this.props.timeCaption || + // We always want keyboard accessibility on + this.props.disabledKeyboardNavigation || + // This is easy enough to do. It can conflict with isLoading state + this.props.isClearable || + // There is no reason to launch the datepicker in its own modal. Can always build these ourselves this.props.withPortal ) { datePickerOrError = ( @@ -180,6 +194,7 @@ EuiDatePicker.propTypes = { maxDate: PropTypes.instanceOf(moment), minTime: PropTypes.instanceOf(moment), maxTime: PropTypes.instanceOf(moment), + openToDate: PropTypes.instanceOf(moment), }; EuiDatePicker.defaultProps = { From d2fc3479367626003ca1d01e8ba30cfbff0148fd Mon Sep 17 00:00:00 2001 From: Dave Snider Date: Mon, 9 Apr 2018 22:19:26 -0700 Subject: [PATCH 09/42] cleanup css / prop layer --- src-docs/src/views/date_picker/date_picker.js | 2 - .../views/date_picker/date_picker_example.js | 1 + src/components/date_picker/_date_picker.scss | 318 +++++++----------- src/components/date_picker/date_picker.js | 8 +- 4 files changed, 128 insertions(+), 201 deletions(-) diff --git a/src-docs/src/views/date_picker/date_picker.js b/src-docs/src/views/date_picker/date_picker.js index 3a1fa05a8f3..ae36a083265 100644 --- a/src-docs/src/views/date_picker/date_picker.js +++ b/src-docs/src/views/date_picker/date_picker.js @@ -34,8 +34,6 @@ export default class extends Component { showTimeSelect selected={this.state.startDate} onChange={this.handleChange} - excludeDates={[moment(), moment().subtract(1, "days")]} - isLoading /> ); diff --git a/src-docs/src/views/date_picker/date_picker_example.js b/src-docs/src/views/date_picker/date_picker_example.js index 39f016ec351..3e4eba047eb 100644 --- a/src-docs/src/views/date_picker/date_picker_example.js +++ b/src-docs/src/views/date_picker/date_picker_example.js @@ -41,6 +41,7 @@ export const DatePickerExample = { ), components: { EuiDatePicker }, demo: , + props: { EuiDatePicker }, }, { title: 'Datepicker range', source: [{ diff --git a/src/components/date_picker/_date_picker.scss b/src/components/date_picker/_date_picker.scss index 3363bb25a64..fb8b118b9dc 100644 --- a/src/components/date_picker/_date_picker.scss +++ b/src/components/date_picker/_date_picker.scss @@ -28,66 +28,6 @@ $datepicker__time-width: auto !default; } } -%triangle-arrow { - margin-left: -$datepicker__triangle-size; - position: absolute; - - &, - &::before { - box-sizing: content-box; - position: absolute; - border: $datepicker__triangle-size solid transparent; - - height: 0; - width: 1px; - } - - &::before { - content: ""; - z-index: -1; - border-width: $datepicker__triangle-size; - - left: -$datepicker__triangle-size; - border-bottom-color: $datepicker__border-color; - } -} - -%triangle-arrow-up { - @extend %triangle-arrow; - - top: 0; - margin-top: -$datepicker__triangle-size; - - &, - &::before { - border-top: none; - border-bottom-color: $datepicker__background-color; - } - - &::before { - top: -1px; - border-bottom-color: $datepicker__border-color; - } -} - -%triangle-arrow-down { - @extend %triangle-arrow; - - bottom: 0; - margin-bottom: -$datepicker__triangle-size; - - &, - &::before { - border-bottom: none; - border-top-color: #fff; - } - - &::before { - bottom: -1px; - border-top-color: $datepicker__border-color; - } -} - // Some wrapping cascade is needed in a couple rare cases. This is the only // "new" selectors added to this sass. @@ -137,8 +77,6 @@ $datepicker__time-width: auto !default; } .react-datepicker__triangle { - position: absolute; - left: 50px; } .react-datepicker-popper { @@ -148,14 +86,12 @@ $datepicker__time-width: auto !default; &[data-placement^="bottom"] { .react-datepicker__triangle { - @extend %triangle-arrow-up; } } &[data-placement^="top"] { .react-datepicker__triangle { - @extend %triangle-arrow-down; } } @@ -163,8 +99,6 @@ $datepicker__time-width: auto !default; margin-left: $datepicker__triangle-size; .react-datepicker__triangle { - left: auto; - right: 42px; } } @@ -172,8 +106,6 @@ $datepicker__time-width: auto !default; margin-right: $datepicker__triangle-size; .react-datepicker__triangle { - left: 42px; - right: auto; } } } @@ -310,14 +242,14 @@ $datepicker__time-width: auto !default; border-radius: 0 $euiBorderRadius $euiBorderRadius 0; flex-grow: 1; - &--with-today-button { - display: inline; - border: 1px solid #aeaeae; - border-radius: 0.3rem; - position: absolute; - right: $datepicker__time-width; - top: 0; - } + // &--with-today-button { + // display: inline; + // border: 1px solid #aeaeae; + // border-radius: 0.3rem; + // position: absolute; + // right: $datepicker__time-width; + // top: 0; + // } .react-datepicker__time { position: relative; @@ -393,7 +325,7 @@ $datepicker__time-width: auto !default; color: $datepicker__text-color; display: inline-block; width: $datepicker__item-size; - line-height: $datepicker__item-size - 4px; + line-height: $datepicker__item-size - $euiSizeXS; text-align: center; margin: 0 $datepicker__day-margin; } @@ -425,7 +357,7 @@ $datepicker__time-width: auto !default; &--highlighted { border-radius: $datepicker__border-radius; background-color: $datepicker__highlighted-color; - color: #fff; + color: $euiColorGhost; &:hover { background-color: darken($datepicker__highlighted-color, 5%); @@ -462,7 +394,7 @@ $datepicker__time-width: auto !default; background-color: $datepicker__selected-color; line-height: 28px; border: solid 2px $euiColorPrimary; - color: #fff; + color: $euiColorGhost; &:hover { background-color: darken($datepicker__selected-color, 5%); @@ -530,12 +462,6 @@ $datepicker__time-width: auto !default; &--down-arrow { display: none; - // display: inline-block; - // float: right; - // height: 8px; - // width: 8px; - // background-size: 8px 8px; - // @include datePicker__arrow; } } @@ -565,10 +491,10 @@ $datepicker__time-width: auto !default; cursor: pointer; } - &--scrollable { - height: 150px; - overflow-y: scroll; - } + // &--scrollable { + // height: 150px; + // overflow-y: scroll; + // } } // Strike that, reverse it Willy Wonka style @@ -631,110 +557,110 @@ $datepicker__time-width: auto !default; } } -.react-datepicker__close-icon { - background-color: transparent; - border: 0; - cursor: pointer; - display: inline-block; - height: 0; - outline: 0; - padding: 0; - vertical-align: middle; - - &::after { - background-color: $datepicker__selected-color; - border-radius: 50%; - bottom: 0; - box-sizing: border-box; - color: #fff; - content: "\00d7"; - cursor: pointer; - font-size: 12px; - height: 16px; - width: 16px; - line-height: 1; - margin: -8px auto 0; - padding: 2px; - position: absolute; - right: 7px; - text-align: center; - top: 50%; - } -} - -.react-datepicker__today-button { - background: $datepicker__background-color; - border-top: 1px solid $datepicker__border-color; - cursor: pointer; - text-align: center; - font-weight: bold; - padding: 5px 0; - clear: left; -} - -.react-datepicker__portal { - position: fixed; - width: 100vw; - height: 100vh; - background-color: rgba(0, 0, 0, 0.8); - left: 0; - top: 0; - justify-content: center; - align-items: center; - display: flex; - z-index: 2147483647; - - .react-datepicker__day-name, - .react-datepicker__day, - .react-datepicker__time-name { - width: 3rem; - line-height: 3rem; - } - - // Resize for small screens - @media (max-width: 400px), (max-height: 550px) { - .react-datepicker__day-name, - .react-datepicker__day, - .react-datepicker__time-name { - width: 2rem; - line-height: 2rem; - } - } - - .react-datepicker__current-month, - .react-datepicker-time__header { - font-size: $datepicker__font-size * 1.8; - } - - .react-datepicker__navigation { - border: 1.8 * $datepicker__navigation-size solid transparent; - } - - .react-datepicker__navigation--previous { - border-right-color: $datepicker__muted-color; - - &:hover { - border-right-color: darken($datepicker__muted-color, 10%); - } - - &--disabled, - &--disabled:hover { - border-right-color: $datepicker__navigation-disabled-color; - cursor: default; - } - } - - .react-datepicker__navigation--next { - border-left-color: $datepicker__muted-color; - - &:hover { - border-left-color: darken($datepicker__muted-color, 10%); - } - - &--disabled, - &--disabled:hover { - border-left-color: $datepicker__navigation-disabled-color; - cursor: default; - } - } -} +// .react-datepicker__close-icon { +// background-color: transparent; +// border: 0; +// cursor: pointer; +// display: inline-block; +// height: 0; +// outline: 0; +// padding: 0; +// vertical-align: middle; +// +// &::after { +// background-color: $datepicker__selected-color; +// border-radius: 50%; +// bottom: 0; +// box-sizing: border-box; +// color: #fff; +// content: "\00d7"; +// cursor: pointer; +// font-size: 12px; +// height: 16px; +// width: 16px; +// line-height: 1; +// margin: -8px auto 0; +// padding: 2px; +// position: absolute; +// right: 7px; +// text-align: center; +// top: 50%; +// } +// } +// +// .react-datepicker__today-button { +// background: $datepicker__background-color; +// border-top: 1px solid $datepicker__border-color; +// cursor: pointer; +// text-align: center; +// font-weight: bold; +// padding: 5px 0; +// clear: left; +// } +// +// .react-datepicker__portal { +// position: fixed; +// width: 100vw; +// height: 100vh; +// background-color: rgba(0, 0, 0, 0.8); +// left: 0; +// top: 0; +// justify-content: center; +// align-items: center; +// display: flex; +// z-index: 2147483647; +// +// .react-datepicker__day-name, +// .react-datepicker__day, +// .react-datepicker__time-name { +// width: 3rem; +// line-height: 3rem; +// } +// +// // Resize for small screens +// @media (max-width: 400px), (max-height: 550px) { +// .react-datepicker__day-name, +// .react-datepicker__day, +// .react-datepicker__time-name { +// width: 2rem; +// line-height: 2rem; +// } +// } +// +// .react-datepicker__current-month, +// .react-datepicker-time__header { +// font-size: $datepicker__font-size * 1.8; +// } +// +// .react-datepicker__navigation { +// border: 1.8 * $datepicker__navigation-size solid transparent; +// } +// +// .react-datepicker__navigation--previous { +// border-right-color: $datepicker__muted-color; +// +// &:hover { +// border-right-color: darken($datepicker__muted-color, 10%); +// } +// +// &--disabled, +// &--disabled:hover { +// border-right-color: $datepicker__navigation-disabled-color; +// cursor: default; +// } +// } +// +// .react-datepicker__navigation--next { +// border-left-color: $datepicker__muted-color; +// +// &:hover { +// border-left-color: darken($datepicker__muted-color, 10%); +// } +// +// &--disabled, +// &--disabled:hover { +// border-left-color: $datepicker__navigation-disabled-color; +// cursor: default; +// } +// } +// } diff --git a/src/components/date_picker/date_picker.js b/src/components/date_picker/date_picker.js index 18baff97077..172fd320ffb 100644 --- a/src/components/date_picker/date_picker.js +++ b/src/components/date_picker/date_picker.js @@ -63,6 +63,7 @@ export class EuiDatePicker extends Component { dayClassName, shouldCloseOnSelect, openToDate, + disabled, ...rest } = this.props; @@ -97,7 +98,7 @@ export class EuiDatePicker extends Component { @@ -178,7 +180,7 @@ EuiDatePicker.propTypes = { dayClassName: PropTypes.string, placeholder: PropTypes.string, icon: PropTypes.string, - local: PropTypes.string, + locale: PropTypes.string, isInvalid: PropTypes.bool, inputRef: PropTypes.func, fullWidth: PropTypes.bool, @@ -202,6 +204,6 @@ EuiDatePicker.defaultProps = { isLoading: false, shouldCloseOnSelect: true, shadow: true, - dateFormat:"MM/DD/YYY hh:mm A", + dateFormat:"MM/DD/YYYY hh:mm A", timeFormat:"hh:mm A", }; From 8391215c94fdea46ab8011513ab64a3fbaf36b46 Mon Sep 17 00:00:00 2001 From: Dave Snider Date: Tue, 10 Apr 2018 13:22:58 -0700 Subject: [PATCH 10/42] docs for states and locale --- src-docs/src/views/date_picker/date_picker.js | 1 + .../views/date_picker/date_picker_example.js | 44 +++++++++++++++++++ src/components/date_picker/date_picker.js | 2 +- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src-docs/src/views/date_picker/date_picker.js b/src-docs/src/views/date_picker/date_picker.js index ae36a083265..14f0dca56d9 100644 --- a/src-docs/src/views/date_picker/date_picker.js +++ b/src-docs/src/views/date_picker/date_picker.js @@ -34,6 +34,7 @@ export default class extends Component { showTimeSelect selected={this.state.startDate} onChange={this.handleChange} + readonly /> ); diff --git a/src-docs/src/views/date_picker/date_picker_example.js b/src-docs/src/views/date_picker/date_picker_example.js index 3e4eba047eb..53fb9fd9877 100644 --- a/src-docs/src/views/date_picker/date_picker_example.js +++ b/src-docs/src/views/date_picker/date_picker_example.js @@ -15,6 +15,14 @@ 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 Inline from './inline'; const inlineSource = require('!!raw-loader!./inline'); const inlineHtml = renderToHtml(Inline); @@ -42,6 +50,42 @@ export const DatePickerExample = { components: { EuiDatePicker }, demo: , props: { EuiDatePicker }, + }, { + title: 'Datepicker states', + source: [{ + type: GuideSectionTypes.JS, + code: statesSource, + }, { + type: GuideSectionTypes.HTML, + code: statesHtml, + }], + text: ( +

+ The passed icon needs to come from our list of svg icons. Can be flipped { + // eslint-disable-next-line react/no-unescaped-entities + } to the other side by passing iconSide="right". +

+ ), + demo: , + }, { + title: 'Locale', + source: [{ + type: GuideSectionTypes.JS, + code: localeSource, + }, { + type: GuideSectionTypes.HTML, + code: localeHtml, + }], + text: ( +

+ Locale formatting is achieved by using the locale, + timeFormat and dateFormat props. + The later will take any moment() notation. Check + Date format by country + for formatting examples. +

+ ), + demo: , }, { title: 'Datepicker range', source: [{ diff --git a/src/components/date_picker/date_picker.js b/src/components/date_picker/date_picker.js index 172fd320ffb..77cbb68b26d 100644 --- a/src/components/date_picker/date_picker.js +++ b/src/components/date_picker/date_picker.js @@ -97,7 +97,7 @@ export class EuiDatePicker extends Component { > Date: Tue, 10 Apr 2018 13:43:55 -0700 Subject: [PATCH 11/42] time selection docs --- .../views/date_picker/date_picker_example.js | 35 ++++++-- src-docs/src/views/date_picker/locale.js | 83 +++++++++++++++++++ src-docs/src/views/date_picker/states.js | 71 ++++++++++++++++ src-docs/src/views/date_picker/time_select.js | 66 +++++++++++++++ 4 files changed, 250 insertions(+), 5 deletions(-) create mode 100644 src-docs/src/views/date_picker/locale.js create mode 100644 src-docs/src/views/date_picker/states.js create mode 100644 src-docs/src/views/date_picker/time_select.js diff --git a/src-docs/src/views/date_picker/date_picker_example.js b/src-docs/src/views/date_picker/date_picker_example.js index 53fb9fd9877..ad906751114 100644 --- a/src-docs/src/views/date_picker/date_picker_example.js +++ b/src-docs/src/views/date_picker/date_picker_example.js @@ -23,6 +23,10 @@ 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); @@ -67,6 +71,26 @@ export const DatePickerExample = {

), 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: