diff --git a/CHANGELOG.md b/CHANGELOG.md
index 330d53f14a3..e822c37bf87 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
## [`master`](https://github.com/elastic/eui/tree/master)
- Created `EuiDualRange` using components from modularized, refactored `EuiRange`. New util service `isWithinRange` is the first in the number category. ([#1485](https://github.com/elastic/eui/pull/1485))
+- Upgraded `lodash` to v4, taking advantage of modular imports. ([#1534](https://github.com/elastic/eui/pull/1534))
**Bug fixes**
diff --git a/package.json b/package.json
index 9eac97b5827..ed2780c1f53 100644
--- a/package.json
+++ b/package.json
@@ -49,7 +49,7 @@
"highlight.js": "^9.12.0",
"html": "^1.0.0",
"keymirror": "^0.1.1",
- "lodash": "npm:@elastic/lodash@3.10.1-kibana1",
+ "lodash": "^4.17.11",
"numeral": "^2.0.6",
"prop-types": "^15.6.0",
"react-ace": "^5.5.0",
diff --git a/src-docs/src/components/guide_section/guide_section.js b/src-docs/src/components/guide_section/guide_section.js
index 35e86ed5441..4ba03850c4e 100644
--- a/src-docs/src/components/guide_section/guide_section.js
+++ b/src-docs/src/components/guide_section/guide_section.js
@@ -1,6 +1,5 @@
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
-import { flatten } from 'lodash';
import {
EuiCode,
@@ -273,9 +272,9 @@ export class GuideSection extends Component {
renderProps() {
const { props } = this.props;
- return flatten(
- this.componentNames.map(componentName => this.renderPropsForComponent(componentName, props[componentName]))
- );
+ return this.componentNames
+ .map(componentName => this.renderPropsForComponent(componentName, props[componentName]))
+ .reduce((a, b) => a.concat(b), []); // Flatten the resulting array
}
renderChrome() {
diff --git a/src-docs/src/views/header/global_filter_form.js b/src-docs/src/views/header/global_filter_form.js
index 9c4d6cd326a..abc711a281c 100644
--- a/src-docs/src/views/header/global_filter_form.js
+++ b/src-docs/src/views/header/global_filter_form.js
@@ -1,6 +1,5 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
-// import { pull } from 'lodash';
import {
EuiFlexGroup,
diff --git a/src-docs/src/views/search_bar/controlled_search_bar.js b/src-docs/src/views/search_bar/controlled_search_bar.js
index 9bdf619543c..905c537811c 100644
--- a/src-docs/src/views/search_bar/controlled_search_bar.js
+++ b/src-docs/src/views/search_bar/controlled_search_bar.js
@@ -1,5 +1,5 @@
import React, { Component, Fragment } from 'react';
-import { times } from 'lodash';
+import { times } from '../../../../src/services/utils';
import { Random } from '../../../../src/services/random';
import {
EuiHealth,
diff --git a/src-docs/src/views/search_bar/search_bar.js b/src-docs/src/views/search_bar/search_bar.js
index 9ef817d670a..529761b3722 100644
--- a/src-docs/src/views/search_bar/search_bar.js
+++ b/src-docs/src/views/search_bar/search_bar.js
@@ -1,5 +1,5 @@
import React, { Component, Fragment } from 'react';
-import { times } from 'lodash';
+import { times } from '../../../../src/services/utils';
import { Random } from '../../../../src/services/random';
import {
EuiHealth,
diff --git a/src-docs/src/views/search_bar/search_bar_filters.js b/src-docs/src/views/search_bar/search_bar_filters.js
index 086bef43785..242a7c59547 100644
--- a/src-docs/src/views/search_bar/search_bar_filters.js
+++ b/src-docs/src/views/search_bar/search_bar_filters.js
@@ -1,5 +1,5 @@
import React, { Component, Fragment } from 'react';
-import { times } from 'lodash';
+import { times } from '../../../../src/services/utils';
import { Random } from '../../../../src/services/random';
import {
EuiHealth,
diff --git a/src-docs/src/views/tables/footer/footer.js b/src-docs/src/views/tables/footer/footer.js
index dfcab718148..5ee172b6c60 100644
--- a/src-docs/src/views/tables/footer/footer.js
+++ b/src-docs/src/views/tables/footer/footer.js
@@ -14,7 +14,7 @@ import {
EuiFlexItem,
} from '../../../../../src/components';
-import { uniq } from 'lodash';
+import uniqBy from 'lodash/uniqBy';
/*
Example user object:
@@ -152,7 +152,7 @@ export class Table extends Component {
field: 'github',
name: 'Github',
footer: ({ items }) => (
- {uniq(items, 'github').length} users
+ {uniqBy(items, 'github').length} users
),
render: (username) => (
@@ -169,7 +169,7 @@ export class Table extends Component {
field: 'nationality',
name: 'Nationality',
footer: ({ items }) => (
- {uniq(items, 'nationality').length} countries
+ {uniqBy(items, 'nationality').length} countries
),
render: (countryCode) => {
const country = store.getCountry(countryCode);
diff --git a/src/components/accessibility/keyboard_accessible.test.tsx b/src/components/accessibility/keyboard_accessible.test.tsx
index 5fd99cd6162..a5803b561fb 100644
--- a/src/components/accessibility/keyboard_accessible.test.tsx
+++ b/src/components/accessibility/keyboard_accessible.test.tsx
@@ -1,11 +1,14 @@
import React from 'react';
import { render, shallow } from 'enzyme';
-import { noop } from 'lodash';
import { EuiKeyboardAccessible } from './keyboard_accessible';
import { keyCodes } from '../../services';
+const noop = () => {
+ // eslint-disable-line no-empty
+};
+
describe('EuiKeyboardAccessible', () => {
describe('throws an error', () => {
// tslint:disable-next-line:no-console
diff --git a/src/components/basic_table/basic_table.js b/src/components/basic_table/basic_table.js
index d6ddad381c6..a197cc3dea2 100644
--- a/src/components/basic_table/basic_table.js
+++ b/src/components/basic_table/basic_table.js
@@ -4,7 +4,6 @@ import React, {
} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
-import { dropWhile, slice } from 'lodash';
import {
formatAuto, formatBoolean, formatDate, formatNumber, formatText, LEFT_ALIGNMENT, PropertySortType,
RIGHT_ALIGNMENT, SortDirection
@@ -760,7 +759,8 @@ export class EuiBasicTable extends Component {
if (column.actions.length > 2) {
// if any of the actions `isPrimary`, add them inline as well, but only the first 2
- actualActions = slice(dropWhile(column.actions, function (o) { return !o.isPrimary; }), 0, 2);
+ const primaryActions = column.actions.filter(o => o.isPrimary);
+ actualActions = primaryActions.slice(0, 2);
// if we have more than 1 action, we don't show them all in the cell, instead we
// put them all in a popover tool. This effectively means we can only have a maximum
diff --git a/src/components/date_picker/super_date_picker/relative_utils.js b/src/components/date_picker/super_date_picker/relative_utils.js
index 4732080fe1b..8d30d1ce6f3 100644
--- a/src/components/date_picker/super_date_picker/relative_utils.js
+++ b/src/components/date_picker/super_date_picker/relative_utils.js
@@ -1,13 +1,14 @@
-
import dateMath from '@elastic/datemath';
import moment from 'moment';
-import _ from 'lodash';
+
+import { get } from '../../../services/objects';
+import { isString } from '../../../services/predicate';
import { relativeUnitsFromLargestToSmallest } from './relative_options';
const ROUND_DELIMETER = '/';
export function parseRelativeParts(value) {
- const matches = _.isString(value) && value.match(/now(([\-\+])([0-9]+)([smhdwMy])(\/[smhdwMy])?)?/);
+ const matches = isString(value) && value.match(/now(([\-\+])([0-9]+)([smhdwMy])(\/[smhdwMy])?)?/);
const isNow = matches && !matches[1];
const operator = matches && matches[2];
@@ -46,14 +47,14 @@ export function parseRelativeParts(value) {
}
export function toRelativeStringFromParts(relativeParts) {
- const count = _.get(relativeParts, `count`, 0);
- const isRounded = _.get(relativeParts, `round`, false);
+ const count = get(relativeParts, `count`, 0);
+ const isRounded = get(relativeParts, `round`, false);
if (count === 0 && !isRounded) {
return 'now';
}
- const matches = _.get(relativeParts, `unit`, 's').match(/([smhdwMy])(\+)?/);
+ const matches = get(relativeParts, `unit`, 's').match(/([smhdwMy])(\+)?/);
const unit = matches[1];
const operator = matches && matches[2] ? matches[2] : '-';
const round = isRounded ? `${ROUND_DELIMETER}${unit}` : '';
diff --git a/src/components/form/checkbox/checkbox.js b/src/components/form/checkbox/checkbox.js
index a5b74cd9ebb..b42f75b3203 100644
--- a/src/components/form/checkbox/checkbox.js
+++ b/src/components/form/checkbox/checkbox.js
@@ -1,7 +1,8 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
-import { omit } from 'lodash';
+
+import { omit } from '../../../services/objects';
const typeToClassNameMap = {
inList: 'euiCheckbox--inList',
diff --git a/src/components/form/form_row/form_row.js b/src/components/form/form_row/form_row.js
index 86e8c13357c..7ad8510a06f 100644
--- a/src/components/form/form_row/form_row.js
+++ b/src/components/form/form_row/form_row.js
@@ -4,7 +4,8 @@ import React, {
} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
-import { get } from 'lodash';
+
+import { get } from '../../../services/objects';
import { EuiFormHelpText } from '../form_help_text';
import { EuiFormErrorText } from '../form_error_text';
diff --git a/src/components/form/range/range_ticks.js b/src/components/form/range/range_ticks.js
index 16c380b809e..f94d89fd145 100644
--- a/src/components/form/range/range_ticks.js
+++ b/src/components/form/range/range_ticks.js
@@ -2,6 +2,8 @@ import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
+import find from 'lodash/find';
+
export const EuiRangeTicks = ({ disabled, onChange, ticks, tickObject, value, max }) => {
// Align with item labels across the range by adding
// left and right negative margins that is half of the tick marks
@@ -13,7 +15,7 @@ export const EuiRangeTicks = ({ disabled, onChange, ticks, tickObject, value, ma
const tickStyle = {};
let customTick;
if (ticks) {
- customTick = ticks.find(o => o.value === tickValue);
+ customTick = find(ticks, o => o.value === tickValue);
if (customTick == null) {
return;
diff --git a/src/components/form/range/range_track.js b/src/components/form/range/range_track.js
index a09fb8d75eb..bdab431799d 100644
--- a/src/components/form/range/range_track.js
+++ b/src/components/form/range/range_track.js
@@ -2,7 +2,7 @@ import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
-import { range } from 'lodash';
+import range from 'lodash/range';
import { EuiRangeLevels, LEVEL_COLORS } from './range_levels';
import { EuiRangeTicks } from './range_ticks';
diff --git a/src/components/search_bar/query/execute_ast.js b/src/components/search_bar/query/execute_ast.js
index ae8770bd83f..6fa1d7991e3 100644
--- a/src/components/search_bar/query/execute_ast.js
+++ b/src/components/search_bar/query/execute_ast.js
@@ -1,4 +1,4 @@
-import { get } from 'lodash';
+import { get } from '../../../services/objects';
import { isString, isArray } from '../../../services/predicate';
import { eq, gt, gte, lt, lte } from './operators';
import { AST } from './ast';
diff --git a/src/components/series_chart/tooltip.js b/src/components/series_chart/tooltip.js
index 5414c83afdd..528b9b6edbc 100644
--- a/src/components/series_chart/tooltip.js
+++ b/src/components/series_chart/tooltip.js
@@ -1,5 +1,4 @@
import React from 'react';
-import _ from 'lodash';
import { Hint } from 'react-vis';
import PropTypes from 'prop-types';
// import {
@@ -69,7 +68,7 @@ import PropTypes from 'prop-types';
// ;
export default function Tooltip({ tooltipPoints, x, y, ...props }) {
- if (_.isEmpty(tooltipPoints)) {
+ if (tooltipPoints.length === 0) {
return null;
}
return ;
diff --git a/src/services/objects.ts b/src/services/objects.ts
index 62ba4fdbf5a..c36f4996d58 100644
--- a/src/services/objects.ts
+++ b/src/services/objects.ts
@@ -1 +1,4 @@
-export { get, omit } from 'lodash';
+import get from 'lodash/get';
+import omit from 'lodash/omit';
+
+export { get, omit };
diff --git a/src/services/predicate/lodash_predicates.ts b/src/services/predicate/lodash_predicates.ts
index 544cf9a7b2c..5e65c3149ee 100644
--- a/src/services/predicate/lodash_predicates.ts
+++ b/src/services/predicate/lodash_predicates.ts
@@ -1,8 +1,8 @@
-export {
- isFunction,
- isArray,
- isString,
- isBoolean,
- isNumber,
- isNaN,
-} from 'lodash';
+import isFunction from 'lodash/isFunction';
+import isArray from 'lodash/isArray';
+import isString from 'lodash/isString';
+import isBoolean from 'lodash/isBoolean';
+import isNumber from 'lodash/isNumber';
+import isNaN from 'lodash/isNaN';
+
+export { isFunction, isArray, isString, isBoolean, isNumber, isNaN };
diff --git a/src/services/utils.ts b/src/services/utils.ts
index 1f6db7ebbd3..90823fde200 100644
--- a/src/services/utils.ts
+++ b/src/services/utils.ts
@@ -1,4 +1,7 @@
-export { times, memoize } from 'lodash';
+import times from 'lodash/times';
+import memoize from 'lodash/memoize';
+
+export { times, memoize };
export const browserTick = (callback: FrameRequestCallback) => {
requestAnimationFrame(callback);
diff --git a/yarn.lock b/yarn.lock
index 483a8c33cc8..0fa64f3090b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -8307,11 +8307,6 @@ lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.5:
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==
-"lodash@npm:@elastic/lodash@3.10.1-kibana1":
- version "3.10.1-kibana1"
- resolved "https://registry.yarnpkg.com/@elastic/lodash/-/lodash-3.10.1-kibana1.tgz#9baa52c296ec06a52461f8516bb94172ef53a7fe"
- integrity sha512-JIL1V6Kd9mhm7OCO5nmpMF8hW2iw1godcXgBikhIlTvsu6hBA8Xnxfc/AukdysTfJo4zWaZ8PzlJX/hKN/DlDA==
-
log-symbols@^1.0.1, log-symbols@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18"