diff --git a/src/components/date_picker/super_date_picker/__snapshots__/super_date_picker.test.tsx.snap b/src/components/date_picker/super_date_picker/__snapshots__/super_date_picker.test.tsx.snap index c8c4d594cba..4677e02206a 100644 --- a/src/components/date_picker/super_date_picker/__snapshots__/super_date_picker.test.tsx.snap +++ b/src/components/date_picker/super_date_picker/__snapshots__/super_date_picker.test.tsx.snap @@ -1,2500 +1,878 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`EuiSuperDatePicker is rendered 1`] = ` - - - - } +
+
+
+ +
+
+
- - - +
+ - - - -`; - -exports[`EuiSuperDatePicker props accepts data-test-subj and passes to EuiFormControlLayout 1`] = ` - - - - } + style="min-inline-size: 118px;" + type="button" > - - - - - - - + Refresh + + + +
`; exports[`EuiSuperDatePicker props compressed is rendered 1`] = ` - - - - } +
+
+
+ +
+
+
- - - +
+ - - - + style="min-inline-size: 118px;" + type="button" + > + + + Refresh + + + +
`; exports[`EuiSuperDatePicker props isAutoRefreshOnly is rendered 1`] = ` - - - - - +
+
+
+
+ +
+ +
+
+
+
+
+ `; exports[`EuiSuperDatePicker props isAutoRefreshOnly passes required props 1`] = ` - - - - - +
+
+
+
+ +
+ +
+
+
+
+
+ `; -exports[`EuiSuperDatePicker props isQuickSelectOnly is rendered 1`] = ` - + + All time + + +`; + +exports[`EuiSuperDatePicker props isDisabled true 1`] = ` +
- - +
+
+ +
+
+
+ +
+
+ + + + +`; + +exports[`EuiSuperDatePicker props isQuickSelectOnly is rendered 1`] = ` +
+
+
+
+ +
+
+
- - + - - - + style="min-inline-size: 118px;" + type="button" + > + + + Refresh + + + +
`; exports[`EuiSuperDatePicker props showUpdateButton can be false 1`] = ` - - - - } +
+
+
+ +
+
+
- - - +
+
+
`; exports[`EuiSuperDatePicker props showUpdateButton can be iconOnly 1`] = ` - - - - } +
+
+
+ +
+
+
- - - +
+ - - - + type="button" + > + + + + Refresh + + + + +
`; exports[`EuiSuperDatePicker props width can be auto 1`] = ` - - - - } +
+
+
+ +
+
+
- - - +
+ - - - + style="min-inline-size: 118px;" + type="button" + > + + + Refresh + + + +
`; exports[`EuiSuperDatePicker props width can be full 1`] = ` - - - - } +
+
+
+ +
+
+
+
+ + + +
+`; + +exports[`EuiSuperDatePicker renders 1`] = ` +
+
+
+
+ +
+
+
+ - - - +
+ - - - + style="min-inline-size: 118px;" + type="button" + > + + + Refresh + + + +
+`; + +exports[`EuiSuperDatePicker renders an EuiDatePickerRange 1`] = ` +
+ +
+
+
+ +
+
+
+
+
+ +
+
+
+ + to + +
+
+
+ +
+
+
+
+
+ + + +
`; diff --git a/src/components/date_picker/super_date_picker/_super_date_picker.scss b/src/components/date_picker/super_date_picker/_super_date_picker.scss index 0d2b3f368a5..f5b20685c7d 100644 --- a/src/components/date_picker/super_date_picker/_super_date_picker.scss +++ b/src/components/date_picker/super_date_picker/_super_date_picker.scss @@ -1,4 +1,6 @@ -.euiSuperDatePicker__flexWrapper { +.euiSuperDatePicker { + display: flex; + gap: $euiSizeS; max-width: 100%; // Set a sensible min-width for when width is auto min-width: MIN(($euiFormMaxWidth / 2) + $euiSuperDatePickerButtonWidth + $euiSizeS, 100%); @@ -8,36 +10,38 @@ width: 100%; } - &.euiSuperDatePicker__flexWrapper--fullWidth { + &--isAutoRefreshOnly { + min-width: MIN($euiFormMaxWidth / 2, 100%); + width: $euiFormMaxWidth; + } + + &--noUpdateButton { + min-width: MIN($euiFormMaxWidth / 2, 100%); + width: $euiSuperDatePickerWidth; + } + + &--fullWidth { width: 100%; } - &.euiSuperDatePicker__flexWrapper--isQuickSelectOnly { + &--isQuickSelectOnly { min-width: 0; } - &.euiSuperDatePicker__flexWrapper--autoWidth { + &--autoWidth { display: inline-flex; width: auto; } -} - -.euiSuperDatePicker__flexWrapper--isAutoRefreshOnly { - min-width: MIN($euiFormMaxWidth / 2, 100%); - width: $euiFormMaxWidth; -} -.euiSuperDatePicker__flexWrapper--noUpdateButton { - min-width: MIN($euiFormMaxWidth / 2, 100%); - width: $euiSuperDatePickerWidth; -} + .euiDatePickerRange { + flex-grow: 1; + } -.euiSuperDatePicker { - // Allow it to always grow to fit the container since the default form max width is too small - // stylelint-disable-next-line declaration-no-important - max-width: 100% !important; + .euiFormControlLayout { + max-width: 100%; // Allow it to always grow to fit the container since the default form max width is too small + } - > .euiFormControlLayout__childrenWrapper { + .euiFormControlLayout__childrenWrapper { display: flex; align-items: center; overflow: hidden; @@ -74,16 +78,18 @@ /** * Make the arrow delimiter match the colors of `.euiDatePopoverButton-needsUpdating` */ -.euiSuperDatePicker--needsUpdating.euiFormControlLayoutDelimited { // Extra specificity needed to override default delimited styles - .euiFormControlLayout__childrenWrapper { - background-color: $euiSuperDatePickerNeedsUpdatingBackgroundColor; - } +.euiSuperDatePicker--needsUpdating { + .euiFormControlLayoutDelimited { // Extra specificity needed to override default delimited styles + .euiFormControlLayout__childrenWrapper { + background-color: $euiSuperDatePickerNeedsUpdatingBackgroundColor; + } - .euiFormControlLayoutDelimited__delimiter { - color: $euiSuperDatePickerNeedsUpdatingTextColor; + .euiFormControlLayoutDelimited__delimiter { + color: $euiSuperDatePickerNeedsUpdatingTextColor; + } } -} -.euiSuperDatePicker .euiFormControlLayout__childrenWrapper { - transition: background $euiAnimSpeedFast ease-in; // Match @mixin euiSuperDatePickerText / .euiDatePopoverButton + .euiFormControlLayout__childrenWrapper { + transition: background $euiAnimSpeedFast ease-in; // Match @mixin euiSuperDatePickerText / .euiDatePopoverButton + } } diff --git a/src/components/date_picker/super_date_picker/super_date_picker.test.tsx b/src/components/date_picker/super_date_picker/super_date_picker.test.tsx index 76046c6f8f6..f4ed527111a 100644 --- a/src/components/date_picker/super_date_picker/super_date_picker.test.tsx +++ b/src/components/date_picker/super_date_picker/super_date_picker.test.tsx @@ -7,7 +7,9 @@ */ import React from 'react'; -import { mount, shallow, ReactWrapper } from 'enzyme'; +import { mount, ReactWrapper } from 'enzyme'; +import { fireEvent } from '@testing-library/dom'; +import { render } from '../../../test/rtl'; import { requiredProps } from '../../../test'; import { shouldRenderCustomStyles } from '../../../test/internal'; @@ -28,8 +30,6 @@ const findInternalInstance = ( const instance = component.instance() as EuiSuperDatePickerInternal; return [instance, component]; }; -const shallowAndDive = (component: React.ReactElement) => - shallow(component).dive().dive(); describe('EuiSuperDatePicker', () => { shouldRenderCustomStyles(, { @@ -40,12 +40,19 @@ describe('EuiSuperDatePicker', () => { skipParentTest: true, }); - test('is rendered', () => { - const component = shallowAndDive( + it('renders', () => { + const { container } = render( ); + expect(container.firstChild).toMatchSnapshot(); + }); - expect(component).toMatchSnapshot(); + it('renders an EuiDatePickerRange', () => { + const { container, getByTestSubject } = render( + + ); + fireEvent.click(getByTestSubject('superDatePickerShowDatesButton')); + expect(container.firstChild).toMatchSnapshot(); }); test('refresh is disabled by default', () => { @@ -195,77 +202,106 @@ describe('EuiSuperDatePicker', () => { describe('showUpdateButton', () => { test('can be false', () => { - const component = shallowAndDive( + const { container } = render( ); - expect(component).toMatchSnapshot(); + expect(container.firstChild).toMatchSnapshot(); }); test('can be iconOnly', () => { - const component = shallowAndDive( + const { container } = render( ); - expect(component).toMatchSnapshot(); + expect(container.firstChild).toMatchSnapshot(); }); }); test('accepts data-test-subj and passes to EuiFormControlLayout', () => { - const component = shallowAndDive( + const { container } = render( ); - expect(component).toMatchSnapshot(); + expect(container.firstChild).toMatchSnapshot(); }); describe('width', () => { test('can be full', () => { - const component = shallowAndDive( + const { container } = render( ); - expect(component).toMatchSnapshot(); + expect(container.firstChild).toMatchSnapshot(); }); test('can be auto', () => { - const component = shallowAndDive( + const { container } = render( ); - expect(component).toMatchSnapshot(); + expect(container.firstChild).toMatchSnapshot(); }); }); describe('compressed', () => { test('is rendered', () => { - const component = shallowAndDive( + const { container } = render( ); - expect(component).toMatchSnapshot(); + expect(container.firstChild).toMatchSnapshot(); }); }); describe('isQuickSelectOnly', () => { test('is rendered', () => { - const component = shallowAndDive( + const { container } = render( ); - expect(component).toMatchSnapshot(); + expect(container.firstChild).toMatchSnapshot(); + }); + }); + + describe('isDisabled', () => { + test('true', () => { + const { container } = render( + + ); + expect(container.firstChild).toMatchSnapshot(); + }); + + // TODO: Convert to storybook once EuiSuperDatePicker is on Emotion + test('config object', () => { + const { getByTestSubject } = render( + All time + ), + }} + /> + ); + expect(getByTestSubject('customDisabledDisplay').textContent).toEqual( + 'All time' + ); + expect( + getByTestSubject('superDatePickerShowDatesButton') + ).toMatchSnapshot(); }); }); describe('isAutoRefreshOnly', () => { it('is rendered', () => { - const component = shallowAndDive( + const { container } = render( ); - expect(component).toMatchSnapshot(); + expect(container.firstChild).toMatchSnapshot(); }); it('passes required props', () => { - const component = shallowAndDive( + const { container } = render( { data-test-subj="autoRefreshOnly" /> ); - expect(component).toMatchSnapshot(); + expect(container.firstChild).toMatchSnapshot(); }); }); }); diff --git a/src/components/date_picker/super_date_picker/super_date_picker.tsx b/src/components/date_picker/super_date_picker/super_date_picker.tsx index 52c928cad84..cf5ce985b0a 100644 --- a/src/components/date_picker/super_date_picker/super_date_picker.tsx +++ b/src/components/date_picker/super_date_picker/super_date_picker.tsx @@ -16,11 +16,11 @@ import classNames from 'classnames'; import moment, { LocaleSpecifier } from 'moment'; // eslint-disable-line import/named import dateMath from '@elastic/datemath'; +import { isObject } from '../../../services/predicate'; import { EuiI18nConsumer } from '../../context'; import { CommonProps } from '../../common'; import { EuiDatePickerRange } from '../date_picker_range'; import { EuiFormControlLayout, EuiFormControlLayoutProps } from '../../form'; -import { EuiFlexGroup, EuiFlexItem } from '../../flex'; import { ShortDate, @@ -82,7 +82,15 @@ export type EuiSuperDatePickerProps = CommonProps & { * Set isAutoRefreshOnly to true to limit the component to only display auto refresh content. */ isAutoRefreshOnly?: boolean; - isDisabled?: boolean; + + /** + * Accepts either a true/false boolean or an object configuration. + * + * The configuration will render the component as disabled, and allow you to + * customize the displayed disabled text. + */ + isDisabled?: boolean | { display: ReactNode }; + isLoading?: boolean; isPaused?: boolean; @@ -170,7 +178,6 @@ type EuiSuperDatePickerInternalProps = EuiSuperDatePickerProps & { dateFormat: string; timeFormat: string; isPaused: boolean; - isDisabled: boolean; }; interface EuiSuperDatePickerState { @@ -423,7 +430,7 @@ export class EuiSuperDatePickerInternal extends Component< customQuickSelectRender={customQuickSelectRender} dateFormat={dateFormat} end={end} - isDisabled={isDisabled} + isDisabled={!!isDisabled} isPaused={isPaused} recentlyUsedRanges={recentlyUsedRanges} refreshInterval={refreshInterval} @@ -458,14 +465,12 @@ export class EuiSuperDatePickerInternal extends Component< utcOffset, compressed, onFocus, - className, - 'data-test-subj': dataTestSubj, } = this.props; const autoRefreshAppend: EuiFormControlLayoutProps['append'] = !isPaused ? ( @@ -504,16 +508,20 @@ export class EuiSuperDatePickerInternal extends Component< 'euiSuperDatePicker__prettyFormat--disabled': isDisabled, })} data-test-subj="superDatePickerShowDatesButton" - disabled={isDisabled} + disabled={!!isDisabled} onClick={this.hidePrettyDuration} onFocus={onFocus} > - + {isDisabledDisplay ? ( + isDisabled.display + ) : ( + + )} ); @@ -524,10 +532,6 @@ export class EuiSuperDatePickerInternal extends Component< {({ locale: contextLocale }) => ( - - + ); }; @@ -632,44 +633,40 @@ export class EuiSuperDatePickerInternal extends Component< compressed, className, } = this.props; + const { hasChanged, isInvalid } = this.state; // Force reduction in width if showing quick select only const width = isQuickSelectOnly ? 'auto' : _width; - const flexWrapperClasses = classNames('euiSuperDatePicker__flexWrapper', { - 'euiSuperDatePicker__flexWrapper--noUpdateButton': !showUpdateButton, - 'euiSuperDatePicker__flexWrapper--isAutoRefreshOnly': isAutoRefreshOnly, - 'euiSuperDatePicker__flexWrapper--isQuickSelectOnly': isQuickSelectOnly, - 'euiSuperDatePicker__flexWrapper--fullWidth': width === 'full', - 'euiSuperDatePicker__flexWrapper--autoWidth': width === 'auto', + const classes = classNames('euiSuperDatePicker', className, { + 'euiSuperDatePicker--needsUpdating': + hasChanged && !isDisabled && !isInvalid, + 'euiSuperDatePicker--noUpdateButton': !showUpdateButton, + 'euiSuperDatePicker--isAutoRefreshOnly': isAutoRefreshOnly, + 'euiSuperDatePicker--isQuickSelectOnly': isQuickSelectOnly, + 'euiSuperDatePicker--fullWidth': width === 'full', + 'euiSuperDatePicker--autoWidth': width === 'auto', }); return ( - +
{isAutoRefreshOnly && onRefreshChange ? ( - - - + ) : ( <> - {this.renderDatePickerRange()} + {this.renderDatePickerRange()} {this.renderUpdateButton()} )} - +
); } } diff --git a/upcoming_changelogs/6821.md b/upcoming_changelogs/6821.md new file mode 100644 index 00000000000..e5093b5b60a --- /dev/null +++ b/upcoming_changelogs/6821.md @@ -0,0 +1,5 @@ +- Updated `EuiSuperDatePicker` to accept an object configuration for `isDisabled` + +**Bug fixes** + +- Fixed broken `EuiSuperDatePicker` styles