diff --git a/CHANGELOG.md b/CHANGELOG.md index be88e7ded34..5eaa3aef4f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - Added a new app icon for Code ([#1467](https://github.com/elastic/eui/pull/1467)) No public interface changes since `6.6.0`. - Re-added EuiI18n, EuiI18nNumber, and EuiContext for localization ([#1466](https://github.com/elastic/eui/pull/1466)) +- Expose `EuiSuperUpdateButton` component from `EuiSuperDatePicker` ([#1470](https://github.com/elastic/eui/pull/1470)) - Set `type="button"` on accordion buttons ([#1468](https://github.com/elastic/eui/pull/1468)) **Bug fixes** 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 7c8da550319..1f2c69f95c2 100644 --- a/src-docs/src/views/date_picker/date_picker_example.js +++ b/src-docs/src/views/date_picker/date_picker_example.js @@ -12,6 +12,7 @@ import { EuiDatePicker, EuiDatePickerRange, EuiSuperDatePicker, + EuiSuperUpdateButton, } from '../../../../src/components'; import DatePicker from './date_picker'; @@ -305,6 +306,6 @@ export const DatePickerExample = { ), demo: , - props: { EuiSuperDatePicker }, + props: { EuiSuperDatePicker, EuiSuperUpdateButton }, }], }; diff --git a/src/components/date_picker/index.js b/src/components/date_picker/index.js index 00f6c0b638a..71ad8ad19b0 100644 --- a/src/components/date_picker/index.js +++ b/src/components/date_picker/index.js @@ -8,4 +8,5 @@ export { export { EuiSuperDatePicker, + EuiSuperUpdateButton, } from './super_date_picker'; diff --git a/src/components/date_picker/super_date_picker/__snapshots__/super_date_picker.test.js.snap b/src/components/date_picker/super_date_picker/__snapshots__/super_date_picker.test.js.snap index 47989b90535..19e03cf7e6f 100644 --- a/src/components/date_picker/super_date_picker/__snapshots__/super_date_picker.test.js.snap +++ b/src/components/date_picker/super_date_picker/__snapshots__/super_date_picker.test.js.snap @@ -3,6 +3,7 @@ exports[`EuiSuperDatePicker is rendered 1`] = ` - - - Refresh - - - - -`; - -exports[`EuiSuperDatePicker isLoading 1`] = ` - - - - } - > - } - iconType={false} - isCustom={true} - startDateControl={
} - > - - - - - - - - Updating - - + needsUpdate={false} + onClick={[Function]} + /> `; diff --git a/src/components/date_picker/super_date_picker/__snapshots__/super_update_button.test.js.snap b/src/components/date_picker/super_date_picker/__snapshots__/super_update_button.test.js.snap new file mode 100644 index 00000000000..59ecd0982c6 --- /dev/null +++ b/src/components/date_picker/super_date_picker/__snapshots__/super_update_button.test.js.snap @@ -0,0 +1,107 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`EuiSuperUpdateButton is rendered 1`] = ` + + + Refresh + + +`; + +exports[`EuiSuperUpdateButton isDisabled 1`] = ` + + + Refresh + + +`; + +exports[`EuiSuperUpdateButton isLoading 1`] = ` + + + Updating + + +`; + +exports[`EuiSuperUpdateButton needsUpdate 1`] = ` + + + Update + + +`; diff --git a/src/components/date_picker/super_date_picker/_index.scss b/src/components/date_picker/super_date_picker/_index.scss index 87d6056d51a..f0a5d0eef9e 100644 --- a/src/components/date_picker/super_date_picker/_index.scss +++ b/src/components/date_picker/super_date_picker/_index.scss @@ -1,5 +1,7 @@ +@import 'variables'; @import 'mixins'; @import 'date_popover/index'; @import 'quick_select_popover/index'; @import 'super_date_picker'; +@import 'super_update_button'; 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 cd9c89b5c5b..0e55797c955 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,5 +1,18 @@ -// sass-lint:disable no-important +.euiSuperDatePicker__flexWrapper { + max-width: 100%; + width: $euiSuperDatePickerWidth + $euiSuperDatePickerButtonWidth + $euiSizeS; +} + +.euiSuperDatePicker__flexWrapper--isAutoRefreshOnly { + width: $euiFormMaxWidth; +} + +.euiSuperDatePicker__flexWrapper--noUpdateButton { + width: $euiSuperDatePickerWidth; +} + .euiSuperDatePicker { + // sass-lint:disable-block no-important // Allow it to always grow to fit the container since the default form max width is too small max-width: 100% !important; @@ -32,19 +45,19 @@ .euiSuperDatePicker__prettyFormatLink { color: $euiLinkColor; -} - -.euiSuperDatePicker__updateButton { - // Just wide enough for all 3 states - min-width: $euiButtonMinWidth + ($euiSizeXS * 1.5); + padding-left: $euiSizeXS; // Adds some separation between date text and link + flex-shrink: 0; } @include euiBreakpoint('xs', 's') { - .euiSuperDatePicker__updateButton { - min-width: 0; + .euiSuperDatePicker__flexWrapper, + .euiSuperDatePicker__flexWrapper--isAutoRefreshOnly, + .euiSuperDatePicker__flexWrapper--noUpdateButton { + width: 100%; + } - .euiSuperDatePicker__updateButtonText { - display: none; - } + .euiSuperDatePicker__prettyFormatLink { + flex-shrink: 1; + min-width: 3em; // Ensures at least "Show" is always visible } } diff --git a/src/components/date_picker/super_date_picker/_super_update_button.scss b/src/components/date_picker/super_date_picker/_super_update_button.scss new file mode 100644 index 00000000000..db02011da0b --- /dev/null +++ b/src/components/date_picker/super_date_picker/_super_update_button.scss @@ -0,0 +1,14 @@ +.euiSuperUpdateButton { + // Just wide enough for all 3 states + min-width: $euiSuperDatePickerButtonWidth; +} + +@include euiBreakpoint('xs', 's') { + .euiSuperUpdateButton { + min-width: 0; + + .euiSuperUpdateButton__text { + display: none; + } + } +} diff --git a/src/components/date_picker/super_date_picker/_variables.scss b/src/components/date_picker/super_date_picker/_variables.scss new file mode 100644 index 00000000000..83f209098c2 --- /dev/null +++ b/src/components/date_picker/super_date_picker/_variables.scss @@ -0,0 +1,2 @@ +$euiSuperDatePickerWidth: $euiSize * 30; +$euiSuperDatePickerButtonWidth: $euiButtonMinWidth + ($euiSizeXS * 1.5); diff --git a/src/components/date_picker/super_date_picker/index.js b/src/components/date_picker/super_date_picker/index.js index 35eb266d870..3d84bbbdc1b 100644 --- a/src/components/date_picker/super_date_picker/index.js +++ b/src/components/date_picker/super_date_picker/index.js @@ -1,3 +1,7 @@ export { EuiSuperDatePicker, } from './super_date_picker'; + +export { + EuiSuperUpdateButton, +} from './super_update_button'; diff --git a/src/components/date_picker/super_date_picker/super_date_picker.js b/src/components/date_picker/super_date_picker/super_date_picker.js index 6d3123621d1..214de7be14f 100644 --- a/src/components/date_picker/super_date_picker/super_date_picker.js +++ b/src/components/date_picker/super_date_picker/super_date_picker.js @@ -1,20 +1,20 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; +import classNames from 'classnames'; import { commonlyUsedRangeShape, recentlyUsedRangeShape } from './types'; import { prettyDuration, showPrettyDuration } from './pretty_duration'; import { prettyInterval } from './pretty_interval'; import dateMath from '@elastic/datemath'; +import { EuiSuperUpdateButton } from './super_update_button'; import { EuiQuickSelectPopover } from './quick_select_popover/quick_select_popover'; import { EuiDatePopoverButton } from './date_popover/date_popover_button'; import { EuiDatePickerRange } from '../date_picker_range'; import { EuiFormControlLayout } from '../../form'; -import { EuiButton } from '../../button'; import { EuiFlexGroup, EuiFlexItem } from '../../flex'; -import { EuiToolTip } from '../../tool_tip'; export class EuiSuperDatePicker extends Component { @@ -128,29 +128,6 @@ export class EuiSuperDatePicker extends Component { }; } - componentWillUnmount() { - this._isMounted = false; - } - - componentDidMount() { - this._isMounted = true; - } - - setTootipRef = node => (this.tooltip = node); - - showTooltip = () => { - if (!this._isMounted || !this.tooltip) { - return; - } - this.tooltip.showToolTip(); - } - hideTooltip = () => { - if (!this._isMounted || !this.tooltip) { - return; - } - this.tooltip.hideToolTip(); - } - setTime = ({ start, end }) => { const startMoment = dateMath.parse(start); const endMoment = dateMath.parse(end, { roundUp: true }); @@ -174,11 +151,6 @@ export class EuiSuperDatePicker extends Component { this.props.onTimeChange({ start, end }); return; } - - this.showTooltip(); - this.tooltipTimeout = setTimeout(() => { - this.hideTooltip(); - }, 2000); } } @@ -286,38 +258,16 @@ export class EuiSuperDatePicker extends Component { return; } - let buttonText = 'Refresh'; - if (this.state.hasChanged || this.props.isLoading) { - buttonText = this.props.isLoading ? 'Updating' : 'Update'; - } - - let tooltipContent; - if (this.state.isInvalid) { - tooltipContent = 'Can\'t update, dates are invalid'; - } else if (this.state.hasChanged && !this.props.isLoading) { - tooltipContent = 'Click to apply'; - } - return ( - - + - {buttonText} - - + /> + ); } @@ -336,10 +286,19 @@ export class EuiSuperDatePicker extends Component { isAutoRefreshOnly={this.props.isAutoRefreshOnly} /> ); + + const flexWrapperClasses = classNames( + 'euiSuperDatePicker__flexWrapper', + { + 'euiSuperDatePicker__flexWrapper--noUpdateButton': !this.props.showUpdateButton, + 'euiSuperDatePicker__flexWrapper--isAutoRefreshOnly': this.props.isAutoRefreshOnly, + } + ); + return ( - + - + - - {this.renderUpdateButton()} - + {this.renderUpdateButton()} ); diff --git a/src/components/date_picker/super_date_picker/super_date_picker.test.js b/src/components/date_picker/super_date_picker/super_date_picker.test.js index 5fa4f20e4ed..9ce76657b9d 100644 --- a/src/components/date_picker/super_date_picker/super_date_picker.test.js +++ b/src/components/date_picker/super_date_picker/super_date_picker.test.js @@ -18,16 +18,4 @@ describe('EuiSuperDatePicker', () => { expect(component) .toMatchSnapshot(); }); - - test('isLoading', () => { - const component = shallow( - - ); - - expect(component) - .toMatchSnapshot(); - }); }); diff --git a/src/components/date_picker/super_date_picker/super_update_button.js b/src/components/date_picker/super_date_picker/super_update_button.js new file mode 100644 index 00000000000..aa9ca8e6476 --- /dev/null +++ b/src/components/date_picker/super_date_picker/super_update_button.js @@ -0,0 +1,107 @@ +import PropTypes from 'prop-types'; +import React, { Component } from 'react'; +import classNames from 'classnames'; + +import { EuiButton } from '../../button'; +import { EuiToolTip } from '../../tool_tip'; + +export class EuiSuperUpdateButton extends Component { + static propTypes = { + needsUpdate: PropTypes.bool, + isLoading: PropTypes.bool, + isDisabled: PropTypes.bool, + onClick: PropTypes.func.isRequired, + /** + * Passes props to `EuiToolTip` + */ + toolTipProps: PropTypes.object, + } + + static defaultProps = { + needsUpdate: false, + isLoading: false, + isDisabled: false, + } + + componentWillUnmount() { + this._isMounted = false; + } + + componentDidMount() { + this._isMounted = true; + } + + componentDidUpdate() { + if (this.props.needsUpdate && !this.props.isDisabled && !this.props.isLoading) { + this.showTooltip(); + this.tooltipTimeout = setTimeout(() => { + this.hideTooltip(); + }, 2000); + } + } + + setTootipRef = node => (this.tooltip = node); + + showTooltip = () => { + if (!this._isMounted || !this.tooltip) { + return; + } + this.tooltip.showToolTip(); + } + + hideTooltip = () => { + if (!this._isMounted || !this.tooltip) { + return; + } + this.tooltip.hideToolTip(); + } + + render() { + const { + className, + needsUpdate, + isLoading, + isDisabled, + onClick, + toolTipProps, + ...rest + } = this.props; + + const classes = classNames('euiSuperUpdateButton', className); + + let buttonText = 'Refresh'; + if (needsUpdate || isLoading) { + buttonText = isLoading ? 'Updating' : 'Update'; + } + + let tooltipContent; + if (isDisabled) { + tooltipContent = 'Cannot update'; + } else if (needsUpdate && !isLoading) { + tooltipContent = 'Click to apply'; + } + + return ( + + + {buttonText} + + + ); + } +} diff --git a/src/components/date_picker/super_date_picker/super_update_button.test.js b/src/components/date_picker/super_date_picker/super_update_button.test.js new file mode 100644 index 00000000000..b5e098e964b --- /dev/null +++ b/src/components/date_picker/super_date_picker/super_update_button.test.js @@ -0,0 +1,57 @@ +import React from 'react'; +import { shallow } from 'enzyme'; + +import { + EuiSuperUpdateButton, +} from './super_update_button'; + +const noop = () => {}; + +describe('EuiSuperUpdateButton', () => { + test('is rendered', () => { + const component = shallow( + + ); + + expect(component) + .toMatchSnapshot(); + }); + + test('needsUpdate', () => { + const component = shallow( + + ); + + expect(component) + .toMatchSnapshot(); + }); + + test('isDisabled', () => { + const component = shallow( + + ); + + expect(component) + .toMatchSnapshot(); + }); + + test('isLoading', () => { + const component = shallow( + + ); + + expect(component) + .toMatchSnapshot(); + }); +}); diff --git a/src/components/index.js b/src/components/index.js index 654bed85b61..b62b5953f65 100644 --- a/src/components/index.js +++ b/src/components/index.js @@ -79,6 +79,7 @@ export { EuiDatePicker, EuiDatePickerRange, EuiSuperDatePicker, + EuiSuperUpdateButton, } from './date_picker'; export {