diff --git a/CHANGELOG.md b/CHANGELOG.md
index 61d33824fe4f..833636571b11 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,11 +1,17 @@
## [`master`](https://github.com/elastic/eui/tree/master)
- Added `spacesApp` logo to `EuiIcon` set ([#1065](https://github.com/elastic/eui/pull/1065))
+- Added `!default` to border SASS props ([#1079](https://github.com/elastic/eui/pull/1079))
+- Added `repositionOnScroll` prop to `EuiPopover` which enables repositioning the popover when the window is scrolled. ([#1064](https://github.com/elastic/eui/pull/1064))
+- Allow `_` and `*` characters to be used in `EuiSearchBar` query terms ([#1058](https://github.com/elastic/eui/pull/1058))
- Added more `status` options for `EuiSteps` ([#1088](https://github.com/elastic/eui/pull/1088))
**Bug fixes**
- `EuiMutationObserver`'s `children` prop is no longer marked as required ([#1076](https://github.com/elastic/eui/pull/1076))
+- Fixed large drop shadows so they work on darker backgrounds ([#1079](https://github.com/elastic/eui/pull/1079))
+- Added `resize-observer-polyfill` as a dependency (was previously a devDependency) ([#1085](https://github.com/elastic/eui/pull/1085))
+- Fixed `EuiBasicTable` to inform its parent about a selection change triggered by a different set of `items` ([#1086](https://github.com/elastic/eui/pull/1086))
- Fixed `EuiStepsHorizontal`'s title wrapping in IE ([#1088](https://github.com/elastic/eui/pull/1088))
## [`3.3.0`](https://github.com/elastic/eui/tree/v3.3.0)
diff --git a/package.json b/package.json
index 57879b95a0da..92303ee28c0e 100644
--- a/package.json
+++ b/package.json
@@ -52,6 +52,7 @@
"react-input-autosize": "^2.2.1",
"react-virtualized": "^9.18.5",
"react-vis": "1.10.2",
+ "resize-observer-polyfill": "^1.5.0",
"tabbable": "^1.1.0",
"uuid": "^3.1.0"
},
@@ -125,7 +126,6 @@
"react-test-renderer": "^16.2.0",
"redux": "^3.7.2",
"redux-thunk": "^2.2.0",
- "resize-observer-polyfill": "^1.5.0",
"rimraf": "^2.6.2",
"sass-extract": "^2.1.0",
"sass-extract-js": "^0.3.0",
diff --git a/src-docs/src/views/popover/popover_example.js b/src-docs/src/views/popover/popover_example.js
index 4b86b9d15ed6..ac41ed3dedba 100644
--- a/src-docs/src/views/popover/popover_example.js
+++ b/src-docs/src/views/popover/popover_example.js
@@ -44,6 +44,9 @@ import PopoverContainer from './popover_container';
const popoverContainerSource = require('!!raw-loader!./popover_container');
const popoverContainerHtml = renderToHtml(PopoverContainer);
+import PopoverFixed from './popover_fixed';
+const popoverFixedSource = require('!!raw-loader!./popover_fixed');
+const popoverFixedHtml = renderToHtml(PopoverFixed);
export const PopoverExample = {
title: 'Popover',
@@ -204,5 +207,22 @@ export const PopoverExample = {
),
demo: ,
+ }, {
+ title: 'Popover on a fixed element',
+ source: [{
+ type: GuideSectionTypes.JS,
+ code: popoverFixedSource,
+ }, {
+ type: GuideSectionTypes.HTML,
+ code: popoverFixedHtml,
+ }],
+ text: (
+
+
+ Popover content even works on position: fixed; elements.
+
+
+ ),
+ demo: ,
}],
};
diff --git a/src-docs/src/views/popover/popover_fixed.js b/src-docs/src/views/popover/popover_fixed.js
new file mode 100644
index 000000000000..f543a5133531
--- /dev/null
+++ b/src-docs/src/views/popover/popover_fixed.js
@@ -0,0 +1,67 @@
+import React, {
+ Component,
+} from 'react';
+
+import {
+ EuiButton,
+ EuiPopover,
+} from '../../../../src/components';
+
+export default class PopoverContainer extends Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ isExampleShown: false,
+ isPopoverOpen: false,
+ };
+ }
+
+ toggleExample = () => this.setState(({ isExampleShown }) => ({ isExampleShown: !isExampleShown }))
+
+ onButtonClick = () => {
+ this.setState({
+ isPopoverOpen: !this.state.isPopoverOpen,
+ });
+ }
+
+ closePopover = () => {
+ this.setState({
+ isPopoverOpen: false,
+ });
+ }
+
+ setPanelRef = node => this.panel = node;
+
+ render() {
+ const button = (
+
+ Show fixed popover
+
+ );
+
+ return (
+
+ Toggle Example
+ {this.state.isExampleShown && (
+
+
+ This popover scrolls with the button element!
+
+
+ )}
+
+ );
+ }
+}
diff --git a/src/components/basic_table/basic_table.js b/src/components/basic_table/basic_table.js
index fba26f2c5f4b..fb323ea9e6a5 100644
--- a/src/components/basic_table/basic_table.js
+++ b/src/components/basic_table/basic_table.js
@@ -199,7 +199,15 @@ export class EuiBasicTable extends Component {
nextProps.items.findIndex(item => getItemId(item, itemId) === getItemId(selectedItem, itemId)) !== -1
));
- return { selection };
+ if (selection.length !== prevState.selection.length) {
+ if (nextProps.selection.onSelectionChange) {
+ nextProps.selection.onSelectionChange(selection);
+ }
+
+ return { selection };
+ }
+
+ return null;
}
constructor(props) {
diff --git a/src/components/popover/popover.js b/src/components/popover/popover.js
index 719b1013b73a..8a0db98038c0 100644
--- a/src/components/popover/popover.js
+++ b/src/components/popover/popover.js
@@ -153,6 +153,10 @@ export class EuiPopover extends Component {
this.setState({ suppressingPopover: false, isOpening: true }); // eslint-disable-line react/no-did-mount-set-state
}
+ if (this.props.repositionOnScroll) {
+ window.addEventListener('scroll', this.positionPopover);
+ }
+
this.updateFocus();
}
@@ -169,6 +173,15 @@ export class EuiPopover extends Component {
});
}
+ // update scroll listener
+ if (prevProps.repositionOnScroll !== this.props.repositionOnScroll) {
+ if (this.props.repositionOnScroll) {
+ window.addEventListener('scroll', this.positionPopover);
+ } else {
+ window.removeEventListener('scroll', this.positionPopover);
+ }
+ }
+
// The popover is being closed.
if (prevProps.isOpen && !this.props.isOpen) {
// If the user has just closed the popover, queue up the removal of the content after the
@@ -184,6 +197,7 @@ export class EuiPopover extends Component {
}
componentWillUnmount() {
+ window.removeEventListener('scroll', this.positionPopover);
clearTimeout(this.closingTransitionTimeout);
}
@@ -420,6 +434,8 @@ EuiPopover.propTypes = {
PropTypes.node,
PropTypes.instanceOf(HTMLElement)
]),
+ /** When `true`, the popover's position is re-calculated when the user scrolls, this supports having fixed-position popover anchors. */
+ repositionOnScroll: PropTypes.bool,
};
EuiPopover.defaultProps = {
diff --git a/src/components/search_bar/query/default_syntax.js b/src/components/search_bar/query/default_syntax.js
index 0f6ca5835df5..5d7ba1bcf760 100644
--- a/src/components/search_bar/query/default_syntax.js
+++ b/src/components/search_bar/query/default_syntax.js
@@ -127,7 +127,7 @@ word
wordChar
= alnum
- / [-]
+ / [-_*]
/ escapedChar
escapedChar
diff --git a/src/components/search_bar/query/default_syntax.test.js b/src/components/search_bar/query/default_syntax.test.js
index c74b710a3d6f..61251fb79a9b 100644
--- a/src/components/search_bar/query/default_syntax.test.js
+++ b/src/components/search_bar/query/default_syntax.test.js
@@ -661,6 +661,38 @@ describe('defaultSyntax', () => {
expect(clause.value).toBe('truest');
});
+ describe('wordChar', () => {
+ test('alphanumeric characters', () => {
+ const ast = defaultSyntax.parse('logstash');
+ const clauses = ast.getTermClauses();
+ expect(clauses).toEqual([{
+ type: 'term',
+ value: 'logstash',
+ match: 'must',
+ }]);
+ });
+
+ test('escaped characters', () => {
+ const ast = defaultSyntax.parse('\\-');
+ const clauses = ast.getTermClauses();
+ expect(clauses).toEqual([{
+ type: 'term',
+ value: '-',
+ match: 'must',
+ }]);
+ });
+
+ test('special characters', () => {
+ const ast = defaultSyntax.parse('*_-');
+ const clauses = ast.getTermClauses();
+ expect(clauses).toEqual([{
+ type: 'term',
+ value: '*_-',
+ match: 'must',
+ }]);
+ });
+ });
+
test('number range expressions', () => {
const query = `num1>6 -num2>=8 num3<4 -num4<=2`;