diff --git a/.sass-lint.yml b/.sass-lint.yml index 583a70c8176..d952df73334 100644 --- a/.sass-lint.yml +++ b/.sass-lint.yml @@ -5,7 +5,7 @@ files: ignore: # These are themes of outside libraries we import - 'src/components/series_chart/**/*.s+(a|c)ss' - - 'src/components/date_picker/**/*.s+(a|c)ss' + - 'src/global_styling/react_date_picker/**/*.s+(a|c)ss' rules: quotes: - 2 diff --git a/CHANGELOG.md b/CHANGELOG.md index b7f015c7e9e..3f27b36d725 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ - Fixed usage of `outsideClickCloses` prop of `EuiFlyout` ([#4986](https://github.com/elastic/eui/pull/4986)) +**Theme: Amsterdam** + +- Updated styles for `EuiDatePicker` ([#5000](https://github.com/elastic/eui/pull/5000)) + ## [`37.1.0`](https://github.com/elastic/eui/tree/v37.1.0) - Added `isDisabled` prop to `EuiFormRow` that disables the child field element ([#4908](https://github.com/elastic/eui/pull/4908)) diff --git a/src-docs/src/views/icon/icon_example.js b/src-docs/src/views/icon/icon_example.js index ba12d9b6d91..1a1b5589f7d 100644 --- a/src-docs/src/views/icon/icon_example.js +++ b/src-docs/src/views/icon/icon_example.js @@ -79,6 +79,13 @@ export const IconExample = { use the default size of{' '} size="m".

+

+ If you would like to contribute to our growing list of glyphs, + you can follow{' '} + + these guidelines + . +

), demo: , diff --git a/src/components/date_picker/__snapshots__/date_picker.test.tsx.snap b/src/components/date_picker/__snapshots__/date_picker.test.tsx.snap index 863934edc64..5e194cd2d9c 100644 --- a/src/components/date_picker/__snapshots__/date_picker.test.tsx.snap +++ b/src/components/date_picker/__snapshots__/date_picker.test.tsx.snap @@ -1,22 +1,20 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`EuiDatePicker is rendered 1`] = ` - - + - - - - - - - - + + + + + + `; @@ -64,742 +62,738 @@ exports[`EuiDatePicker is rendered 2`] = ` `; exports[`EuiDatePicker localization accepts the locale prop 1`] = ` - - +
+ + +
- - -
+ 7월 2019 +
+
- 7월 2019 -
-
-
- - - 7월 - -
-
-
-
+ - - - 2019 - -
+ 7월 +
- 일 -
-
- 월 -
-
- 화 -
-
- 수 -
-
- 목 -
-
- 금 -
-
- 토 + + + 2019 +
-
-
- 30 -
-
- 1 -
-
- 2 -
-
- 3 -
-
- 4 -
-
- 5 -
-
- 6 -
+ 일
-
- 7 -
-
- 8 -
-
- 9 -
-
- 10 -
-
- 11 -
-
- 12 -
-
- 13 -
+ 월
-
- 14 -
-
- 15 -
-
- 16 -
-
- 17 -
-
- 18 -
-
- 19 -
-
- 20 -
+ 화
-
- 21 -
-
- 22 -
-
- 23 -
-
- 24 -
-
- 25 -
-
- 26 -
-
- 27 -
+ 수
-
- 28 -
-
- 29 -
-
- 30 -
-
- 31 -
-
- 1 -
-
- 2 -
-
- 3 -
+ 목 +
+
+ 금 +
+
+ 토
-
-
-
- - -`; - -exports[`EuiDatePicker localization inherits locale from context 1`] = ` - - -
-
-
- - -
+
- juillet 2019 + 30
-
-
- - - juillet - -
-
-
-
- - - 2019 - -
-
+ 1
-
- lu -
-
- ma -
-
- me -
-
- je -
-
- ve -
-
- sa -
-
- di -
+ 2 +
+
+ 3 +
+
+ 4 +
+
+ 5 +
+
+ 6
-
-
- 1 -
-
- 2 -
-
- 3 -
-
- 4 -
-
- 5 -
-
- 6 -
-
- 7 -
+ 7
-
- 8 -
-
- 9 -
-
- 10 -
-
- 11 -
-
- 12 -
-
- 13 -
-
- 14 -
+ 8
-
- 15 -
-
- 16 -
-
- 17 -
-
- 18 -
-
- 19 -
-
- 20 -
-
- 21 -
+ 9
-
- 22 -
-
- 23 -
-
- 24 -
-
- 25 -
-
- 26 -
-
- 27 -
-
- 28 -
+ 10
+ 11 +
+
+ 12 +
+
+ 13 +
+
+
+
+ 14 +
+
+ 15 +
+
+ 16 +
+
+ 17 +
+
+ 18 +
+
+ 19 +
+
+ 20 +
+
+
+
+ 21 +
+
+ 22 +
+
+ 23 +
+
+ 24 +
+
+ 25 +
+
+ 26 +
+
+ 27 +
+
+
+
+ 28 +
+
+ 29 +
+
+ 30 +
+
+ 31 +
+
+ 1 +
+
+ 2 +
+
+ 3 +
+
+
+
+
+
+
+
+`; + +exports[`EuiDatePicker localization inherits locale from context 1`] = ` + +
+
+
+
+ + +
+
+
+ juillet 2019 +
+
+
- 29 -
-
- 30 -
-
- 31 -
-
- 1 -
-
- 2 -
-
- 3 + + + juillet +
+
+
- 4 + + + 2019 +
+
+
+ lu +
+
+ ma +
+
+ me +
+
+ je +
+
+ ve +
+
+ sa +
+
+ di +
+
+
+
+ +
+
+ 1 +
+
+ 2 +
+
+ 3 +
+
+ 4 +
+
+ 5 +
+
+ 6 +
+
+ 7 +
+
+
+
+ 8 +
+
+ 9 +
+
+ 10 +
+
+ 11 +
+
+ 12 +
+
+ 13 +
+
+ 14 +
+
+
+
+ 15 +
+
+ 16 +
+
+ 17 +
+
+ 18 +
+
+ 19 +
+
+ 20 +
+
+ 21 +
+
+
+
+ 22 +
+
+ 23 +
+
+ 24 +
+
+ 25 +
+
+ 26 +
+
+ 27 +
+
+ 28 +
+
+
+
+ 29 +
+
+ 30 +
+
+ 31 +
+
+ 1 +
+
+ 2 +
+
+ 3 +
+
+ 4 +
+
- +
`; @@ -820,163 +814,161 @@ exports[`EuiDatePicker popoverPlacement top-end is rendered 1`] = ` showTimeSelect={false} timeFormat="hh:mm A" > - - + -
-
- - - + + + +
+ } + > + + + - -
- } - > - - -
-
- -
+
-
-
-
- - - - + + + + + + + +
-
- - + - -
- -
+ /> + +
+ +
+
- - +
+ `; diff --git a/src/components/date_picker/__snapshots__/date_picker_range.test.tsx.snap b/src/components/date_picker/__snapshots__/date_picker_range.test.tsx.snap index 3fc722b7092..bf6bdc15fc7 100644 --- a/src/components/date_picker/__snapshots__/date_picker_range.test.tsx.snap +++ b/src/components/date_picker/__snapshots__/date_picker_range.test.tsx.snap @@ -6,46 +6,44 @@ exports[`EuiDatePickerRange is rendered 1`] = ` class="euiDatePickerRange testClass1 testClass2" data-test-subj="test subject string" > - - +
-
- -
+
-
+
+ - -
+ aria-hidden="true" + class="euiFormControlLayoutCustomIcon__icon" + data-euiicon-type="calendar" + /> +
- +
- - +
-
- -
+
- +
`; diff --git a/src/components/date_picker/_date_picker_range.scss b/src/components/date_picker/_date_picker_range.scss index a48c3373f5a..342436bec26 100644 --- a/src/components/date_picker/_date_picker_range.scss +++ b/src/components/date_picker/_date_picker_range.scss @@ -5,7 +5,7 @@ .euiDatePickerRange { @include euiFormControlSize(auto, $includeAlternates: true); // Match just the regular drop shadow of inputs - @include euiFormControlDefaultShadow(); + @include euiFormControlDefaultShadow; display: flex; align-items: center; padding: 1px; /* 1 */ @@ -16,9 +16,19 @@ } .euiFieldText.euiDatePicker { - box-shadow: none !important; // including all states + // including all states + box-shadow: none !important; // sass-lint:disable-line no-important text-align: center; + } + + .euiDatePickerRange__start { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + .euiDatePickerRange__end { + border-top-left-radius: 0; + border-bottom-left-radius: 0; } .react-datepicker-popper .euiFieldText.euiDatePicker { @@ -38,8 +48,9 @@ // Direct descendent selectors to override `> span` > .euiDatePickerRange__delimeter { - background-color: transparent !important; // override .euiFormControlLayout--group .euiText - line-height: 1 !important; + // override .euiFormControlLayout--group .euiText + background-color: transparent !important; // sass-lint:disable-line no-important + line-height: 1 !important; // sass-lint:disable-line no-important flex: 0 0 auto; padding-left: $euiFormControlPadding / 2; padding-right: $euiFormControlPadding / 2; diff --git a/src/components/date_picker/_index.scss b/src/components/date_picker/_index.scss index 36875c07a21..962d4bc7df3 100644 --- a/src/components/date_picker/_index.scss +++ b/src/components/date_picker/_index.scss @@ -1,5 +1,4 @@ -// Uses some form mixins -@import 'variables'; -@import 'date_picker'; +// The react-date-picker overrides exists in the global_styling folder +// to easily style differently between default and Amsterdam theme @import 'date_picker_range'; @import 'super_date_picker/index'; diff --git a/src/components/date_picker/date_picker.tsx b/src/components/date_picker/date_picker.tsx index 1fb8d0d2f8b..c58579b25b5 100644 --- a/src/components/date_picker/date_picker.tsx +++ b/src/components/date_picker/date_picker.tsx @@ -213,7 +213,9 @@ export class EuiDatePicker extends Component<_EuiDatePickerProps> { // 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 + this.props.withPortal || + // Causes Error: Cannot read property 'clone' of undefined + this.props.showMonthYearDropdown ) { return ( @@ -223,60 +225,56 @@ export class EuiDatePicker extends Component<_EuiDatePickerProps> { } return ( - - - - - - {({ locale: contextLocale }) => { - return ( - - ); - }} - - - - + + + + + {({ locale: contextLocale }) => { + return ( + + ); + }} + + + ); } diff --git a/src/components/date_picker/date_picker_range.tsx b/src/components/date_picker/date_picker_range.tsx index 8402239ed18..82fd1ef5c2f 100644 --- a/src/components/date_picker/date_picker_range.tsx +++ b/src/components/date_picker/date_picker_range.tsx @@ -29,7 +29,7 @@ export type EuiDatePickerRangeProps = CommonProps & { /** * The end date `EuiDatePicker` element */ - endDateControl: ReactNode; + endDateControl: ReactElement; fullWidth?: boolean; /** @@ -46,7 +46,7 @@ export type EuiDatePickerRangeProps = CommonProps & { /** * The start date `EuiDatePicker` element */ - startDateControl: ReactNode; + startDateControl: ReactElement; }; export const EuiDatePickerRange: FunctionComponent = ({ @@ -80,6 +80,10 @@ export const EuiDatePickerRange: FunctionComponent = ({ readOnly: readOnly, iconType: typeof iconType === 'boolean' ? undefined : iconType, showIcon: !!iconType, + className: classNames( + 'euiDatePickerRange__start', + startDateControl.props.className + ), } ); @@ -90,6 +94,10 @@ export const EuiDatePickerRange: FunctionComponent = ({ fullWidth: fullWidth, readOnly: readOnly, popoverPlacement: 'bottom-end', + className: classNames( + 'euiDatePickerRange__end', + startDateControl.props.className + ), } ); } diff --git a/src/global_styling/functions/_colors.scss b/src/global_styling/functions/_colors.scss index 6fa3b9bd842..25834e10add 100644 --- a/src/global_styling/functions/_colors.scss +++ b/src/global_styling/functions/_colors.scss @@ -72,7 +72,7 @@ // Given $color, decide whether $lightText or $darkText should be used as the text color // ex: chooseLightOrDarkText(#EEE, #FFF, #000) would return #000 because it has // a higher contrast than #FFF against a #EEE background. -@function chooseLightOrDarkText($background, $lightText, $darkText) { +@function chooseLightOrDarkText($background, $lightText: $euiColorGhost, $darkText: $euiColorInk) { $lightContrast: contrastRatio($background, $lightText); $darkContrast: contrastRatio($background, $darkText); diff --git a/src/global_styling/index.scss b/src/global_styling/index.scss index 573503099da..e480e5adb92 100644 --- a/src/global_styling/index.scss +++ b/src/global_styling/index.scss @@ -14,3 +14,6 @@ // The reset file makes use of variables and mixins @import 'reset/index'; + +// Customization of the React Date Picker +@import 'react_date_picker/index'; diff --git a/src/components/date_picker/_date_picker.scss b/src/global_styling/react_date_picker/_date_picker.scss similarity index 99% rename from src/components/date_picker/_date_picker.scss rename to src/global_styling/react_date_picker/_date_picker.scss index adc8ed3290d..8ee36693b24 100644 --- a/src/components/date_picker/_date_picker.scss +++ b/src/global_styling/react_date_picker/_date_picker.scss @@ -15,7 +15,7 @@ // Because we don't have control over react-datepicker's dom we use SVG URIs for the navigation arrows. // There is one for light and dark. -@mixin datePicker__arrow { +@mixin datePickerArrow { background-position: center; @if (lightness($euiColorEmptyShade) > 50) { background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiI+ICA8ZGVmcz4gICAgPHBhdGggaWQ9ImFycm93X2Rvd24tYSIgZD0iTTEzLjA2ODg1MDgsNS4xNTcyNTAzOCBMOC4zODQyMzk3NSw5Ljc2ODI3NDI4IEM4LjE3MDU0NDE1LDkuOTc4NjEzMDggNy44Mjk5OTIxNCw5Ljk3OTE0MDk1IDcuNjE1NzYwMjUsOS43NjgyNzQyOCBMMi45MzExNDkxNSw1LjE1NzI1MDM4IEMyLjcxODEzNTksNC45NDc1ODMyMSAyLjM3Mjc3MzE5LDQuOTQ3NTgzMjEgMi4xNTk3NTk5NCw1LjE1NzI1MDM4IEMxLjk0Njc0NjY5LDUuMzY2OTE3NTYgMS45NDY3NDY2OSw1LjcwNjg1NTIyIDIuMTU5NzU5OTQsNS45MTY1MjI0IEw2Ljg0NDM3MTA0LDEwLjUyNzU0NjMgQzcuNDg1MTc0MjQsMTEuMTU4MjgzNiA4LjUxNjQ0OTc5LDExLjE1NjY4NTEgOS4xNTU2Mjg5NiwxMC41Mjc1NDYzIEwxMy44NDAyNDAxLDUuOTE2NTIyNCBDMTQuMDUzMjUzMyw1LjcwNjg1NTIyIDE0LjA1MzI1MzMsNS4zNjY5MTc1NiAxMy44NDAyNDAxLDUuMTU3MjUwMzggQzEzLjYyNzIyNjgsNC45NDc1ODMyMSAxMy4yODE4NjQxLDQuOTQ3NTgzMjEgMTMuMDY4ODUwOCw1LjE1NzI1MDM4IFoiLz4gIDwvZGVmcz4gIDxnIGZpbGwtcnVsZT0iZXZlbm9kZCI+ICAgIDx1c2UgZmlsbC1ydWxlPSJub256ZXJvIiB4bGluazpocmVmPSIjYXJyb3dfZG93bi1hIi8+ICA8L2c+PC9zdmc+); @@ -193,7 +193,7 @@ overflow: hidden; &--previous { - @include datePicker__arrow; + @include datePickerArrow; left: $euiSize + $euiSizeXS; height: $euiSize; width: $euiSize; @@ -223,7 +223,7 @@ } &--next { - @include datePicker__arrow; + @include datePickerArrow; // Pixel value because of some padding on the icon right: 20px; height: $euiSize; diff --git a/src/global_styling/react_date_picker/_index.scss b/src/global_styling/react_date_picker/_index.scss new file mode 100644 index 00000000000..48ea2f99771 --- /dev/null +++ b/src/global_styling/react_date_picker/_index.scss @@ -0,0 +1,2 @@ +@import 'variables'; +@import 'date_picker'; diff --git a/src/components/date_picker/_variables.scss b/src/global_styling/react_date_picker/_variables.scss similarity index 100% rename from src/components/date_picker/_variables.scss rename to src/global_styling/react_date_picker/_variables.scss diff --git a/src/themes/eui-amsterdam/global_styling/index.scss b/src/themes/eui-amsterdam/global_styling/index.scss index 9df71159436..36432e23208 100644 --- a/src/themes/eui-amsterdam/global_styling/index.scss +++ b/src/themes/eui-amsterdam/global_styling/index.scss @@ -14,3 +14,6 @@ // The reset file makes use of variables and mixins @import 'reset/index'; + +// Customization of the React Date Picker +@import 'react_date_picker/index'; diff --git a/src/themes/eui-amsterdam/global_styling/mixins/_button.scss b/src/themes/eui-amsterdam/global_styling/mixins/_button.scss index 82662791e83..fd24f97ef85 100644 --- a/src/themes/eui-amsterdam/global_styling/mixins/_button.scss +++ b/src/themes/eui-amsterdam/global_styling/mixins/_button.scss @@ -15,22 +15,46 @@ } } -// Creates the Amsterdam style of button with a transparent background -@mixin euiButtonDefaultStyle($color, $transparency: $euiButtonDefaultTransparency) { +/* + * Creates the Amsterdam style of button with a transparent background + */ +@mixin euiButtonDefaultStyle($color: 'primary', $includeStates: true, $transparency: $euiButtonDefaultTransparency) { + $backgroundColor: $color; + + @if (map-has-key($euiButtonTypes, $color)) { + $backgroundColor: map-get($euiButtonTypes, $color); + } + $percentConversion: $transparency * 100%; // This variable simulates the possibly darkest background the button could be on // Simulates the 20% opaque color on top of the page background color - $backgroundColorSimulated: mix($euiPageBackgroundColor, $color, $percentConversion); + $backgroundColorSimulated: mix($euiPageBackgroundColor, $backgroundColor, $percentConversion); // Then we can calculate the darkest text color needed - color: makeHighContrastColor($color, $backgroundColorSimulated); + color: makeHighContrastColor($backgroundColor, $backgroundColorSimulated); // But still use transparency - background-color: transparentize($color, $transparency); + background-color: transparentize($backgroundColor, $transparency); - &:not([class*='isDisabled']) { - &:hover, - &:focus { - // Duplicated from inert state simply to override default theme - background-color: transparentize($color, $transparency); + @if ($includeStates) { + &:not([class*='isDisabled']) { + &:hover, + &:focus { + // Duplicated from inert state simply to override default theme + background-color: transparentize($backgroundColor, $transparency); + } } } } + +/* + * Creates the Amsterdam style of fill button + */ +@mixin euiButtonFillStyle($color: 'primary') { + $backgroundColor: $color; + + @if (map-has-key($euiButtonTypes, $color)) { + $backgroundColor: map-get($euiButtonTypes, $color); + } + + background-color: $backgroundColor; + color: chooseLightOrDarkText($backgroundColor); +} diff --git a/src/themes/eui-amsterdam/global_styling/react_date_picker/_date_picker.scss b/src/themes/eui-amsterdam/global_styling/react_date_picker/_date_picker.scss new file mode 100644 index 00000000000..8d0c82870dd --- /dev/null +++ b/src/themes/eui-amsterdam/global_styling/react_date_picker/_date_picker.scss @@ -0,0 +1,112 @@ +/* This file is a heavy retheme of react-datepicker's Sass as of v1.4.0 +** https://github.com/Hacker0x01/react-datepicker +*/ + + +.euiDatePicker { + display: block; + + .euiFormControlLayout { + height: auto; + } + + &.euiDatePicker--inline { + .euiFormControlLayout { + display: inline-block; + width: auto; + } + } + + &.euiDatePicker--shadow { + .react-datepicker-popper { + @include euiBottomShadowMedium; + border: $euiBorderThin; + background-color: $euiColorEmptyShade; + border-radius: 0 0 $euiBorderRadius $euiBorderRadius; + } + + // If the shadow is on, and it is inline, we need to put the shadow on the datepicker + // itself rather than the popper. + &.euiDatePicker--inline { + .react-datepicker { + @include euiBottomShadowMedium; + border: $euiBorderThin; + background-color: $euiColorEmptyShade; + border-radius: $euiBorderRadius; + } + } + } +} + +.react-datepicker { + font-size: $euiFontSizeXS; + color: $euiTextColor; + display: flex; + border-radius: $euiBorderRadius; + padding: $euiDatePickerPadding; + justify-content: center; +} + +.euiDatePicker.euiDatePicker--shadow .react-datepicker-popper { + z-index: $euiZContentMenu; + animation: euiAnimFadeIn $euiAnimSpeedFast ease-in; + + &[data-placement^='top'] { + @include euiBottomShadowFlat; + border-radius: $euiBorderRadius $euiBorderRadius 0 0; + } + + &[data-placement^='right'] { + margin-left: 0; + } + + &[data-placement^='left'] { + margin-right: 0; + } +} + +// Hidden things that we don't want to show/use, ever +.react-datepicker__current-month, +.react-datepicker-time__header { + display: none; +} + +.react-datepicker__screenReaderOnly { + @include euiScreenReaderOnly; +} + +.react-datepicker__focusTrap { + display: flex; + justify-content: center; +} + +.react-datepicker__month-container { + flex-grow: 1; + margin-top: $euiSizeXL + $euiDatePickerGap; +} + +.react-datepicker__header { + display: flex; + flex-direction: column; +} + +.react-datepicker-time__header { + @include euiTextTruncate; +} + +.react-datepicker__month { + text-align: center; + border-radius: $euiBorderRadius; +} + +// On small screens put the times at the bottom +@include euiBreakpoint('xs') { + .react-datepicker__focusTrap, + .react-datepicker { + flex-direction: column; + } + + .react-datepicker__time-box { + margin-top: 0; + } +} diff --git a/src/themes/eui-amsterdam/global_styling/react_date_picker/_date_picker_days.scss b/src/themes/eui-amsterdam/global_styling/react_date_picker/_date_picker_days.scss new file mode 100644 index 00000000000..fbffbad2697 --- /dev/null +++ b/src/themes/eui-amsterdam/global_styling/react_date_picker/_date_picker_days.scss @@ -0,0 +1,130 @@ +/** + * LEGEND + * __day-name : Week headers like Su, Mo, etc + * __day : Number on the calendar + * --highlighted + * --disabled : _this.isDisabled(), + * --selected : _this.isSameDay(_this.props.selected), + * --range-start : _this.isRangeStart(), + * --range-end : _this.isRangeEnd(), + * --keyboard-selected : _this.isKeyboardSelected(), + * --in-range : _this.isInRange(), + * --in-selecting-range : _this.isInSelectingRange(), + * --selecting-range-start : _this.isSelectingRangeStart(), + * --selecting-range-end : _this.isSelectingRangeEnd(), + * --today : _this.isSameDay(now(_this.props.utcOffset)), + * --weekend : _this.isWeekend(), + * --outside-month : _this.isOutsideMonth() + */ + + +.react-datepicker__day-names, +.react-datepicker__week { + white-space: nowrap; + display: flex; + justify-content: space-between; + flex-grow: 1; +} + +.react-datepicker__day-name, +.react-datepicker__day { + font-weight: $euiFontWeightMedium; + text-align: center; + color: $euiTitleColor; + display: inline-block; + width: $euiSizeXL; + line-height: $euiSizeXL; + border-radius: $euiBorderRadiusSmall; + margin: ($euiSizeXS / 2); +} + +.react-datepicker__day-name { + color: $euiTextSubduedColor; +} + +.react-datepicker__day { + cursor: pointer; + transition: transform $euiAnimSpeedExtraFast ease-in-out; + + &:hover { + @include euiButtonDefaultStyle('primary', false); + text-decoration: underline; + + @include euiCanAnimate { + // Setting the transform under can animate because its jarring + transform: scale(1.1); + } + } + + &--today { + color: $euiColorPrimary; + font-weight: $euiFontWeightBold; + } + + &--outside-month { + color: $euiTextSubduedColor; + } + + &--highlighted, + &--highlighted:hover { + @include euiButtonDefaultStyle('success', false); + } + + &--in-range, + &--in-range:hover { + @include euiButtonDefaultStyle('primary', false); + } + + // Ranges use 2 side box-shadows that are the same as the button style + // to create a solid blue highlight, only rounded at the ends + &--in-range:not(&--selected):not(:hover) { + // sass-lint:disable-block indentation + box-shadow: -2px 0 transparentize($euiColorPrimary, $euiButtonDefaultTransparency), + 2px 0 transparentize($euiColorPrimary, $euiButtonDefaultTransparency); + border-radius: 0; + + &:first-of-type { + box-shadow: 2px 0 transparentize($euiColorPrimary, $euiButtonDefaultTransparency); + } + + &:last-of-type { + box-shadow: -2px 0 transparentize($euiColorPrimary, $euiButtonDefaultTransparency); + } + } + + &--in-range#{&}--range-start:not(&--selected) { + border-top-left-radius: $euiBorderRadiusSmall; + border-bottom-left-radius: $euiBorderRadiusSmall; + } + + &--in-range#{&}--range-end:not(&--selected) { + border-top-right-radius: $euiBorderRadiusSmall; + border-bottom-right-radius: $euiBorderRadiusSmall; + } + + &--selected, + &--in-selecting-range, + &--selected:hover, + &--in-selecting-range:hover { + @include euiButtonFillStyle; + } + + &--in-selecting-range:not(&--in-range) { + background-color: transparentize($euiColorDanger, .5); //todo + } + + &--disabled, + &--disabled:hover { + $backgroundColorSimulated: mix($euiPageBackgroundColor, $euiButtonColorDisabled, 90%); + background-color: transparentize($euiButtonColorDisabled, .9); + color: makeDisabledContrastColor($euiButtonColorDisabled, $backgroundColorSimulated); + cursor: not-allowed; + text-decoration: none; + transform: none; + } + + &--disabled.react-datepicker__day--selected, + &--disabled.react-datepicker__day--selected:hover { + color: $euiTextColor; + } +} diff --git a/src/themes/eui-amsterdam/global_styling/react_date_picker/_date_picker_month_year.scss b/src/themes/eui-amsterdam/global_styling/react_date_picker/_date_picker_month_year.scss new file mode 100644 index 00000000000..9c79ebe05b5 --- /dev/null +++ b/src/themes/eui-amsterdam/global_styling/react_date_picker/_date_picker_month_year.scss @@ -0,0 +1,156 @@ +/** + * LEGEND + * __header__dropdown : Contains the month and year, but affords for the navigational arrows + + * __month-dropdown-container: Contains both static/selected control and the dropdown + * __month-read-view: The static control + * __month-dropdown: The absolutely positioned list + * __month-option: Each option in the list + * --selected_month + * --selected + * --preselected + + * __year-dropdown-container: Contains both static/selected control and the dropdown + * __year-read-view: The static control + * __year-dropdown: The absolutely positioned list + * __year-option: Each option in the list + * --selected_year + * --selected + * --preselected + */ + +// Absolutely positioned across the *whole* top of the calendar +.react-datepicker__header__dropdown { + padding: $euiDatePickerGap * 2; + display: flex; + // sass-lint:disable-block no-misspelled-properties + gap: $euiDatePickerGap; + position: absolute; + top: 0; + left: $euiDatePickerButtonSize + $euiDatePickerGap; + right: $euiDatePickerButtonSize + $euiDatePickerGap; + justify-content: center; +} + +/** + * Make the top selectors look like select inputs + */ +.react-datepicker__year-read-view, +.react-datepicker__month-read-view, +.react-datepicker__month-year-read-view { + @include euiFormControlStyle($borderOnly: false, $includeStates: false, $includeSizes: false); + @include euiFormControlStyleCompressed($borderOnly: true, $includeStates: false); + height: $euiFormControlCompressedHeight; + font-weight: $euiFontWeightMedium; + display: flex; + flex-direction: row-reverse; + justify-content: space-between; + align-items: center; + + &:hover { + cursor: pointer; + text-decoration: underline; + } + + &--down-arrow { + @include datePickerCaret; + right: $euiSizeS; + height: $euiSizeM; + width: $euiSizeM; + display: inline-block; + background-size: cover; + } + + &--selected-month, + &--selected-year { + @include euiTextTruncate; + } +} + +.react-datepicker__year-dropdown-container, +.react-datepicker__month-dropdown-container { + position: relative; + display: inline-block; + flex-grow: 1; + max-width: $euiFormMaxWidth; +} + +// Using the unnamed div for the years dropdown because we want to be able to control the +// flex direction of the years but you can't put overflow on a flex group +.react-datepicker__year-dropdown-container > div:not([class*='read-view']), +.react-datepicker__month-dropdown { + @include euiYScroll; + @include euiBottomShadowSmall; + height: 250px; // Set an explicit height, something at least smaller than the overall height + background-color: $euiColorEmptyShade; + position: absolute; + z-index: 1; + border-radius: $euiBorderRadius; + min-width: $euiDatePickerMinControlWidth; + width: 100%; +} + +.react-datepicker__year-dropdown-container > div:not([class*='read-view']) { + // Reverse the direction of the years so that earlier is first + .react-datepicker__year-dropdown { + padding: $euiSizeXS; + display: flex; + flex-direction: column-reverse; + justify-content: flex-end; + } +} + +.react-datepicker__month-dropdown-container { + flex-grow: 2; + + .react-datepicker__month-dropdown { + padding: $euiSizeXS; + min-width: $euiDatePickerMaxControlWidth; + } +} + +// Hide the first and last options which trigger adding one more year to the list +// But container no text or any content so its inaccessible +.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 { + padding: 0 $euiSizeS; + height: $euiButtonHeightXSmall; + line-height: $euiButtonHeightXSmall; + border-radius: $euiBorderRadiusSmall; + font-size: $euiFontSizeS; + margin: $euiDatePickerGap 0; + cursor: pointer; + + &:hover, + &:focus { + text-decoration: underline; + } + + &--selected { + display: none; + } +} + +.react-datepicker__year-option--preselected, +.react-datepicker__month-option--preselected { + &, + &:hover { + background: $euiFocusBackgroundColor; + } +} + +.react-datepicker__year-option--selected_year, +.react-datepicker__month-option--selected_month { + &, + &:hover { + @include euiButtonFillStyle; + } +} diff --git a/src/themes/eui-amsterdam/global_styling/react_date_picker/_date_picker_navigation.scss b/src/themes/eui-amsterdam/global_styling/react_date_picker/_date_picker_navigation.scss new file mode 100644 index 00000000000..b88cfe3983e --- /dev/null +++ b/src/themes/eui-amsterdam/global_styling/react_date_picker/_date_picker_navigation.scss @@ -0,0 +1,30 @@ +.react-datepicker__navigation--next, +.react-datepicker__navigation--previous { + @include datePickerArrow; + cursor: pointer; + position: absolute; + top: $euiDatePickerGap * 2; + height: $euiDatePickerButtonSize; + width: $euiDatePickerButtonSize; + z-index: 1; + text-indent: -999em; + overflow: hidden; + background-repeat: no-repeat; + border-radius: $euiBorderRadiusSmall; + background-position: center; + + &:hover, + &:focus { + background-color: $euiFocusBackgroundColor; + } +} + +.react-datepicker__navigation--previous { + left: $euiDatePickerGap * 2; + transform: rotate(180deg); + transform-origin: center; +} + +.react-datepicker__navigation--next { + right: $euiDatePickerGap * 2; +} diff --git a/src/themes/eui-amsterdam/global_styling/react_date_picker/_date_picker_times.scss b/src/themes/eui-amsterdam/global_styling/react_date_picker/_date_picker_times.scss new file mode 100644 index 00000000000..5c63b8f75a8 --- /dev/null +++ b/src/themes/eui-amsterdam/global_styling/react_date_picker/_date_picker_times.scss @@ -0,0 +1,108 @@ +/** + * LEGEND + * __time-list-item : + * --preselected : closest current time but not selected (also applied when using arrow keys to indicate focus) + * --selected + * --disabled + * --injected + */ + +.react-datepicker__header--time { + display: none; +} + +.react-datepicker__time-container { + border-left: $euiBorderColor; + width: auto; + display: flex; + margin-top: $euiSizeXL + ($euiDatePickerGap * 2); + margin-left: $euiSizeS; + flex-grow: 1; + background-color: $euiPageBackgroundColor; + border-radius: $euiBorderRadius; + + &--focus { + .react-datepicker__time-list-item--preselected { + text-decoration: underline; + } + } +} + +.react-datepicker__time, +.react-datepicker__time-box { + display: flex; + flex-direction: column; + flex-grow: 1; +} + +.react-datepicker__time-list { + @include euiYScroll; + padding: $euiSizeXS $euiSizeM; + // Set the min-height with the following, but it should stretch to fit if the container is larger + height: 100px !important; // sass-lint:disable-line no-important + display: flex; + flex-direction: column; + flex-grow: 1; + align-items: center; + gap: $euiSizeXS; // sass-lint:disable-line no-misspelled-properties +} + +// Mainly a copy/paste of .euiEmptyButton +.react-datepicker__time-list-item { + @include euiButton; + // sass-lint:disable-block no-important + transform: none !important; /* 1 */ + animation: none !important; /* 1 */ + transition-timing-function: ease-in; /* 2 */ + transition-duration: $euiAnimSpeedFast; /* 2 */ + + padding: 0 $euiSizeS; + height: $euiButtonHeightXSmall; + line-height: $euiButtonHeightXSmall; + border-radius: $euiBorderRadiusSmall; + font-size: $euiFontSizeXS; + + &--disabled, + &--disabled:hover { + text-decoration: none !important; + cursor: not-allowed; + color: $euiButtonColorDisabledText; + background-color: transparent; + } + + &--injected, + &--injected:hover { + @include euiButtonDefaultStyle('success', false); + } + + &--preselected, + &--preselected:hover { + background: $euiFocusBackgroundColor; + } + + &--selected, + &--selected:hover { + @include euiButtonFillStyle; + } +} + + +// When in time only mode we make the dropdown look more like the combo box styling. +.react-datepicker--time-only { + padding: 0 !important; // sass-lint:disable-line no-important + + .react-datepicker__time-container { + background-color: transparent; + margin: 0; + } + + .react-datepicker__time-list { + height: 204px !important; // sass-lint:disable-line no-important + } + + .react-datepicker__time-list-item { + font-size: $euiFontSizeS; + min-width: $euiButtonMinWidth; + text-align: left; + } +} diff --git a/src/themes/eui-amsterdam/global_styling/react_date_picker/_index.scss b/src/themes/eui-amsterdam/global_styling/react_date_picker/_index.scss new file mode 100644 index 00000000000..3e68b4b3189 --- /dev/null +++ b/src/themes/eui-amsterdam/global_styling/react_date_picker/_index.scss @@ -0,0 +1,8 @@ +@import 'variables'; +@import 'mixins'; + +@import 'date_picker_days'; +@import 'date_picker_times'; +@import 'date_picker_month_year'; +@import 'date_picker_navigation'; +@import 'date_picker'; diff --git a/src/themes/eui-amsterdam/global_styling/react_date_picker/_mixins.scss b/src/themes/eui-amsterdam/global_styling/react_date_picker/_mixins.scss new file mode 100644 index 00000000000..44cf8a91571 --- /dev/null +++ b/src/themes/eui-amsterdam/global_styling/react_date_picker/_mixins.scss @@ -0,0 +1,20 @@ +// Because we don't have control over react-datepicker's dom we use SVG URIs for the navigation arrows. +// There is one for light and dark. +// sass-lint:disable-block url-quotes +@mixin datePickerCaret { + background-position: center; + @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=); + } +} + +@mixin datePickerArrow { + background-position: center; + @if (lightness($euiColorEmptyShade) > 50) { + background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+PHBhdGggZmlsbD0iIzM0Mzc0MSIgZD0iTTExLjY5MiA3SDMuNTU2QzMuMjQ5IDcgMyA3LjIyNCAzIDcuNXMuMjQ5LjUuNTU2LjVoOC4xMzZsLTQuMDk2IDQuMDk2YS41LjUgMCAwMC43MDcuNzA3bDQuMjQzLTQuMjQyYy4yNTgtLjI1OS40MDMtLjU4Ny40MzMtLjkyNWEuNDU0LjQ1NCAwIDAwMC0uMjcyIDEuNDk0IDEuNDk0IDAgMDAtLjQzMy0uOTI1TDguMzAzIDIuMTk3YS41LjUgMCAxMC0uNzA3LjcwN0wxMS42OTIgN3oiLz48L3N2Zz4=); + } @else { + background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+PHBhdGggZmlsbD0iI0ZGRiIgZD0iTTExLjY5MiA3SDMuNTU2QzMuMjQ5IDcgMyA3LjIyNCAzIDcuNXMuMjQ5LjUuNTU2LjVoOC4xMzZsLTQuMDk2IDQuMDk2YS41LjUgMCAwMC43MDcuNzA3bDQuMjQzLTQuMjQyYy4yNTgtLjI1OS40MDMtLjU4Ny40MzMtLjkyNWEuNDU0LjQ1NCAwIDAwMC0uMjcyIDEuNDk0IDEuNDk0IDAgMDAtLjQzMy0uOTI1TDguMzAzIDIuMTk3YS41LjUgMCAxMC0uNzA3LjcwN0wxMS42OTIgN3oiLz48L3N2Zz4=); + } +} diff --git a/src/themes/eui-amsterdam/global_styling/react_date_picker/_variables.scss b/src/themes/eui-amsterdam/global_styling/react_date_picker/_variables.scss new file mode 100644 index 00000000000..b6fc93b9f96 --- /dev/null +++ b/src/themes/eui-amsterdam/global_styling/react_date_picker/_variables.scss @@ -0,0 +1,9 @@ +$euiDatePickerCalendarWidth: 284px; + +$euiDatePickerPadding: $euiSizeS; +$euiDatePickerGap: $euiSizeXS; +$euiDatePickerCalendarColumns: 7; // Just to make calculations obvious +$euiDatePickerButtonSize: $euiSizeXL; + +$euiDatePickerMinControlWidth: 100px; +$euiDatePickerMaxControlWidth: 140px;