From 3e9f9efd383810d5fcb883e33915a1238048e090 Mon Sep 17 00:00:00 2001
From: Caroline Horn <549577+cchaos@users.noreply.github.com>
Date: Fri, 12 Jul 2019 12:14:55 -0400
Subject: [PATCH 01/20] [Feature branch] Updated form control border color
(#2114)
* Updated form control border color
* Slighly more transparent
* change sass var name to $euiFormBorderOpaqueColor
---
src/components/form/_mixins.scss | 4 ++--
src/components/form/_variables.scss | 5 +++--
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/components/form/_mixins.scss b/src/components/form/_mixins.scss
index b9d85ca47e4..be0bc3ba6ce 100644
--- a/src/components/form/_mixins.scss
+++ b/src/components/form/_mixins.scss
@@ -122,12 +122,12 @@
background-size: 100% 100%; /* 3 */
@if ($borderOnly) {
- box-shadow: inset 0 0 0 1px transparentize($euiColorFullShade, .84);
+ box-shadow: inset 0 0 0 1px $euiFormBorderColor;
} @else {
box-shadow:
0 1px 1px -1px transparentize($euiShadowColor, .8),
0 4px 4px -2px transparentize($euiShadowColor, .8),
- inset 0 0 0 1px transparentize($euiColorFullShade, .84);
+ inset 0 0 0 1px $euiFormBorderColor;
}
}
diff --git a/src/components/form/_variables.scss b/src/components/form/_variables.scss
index eae29dabd11..e42d4f02023 100644
--- a/src/components/form/_variables.scss
+++ b/src/components/form/_variables.scss
@@ -16,8 +16,9 @@ $euiSwitchIconHeight: $euiSize !default;
// Coloring
$euiFormBackgroundColor: tintOrShade($euiColorLightestShade, 60%, 40%) !default;
$euiFormBackgroundDisabledColor: darken($euiColorLightestShade, 2%) !default;
-$euiFormBorderColor: transparentize($euiColorFullShade, .9) !default;
-$euiFormBorderDisabledColor: transparentize($euiColorFullShade, .92) !default;
+$euiFormBorderOpaqueColor: shade(desaturate(adjust-hue($euiColorPrimary, 22), 22.95), 26%) !default;
+$euiFormBorderColor: transparentize($euiFormBorderOpaqueColor, .9) !default;
+$euiFormBorderDisabledColor: transparentize($euiFormBorderOpaqueColor, .9) !default;
$euiFormCustomControlDisabledIconColor: shadeOrTint($euiColorMediumShade, 38%, 48.5%) !default; // exact 508c foreground for $euiColorLightShade
$euiFormControlDisabledColor: $euiColorMediumShade !default;
$euiFormControlBoxShadow: 0 1px 1px -1px transparentize($euiShadowColor, .8), 0 3px 2px -2px transparentize($euiShadowColor, .8);
From 6ba098bbd3c3021d9d64aaa47e85705dc6e02bbd Mon Sep 17 00:00:00 2001
From: Caroline Horn <549577+cchaos@users.noreply.github.com>
Date: Tue, 23 Jul 2019 10:19:49 -0400
Subject: [PATCH 02/20] [Feature branch] Added EuiFormControlLayoutDelimited
component (#2117)
As a layout helper component to create date and number ranges
* Added Sass var for `$euiFormControlLayoutGroupInputHeight` and compressed version
---
.../form_control_layout_range.js | 137 ++++++++++++++++++
.../form_controls/form_controls_example.js | 45 ++++++
.../date_picker/_date_picker_range.scss | 3 +-
.../super_date_picker/_mixins.scss | 6 +-
src/components/form/_index.scss | 2 -
src/components/form/_mixins.scss | 7 +-
src/components/form/_variables.scss | 2 +-
...orm_control_layout_delimited.test.tsx.snap | 100 +++++++++++++
.../_form_control_layout.scss | 13 +-
.../_form_control_layout_range.scss | 56 +++++++
.../form/form_control_layout/_index.scss | 2 +
.../form/form_control_layout/_variables.scss | 8 +
.../form_control_layout.tsx | 54 +------
.../form_control_layout_delimited.test.tsx | 52 +++++++
.../form_control_layout_delimited.tsx | 56 +++++++
.../form/form_control_layout/index.ts | 2 +
src/components/form/index.js | 5 +-
src/components/form/select/_select.scss | 4 +-
src/components/index.js | 1 +
19 files changed, 494 insertions(+), 61 deletions(-)
create mode 100644 src-docs/src/views/form_controls/form_control_layout_range.js
create mode 100644 src/components/form/form_control_layout/__snapshots__/form_control_layout_delimited.test.tsx.snap
create mode 100644 src/components/form/form_control_layout/_form_control_layout_range.scss
create mode 100644 src/components/form/form_control_layout/_variables.scss
create mode 100644 src/components/form/form_control_layout/form_control_layout_delimited.test.tsx
create mode 100644 src/components/form/form_control_layout/form_control_layout_delimited.tsx
diff --git a/src-docs/src/views/form_controls/form_control_layout_range.js b/src-docs/src/views/form_controls/form_control_layout_range.js
new file mode 100644
index 00000000000..a11d465fc05
--- /dev/null
+++ b/src-docs/src/views/form_controls/form_control_layout_range.js
@@ -0,0 +1,137 @@
+import React, { Fragment } from 'react';
+
+import {
+ EuiFormControlLayoutDelimited,
+ EuiSpacer,
+ EuiFormLabel,
+ EuiIcon,
+} from '../../../../src/components';
+
+export default () => (
+
+
+ }
+ endControl={
+
+ }
+ />
+
+
+ px}
+ startControl={
+
+ }
+ endControl={
+
+ }
+ />
+
+
+
+ }
+ endControl={
+
+ }
+ />
+
+
+ {} }}
+ isLoading
+ startControl={
+
+ }
+ endControl={
+
+ }
+ />
+
+
+
+ }
+ endControl={
+
+ }
+ />
+
+
+
+ }
+ endControl={
+
+ }
+ />
+
+
+
+ }
+ endControl={
+
+ }
+ />
+
+
+
+ Add}
+ startControl={
+
+ }
+ delimiter="+"
+ endControl={
+
+ }
+ />
+
+
+
+ Merge}
+ startControl={
+
+ }
+ delimiter={ }
+ endControl={
+
+ }
+ />
+
+
+
+ Read only}
+ startControl={
+
+ }
+ endControl={
+
+ }
+ />
+
+);
diff --git a/src-docs/src/views/form_controls/form_controls_example.js b/src-docs/src/views/form_controls/form_controls_example.js
index 7fcdb3d04f0..9d186929cd1 100644
--- a/src-docs/src/views/form_controls/form_controls_example.js
+++ b/src-docs/src/views/form_controls/form_controls_example.js
@@ -18,6 +18,7 @@ import {
EuiFieldText,
EuiFilePicker,
EuiFormControlLayout,
+ EuiFormControlLayoutDelimited,
EuiLink,
EuiRadio,
EuiRadioGroup,
@@ -78,6 +79,10 @@ import FormControlLayout from './form_control_layout';
const formControlLayoutSource = require('!!raw-loader!./form_control_layout');
const formControlLayoutHtml = renderToHtml(FormControlLayout);
+import FormControlLayoutRange from './form_control_layout_range';
+const formControlLayoutRangeSource = require('!!raw-loader!./form_control_layout_range');
+const formControlLayoutRangeHtml = renderToHtml(FormControlLayoutRange);
+
export const FormControlsExample = {
title: 'Form controls',
sections: [
@@ -351,5 +356,45 @@ export const FormControlsExample = {
},
demo: ,
},
+ {
+ title: 'Form control layout delimited',
+ source: [
+ {
+ type: GuideSectionTypes.JS,
+ code: formControlLayoutRangeSource,
+ },
+ {
+ type: GuideSectionTypes.HTML,
+ code: formControlLayoutRangeHtml,
+ },
+ ],
+ text: (
+
+
+ Building block only
+
+
+
+ Like EuiFormControlLayout ,{' '}
+ EuiFormControlLayoutDelimited is generally used
+ internally to consistently style form controls. This component
+ specifically lays out two form controls with center text or icon.
+
+
+ It takes all of the same props as{' '}
+ EuiFormControlLayout except for{' '}
+ children . Instead it requires both a{' '}
+ single startControl and a{' '}
+ single endControl . You can
+ optionally change the center content to a different string or node
+ (like an EuiIcon).
+
+
+ ),
+ props: {
+ EuiFormControlLayoutDelimited,
+ },
+ demo: ,
+ },
],
};
diff --git a/src/components/date_picker/_date_picker_range.scss b/src/components/date_picker/_date_picker_range.scss
index 583562cd5a3..cedeb5772b4 100644
--- a/src/components/date_picker/_date_picker_range.scss
+++ b/src/components/date_picker/_date_picker_range.scss
@@ -1,5 +1,6 @@
@import '../form/variables';
@import '../form/mixins';
+@import '../form/form_control_layout/variables';
/**
* 1. Account for inner box-shadow style border
@@ -34,7 +35,7 @@
padding: 0;
.euiDatePicker {
- height: $euiFormControlHeight - 2px;
+ height: $euiFormControlLayoutGroupInputHeight;
}
}
diff --git a/src/components/date_picker/super_date_picker/_mixins.scss b/src/components/date_picker/super_date_picker/_mixins.scss
index 02db2c4fd55..4f5a7a5e23a 100644
--- a/src/components/date_picker/super_date_picker/_mixins.scss
+++ b/src/components/date_picker/super_date_picker/_mixins.scss
@@ -1,10 +1,12 @@
+@import '../../form/form_control_layout/variables';
+
@mixin euiSuperDatePickerText {
@include euiFormControlText;
display: block;
width: 100%;
padding: 0 $euiSizeS;
- line-height: $euiFormControlHeight - 2px;
- height: $euiFormControlHeight - 2px;
+ line-height: $euiFormControlLayoutGroupInputHeight;
+ height: $euiFormControlLayoutGroupInputHeight;
word-break: break-all;
transition: background $euiAnimSpeedFast ease-in;
}
diff --git a/src/components/form/_index.scss b/src/components/form/_index.scss
index 689fdbb54a3..e8f451f6b3f 100644
--- a/src/components/form/_index.scss
+++ b/src/components/form/_index.scss
@@ -1,5 +1,3 @@
-@import 'form_control_layout/mixins';
-
@import 'variables';
@import 'mixins';
diff --git a/src/components/form/_mixins.scss b/src/components/form/_mixins.scss
index be0bc3ba6ce..2247c481e1e 100644
--- a/src/components/form/_mixins.scss
+++ b/src/components/form/_mixins.scss
@@ -1,3 +1,6 @@
+@import 'variables';
+@import 'form_control_layout/variables';
+
@mixin euiPlaceholderPerBrowser {
// sass-lint:disable-block no-vendor-prefixes
// Each prefix must be its own content block
@@ -54,11 +57,11 @@
}
&--inGroup:not(:read-only) {
- height: $euiFormControlHeight - 2px; /* 2 */
+ height: $euiFormControlLayoutGroupInputHeight; /* 2 */
}
&--inGroup#{&}--compressed:not(:read-only) {
- height: $euiFormControlCompressedHeight - 2px; /* 2 */
+ height: $euiFormControlLayoutGroupInputCompressedHeight; /* 2 */
}
}
}
diff --git a/src/components/form/_variables.scss b/src/components/form/_variables.scss
index e42d4f02023..f192c28b9e6 100644
--- a/src/components/form/_variables.scss
+++ b/src/components/form/_variables.scss
@@ -16,7 +16,7 @@ $euiSwitchIconHeight: $euiSize !default;
// Coloring
$euiFormBackgroundColor: tintOrShade($euiColorLightestShade, 60%, 40%) !default;
$euiFormBackgroundDisabledColor: darken($euiColorLightestShade, 2%) !default;
-$euiFormBorderOpaqueColor: shade(desaturate(adjust-hue($euiColorPrimary, 22), 22.95), 26%) !default;
+$euiFormBorderOpaqueColor: shadeOrTint(desaturate(adjust-hue($euiColorPrimary, 22), 22.95), 26%, 60%) !default;
$euiFormBorderColor: transparentize($euiFormBorderOpaqueColor, .9) !default;
$euiFormBorderDisabledColor: transparentize($euiFormBorderOpaqueColor, .9) !default;
$euiFormCustomControlDisabledIconColor: shadeOrTint($euiColorMediumShade, 38%, 48.5%) !default; // exact 508c foreground for $euiColorLightShade
diff --git a/src/components/form/form_control_layout/__snapshots__/form_control_layout_delimited.test.tsx.snap b/src/components/form/form_control_layout/__snapshots__/form_control_layout_delimited.test.tsx.snap
new file mode 100644
index 00000000000..e42a39191cb
--- /dev/null
+++ b/src/components/form/form_control_layout/__snapshots__/form_control_layout_delimited.test.tsx.snap
@@ -0,0 +1,100 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`EuiFormControlLayoutDelimited is rendered 1`] = `
+
+`;
+
+exports[`EuiFormControlLayoutDelimited props delimiter is rendered as a node 1`] = `
+
+`;
+
+exports[`EuiFormControlLayoutDelimited props delimiter is rendered as a string 1`] = `
+
+`;
diff --git a/src/components/form/form_control_layout/_form_control_layout.scss b/src/components/form/form_control_layout/_form_control_layout.scss
index 6910a59c6c8..12cfbafe776 100644
--- a/src/components/form/form_control_layout/_form_control_layout.scss
+++ b/src/components/form/form_control_layout/_form_control_layout.scss
@@ -28,7 +28,7 @@
.euiFormControlLayout__prepend,
.euiFormControlLayout__append {
flex-shrink: 0;
- height: $euiFormControlHeight - 2px; /* 1 */
+ height: $euiFormControlLayoutGroupInputHeight;
line-height: $euiFontSize;
border: none; // remove any border in case it exists
@@ -66,7 +66,7 @@
&.euiFormControlLayout--compressed {
.euiFormControlLayout__prepend,
.euiFormControlLayout__append {
- height: $euiFormControlCompressedHeight - 2px; /* 1 */
+ height: $euiFormControlLayoutGroupInputCompressedHeight;
&.euiFormLabel,
&.euiText {
@@ -76,12 +76,19 @@
}
}
+ > .euiFormControlLayout--compressed {
+ height: $euiFormControlLayoutGroupInputCompressedHeight;
+ }
+
//
// ReadOnly alterations
&.euiFormControlLayout--readOnly {
@include euiFormControlReadOnlyStyle;
padding: 0; /* 1 */
- background-color: transparent; // Ensures the input and layout don't double up on background color
+
+ input {
+ background-color: transparent; // Ensures the input and layout don't double up on background color
+ }
.euiFormControlLayout__prepend,
.euiFormControlLayout__append {
diff --git a/src/components/form/form_control_layout/_form_control_layout_range.scss b/src/components/form/form_control_layout/_form_control_layout_range.scss
new file mode 100644
index 00000000000..81c7af082c3
--- /dev/null
+++ b/src/components/form/form_control_layout/_form_control_layout_range.scss
@@ -0,0 +1,56 @@
+.euiFormControlLayoutDelimited {
+ // Match just the regular drop shadow of inputs
+ @include euiFormControlDefaultShadow;
+ padding: 1px; /* 1 */
+
+ > .euiFormControlLayout__childrenWrapper {
+ display: flex;
+ align-items: center;
+ }
+
+ input {
+ height: $euiFormControlLayoutGroupInputHeight;
+ }
+
+ &[class*='--compressed'] input {
+ height: $euiFormControlLayoutGroupInputCompressedHeight;
+ padding-top: 0; // Fixes IE
+ padding-bottom: 0; // Fixes IE
+ }
+
+ &[class*='--fullWidth'] input {
+ max-width: none;
+ }
+
+ .euiFormControlLayoutIcons {
+ // Absolutely positioning the icons doesn't work because they
+ // overlay only one of controls making the layout unbalanced
+ position: static; // Overrider absolute
+ padding-left: $euiFormControlPadding;
+ padding-right: $euiFormControlPadding;
+ flex-shrink: 0; // Fixes IE
+
+ &:not(.euiFormControlLayoutIcons--right) {
+ order: -1;
+ }
+ }
+}
+
+.euiFormControlLayoutDelimited__child--noStyle {
+ // sass-lint:disable-block no-important
+ box-shadow: none !important;
+ border-radius: 0 !important;
+}
+
+.euiFormControlLayoutDelimited__child--centered {
+ text-align: center;
+}
+
+.euiFormControlLayoutDelimited__delimeter {
+ // sass-lint:disable-block no-important
+ // Override EuiText line-height
+ line-height: 1 !important;
+ flex: 0 0 auto;
+ padding-left: $euiFormControlPadding / 2;
+ padding-right: $euiFormControlPadding / 2;
+}
diff --git a/src/components/form/form_control_layout/_index.scss b/src/components/form/form_control_layout/_index.scss
index f5a9b5d33bc..d14b350f0ef 100644
--- a/src/components/form/form_control_layout/_index.scss
+++ b/src/components/form/form_control_layout/_index.scss
@@ -1,5 +1,7 @@
+@import 'variables';
@import 'mixins';
@import 'form_control_layout';
+@import 'form_control_layout_range';
@import 'form_control_layout_icons';
@import 'form_control_layout_clear_button';
@import 'form_control_layout_custom_icon';
diff --git a/src/components/form/form_control_layout/_variables.scss b/src/components/form/form_control_layout/_variables.scss
new file mode 100644
index 00000000000..8e04c7aeba1
--- /dev/null
+++ b/src/components/form/form_control_layout/_variables.scss
@@ -0,0 +1,8 @@
+@import '../variables';
+
+/**
+ * 1. Account for inner box-shadow style border
+ */
+
+$euiFormControlLayoutGroupInputHeight: $euiFormControlHeight - 2px; /* 1 */
+$euiFormControlLayoutGroupInputCompressedHeight: $euiFormControlCompressedHeight - 2px; /* 1 */
diff --git a/src/components/form/form_control_layout/form_control_layout.tsx b/src/components/form/form_control_layout/form_control_layout.tsx
index aaf51f8fa70..b0198868c9a 100644
--- a/src/components/form/form_control_layout/form_control_layout.tsx
+++ b/src/components/form/form_control_layout/form_control_layout.tsx
@@ -17,28 +17,8 @@ export { ICON_SIDES } from './form_control_layout_icons';
type ReactElements = ReactElement | ReactElement[];
-// if `prepend` and/or `append` is specified then `children` must be undefined or a single ReactElement
-interface AppendWithChildren {
- append: ReactElements;
- children?: ReactElement;
-}
-interface PrependWithChildren {
- prepend: ReactElements;
- children?: ReactElement;
-}
-type SiblingsWithChildren = AppendWithChildren | PrependWithChildren;
-
-type ChildrenOptions =
- | SiblingsWithChildren
- | {
- append?: undefined | null;
- prepend?: undefined | null;
- children?: ReactNode;
- };
-
type EuiFormControlLayoutProps = CommonProps &
- HTMLAttributes &
- ChildrenOptions & {
+ HTMLAttributes & {
/**
* Creates an input group with element(s) coming before children
*/
@@ -47,6 +27,7 @@ type EuiFormControlLayoutProps = CommonProps &
* Creates an input group with element(s) coming after children
*/
append?: ReactElements;
+ children?: ReactNode;
icon?: EuiFormControlLayoutIconsProps['icon'];
clear?: EuiFormControlLayoutIconsProps['clear'];
fullWidth?: boolean;
@@ -57,14 +38,6 @@ type EuiFormControlLayoutProps = CommonProps &
readOnly?: boolean;
};
-function isChildrenIsReactElement(
- append: EuiFormControlLayoutProps['append'],
- prepend: EuiFormControlLayoutProps['prepend'],
- children: EuiFormControlLayoutProps['children']
-): children is ReactElement {
- return (!!append || !!prepend) && children != null;
-}
-
export class EuiFormControlLayout extends Component {
render() {
const {
@@ -94,23 +67,14 @@ export class EuiFormControlLayout extends Component {
className
);
- const prependNodes = this.renderPrepends();
- const appendNodes = this.renderAppends();
-
- let clonedChildren;
- if (isChildrenIsReactElement(append, prepend, children)) {
- clonedChildren = cloneElement(children, {
- className: `${
- children.props.className
- } euiFormControlLayout__child--noStyle`,
- });
- }
+ const prependNodes = this.renderPrepends(prepend);
+ const appendNodes = this.renderAppends(append);
return (
{prependNodes}
- {clonedChildren || children}
+ {children}
{
);
}
- renderPrepends() {
- const { prepend } = this.props;
-
+ renderPrepends(prepend: ReactElements | undefined | null) {
if (!prepend) {
return;
}
@@ -137,9 +99,7 @@ export class EuiFormControlLayout extends Component {
return prependNodes;
}
- renderAppends() {
- const { append } = this.props;
-
+ renderAppends(append: ReactElements | undefined | null) {
if (!append) {
return;
}
diff --git a/src/components/form/form_control_layout/form_control_layout_delimited.test.tsx b/src/components/form/form_control_layout/form_control_layout_delimited.test.tsx
new file mode 100644
index 00000000000..22dce0c5498
--- /dev/null
+++ b/src/components/form/form_control_layout/form_control_layout_delimited.test.tsx
@@ -0,0 +1,52 @@
+import React from 'react';
+import { render } from 'enzyme';
+import { requiredProps } from '../../../test/required_props';
+
+import { EuiFormControlLayoutDelimited } from './form_control_layout_delimited';
+import { EuiIcon } from '../../icon';
+
+describe('EuiFormControlLayoutDelimited', () => {
+ test('is rendered', () => {
+ const component = render(
+ start}
+ endControl={end }
+ {...requiredProps}
+ />
+ );
+
+ expect(component).toMatchSnapshot();
+ });
+
+ describe('props', () => {
+ describe('delimiter', () => {
+ describe('is rendered', () => {
+ test('as a string', () => {
+ const component = render(
+ start}
+ endControl={end }
+ delimiter="+"
+ />
+ );
+
+ expect(component).toMatchSnapshot();
+ });
+
+ test('as a node', () => {
+ const icon = ;
+
+ const component = render(
+ start}
+ endControl={end }
+ delimiter={icon}
+ />
+ );
+
+ expect(component).toMatchSnapshot();
+ });
+ });
+ });
+ });
+});
diff --git a/src/components/form/form_control_layout/form_control_layout_delimited.tsx b/src/components/form/form_control_layout/form_control_layout_delimited.tsx
new file mode 100644
index 00000000000..56f3b34481a
--- /dev/null
+++ b/src/components/form/form_control_layout/form_control_layout_delimited.tsx
@@ -0,0 +1,56 @@
+import React, {
+ FunctionComponent,
+ ReactElement,
+ cloneElement,
+ ReactNode,
+} from 'react';
+import classNames from 'classnames';
+
+import { EuiText } from '../../text';
+import { EuiFormControlLayout } from './form_control_layout';
+
+type EuiFormControlLayoutDelimitedProps = Partial & {
+ /**
+ * Left side control
+ */
+ startControl: ReactElement;
+ /**
+ * Right side control
+ */
+ endControl: ReactElement;
+ /**
+ * The center content. Accepts a string to be wrapped in a subdued EuiText
+ * or a single ReactElement
+ */
+ delimiter?: ReactNode;
+ className?: string;
+};
+
+export const EuiFormControlLayoutDelimited: FunctionComponent<
+ EuiFormControlLayoutDelimitedProps
+> = ({ startControl, endControl, delimiter = '→', className, ...rest }) => {
+ const classes = classNames('euiFormControlLayoutDelimited', className);
+
+ return (
+
+ {addClassesToControl(startControl)}
+
+ {delimiter}
+
+ {addClassesToControl(endControl)}
+
+ );
+};
+
+function addClassesToControl(control: ReactElement) {
+ return cloneElement(control, {
+ className: classNames(
+ control.props.className,
+ 'euiFormControlLayoutDelimited__child--noStyle',
+ 'euiFormControlLayoutDelimited__child--centered'
+ ),
+ });
+}
diff --git a/src/components/form/form_control_layout/index.ts b/src/components/form/form_control_layout/index.ts
index 79e0774a1f0..0f16df04588 100644
--- a/src/components/form/form_control_layout/index.ts
+++ b/src/components/form/form_control_layout/index.ts
@@ -5,3 +5,5 @@ export {
export {
EuiFormControlLayoutCustomIcon,
} from './form_control_layout_custom_icon';
+
+export { EuiFormControlLayoutDelimited } from './form_control_layout_delimited';
diff --git a/src/components/form/index.js b/src/components/form/index.js
index 75310f40940..0c0d51a554b 100644
--- a/src/components/form/index.js
+++ b/src/components/form/index.js
@@ -6,7 +6,10 @@ export { EuiFieldSearch } from './field_search';
export { EuiFieldText } from './field_text';
export { EuiFilePicker } from './file_picker';
export { EuiForm } from './form';
-export { EuiFormControlLayout } from './form_control_layout';
+export {
+ EuiFormControlLayout,
+ EuiFormControlLayoutDelimited,
+} from './form_control_layout';
export { EuiFormErrorText } from './form_error_text';
export { EuiFormHelpText } from './form_help_text';
export { EuiFormLabel } from './form_label';
diff --git a/src/components/form/select/_select.scss b/src/components/form/select/_select.scss
index 9dc5e60b1a8..93e2f795623 100644
--- a/src/components/form/select/_select.scss
+++ b/src/components/form/select/_select.scss
@@ -20,11 +20,11 @@
}
&--inGroup {
- line-height: $euiFormControlHeight - 2px; /* 2 */
+ line-height: $euiFormControlLayoutGroupInputHeight; /* 2 */
}
&--inGroup#{&}--compressed {
- line-height: $euiFormControlCompressedHeight - 2px; /* 2 */
+ line-height: $euiFormControlLayoutGroupInputCompressedHeight; /* 2 */
}
// Turn off linter for some MS specific bits.
diff --git a/src/components/index.js b/src/components/index.js
index 8b66e302984..85a5dd2ac8f 100644
--- a/src/components/index.js
+++ b/src/components/index.js
@@ -106,6 +106,7 @@ export {
EuiFilePicker,
EuiForm,
EuiFormControlLayout,
+ EuiFormControlLayoutDelimited,
EuiFormErrorText,
EuiFormHelpText,
EuiFormLabel,
From 9280bedde29cee2b3547b46cee61ecb1ea2c817d Mon Sep 17 00:00:00 2001
From: Caroline Horn <549577+cchaos@users.noreply.github.com>
Date: Thu, 25 Jul 2019 10:11:28 -0400
Subject: [PATCH 03/20] [Feature branch] Compressed EuiSuperSelect dropdown
(#2155)
- Added truncation example
- Added max-height
---
src-docs/src/views/super_select/super_select.js | 7 +++++--
.../views/super_select/super_select_complex.js | 5 +----
.../context_menu/_context_menu_item.scss | 1 +
.../form/super_select/_super_select.scss | 16 +++++++++++++++-
src/components/form/super_select/super_select.js | 5 ++++-
.../form/super_select/super_select.test.js | 13 +++++++++++++
6 files changed, 39 insertions(+), 8 deletions(-)
diff --git a/src-docs/src/views/super_select/super_select.js b/src-docs/src/views/super_select/super_select.js
index d6414d6d76f..b356b870072 100644
--- a/src-docs/src/views/super_select/super_select.js
+++ b/src-docs/src/views/super_select/super_select.js
@@ -19,8 +19,11 @@ export default class extends Component {
},
{
value: 'option_three',
- inputDisplay:
- 'Option three has a super long text to see if it will truncate or what',
+ inputDisplay: (
+
+ Option three has a super long text and added truncation
+
+ ),
},
];
diff --git a/src-docs/src/views/super_select/super_select_complex.js b/src-docs/src/views/super_select/super_select_complex.js
index 881d42842a5..fc44e4bef25 100644
--- a/src-docs/src/views/super_select/super_select_complex.js
+++ b/src-docs/src/views/super_select/super_select_complex.js
@@ -1,6 +1,6 @@
import React, { Component, Fragment } from 'react';
-import { EuiSuperSelect, EuiSpacer, EuiText } from '../../../../src/components';
+import { EuiSuperSelect, EuiText } from '../../../../src/components';
export default class extends Component {
constructor(props) {
@@ -13,7 +13,6 @@ export default class extends Component {
dropdownDisplay: (
Option one
-
Has a short description giving more detail to the option.
@@ -28,7 +27,6 @@ export default class extends Component {
dropdownDisplay: (
Option two
-
Has a short description giving more detail to the option.
@@ -43,7 +41,6 @@ export default class extends Component {
dropdownDisplay: (
Option three
-
Has a short description giving more detail to the option.
diff --git a/src/components/context_menu/_context_menu_item.scss b/src/components/context_menu/_context_menu_item.scss
index c3c2dfc9f04..8675f1429cb 100644
--- a/src/components/context_menu/_context_menu_item.scss
+++ b/src/components/context_menu/_context_menu_item.scss
@@ -31,6 +31,7 @@
.euiContextMenuItem__text {
flex-grow: 1;
+ overflow: hidden; // allows for text truncation
}
.euiContextMenuItem__arrow {
diff --git a/src/components/form/super_select/_super_select.scss b/src/components/form/super_select/_super_select.scss
index cfae17820d0..19e9f4212fb 100644
--- a/src/components/form/super_select/_super_select.scss
+++ b/src/components/form/super_select/_super_select.scss
@@ -11,6 +11,13 @@
}
}
+.euiSuperSelect__listbox {
+ @include euiScrollBar;
+ max-height: 300px;
+ overflow: hidden;
+ overflow-y: auto;
+}
+
.euiSuperSelect__popoverPanel[class*='bottom'] { /* 3 */
border-top-color: transparentize($euiBorderColor, .2);
border-top-right-radius: 0; /* 2 */
@@ -26,11 +33,18 @@
}
.euiSuperSelect__item {
- &:hover,
+ @include euiFontSizeS;
+ padding: $euiSizeS;
+
+ &:hover:not(:disabled),
&:focus {
text-decoration: none;
background-color: $euiFocusBackgroundColor;
}
+
+ &:disabled {
+ cursor: not-allowed;
+ }
}
.euiSuperSelect__item--hasDividers:not(:last-of-type) {
diff --git a/src/components/form/super_select/super_select.js b/src/components/form/super_select/super_select.js
index 67c4b386cac..19ebab80986 100644
--- a/src/components/form/super_select/super_select.js
+++ b/src/components/form/super_select/super_select.js
@@ -165,6 +165,7 @@ export class EuiSuperSelect extends Component {
itemLayoutAlign,
fullWidth,
popoverClassName,
+ compressed,
...rest
} = this.props;
@@ -206,6 +207,7 @@ export class EuiSuperSelect extends Component {
className={buttonClasses}
fullWidth={fullWidth}
isInvalid={isInvalid}
+ compressed={compressed}
{...rest}
/>
);
@@ -222,7 +224,6 @@ export class EuiSuperSelect extends Component {
onKeyDown={this.onItemKeyDown}
layoutAlign={itemLayoutAlign}
buttonRef={node => this.setItemNode(node, index)}
- style={{ width: this.state.menuWidth }}
role="option"
id={value}
aria-selected={valueOfSelected === value}
@@ -256,8 +257,10 @@ export class EuiSuperSelect extends Component {
{items}
diff --git a/src/components/form/super_select/super_select.test.js b/src/components/form/super_select/super_select.test.js
index 7023fa6c7f6..20702df0380 100644
--- a/src/components/form/super_select/super_select.test.js
+++ b/src/components/form/super_select/super_select.test.js
@@ -42,6 +42,19 @@ describe('EuiSuperSelect', () => {
expect(component).toMatchSnapshot();
});
+ test('compressed is rendered', () => {
+ const component = render(
+ {}}
+ compressed
+ />
+ );
+
+ expect(component).toMatchSnapshot();
+ });
+
test('select component is rendered', () => {
const component = render(
Date: Tue, 30 Jul 2019 13:38:11 -0400
Subject: [PATCH 04/20] [Feature Branch] Update compressed form control styles
(#2174)
* Updated compressed visual style in mixin
* Compressed updates to from control groups
* Fix compressed state overrides
* Reduce horizontal padding for compressed
* Icons and button icons in input groups
* Added a compressed option for from` euiFormControlLayoutPadding`
* Added compressed padding for inputs with icons
* Fix readonly & compressed input groups
* Fix group heights
* Update file picker with new compressed styles
* Fix delimited compressed and fullwidth styles
* Fixed EuiComboBox
* Added reduced padding for EuiColorPicker
* Fixed date pickers
* Variables for border-radius
---
.../__snapshots__/color_picker.test.js.snap | 16 ++--
.../color_picker/_color_picker.scss | 15 ++++
src/components/color_picker/color_picker.js | 1 +
src/components/combo_box/_combo_box.scss | 9 ++-
.../combo_box_input/_combo_box_pill.scss | 18 ++++-
src/components/date_picker/_date_picker.scss | 4 +
.../quick_select_popover.test.js.snap | 2 +
.../_quick_select_popover.scss | 4 +
.../quick_select_popover.js | 1 +
src/components/form/_mixins.scss | 50 +++++++++----
src/components/form/_variables.scss | 5 +-
.../form/field_number/_field_number.scss | 4 +
.../form/field_password/_field_password.scss | 4 +
.../form/field_search/_field_search.scss | 4 +
.../form/field_text/_field_text.scss | 4 +
.../form/file_picker/_file_picker.scss | 33 ++++----
.../form/file_picker/file_picker.js | 10 +--
...orm_control_layout_delimited.test.tsx.snap | 12 +--
.../_form_control_layout.scss | 75 +++++++++++++++----
...ss => _form_control_layout_delimited.scss} | 48 +++++++++---
.../_form_control_layout_icons.scss | 9 +++
.../form/form_control_layout/_index.scss | 2 +-
.../form/form_control_layout/_mixins.scss | 18 +++--
.../form/form_control_layout/_variables.scss | 1 +
.../form_control_layout_delimited.tsx | 3 +-
src/components/form/select/_select.scss | 1 +
.../super_select/_super_select_control.scss | 1 +
27 files changed, 261 insertions(+), 93 deletions(-)
rename src/components/form/form_control_layout/{_form_control_layout_range.scss => _form_control_layout_delimited.scss} (50%)
diff --git a/src/components/color_picker/__snapshots__/color_picker.test.js.snap b/src/components/color_picker/__snapshots__/color_picker.test.js.snap
index 9156adca9ac..2c1ee677c44 100644
--- a/src/components/color_picker/__snapshots__/color_picker.test.js.snap
+++ b/src/components/color_picker/__snapshots__/color_picker.test.js.snap
@@ -25,7 +25,7 @@ exports[`renders EuiColorPicker 1`] = `
{([openLabel, closeLabel]) => (
input {
@@ -73,6 +73,10 @@
&.euiComboBox-isOpen {
.euiComboBox__inputWrap {
@include euiFormControlFocusStyle;
+
+ &--compressed {
+ @include euiFormControlFocusStyle($borderOnly: true);
+ }
}
}
@@ -90,6 +94,7 @@
&.euiComboBox--compressed {
.euiComboBox__inputWrap {
+ // height: $euiFormControlCompressedHeight; /* 2 */
line-height: $euiFormControlCompressedHeight; /* 2 */
padding-top: 0;
padding-bottom: 0;
diff --git a/src/components/combo_box/combo_box_input/_combo_box_pill.scss b/src/components/combo_box/combo_box_input/_combo_box_pill.scss
index b45de89e028..76885f306de 100644
--- a/src/components/combo_box/combo_box_input/_combo_box_pill.scss
+++ b/src/components/combo_box/combo_box_input/_combo_box_pill.scss
@@ -1,10 +1,22 @@
-// Overwrites the base styling of EuiBadge, to give it a larger size and margins
-// that make sense in the input wrap.
+/*
+ * 1. Overwrites the base styling of EuiBadge, to give it a larger size and margins
+ * that make sense in the input wrap.
+ */
.euiComboBoxPill {
- margin: $euiSizeXS !important; // sass-lint:disable-line no-important
+ height: $euiSizeL - 2px;
line-height: $euiSizeL - 2px;
vertical-align: baseline;
+ &,
+ & + & /* 1 */ {
+ margin: $euiSizeXS;
+ }
+
+ .euiComboBox--compressed &,
+ .euiComboBox--compressed & + & /* 1 */ {
+ margin: $euiSizeXS $euiSizeXS 0 0;
+ }
+
&--plainText {
@include euiFont;
@include euiTextTruncate;
diff --git a/src/components/date_picker/_date_picker.scss b/src/components/date_picker/_date_picker.scss
index e5e693ff171..b4ef09779af 100644
--- a/src/components/date_picker/_date_picker.scss
+++ b/src/components/date_picker/_date_picker.scss
@@ -28,6 +28,10 @@
// This is mostly here so that we can provide an inline version that doesn't have the
// shadows and depth.
.euiDatePicker {
+ .euiFormControlLayout {
+ height: auto;
+ }
+
&.euiDatePicker--shadow {
.react-datepicker-popper {
@include euiBottomShadowMedium;
diff --git a/src/components/date_picker/super_date_picker/quick_select_popover/__snapshots__/quick_select_popover.test.js.snap b/src/components/date_picker/super_date_picker/quick_select_popover/__snapshots__/quick_select_popover.test.js.snap
index a9a9fd442a9..aa037a3d983 100644
--- a/src/components/date_picker/super_date_picker/quick_select_popover/__snapshots__/quick_select_popover.test.js.snap
+++ b/src/components/date_picker/super_date_picker/quick_select_popover/__snapshots__/quick_select_popover.test.js.snap
@@ -2,6 +2,7 @@
exports[`EuiQuickSelectPopover is rendered 1`] = `
start
@@ -24,7 +24,7 @@ exports[`EuiFormControlLayoutDelimited is rendered 1`] = `
end
@@ -40,7 +40,7 @@ exports[`EuiFormControlLayoutDelimited props delimiter is rendered as a node 1`]
class="euiFormControlLayout__childrenWrapper"
>
start
@@ -61,7 +61,7 @@ exports[`EuiFormControlLayoutDelimited props delimiter is rendered as a node 1`]
end
@@ -77,7 +77,7 @@ exports[`EuiFormControlLayoutDelimited props delimiter is rendered as a string 1
class="euiFormControlLayout__childrenWrapper"
>
start
@@ -91,7 +91,7 @@ exports[`EuiFormControlLayoutDelimited props delimiter is rendered as a string 1
end
diff --git a/src/components/form/form_control_layout/_form_control_layout.scss b/src/components/form/form_control_layout/_form_control_layout.scss
index 12cfbafe776..db4b0a93d0f 100644
--- a/src/components/form/form_control_layout/_form_control_layout.scss
+++ b/src/components/form/form_control_layout/_form_control_layout.scss
@@ -3,7 +3,7 @@
.euiFormControlLayout {
// Let the height expand as needed
- @include euiFormControlSize(auto, $includeAlternates: true);
+ @include euiFormControlSize($includeAlternates: true);
}
.euiFormControlLayout__childrenWrapper {
@@ -18,7 +18,7 @@
// Match just the regular drop shadow of inputs
@include euiFormControlDefaultShadow;
display: flex;
- align-items: center;
+ align-items: stretch;
padding: 1px; /* 1 */
.euiFormControlLayout__childrenWrapper {
@@ -28,25 +28,61 @@
.euiFormControlLayout__prepend,
.euiFormControlLayout__append {
flex-shrink: 0;
- height: $euiFormControlLayoutGroupInputHeight;
- line-height: $euiFontSize;
+ height: 100%;
+ line-height: $euiFontSize - 1px; // The 1px less aligns the icons better
border: none; // remove any border in case it exists
+ border-radius: 0;
+
+ &:first-child {
+ border-top-left-radius: $euiFormControlLayoutGroupInputCompressedBorderRadius;
+ border-bottom-left-radius: $euiFormControlLayoutGroupInputCompressedBorderRadius;
+ }
+
+ &:last-child {
+ border-top-right-radius: $euiFormControlLayoutGroupInputCompressedBorderRadius;
+ border-bottom-right-radius: $euiFormControlLayoutGroupInputCompressedBorderRadius;
+ }
&:disabled {
background-color: $euiFormBackgroundDisabledColor;
color: $euiFormControlDisabledColor; // ensures established contrast
}
+ // sass-lint:disable-block no-important
// This is the only way to target specific components to override styling
+ &.euiFormLabel,
+ &.euiText,
+ &.euiButtonIcon,
+ &.euiIcon {
+ background-color: $euiFormInputGroupLabelBackground;
+
+ & + .euiFormControlLayout__prepend,
+ & + .euiFormControlLayout__append {
+ padding-left: 0 !important;
+
+ &.euiButtonIcon,
+ &.euiIcon {
+ width: $euiSizeL;
+ }
+ }
+ }
+
&.euiFormLabel,
&.euiText {
white-space: nowrap;
margin-bottom: 0;
padding: $euiFormControlPadding;
border: none;
- background-color: $euiFormInputGroupLabelBackground;
line-height: $euiFontSize;
}
+
+ &.euiButtonIcon,
+ &.euiIcon {
+ padding: 0 $euiSizeS;
+ width: $euiSizeXL;
+ border: none;
+ transform: none !important;
+ }
}
//
@@ -64,22 +100,28 @@
// Compressed alterations
&.euiFormControlLayout--compressed {
+ @include euiFormControlDefaultShadow($borderOnly: true);
+ border-radius: $euiBorderRadius / 2;
+
.euiFormControlLayout__prepend,
.euiFormControlLayout__append {
- height: $euiFormControlLayoutGroupInputCompressedHeight;
+ &:first-child {
+ border-top-left-radius: $euiFormControlLayoutGroupInputCompressedBorderRadius;
+ border-bottom-left-radius: $euiFormControlLayoutGroupInputCompressedBorderRadius;
+ }
+
+ &:last-child {
+ border-top-right-radius: $euiFormControlLayoutGroupInputCompressedBorderRadius;
+ border-bottom-right-radius: $euiFormControlLayoutGroupInputCompressedBorderRadius;
+ }
&.euiFormLabel,
&.euiText {
- padding-top: $euiFormControlCompressedPadding;
- padding-bottom: $euiFormControlCompressedPadding;
+ padding: $euiFormControlCompressedPadding;
}
}
}
- > .euiFormControlLayout--compressed {
- height: $euiFormControlLayoutGroupInputCompressedHeight;
- }
-
//
// ReadOnly alterations
&.euiFormControlLayout--readOnly {
@@ -89,10 +131,17 @@
input {
background-color: transparent; // Ensures the input and layout don't double up on background color
}
+ }
+
+ //
+ // ReadOnly-Compressed alterations
+ &.euiFormControlLayout--compressed.euiFormControlLayout--readOnly {
.euiFormControlLayout__prepend,
.euiFormControlLayout__append {
- height: $euiFormControlHeight; // Matching input height, as euiFormControlSize() does not apply to the smaller height to readOnly states
+ height: $euiFormControlCompressedHeight;
+ border-top-left-radius: $euiFormControlCompressedBorderRadius;
+ border-bottom-left-radius: $euiFormControlCompressedBorderRadius;
}
}
}
diff --git a/src/components/form/form_control_layout/_form_control_layout_range.scss b/src/components/form/form_control_layout/_form_control_layout_delimited.scss
similarity index 50%
rename from src/components/form/form_control_layout/_form_control_layout_range.scss
rename to src/components/form/form_control_layout/_form_control_layout_delimited.scss
index 81c7af082c3..824785c0d1d 100644
--- a/src/components/form/form_control_layout/_form_control_layout_range.scss
+++ b/src/components/form/form_control_layout/_form_control_layout_delimited.scss
@@ -1,6 +1,11 @@
+@import '../variables';
+@import '../mixins';
+
.euiFormControlLayoutDelimited {
// Match just the regular drop shadow of inputs
@include euiFormControlDefaultShadow;
+ display: flex;
+ align-items: stretch;
padding: 1px; /* 1 */
> .euiFormControlLayout__childrenWrapper {
@@ -8,18 +13,34 @@
align-items: center;
}
- input {
- height: $euiFormControlLayoutGroupInputHeight;
+ &[class*='--compressed'] {
+ @include euiFormControlDefaultShadow($borderOnly: true);
+ border-radius: $euiBorderRadius / 2;
+
+ .euiFormControlLayoutDelimited__input {
+ height: 100%;
+ padding-top: 0; // Fixes IE
+ padding-bottom: 0; // Fixes IE
+ padding-left: $euiFormControlCompressedPadding;
+ padding-right: $euiFormControlCompressedPadding;
+ }
+
+ .euiFormControlLayoutIcons {
+ padding-left: $euiFormControlCompressedPadding;
+ padding-right: $euiFormControlCompressedPadding;
+ }
}
- &[class*='--compressed'] input {
- height: $euiFormControlLayoutGroupInputCompressedHeight;
- padding-top: 0; // Fixes IE
- padding-bottom: 0; // Fixes IE
+ &[class*='--fullWidth'] .euiFormControlLayout__childrenWrapper {
+ width: 100%;
}
- &[class*='--fullWidth'] input {
- max-width: none;
+ &[class*='--readOnly'] {
+ @include euiFormControlReadOnlyStyle;
+
+ input {
+ background-color: transparent; // Ensures the input and layout don't double up on background color
+ }
}
.euiFormControlLayoutIcons {
@@ -36,14 +57,17 @@
}
}
-.euiFormControlLayoutDelimited__child--noStyle {
+.euiFormControlLayoutDelimited__input {
// sass-lint:disable-block no-important
box-shadow: none !important;
border-radius: 0 !important;
-}
-
-.euiFormControlLayoutDelimited__child--centered {
text-align: center;
+ height: 100%;
+ min-width: 0; // Fixes FF
+
+ .euiFormControlLayoutDelimited[class*='--compressed'] & {
+ max-width: none;
+ }
}
.euiFormControlLayoutDelimited__delimeter {
diff --git a/src/components/form/form_control_layout/_form_control_layout_icons.scss b/src/components/form/form_control_layout/_form_control_layout_icons.scss
index 5d2b4e12eb4..732b12d1dcb 100644
--- a/src/components/form/form_control_layout/_form_control_layout_icons.scss
+++ b/src/components/form/form_control_layout/_form_control_layout_icons.scss
@@ -10,11 +10,20 @@
> * + * {
margin-left: $euiFormControlPadding / 2;
}
+
+ .euiFormControlLayout--compressed & {
+ left: $euiFormControlCompressedPadding;
+ }
}
.euiFormControlLayoutIcons--right {
left: auto;
right: $euiFormControlPadding;
+
+ .euiFormControlLayout--compressed & {
+ left: auto;
+ right: $euiFormControlCompressedPadding;
+ }
}
// If the control is disabled, change the color of the icons
diff --git a/src/components/form/form_control_layout/_index.scss b/src/components/form/form_control_layout/_index.scss
index d14b350f0ef..a3a22b9f3a7 100644
--- a/src/components/form/form_control_layout/_index.scss
+++ b/src/components/form/form_control_layout/_index.scss
@@ -1,7 +1,7 @@
@import 'variables';
@import 'mixins';
@import 'form_control_layout';
-@import 'form_control_layout_range';
+@import 'form_control_layout_delimited';
@import 'form_control_layout_icons';
@import 'form_control_layout_clear_button';
@import 'form_control_layout_custom_icon';
diff --git a/src/components/form/form_control_layout/_mixins.scss b/src/components/form/form_control_layout/_mixins.scss
index 8a174285f9a..bd4ab8c56e5 100644
--- a/src/components/form/form_control_layout/_mixins.scss
+++ b/src/components/form/form_control_layout/_mixins.scss
@@ -1,14 +1,22 @@
-@mixin euiFormControlLayoutPadding($numOfIcons, $side: 'right') {
- $iconPaddingStart: $euiSizeXXL;
+@import '../variables';
+
+@mixin euiFormControlLayoutPadding($numOfIcons, $side: 'right', $compressed: false) {
+ $firstIconSize: $euiFormControlPadding + $euiSize + $euiFormControlPadding;
+ $secondIconSize: $euiFormControlPadding + $euiSize;
+
+ @if ($compressed) {
+ $firstIconSize: $euiFormControlCompressedPadding + $euiSize + $euiFormControlCompressedPadding;
+ $secondIconSize: $euiFormControlCompressedPadding + $euiSize;
+ }
@if variable-exists(numOfIcons) == false {
@error '$numOfIcons:integer (1-3) must be provided to @mixin euiFormControlLayoutPadding().';
} @else if $numOfIcons == 1 {
- padding-#{$side}: $iconPaddingStart;
+ padding-#{$side}: $firstIconSize;
} @else if $numOfIcons == 2 {
- padding-#{$side}: $iconPaddingStart + $euiSize;
+ padding-#{$side}: $firstIconSize + $secondIconSize;
} @else if $numOfIcons == 3 {
- padding-#{$side}: $iconPaddingStart + ($euiSize * 2) + $euiSizeS;
+ padding-#{$side}: $firstIconSize + ($secondIconSize * 2);
}
}
diff --git a/src/components/form/form_control_layout/_variables.scss b/src/components/form/form_control_layout/_variables.scss
index 8e04c7aeba1..75232099a40 100644
--- a/src/components/form/form_control_layout/_variables.scss
+++ b/src/components/form/form_control_layout/_variables.scss
@@ -6,3 +6,4 @@
$euiFormControlLayoutGroupInputHeight: $euiFormControlHeight - 2px; /* 1 */
$euiFormControlLayoutGroupInputCompressedHeight: $euiFormControlCompressedHeight - 2px; /* 1 */
+$euiFormControlLayoutGroupInputCompressedBorderRadius: $euiFormControlCompressedBorderRadius / 2;
diff --git a/src/components/form/form_control_layout/form_control_layout_delimited.tsx b/src/components/form/form_control_layout/form_control_layout_delimited.tsx
index 56f3b34481a..57a6a426dc4 100644
--- a/src/components/form/form_control_layout/form_control_layout_delimited.tsx
+++ b/src/components/form/form_control_layout/form_control_layout_delimited.tsx
@@ -49,8 +49,7 @@ function addClassesToControl(control: ReactElement) {
return cloneElement(control, {
className: classNames(
control.props.className,
- 'euiFormControlLayoutDelimited__child--noStyle',
- 'euiFormControlLayoutDelimited__child--centered'
+ 'euiFormControlLayoutDelimited__input'
),
});
}
diff --git a/src/components/form/select/_select.scss b/src/components/form/select/_select.scss
index 93e2f795623..26db7bbcebb 100644
--- a/src/components/form/select/_select.scss
+++ b/src/components/form/select/_select.scss
@@ -14,6 +14,7 @@
padding-bottom: 0; /* 2 */
&--compressed {
+ @include euiFormControlWithIcon($side: 'right', $compressed: true); /* 1 */
line-height: $euiFormControlCompressedHeight; /* 2 */
padding-top: 0; /* 2 */
padding-bottom: 0; /* 2 */
diff --git a/src/components/form/super_select/_super_select_control.scss b/src/components/form/super_select/_super_select_control.scss
index 07460eba20b..2d96c6a81b0 100644
--- a/src/components/form/super_select/_super_select_control.scss
+++ b/src/components/form/super_select/_super_select_control.scss
@@ -24,6 +24,7 @@
}
&--compressed {
+ @include euiFormControlWithIcon($side: 'right', $compressed: true); /* 1 */
line-height: $euiFormControlCompressedHeight; /* 2 */
padding-top: 0; /* 2 */
padding-bottom: 0; /* 2 */
From 335c806e38e22f94ef26fe295d97dcbf8a9a8c0a Mon Sep 17 00:00:00 2001
From: Caroline Horn <549577+cchaos@users.noreply.github.com>
Date: Tue, 13 Aug 2019 09:29:24 -0400
Subject: [PATCH 05/20] [Feature branch] Compressed form rows (#2181)
* Removed padding from compressed form row
* Create mixin for `euiTextBreakWord`
* Added option for horizontal compressed style
Breaking: `compressed` is no longer passed to children
* [Docs] Final compressed doc example changes
* Fix combobox height
* Fixed usages where spacers were needed
* Deprecated `displayOnly` for `display: center`
---
.../guide_locale_selector.js | 1 -
.../guide_page/guide_page_chrome.js | 10 +-
.../src/views/color_picker/custom_button.js | 2 +
src-docs/src/views/combo_box/containers.js | 2 +
src-docs/src/views/context/context.js | 2 +
.../src/views/context_menu/context_menu.js | 2 +
.../src/views/flyout/flyout_complicated.js | 1 +
.../src/views/form_layouts/form_compressed.js | 44 +-
.../form_layouts/form_layouts_example.js | 34 +-
src-docs/src/views/form_layouts/form_rows.js | 3 +
.../src/views/form_layouts/inline_popover.js | 3 +
.../src/views/form_layouts/inline_sizing.js | 6 +-
.../src/views/form_validation/validation.js | 3 +
src-docs/src/views/popover/trap_focus.js | 3 +
src/components/combo_box/_combo_box.scss | 6 +-
.../date_popover/relative_tab.js | 2 +-
.../__snapshots__/quick_select.test.js.snap | 20 +-
.../quick_select_popover/quick_select.js | 3 +
.../quick_select_popover/refresh_interval.js | 2 +
src/components/expression/_expression.scss | 2 +-
.../described_form_group.test.js.snap | 89 ++--
.../form/file_picker/_file_picker.scss | 3 +-
.../form/form_help_text/_form_help_text.scss | 2 +-
.../form/form_label/_form_label.scss | 1 -
.../__snapshots__/form_row.test.js.snap | 425 ++++++++++++------
src/components/form/form_row/_form_row.scss | 53 ++-
src/components/form/form_row/form_row.js | 86 ++--
src/components/form/form_row/form_row.test.js | 28 +-
src/components/form/form_row/index.d.ts | 1 +
src/components/table/_table.scss | 2 +-
src/global_styling/mixins/_typography.scss | 13 +-
src/global_styling/utility/_utility.scss | 5 +-
32 files changed, 602 insertions(+), 257 deletions(-)
diff --git a/src-docs/src/components/guide_locale_selector/guide_locale_selector.js b/src-docs/src/components/guide_locale_selector/guide_locale_selector.js
index e6f8c1065b6..52f545c5478 100644
--- a/src-docs/src/components/guide_locale_selector/guide_locale_selector.js
+++ b/src-docs/src/components/guide_locale_selector/guide_locale_selector.js
@@ -12,7 +12,6 @@ export const GuideLocaleSelector = ({ selectedLocale, onToggleLocale }) => {
onChange={() =>
onToggleLocale(selectedLocale === 'en' ? 'en-xa' : 'en')
}
- compressed={true}
/>
);
diff --git a/src-docs/src/components/guide_page/guide_page_chrome.js b/src-docs/src/components/guide_page/guide_page_chrome.js
index 9971aefb689..352ac98ab62 100644
--- a/src-docs/src/components/guide_page/guide_page_chrome.js
+++ b/src-docs/src/components/guide_page/guide_page_chrome.js
@@ -166,12 +166,10 @@ export class GuidePageChrome extends Component {
selectedTheme={this.props.selectedTheme}
/>
{location.host === 'localhost:8030' ? ( // eslint-disable-line no-restricted-globals
-
-
-
+
) : null}
diff --git a/src-docs/src/views/color_picker/custom_button.js b/src-docs/src/views/color_picker/custom_button.js
index 31d715b6a91..57625d7af47 100644
--- a/src-docs/src/views/color_picker/custom_button.js
+++ b/src-docs/src/views/color_picker/custom_button.js
@@ -5,6 +5,7 @@ import {
EuiFormRow,
EuiColorPickerSwatch,
EuiBadge,
+ EuiSpacer,
} from '../../../../src/components';
import { isValidHex } from '../../../../src/services';
@@ -43,6 +44,7 @@ export class CustomButton extends Component {
}
/>
+
+
+
+
+
{action}
)}
diff --git a/src-docs/src/views/context_menu/context_menu.js b/src-docs/src/views/context_menu/context_menu.js
index 6b7aa521605..1b724641ca3 100644
--- a/src-docs/src/views/context_menu/context_menu.js
+++ b/src-docs/src/views/context_menu/context_menu.js
@@ -7,6 +7,7 @@ import {
EuiIcon,
EuiPopover,
EuiSwitch,
+ EuiSpacer,
} from '../../../../src/components';
function flattenPanelTree(tree, array = []) {
@@ -87,6 +88,7 @@ export default class extends Component {
label="Current time range"
/>
+
Copy iFrame code
),
diff --git a/src-docs/src/views/flyout/flyout_complicated.js b/src-docs/src/views/flyout/flyout_complicated.js
index 6901f5e3014..343d5412e63 100644
--- a/src-docs/src/views/flyout/flyout_complicated.js
+++ b/src-docs/src/views/flyout/flyout_complicated.js
@@ -195,6 +195,7 @@ export class FlyoutComplicated extends Component {
+
{flyoutContent}
{htmlCode}
diff --git a/src-docs/src/views/form_layouts/form_compressed.js b/src-docs/src/views/form_layouts/form_compressed.js
index 7151cd19c48..8ab9ba27cb8 100644
--- a/src-docs/src/views/form_layouts/form_compressed.js
+++ b/src-docs/src/views/form_layouts/form_compressed.js
@@ -10,6 +10,7 @@ import {
EuiFilePicker,
EuiRange,
EuiSelect,
+ EuiSpacer,
EuiSwitch,
EuiPanel,
} from '../../../../src/components';
@@ -57,9 +58,16 @@ export default class extends Component {
],
radioIdSelected: `${idPrefix}5`,
comboBoxSelectionOptions: [],
+ value: '20',
};
}
+ onRangeChange = e => {
+ this.setState({
+ value: e.target.value,
+ });
+ };
+
onSwitchChange = () => {
this.setState({
isSwitchChecked: !this.state.isSwitchChecked,
@@ -92,31 +100,35 @@ export default class extends Component {
-
+ display="columnCompressed">
+
-
+
-
-
+
+
-
+
this.setState({ comboBoxSelectionOptions })
@@ -124,13 +136,22 @@ export default class extends Component {
/>
-
-
+
+
+ display="rowCompressed">
-
+
+
+
Save form
diff --git a/src-docs/src/views/form_layouts/form_layouts_example.js b/src-docs/src/views/form_layouts/form_layouts_example.js
index dd71d1199b8..47bb218318a 100644
--- a/src-docs/src/views/form_layouts/form_layouts_example.js
+++ b/src-docs/src/views/form_layouts/form_layouts_example.js
@@ -108,7 +108,7 @@ export const FormLayoutsExample = {
`,
},
{
- title: 'Compressed',
+ title: 'Compressed and horizontal',
source: [
{
type: GuideSectionTypes.JS,
@@ -122,21 +122,33 @@ export const FormLayoutsExample = {
text: (
If the particular form is in an area with a small amount of real
- estate, you can add the prop compressed to the{' '}
- EuiFormRow s and it will pass down to the form
- controls.
+ estate, you can pass{' '}
+ display="rowCompressed" to the{' '}
+ EuiFormRow s but you will also need to pass{' '}
+ compressed=true to the form controls themselves.
+ For editor style controls, pass{' '}
+ display="columnCompressed" to align the
+ labels and inputs horizontally.
),
props: {
EuiFormRow,
},
demo: ,
- snippet: `
-
+
`,
+ `
+
+ `,
+ ],
},
{
title: 'Described form groups',
@@ -224,12 +236,16 @@ export const FormLayoutsExample = {
When supplying children to an EuiFormRow that is{' '}
not a form control, and you need to the content to
- vertically center with the other form controls, add the prop{' '}
- displayOnly .
+ vertically center with the other form controls, change the{' '}
+ display prop to center or{' '}
+ centerCompressed .
),
demo: ,
+ snippet: `
+
+ `,
},
{
title: 'In a popover',
diff --git a/src-docs/src/views/form_layouts/form_rows.js b/src-docs/src/views/form_layouts/form_rows.js
index 00ea340f377..42b14c9ab53 100644
--- a/src-docs/src/views/form_layouts/form_rows.js
+++ b/src-docs/src/views/form_layouts/form_rows.js
@@ -10,6 +10,7 @@ import {
EuiLink,
EuiRange,
EuiSelect,
+ EuiSpacer,
EuiSwitch,
EuiText,
} from '../../../../src/components';
@@ -135,6 +136,8 @@ export default class extends Component {
/>
+
+
Save form
diff --git a/src-docs/src/views/form_layouts/inline_popover.js b/src-docs/src/views/form_layouts/inline_popover.js
index 23a9fa41e66..c9af9fa01d7 100644
--- a/src-docs/src/views/form_layouts/inline_popover.js
+++ b/src-docs/src/views/form_layouts/inline_popover.js
@@ -10,6 +10,7 @@ import {
EuiFlexItem,
EuiFieldNumber,
EuiRange,
+ EuiSpacer,
EuiSwitch,
} from '../../../../src/components';
@@ -125,6 +126,8 @@ export default class extends Component {
+
+
Save
);
diff --git a/src-docs/src/views/form_layouts/inline_sizing.js b/src-docs/src/views/form_layouts/inline_sizing.js
index d8602cae275..d66e8da3c98 100644
--- a/src-docs/src/views/form_layouts/inline_sizing.js
+++ b/src-docs/src/views/form_layouts/inline_sizing.js
@@ -23,13 +23,13 @@ export default () => (
-
+
-
- Save
+
+ Save
diff --git a/src-docs/src/views/form_validation/validation.js b/src-docs/src/views/form_validation/validation.js
index ae1c6834413..b1667d0ccfc 100644
--- a/src-docs/src/views/form_validation/validation.js
+++ b/src-docs/src/views/form_validation/validation.js
@@ -7,6 +7,7 @@ import {
EuiFormRow,
EuiTextArea,
EuiFieldText,
+ EuiSpacer,
} from '../../../../src/components';
export default class extends Component {
@@ -70,6 +71,8 @@ export default class extends Component {
/>
+
+
{button}
diff --git a/src-docs/src/views/popover/trap_focus.js b/src-docs/src/views/popover/trap_focus.js
index 6b62246e343..7d69f04ceb5 100644
--- a/src-docs/src/views/popover/trap_focus.js
+++ b/src-docs/src/views/popover/trap_focus.js
@@ -4,6 +4,7 @@ import {
EuiButton,
EuiFormRow,
EuiPopover,
+ EuiSpacer,
EuiSwitch,
} from '../../../../src/components';
@@ -54,6 +55,8 @@ export default class extends Component {
+
+
Copy IFRAME code
);
diff --git a/src/components/combo_box/_combo_box.scss b/src/components/combo_box/_combo_box.scss
index e962ee457ff..4f3e2be4976 100644
--- a/src/components/combo_box/_combo_box.scss
+++ b/src/components/combo_box/_combo_box.scss
@@ -11,7 +11,7 @@
*/
&--compressed,
- .euiFormControlLayout--compressed {
+ .euiFormControlLayout {
height: auto;
}
@@ -98,6 +98,10 @@
line-height: $euiFormControlCompressedHeight; /* 2 */
padding-top: 0;
padding-bottom: 0;
+
+ &.euiComboBox__inputWrap-isClearable {
+ @include euiFormControlLayoutPadding(2, $compressed: true); /* 2 */
+ }
}
}
}
diff --git a/src/components/date_picker/super_date_picker/date_popover/relative_tab.js b/src/components/date_picker/super_date_picker/date_popover/relative_tab.js
index 008913739e1..1399f260242 100644
--- a/src/components/date_picker/super_date_picker/date_popover/relative_tab.js
+++ b/src/components/date_picker/super_date_picker/date_popover/relative_tab.js
@@ -104,7 +104,7 @@ export class EuiRelativeTab extends Component {
-
+
@@ -160,6 +161,7 @@ export class EuiQuickSelect extends Component {
aria-label="Quick time value"
value={this.state.timeValue}
onChange={this.onTimeValueChange}
+ compressed
/>
@@ -170,6 +172,7 @@ export class EuiQuickSelect extends Component {
value={this.state.timeUnits}
options={timeUnitsOptions}
onChange={this.onTimeUnitsChange}
+ compressed
/>
diff --git a/src/components/date_picker/super_date_picker/quick_select_popover/refresh_interval.js b/src/components/date_picker/super_date_picker/quick_select_popover/refresh_interval.js
index fc618ef33f5..e7f5e52b1cb 100644
--- a/src/components/date_picker/super_date_picker/quick_select_popover/refresh_interval.js
+++ b/src/components/date_picker/super_date_picker/quick_select_popover/refresh_interval.js
@@ -128,6 +128,7 @@ export class EuiRefreshInterval extends Component {
onChange={this.onValueChange}
aria-label="Refresh interval value"
data-test-subj="superDatePickerRefreshIntervalInput"
+ compressed
/>
@@ -139,6 +140,7 @@ export class EuiRefreshInterval extends Component {
options={refreshUnitsOptions}
onChange={this.onUnitsChange}
data-test-subj="superDatePickerRefreshIntervalUnitsSelect"
+ compressed
/>
diff --git a/src/components/expression/_expression.scss b/src/components/expression/_expression.scss
index 3ee436b8af4..3797018cc0b 100644
--- a/src/components/expression/_expression.scss
+++ b/src/components/expression/_expression.scss
@@ -3,7 +3,7 @@
* but then wrap long words
*/
.euiExpression {
- @include euiTextOverflowWrap; /* 1 */
+ @include euiTextBreakWord; /* 1 */
@include euiFontSizeS;
@include euiCodeFont;
diff --git a/src/components/form/described_form_group/__snapshots__/described_form_group.test.js.snap b/src/components/form/described_form_group/__snapshots__/described_form_group.test.js.snap
index 7009392b9b5..7c5dbeffbc1 100644
--- a/src/components/form/described_form_group/__snapshots__/described_form_group.test.js.snap
+++ b/src/components/form/described_form_group/__snapshots__/described_form_group.test.js.snap
@@ -36,6 +36,7 @@ exports[`EuiDescribedFormGroup is rendered 1`] = `
>
-
+
Label
-
-
-
+
- Error one
-
-
-
-
+ Error one
+
+
+
- Error two
-
-
-
-
+ Error two
+
+
+
- Help text
-
-
+
+ Help text
+
+
+
diff --git a/src/components/form/file_picker/_file_picker.scss b/src/components/form/file_picker/_file_picker.scss
index bb8aca6035a..f22ba6b295e 100644
--- a/src/components/form/file_picker/_file_picker.scss
+++ b/src/components/form/file_picker/_file_picker.scss
@@ -44,6 +44,7 @@
.euiFilePicker--compressed & {
top: $euiSizeS;
+ left: $euiSizeS;
}
.euiFilePicker--large & {
@@ -76,7 +77,7 @@
.euiFilePicker--compressed & {
@include euiFormControlStyleCompressed($includeStates: false);
- @include euiFormControlWithIcon; /* 2 */
+ @include euiFormControlWithIcon($compressed: true); /* 2 */
height: $euiFormControlCompressedHeight;
}
diff --git a/src/components/form/form_help_text/_form_help_text.scss b/src/components/form/form_help_text/_form_help_text.scss
index 2bce1e4caad..d449b0e2c6a 100644
--- a/src/components/form/form_help_text/_form_help_text.scss
+++ b/src/components/form/form_help_text/_form_help_text.scss
@@ -1,5 +1,5 @@
.euiFormHelpText {
@include euiFontSizeXS;
- padding-top: $euiSizeS;
+ padding-top: $euiSizeXS;
color: $euiColorDarkShade;
}
diff --git a/src/components/form/form_label/_form_label.scss b/src/components/form/form_label/_form_label.scss
index e321f960221..887d7de476c 100644
--- a/src/components/form/form_label/_form_label.scss
+++ b/src/components/form/form_label/_form_label.scss
@@ -4,7 +4,6 @@
.euiFormLabel {
@include euiFontSizeXS;
display: inline-block;
- margin-bottom: $euiSizeXS;
transition: all $euiAnimSpeedFast $euiAnimSlightResistance;
color: $euiTitleColor;
font-weight: $euiFontWeightSemiBold;
diff --git a/src/components/form/form_row/__snapshots__/form_row.test.js.snap b/src/components/form/form_row/__snapshots__/form_row.test.js.snap
index 0ef700dad94..c239a1bc3ac 100644
--- a/src/components/form/form_row/__snapshots__/form_row.test.js.snap
+++ b/src/components/form/form_row/__snapshots__/form_row.test.js.snap
@@ -3,6 +3,7 @@
exports[`EuiFormRow behavior onBlur is called in child 1`] = `
-
`;
@@ -44,6 +52,7 @@ exports[`EuiFormRow behavior onBlur is called in child 1`] = `
exports[`EuiFormRow behavior onBlur works in parent even if not in child 1`] = `
-
`;
@@ -85,6 +101,7 @@ exports[`EuiFormRow behavior onBlur works in parent even if not in child 1`] = `
exports[`EuiFormRow behavior onFocus is called in child 1`] = `
-
`;
@@ -126,6 +150,7 @@ exports[`EuiFormRow behavior onFocus is called in child 1`] = `
exports[`EuiFormRow behavior onFocus works in parent even if not in child 1`] = `
-
`;
@@ -171,9 +203,28 @@ exports[`EuiFormRow is rendered 1`] = `
data-test-subj="test subject string"
id="generated-id-row"
>
-
+
+
+
+
+`;
+
+exports[`EuiFormRow props compressed is rendered 1`] = `
+
`;
@@ -182,12 +233,91 @@ exports[`EuiFormRow props describedByIds is rendered 1`] = `
className="euiFormRow"
id="generated-id-row"
>
-
+
+
+
+
+`;
+
+exports[`EuiFormRow props display type center is rendered 1`] = `
+
+`;
+
+exports[`EuiFormRow props display type centerCompressed is rendered 1`] = `
+
+`;
+
+exports[`EuiFormRow props display type columnCompressed is rendered 1`] = `
+
+`;
+
+exports[`EuiFormRow props display type row is rendered 1`] = `
+
+`;
+
+exports[`EuiFormRow props display type rowCompressed is rendered 1`] = `
+
`;
@@ -197,7 +327,7 @@ exports[`EuiFormRow props displayOnly is rendered 1`] = `
id="generated-id-row"
>
`;
@@ -239,16 +373,20 @@ exports[`EuiFormRow props error as string is rendered 1`] = `
class="euiFormRow"
id="generated-id-row"
>
-
`;
@@ -258,9 +396,13 @@ exports[`EuiFormRow props error is not rendered if isInvalid is false 1`] = `
class="euiFormRow"
id="generated-id-row"
>
-
+
+
+
`;
@@ -269,9 +411,13 @@ exports[`EuiFormRow props fullWidth is rendered 1`] = `
class="euiFormRow euiFormRow--fullWidth"
id="generated-id-row"
>
-
+
+
+
`;
@@ -280,9 +426,13 @@ exports[`EuiFormRow props hasEmptyLabelSpace is rendered 1`] = `
class="euiFormRow euiFormRow--hasEmptyLabelSpace"
id="generated-id-row"
>
-
+
+
+
`;
@@ -291,17 +441,21 @@ exports[`EuiFormRow props helpText is rendered 1`] = `
class="euiFormRow"
id="generated-id-row"
>
-
-
- This is help text.
-
+
+
+
+ This is help text.
+
+
`;
@@ -311,9 +465,13 @@ exports[`EuiFormRow props id is rendered 1`] = `
class="euiFormRow"
id="id-row"
>
-
+
+
+
`;
@@ -322,18 +480,24 @@ exports[`EuiFormRow props isInvalid is rendered 1`] = `
class="euiFormRow"
id="generated-id-row"
>
-
`;
@@ -342,36 +506,29 @@ exports[`EuiFormRow props label append is rendered 1`] = `
className="euiFormRow"
id="generated-id-row"
>
-
-
-
-
- label
-
-
-
-
- append
-
-
-
+ label
+
+
+ append
+
+
+
+
`;
@@ -380,8 +537,11 @@ exports[`EuiFormRow props label is rendered 1`] = `
className="euiFormRow"
id="generated-id-row"
>
-
`;
@@ -403,8 +567,11 @@ exports[`EuiFormRow props label renders as a legend and subsquently a fieldset w
className="euiFormRow"
id="generated-id-row"
>
-
+
-
+
+
+
`;
diff --git a/src/components/form/form_row/_form_row.scss b/src/components/form/form_row/_form_row.scss
index b4220f576ab..f0c6ff0e701 100644
--- a/src/components/form/form_row/_form_row.scss
+++ b/src/components/form/form_row/_form_row.scss
@@ -6,9 +6,8 @@
display: flex; /* 1 */
flex-direction: column; /* 1 */
max-width: $euiFormMaxWidth;
- padding-bottom: $euiSizeS;
- + * {
+ + .euiFormRow {
margin-top: $euiSize;
}
}
@@ -18,26 +17,60 @@
}
.euiFormRow--hasEmptyLabelSpace {
- margin-top: $euiFontSizeXS + $euiSizeS; /* 2 */
+ margin-top: ($euiFontSizeXS * $euiLineHeight) + $euiSizeXS; /* 2 */
// the following ensure that contents that aren't inheritly the same height
// as inputs will align to the vertical center
- min-height: $euiSizeXXL;
+ min-height: $euiFormControlHeight;
padding-bottom: 0;
justify-content: center;
}
-.euiFormRow--compressed {
- + * {
- margin-top: $euiSizeS;
+.euiFormRow__labelWrapper {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ margin-bottom: $euiSizeXS;
+}
+
+.euiFormRow--horizontal {
+ flex-direction: row;
+ align-items: stretch;
+
+ .euiFormRow__label {
+ @include euiTextBreakWord;
+ hyphens: auto;
+ max-width: 100%; // Fixes IE
+ }
+
+ .euiFormRow__labelWrapper {
+ display: block;
+ line-height: $euiFormControlCompressedHeight - 1px; // The 1px less helps the alignment of the text baseline
+ width: calc(33% - #{$euiSizeS});
+ margin-right: $euiSizeS;
+ margin-bottom: 0;
}
- .euiFormRow__text {
- padding-top: $euiSizeM / 2;
+ .euiFormRow__fieldWrapper {
+ width: 67%;
+ }
+
+ + .euiFormRow--horizontal {
+ margin-top: $euiSizeS;
}
}
-.euiFormRow__displayOnlyWrapper {
+.euiFormRow__fieldWrapperDisplayOnly {
min-height: $euiFormControlHeight;
display: flex;
align-items: center;
}
+
+.euiFormRow--compressed {
+ &.euiFormRow--hasEmptyLabelSpace {
+ min-height: $euiFormControlCompressedHeight;
+ }
+
+ .euiFormRow__fieldWrapperDisplayOnly {
+ min-height: $euiFormControlCompressedHeight;
+ }
+}
diff --git a/src/components/form/form_row/form_row.js b/src/components/form/form_row/form_row.js
index 79835cb54df..2eed0fdca96 100644
--- a/src/components/form/form_row/form_row.js
+++ b/src/components/form/form_row/form_row.js
@@ -8,10 +8,19 @@ import { withRequiredProp } from '../../../utils/prop_types/with_required_prop';
import { EuiFormHelpText } from '../form_help_text';
import { EuiFormErrorText } from '../form_error_text';
import { EuiFormLabel } from '../form_label';
-import { EuiFlexGroup, EuiFlexItem } from '../../flex';
import makeId from './make_id';
+const displayToClassNameMap = {
+ row: null,
+ rowCompressed: 'euiFormRow--compressed',
+ columnCompressed: 'euiFormRow--compressed euiFormRow--horizontal',
+ center: null,
+ centerCompressed: 'euiFormRow--compressed',
+};
+
+export const DISPLAYS = Object.keys(displayToClassNameMap);
+
export class EuiFormRow extends Component {
constructor(props) {
super(props);
@@ -63,19 +72,39 @@ export class EuiFormRow extends Component {
className,
describedByIds,
compressed,
+ display,
displayOnly,
...rest
} = this.props;
const { id } = this.state;
+ /**
+ * Remove when `compressed` is deprecated
+ */
+ let shimDisplay;
+ if (compressed && display === 'row') {
+ shimDisplay = 'rowCompressed';
+ } else {
+ shimDisplay = display;
+ }
+
+ /**
+ * Remove when `displayOnly` is deprecated
+ */
+ if (compressed && displayOnly) {
+ shimDisplay = 'centerCompressed';
+ } else if (displayOnly && display === 'row') {
+ shimDisplay = 'center';
+ }
+
const classes = classNames(
'euiFormRow',
{
'euiFormRow--hasEmptyLabelSpace': hasEmptyLabelSpace,
'euiFormRow--fullWidth': fullWidth,
- 'euiFormRow--compressed': compressed,
},
+ displayToClassNameMap[shimDisplay],
className
);
@@ -110,11 +139,11 @@ export class EuiFormRow extends Component {
const isLegend = label && labelType === 'legend' ? true : false;
const labelID = isLegend ? `${id}-${labelType}` : undefined;
- if (label) {
+ if (label || labelAppend) {
optionalLabel = (
- // Outer div ensures the label is inline-block (only takes up as much room as it needs)
-
+
{label}
+ {labelAppend && ' '}
+ {labelAppend}
);
}
- if (labelAppend) {
- optionalLabel = (
-
- {optionalLabel}
- {labelAppend}
-
- );
- }
-
const optionalProps = {};
const describingIds = [...describedByIds];
@@ -155,17 +173,17 @@ export class EuiFormRow extends Component {
optionalProps['aria-describedby'] = describingIds.join(' ');
}
- let field = cloneElement(Children.only(children), {
+ const field = cloneElement(Children.only(children), {
id,
onFocus: this.onFocus,
onBlur: this.onBlur,
- compressed: compressed,
...optionalProps,
});
- if (displayOnly) {
- field =
{field}
;
- }
+ const fieldWrapperClasses = classNames('euiFormRow__fieldWrapper', {
+ euiFormRow__fieldWrapperDisplayOnly:
+ displayOnly || display.startsWith('center'),
+ });
const Element = labelType === 'legend' ? 'fieldset' : 'div';
@@ -177,9 +195,11 @@ export class EuiFormRow extends Component {
aria-labelledby={labelID} // Only renders a string if label type is 'legend'
>
{optionalLabel}
- {field}
- {optionalErrors}
- {optionalHelpText}
+
+ {field}
+ {optionalErrors}
+ {optionalHelpText}
+
);
}
@@ -219,11 +239,20 @@ EuiFormRow.propTypes = {
*/
describedByIds: PropTypes.array,
/**
- * Tightens up the spacing and sends down the
- * compressed prop to the input
+ * **DEPRECATED: use `display: rowCompressed` instead.**
+ * When `true`, tightens up the spacing.
*/
compressed: PropTypes.bool,
/**
+ * When `rowCompressed`, just tightens up the spacing;
+ * Set to `columnCompressed` if compressed
+ * and horizontal layout is needed.
+ * Set to `center` or `centerCompressed` to align non-input
+ * content better with inline rows.
+ */
+ display: PropTypes.oneOf(DISPLAYS),
+ /**
+ * **DEPRECATED: use `display: center` instead.**
* Vertically centers non-input style content so it aligns
* better with input style content.
*/
@@ -231,6 +260,7 @@ EuiFormRow.propTypes = {
};
EuiFormRow.defaultProps = {
+ display: 'row',
hasEmptyLabelSpace: false,
fullWidth: false,
describedByIds: [],
diff --git a/src/components/form/form_row/form_row.test.js b/src/components/form/form_row/form_row.test.js
index c32f7d24ac2..69d7e270667 100644
--- a/src/components/form/form_row/form_row.test.js
+++ b/src/components/form/form_row/form_row.test.js
@@ -3,7 +3,7 @@ import { shallow, render, mount } from 'enzyme';
import { requiredProps } from '../../../test';
import sinon from 'sinon';
-import { EuiFormRow } from './form_row';
+import { EuiFormRow, DISPLAYS } from './form_row';
jest.mock('./make_id', () => () => 'generated-id');
@@ -200,6 +200,32 @@ describe('EuiFormRow', () => {
expect(component).toMatchSnapshot();
});
+
+ describe('compressed', () => {
+ test('is rendered', () => {
+ const component = render(
+
+
+
+ );
+
+ expect(component).toMatchSnapshot();
+ });
+ });
+
+ describe('display type', () => {
+ DISPLAYS.forEach(display => {
+ test(`${display} is rendered`, () => {
+ const component = render(
+
+
+
+ );
+
+ expect(component).toMatchSnapshot();
+ });
+ });
+ });
});
describe('behavior', () => {
diff --git a/src/components/form/form_row/index.d.ts b/src/components/form/form_row/index.d.ts
index 93aadba7221..76c08290f4c 100644
--- a/src/components/form/form_row/index.d.ts
+++ b/src/components/form/form_row/index.d.ts
@@ -21,6 +21,7 @@ declare module '@elastic/eui' {
labelAppend?: ReactNode;
describedByIds?: string[];
compressed?: boolean;
+ display?: 'row' | 'rowCompressed' | 'columnCompressed';
displayOnly?: boolean;
};
diff --git a/src/components/table/_table.scss b/src/components/table/_table.scss
index 468c0c96ec3..d4d1aa61d13 100644
--- a/src/components/table/_table.scss
+++ b/src/components/table/_table.scss
@@ -138,7 +138,7 @@
}
.euiTableCellContent__text {
- @include euiTextOverflowWrap; /* 4 */
+ @include euiTextBreakWord; /* 4 */
min-width: 0;
text-overflow: ellipsis;
}
diff --git a/src/global_styling/mixins/_typography.scss b/src/global_styling/mixins/_typography.scss
index a677a7aa711..18d86ffb6b6 100644
--- a/src/global_styling/mixins/_typography.scss
+++ b/src/global_styling/mixins/_typography.scss
@@ -1,4 +1,5 @@
// sass-lint:disable no-vendor-prefixes
+// sass-lint:disable no-important
// Our base fonts
@@ -96,13 +97,11 @@
letter-spacing: -.03em;
}
-// Overflow-wrap for breaking on word
-// Does not work on `display: flex` items
-@mixin euiTextOverflowWrap {
- @include internetExplorerOnly {
- word-break: break-all;
- }
- overflow-wrap: break-word;
+@mixin euiTextBreakWord {
+ // https://css-tricks.com/snippets/css/prevent-long-urls-from-breaking-out-of-container/
+ overflow-wrap: break-word !important; // makes sure the long string will wrap and not bust out of the container
+ word-wrap: break-word !important; // spec says, they are literally just alternate names for each other but some browsers support one and not the other
+ word-break: break-word; // IE doesn't understand but that's ok
}
// Text truncation
diff --git a/src/global_styling/utility/_utility.scss b/src/global_styling/utility/_utility.scss
index d5cc5c41d6f..55765690c41 100644
--- a/src/global_styling/utility/_utility.scss
+++ b/src/global_styling/utility/_utility.scss
@@ -25,10 +25,7 @@
.eui-textInheritColor {color: inherit !important;}
.eui-textBreakWord {
- // https://css-tricks.com/snippets/css/prevent-long-urls-from-breaking-out-of-container/
- overflow-wrap: break-word !important; // makes sure the long string will wrap and not bust out of the container
- word-wrap: break-word !important; // spec says, they are literally just alternate names for each other but some browsers support one and not the other
- word-break: break-word; // IE doesn't understand but that's ok
+ @include euiTextBreakWord;
}
.eui-textBreakAll {
From fe0212198d45006980307f6439a3f59215a918fa Mon Sep 17 00:00:00 2001
From: cchaos
Date: Thu, 29 Aug 2019 12:03:15 -0400
Subject: [PATCH 06/20] Fix snap
---
.../__snapshots__/super_select.test.js.snap | 87 ++++++++++++++-----
1 file changed, 67 insertions(+), 20 deletions(-)
diff --git a/src/components/form/super_select/__snapshots__/super_select.test.js.snap b/src/components/form/super_select/__snapshots__/super_select.test.js.snap
index 8d1d83433eb..174b7a51fad 100644
--- a/src/components/form/super_select/__snapshots__/super_select.test.js.snap
+++ b/src/components/form/super_select/__snapshots__/super_select.test.js.snap
@@ -56,6 +56,62 @@ exports[`EuiSuperSelect is rendered 1`] = `
`;
+exports[`EuiSuperSelect props compressed is rendered 1`] = `
+
+`;
+
exports[`EuiSuperSelect props custom display is propagated to dropdown 1`] = `
@@ -345,6 +402,7 @@ exports[`EuiSuperSelect props more props are propogated to each option 1`] = `
@@ -711,6 +769,7 @@ exports[`EuiSuperSelect props more props are propogated to each option 2`] = `
@@ -799,6 +858,7 @@ exports[`EuiSuperSelect props more props are propogated to each option 2`] = `
@@ -923,7 +983,13 @@ exports[`EuiSuperSelect props more props are propogated to each option 2`] = `
From 5f60fa1099f7a5e766ce536b6a7616fca5d1e01a Mon Sep 17 00:00:00 2001
From: Caroline Horn <549577+cchaos@users.noreply.github.com>
Date: Fri, 6 Sep 2019 14:38:31 -0400
Subject: [PATCH 07/20] Into feature/compressed editor docs (#2295)
* Adding a shared component for the different states of each form control
* New docs section for compressed
* Added `columnCompressedSwitch` to display type of EuiFormRow for better alignment of switch style controls
* Account for tooltips as pre/appends
* Allow passing a string as the pre/appends and it automatically wraps it in a form label
* Made all EuiSuperDatePicker form controls compressed (in popover)
* Connection prepend/appends with input via `htmlFor`
* Allowing passing of `style` to EuiColorPickerSwatch
* Allow an array of strings a pre/append
---
src-docs/src/routes.js | 5 +-
.../src/views/color_picker/kitchen_sink.js | 56 +--
src-docs/src/views/combo_box/combo_box.js | 22 +-
src-docs/src/views/date_picker/states.js | 49 +--
src-docs/src/views/focus_trap/focus_trap.js | 2 +-
.../views/form_compressed/complex_example.js | 293 +++++++++++++++
.../views/form_compressed/form_compressed.js | 166 ++++++++
.../form_compressed_example.js | 214 +++++++++++
.../views/form_compressed/form_horizontal.js | 157 ++++++++
.../form_compressed/form_horizontal_help.js | 59 +++
.../src/views/form_controls/checkbox_group.js | 15 -
.../views/form_controls/display_toggles.js | 223 +++++++++++
.../src/views/form_controls/field_number.js | 75 +---
.../src/views/form_controls/field_password.js | 60 +--
.../src/views/form_controls/field_search.js | 62 +--
.../src/views/form_controls/field_text.js | 61 +--
.../src/views/form_controls/file_picker.js | 60 ++-
.../form_controls/form_controls_example.js | 76 ++--
.../src/views/form_controls/radio_group.js | 15 -
src-docs/src/views/form_controls/select.js | 51 +--
src-docs/src/views/form_controls/text_area.js | 39 +-
.../src/views/form_layouts/form_compressed.js | 181 ---------
.../form_layouts/form_layouts_example.js | 47 ---
.../src/views/form_layouts/inline_sizing.js | 2 +-
.../src/views/super_select/super_select.js | 65 +---
.../color_picker/color_picker_swatch.tsx | 26 +-
.../date_popover/_absolute_tab.scss | 3 +
.../date_popover/_index.scss | 1 +
.../date_popover/absolute_tab.js | 3 +-
.../date_popover/relative_tab.js | 17 +-
.../__snapshots__/quick_select.test.js.snap | 354 +++++++-----------
.../quick_select_popover/quick_select.js | 68 ++--
.../quick_select_popover/refresh_interval.js | 56 ++-
.../__snapshots__/field_number.test.js.snap | 1 +
.../form/field_number/field_number.js | 3 +-
.../__snapshots__/field_text.test.js.snap | 1 +
src/components/form/field_text/field_text.js | 3 +-
.../form_control_layout.test.tsx.snap | 34 +-
.../_form_control_layout.scss | 7 +
.../form_control_layout.test.tsx | 16 +-
.../form_control_layout.tsx | 56 ++-
.../__snapshots__/form_row.test.js.snap | 15 +
src/components/form/form_row/_form_row.scss | 20 +
src/components/form/form_row/form_row.js | 4 +
.../select/__snapshots__/select.test.js.snap | 1 +
src/components/form/select/select.js | 3 +-
46 files changed, 1622 insertions(+), 1125 deletions(-)
create mode 100644 src-docs/src/views/form_compressed/complex_example.js
create mode 100644 src-docs/src/views/form_compressed/form_compressed.js
create mode 100644 src-docs/src/views/form_compressed/form_compressed_example.js
create mode 100644 src-docs/src/views/form_compressed/form_horizontal.js
create mode 100644 src-docs/src/views/form_compressed/form_horizontal_help.js
create mode 100644 src-docs/src/views/form_controls/display_toggles.js
delete mode 100644 src-docs/src/views/form_layouts/form_compressed.js
create mode 100644 src/components/date_picker/super_date_picker/date_popover/_absolute_tab.scss
diff --git a/src-docs/src/routes.js b/src-docs/src/routes.js
index 4fe2080e709..4c176e213dc 100644
--- a/src-docs/src/routes.js
+++ b/src-docs/src/routes.js
@@ -96,6 +96,8 @@ import { FormControlsExample } from './views/form_controls/form_controls_example
import { FormLayoutsExample } from './views/form_layouts/form_layouts_example';
+import { FormCompressedExample } from './views/form_compressed/form_compressed_example';
+
import { FormValidationExample } from './views/form_validation/form_validation_example';
import { HeaderExample } from './views/header/header_example';
@@ -336,8 +338,9 @@ const navigation = [
{
name: 'Forms',
items: [
- FormLayoutsExample,
FormControlsExample,
+ FormLayoutsExample,
+ FormCompressedExample,
FormValidationExample,
SuperSelectExample,
ComboBoxExample,
diff --git a/src-docs/src/views/color_picker/kitchen_sink.js b/src-docs/src/views/color_picker/kitchen_sink.js
index b9cdd4d55c9..3366f7617ad 100644
--- a/src-docs/src/views/color_picker/kitchen_sink.js
+++ b/src-docs/src/views/color_picker/kitchen_sink.js
@@ -1,7 +1,7 @@
import React, { Component } from 'react';
-import { EuiColorPicker, EuiFormRow } from '../../../../src/components';
-import { isValidHex } from '../../../../src/services';
+import { EuiColorPicker } from '../../../../src/components';
+import { DisplayToggles } from '../form_controls/display_toggles';
export class KitchenSink extends Component {
constructor(props) {
@@ -16,55 +16,11 @@ export class KitchenSink extends Component {
};
render() {
- const hasErrors = !isValidHex(this.state.color) && this.state.color !== '';
- const isCompressed = true;
-
- let errors;
- if (hasErrors) {
- errors = ['Provide a valid hex value'];
- }
-
return (
-
-
- console.log('onBlur')}
- onFocus={() => console.log('onFocus')}
- compressed={isCompressed}
- fullWidth={true}
- popoverZIndex={10}
- mode="default"
- swatches={['#333', '#666', '#999', '#CCC', '#FFF']}
- />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ /* DisplayToggles wrapper for Docs only */
+
+
+
);
}
}
diff --git a/src-docs/src/views/combo_box/combo_box.js b/src-docs/src/views/combo_box/combo_box.js
index 015177c6f42..e2144f9db1b 100644
--- a/src-docs/src/views/combo_box/combo_box.js
+++ b/src-docs/src/views/combo_box/combo_box.js
@@ -1,6 +1,7 @@
import React, { Component } from 'react';
import { EuiComboBox } from '../../../../src/components';
+import { DisplayToggles } from '../form_controls/display_toggles';
export default class extends Component {
constructor(props) {
@@ -82,15 +83,18 @@ export default class extends Component {
render() {
const { selectedOptions } = this.state;
return (
-
+ /* DisplayToggles wrapper for Docs only */
+
+
+
);
}
}
diff --git a/src-docs/src/views/date_picker/states.js b/src-docs/src/views/date_picker/states.js
index b1813e50808..eeb6e6eb58d 100644
--- a/src-docs/src/views/date_picker/states.js
+++ b/src-docs/src/views/date_picker/states.js
@@ -5,6 +5,7 @@ import {
EuiSpacer,
EuiFormRow,
} from '../../../../src/components';
+import { DisplayToggles } from '../form_controls/display_toggles';
export default class extends Component {
constructor(props) {
@@ -30,15 +31,18 @@ export default class extends Component {
];
return (
+ /* DisplayToggles wrapper for Docs only */
-
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
{
+ this.setState({ color: value });
+ };
+
+ onSwitchChange = () => {
+ this.setState({
+ isSwitchChecked: !this.state.isSwitchChecked,
+ });
+ };
+
+ onRangeChange = e => {
+ this.setState({
+ opacityValue: e.target.value,
+ });
+ };
+
+ onChange = optionId => {
+ this.setState({
+ buttonGroupIdSelected: optionId,
+ });
+ };
+
+ render() {
+ return (
+
+
+
+
+
+
+
+ }
+ endControl={
+
+ }
+ />
+
+
+
+
+
+
+
+
+ {this.selectTooltipContent}
+
+
+
+
+ Label
+
+
+ }
+ display="columnCompressed">
+
+
+
+
+
+
+
+
+
+ }
+ append="px"
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+ />
+
+
+
+
+
+
+
+
+
+ Label
+
+
+
+
+
+
+
+
+
+
+
+
+ Border
+
+
+
+
+
+
+
+
+
+
+ }
+ />
+
+
+
+ );
+ }
+}
diff --git a/src-docs/src/views/form_compressed/form_compressed.js b/src-docs/src/views/form_compressed/form_compressed.js
new file mode 100644
index 00000000000..00e686db344
--- /dev/null
+++ b/src-docs/src/views/form_compressed/form_compressed.js
@@ -0,0 +1,166 @@
+import React, { Component } from 'react';
+
+import {
+ EuiCheckboxGroup,
+ EuiComboBox,
+ EuiFieldText,
+ EuiFormRow,
+ EuiFilePicker,
+ EuiRange,
+ EuiSelect,
+ EuiSwitch,
+ EuiPanel,
+} from '../../../../src/components';
+
+import makeId from '../../../../src/components/form/form_row/make_id';
+
+export default class extends Component {
+ constructor(props) {
+ super(props);
+
+ const idPrefix = makeId();
+
+ this.state = {
+ isSwitchChecked: false,
+ checkboxes: [
+ {
+ id: `${idPrefix}0`,
+ label: 'Option one',
+ },
+ {
+ id: `${idPrefix}1`,
+ label: 'Option two is checked by default',
+ },
+ {
+ id: `${idPrefix}2`,
+ label: 'Option three',
+ },
+ ],
+ checkboxIdToSelectedMap: {
+ [`${idPrefix}1`]: true,
+ },
+ radios: [
+ {
+ id: `${idPrefix}4`,
+ label: 'Option one',
+ },
+ {
+ id: `${idPrefix}5`,
+ label: 'Option two is selected by default',
+ },
+ {
+ id: `${idPrefix}6`,
+ label: 'Option three',
+ },
+ ],
+ radioIdSelected: `${idPrefix}5`,
+ comboBoxSelectionOptions: [],
+ value: '20',
+ };
+ }
+
+ onRangeChange = e => {
+ this.setState({
+ value: e.target.value,
+ });
+ };
+
+ onSwitchChange = () => {
+ this.setState({
+ isSwitchChecked: !this.state.isSwitchChecked,
+ });
+ };
+
+ onCheckboxChange = optionId => {
+ const newCheckboxIdToSelectedMap = {
+ ...this.state.checkboxIdToSelectedMap,
+ ...{
+ [optionId]: !this.state.checkboxIdToSelectedMap[optionId],
+ },
+ };
+
+ this.setState({
+ checkboxIdToSelectedMap: newCheckboxIdToSelectedMap,
+ });
+ };
+
+ onRadioChange = optionId => {
+ this.setState({
+ radioIdSelected: optionId,
+ });
+ };
+
+ render() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ this.setState({ comboBoxSelectionOptions })
+ }
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+ }
+}
diff --git a/src-docs/src/views/form_compressed/form_compressed_example.js b/src-docs/src/views/form_compressed/form_compressed_example.js
new file mode 100644
index 00000000000..f01395f123e
--- /dev/null
+++ b/src-docs/src/views/form_compressed/form_compressed_example.js
@@ -0,0 +1,214 @@
+import React, { Fragment } from 'react';
+import { Link } from 'react-router';
+
+import { renderToHtml } from '../../services';
+
+import { GuideSectionTypes } from '../../components';
+
+import {
+ EuiCode,
+ EuiFormRow,
+ EuiToolTip,
+ EuiCallOut,
+ EuiText,
+ EuiSpacer,
+} from '../../../../src/components';
+
+import FormCompressed from './form_compressed';
+const formCompressedSource = require('!!raw-loader!./form_compressed');
+const formCompressedHtml = renderToHtml(FormCompressed);
+
+import FormHorizontal from './form_horizontal';
+const formHorizontalSource = require('!!raw-loader!./form_horizontal');
+const formHorizontalHtml = renderToHtml(FormHorizontal);
+
+import FormHelp from './form_horizontal_help';
+const formHelpSource = require('!!raw-loader!./form_horizontal_help');
+const formHelpHtml = renderToHtml(FormHelp);
+
+import ComplexExample from './complex_example';
+const ComplexExampleSource = require('!!raw-loader!./complex_example');
+const ComplexExampleHtml = renderToHtml(ComplexExample);
+
+export const FormCompressedExample = {
+ title: 'Compressed forms',
+ intro: (
+
+
+
+ Also known as Editor-Style Controls , compressed forms
+ and controls were specifically created for use when space is at a
+ premium. They are not intended for use when the form is the main
+ objective of the page. They work best in editor-style applications
+ where form controls are being used to create or edit content on the
+ page.
+
+
+
+
+
+
+ ),
+ sections: [
+ {
+ source: [
+ {
+ type: GuideSectionTypes.JS,
+ code: formCompressedSource,
+ },
+ {
+ type: GuideSectionTypes.HTML,
+ code: formCompressedHtml,
+ },
+ ],
+ text: (
+
+ To use compressed forms, pass{' '}
+ display="rowCompressed" to the
+ EuiFormRows and compressed=true to the form
+ controls themselves.
+
+ ),
+ props: {
+ EuiFormRow,
+ },
+ demo: ,
+ snippet: [
+ `
+
+ `,
+ ],
+ },
+ {
+ title: 'Column layout',
+ source: [
+ {
+ type: GuideSectionTypes.JS,
+ code: formHorizontalSource,
+ },
+ {
+ type: GuideSectionTypes.HTML,
+ code: formHorizontalHtml,
+ },
+ ],
+ text: (
+
+
+ Editor-style controls can be displayed in a two column layout for
+ even better use of limited space, just pass{' '}
+ display="columnCompressed" to align the
+ labels and inputs side by side.
+
+
+ EuiSwitches are a special case in which so you must
+ pass columnCompressedSwitch to the EuiFormRow as
+ the display property.
+
+
+ ),
+ props: {
+ EuiFormRow,
+ },
+ demo: ,
+ snippet: [
+ `
+
+ `,
+ `
+
+ `,
+ ],
+ },
+ {
+ title: 'Contextual help',
+ source: [
+ {
+ type: GuideSectionTypes.JS,
+ code: formHelpSource,
+ },
+ {
+ type: GuideSectionTypes.HTML,
+ code: formHelpHtml,
+ },
+ ],
+ text: (
+
+
+ When using compressed, horizontal form styles, it is best not to
+ overload the UI with expansive help text. If it's short and
+ part of the validation, use helpText . However, if
+ it's an explanation of the control, consider wraping the label
+ with an EuiToolTip and appending
+ the questionInCircle icon to it.
+
+
+ ),
+ props: {
+ EuiFormRow,
+ EuiToolTip,
+ },
+ demo: ,
+ snippet: [
+ `
+
+ `,
+ `
+
+ Label
+
+
+ }>
+
+ `,
+ ],
+ },
+ {
+ title: 'Complex example',
+ source: [
+ {
+ type: GuideSectionTypes.JS,
+ code: ComplexExampleSource,
+ },
+ {
+ type: GuideSectionTypes.HTML,
+ code: ComplexExampleHtml,
+ },
+ ],
+ text: (
+
+
+ This is an example of how to combine compressed form controls with
+ from rows, labels, prepend and appends in a column layout.
+
+
+
+ Pay close attention to the patterns of using{' '}
+ htmlFor and aria-label . For
+ best results each form control that is not wrapped in an
+ EuiFormRow should be supplied an id .
+
+
+
+ ),
+ demo: ,
+ },
+ ],
+};
diff --git a/src-docs/src/views/form_compressed/form_horizontal.js b/src-docs/src/views/form_compressed/form_horizontal.js
new file mode 100644
index 00000000000..63f00966b13
--- /dev/null
+++ b/src-docs/src/views/form_compressed/form_horizontal.js
@@ -0,0 +1,157 @@
+import React, { Component } from 'react';
+
+import {
+ EuiComboBox,
+ EuiFieldText,
+ EuiFormRow,
+ EuiFilePicker,
+ EuiRange,
+ EuiSelect,
+ EuiSwitch,
+ EuiPanel,
+} from '../../../../src/components';
+
+import makeId from '../../../../src/components/form/form_row/make_id';
+
+export default class extends Component {
+ constructor(props) {
+ super(props);
+
+ const idPrefix = makeId();
+
+ this.state = {
+ isSwitchChecked: false,
+ checkboxes: [
+ {
+ id: `${idPrefix}0`,
+ label: 'Option one',
+ },
+ {
+ id: `${idPrefix}1`,
+ label: 'Option two is checked by default',
+ },
+ {
+ id: `${idPrefix}2`,
+ label: 'Option three',
+ },
+ ],
+ checkboxIdToSelectedMap: {
+ [`${idPrefix}1`]: true,
+ },
+ radios: [
+ {
+ id: `${idPrefix}4`,
+ label: 'Option one',
+ },
+ {
+ id: `${idPrefix}5`,
+ label: 'Option two is selected by default',
+ },
+ {
+ id: `${idPrefix}6`,
+ label: 'Option three',
+ },
+ ],
+ radioIdSelected: `${idPrefix}5`,
+ comboBoxSelectionOptions: [],
+ value: '20',
+ };
+ }
+
+ onRangeChange = e => {
+ this.setState({
+ value: e.target.value,
+ });
+ };
+
+ onSwitchChange = () => {
+ this.setState({
+ isSwitchChecked: !this.state.isSwitchChecked,
+ });
+ };
+
+ onCheckboxChange = optionId => {
+ const newCheckboxIdToSelectedMap = {
+ ...this.state.checkboxIdToSelectedMap,
+ ...{
+ [optionId]: !this.state.checkboxIdToSelectedMap[optionId],
+ },
+ };
+
+ this.setState({
+ checkboxIdToSelectedMap: newCheckboxIdToSelectedMap,
+ });
+ };
+
+ onRadioChange = optionId => {
+ this.setState({
+ radioIdSelected: optionId,
+ });
+ };
+
+ render() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ this.setState({ comboBoxSelectionOptions })
+ }
+ />
+
+
+
+
+
+
+
+
+
+
+ );
+ }
+}
diff --git a/src-docs/src/views/form_compressed/form_horizontal_help.js b/src-docs/src/views/form_compressed/form_horizontal_help.js
new file mode 100644
index 00000000000..9cdc912c92d
--- /dev/null
+++ b/src-docs/src/views/form_compressed/form_horizontal_help.js
@@ -0,0 +1,59 @@
+import React, { Component } from 'react';
+
+import {
+ EuiFieldText,
+ EuiFormRow,
+ EuiSelect,
+ EuiPanel,
+ EuiIcon,
+} from '../../../../src/components';
+import { EuiToolTip } from '../../../../src/components/tool_tip';
+
+export default class extends Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ isSwitchChecked: false,
+ value: '20',
+ };
+ }
+
+ onSwitchChange = () => {
+ this.setState({
+ isSwitchChecked: !this.state.isSwitchChecked,
+ });
+ };
+
+ render() {
+ return (
+
+
+
+
+
+
+
+ Label
+
+
+ }
+ display="columnCompressed">
+
+
+
+ );
+ }
+}
diff --git a/src-docs/src/views/form_controls/checkbox_group.js b/src-docs/src/views/form_controls/checkbox_group.js
index 20679cdd113..9edfd40f885 100644
--- a/src-docs/src/views/form_controls/checkbox_group.js
+++ b/src-docs/src/views/form_controls/checkbox_group.js
@@ -72,21 +72,6 @@ export default class extends Component {
onChange={this.onChange}
disabled
/>
-
-
-
-
- Compressed
-
-
-
-
-
);
}
diff --git a/src-docs/src/views/form_controls/display_toggles.js b/src-docs/src/views/form_controls/display_toggles.js
new file mode 100644
index 00000000000..aa9206c2b3f
--- /dev/null
+++ b/src-docs/src/views/form_controls/display_toggles.js
@@ -0,0 +1,223 @@
+import React, { cloneElement, Component, Fragment } from 'react';
+import { Link } from 'react-router';
+import PropTypes from 'prop-types';
+
+import {
+ EuiFlexGroup,
+ EuiSwitch,
+ EuiFlexItem,
+ EuiToolTip,
+ EuiIcon,
+ EuiButtonEmpty,
+ EuiPopover,
+ EuiSpacer,
+} from '../../../../src/components';
+
+export class DisplayToggles extends Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ disabled: false,
+ readOnly: false,
+ loading: false,
+ compressed: false,
+ fullWidth: false,
+ prepend: false,
+ append: false,
+ isPopoverOpen: false,
+ invalid: false,
+ };
+ }
+
+ updateProperty = (checked, property) => {
+ const currentState = { ...this.state };
+ currentState[property] = checked;
+ this.setState(currentState);
+ this.props.onUpdate && this.props.onUpdate(currentState);
+ };
+
+ render() {
+ const {
+ canDisabled,
+ canReadOnly,
+ canLoading,
+ canCompressed,
+ canFullWidth,
+ canPrepend,
+ canAppend,
+ canInvalid,
+ children,
+ extras,
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ onUpdate,
+ } = this.props;
+
+ const canProps = {};
+ if (canDisabled) canProps.disabled = this.state.disabled;
+ if (canReadOnly) canProps.readOnly = this.state.readOnly;
+ if (canLoading) canProps.isLoading = this.state.loading;
+ if (canFullWidth) canProps.fullWidth = this.state.fullWidth;
+ if (canCompressed) canProps.compressed = this.state.compressed;
+ if (canPrepend && this.state.prepend) canProps.prepend = 'Prepend';
+ if (canAppend && this.state.append) canProps.append = 'Append';
+ if (canInvalid) canProps.isInvalid = this.state.invalid;
+
+ return (
+
+ {cloneElement(children, canProps)}
+
+ {
+ this.setState({ isPopoverOpen: false });
+ }}
+ button={
+ {
+ this.setState({ isPopoverOpen: !this.state.isPopoverOpen });
+ }}>
+ Display toggles
+
+ }>
+
+
+ {canDisabled && (
+
+
+ this.updateProperty(e.target.checked, 'disabled')
+ }
+ />
+
+ )}
+ {canReadOnly && (
+
+
+ this.updateProperty(e.target.checked, 'readOnly')
+ }
+ />
+
+ )}
+ {canLoading && (
+
+
+ this.updateProperty(e.target.checked, 'loading')
+ }
+ />
+
+ )}
+ {canInvalid && (
+
+
+ this.updateProperty(e.target.checked, 'invalid')
+ }
+ />
+
+ )}
+ {canFullWidth && (
+
+
+ this.updateProperty(e.target.checked, 'fullWidth')
+ }
+ />
+
+ )}
+ {canCompressed && (
+
+
+ compressed{' '}
+
+
+
+
+
+
+ }
+ checked={this.state.compressed}
+ onChange={e =>
+ this.updateProperty(e.target.checked, 'compressed')
+ }
+ />
+
+ )}
+ {canPrepend && (
+
+
+ this.updateProperty(e.target.checked, 'prepend')
+ }
+ />
+
+ )}
+ {canAppend && (
+
+
+ this.updateProperty(e.target.checked, 'append')
+ }
+ />
+
+ )}
+ {extras &&
+ extras.map((extra, index) => {
+ return (
+
+ {extra}
+
+ );
+ })}
+
+
+
+
+ );
+ }
+}
+
+DisplayToggles.propTypes = {
+ canDisabled: PropTypes.bool,
+ canReadOnly: PropTypes.bool,
+ canLoading: PropTypes.bool,
+ canCompressed: PropTypes.bool,
+ canFullWidth: PropTypes.bool,
+ canFullWidth: PropTypes.bool,
+ canPrepend: PropTypes.bool,
+ canAppend: PropTypes.bool,
+ canInvalid: PropTypes.bool,
+ extras: PropTypes.arrayOf(PropTypes.node),
+ onUpdate: PropTypes.func,
+};
+
+DisplayToggles.defaultProps = {
+ canDisabled: true,
+ canReadOnly: true,
+ canLoading: true,
+ canCompressed: true,
+ canFullWidth: true,
+ canInvalid: true,
+ canPrepend: false,
+ canAppend: false,
+};
diff --git a/src-docs/src/views/form_controls/field_number.js b/src-docs/src/views/form_controls/field_number.js
index ebfc39dfd18..d1c06a5cdca 100644
--- a/src-docs/src/views/form_controls/field_number.js
+++ b/src-docs/src/views/form_controls/field_number.js
@@ -1,6 +1,7 @@
-import React, { Component, Fragment } from 'react';
+import React, { Component } from 'react';
-import { EuiFieldNumber, EuiSpacer, EuiText } from '../../../../src/components';
+import { EuiFieldNumber } from '../../../../src/components';
+import { DisplayToggles } from './display_toggles';
export default class extends Component {
constructor(props) {
@@ -20,79 +21,15 @@ export default class extends Component {
render() {
return (
-
+ /* DisplayToggles wrapper for Docs only */
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- %
-
- }
- placeholder="0 - 100"
- value={this.state.value}
- onChange={this.onChange}
- aria-label="Use aria labels when no actual label is in use"
- />
-
+
);
}
}
diff --git a/src-docs/src/views/form_controls/field_password.js b/src-docs/src/views/form_controls/field_password.js
index 89ef106d4ba..5b8b44e589c 100644
--- a/src-docs/src/views/form_controls/field_password.js
+++ b/src-docs/src/views/form_controls/field_password.js
@@ -1,6 +1,7 @@
-import React, { Component, Fragment } from 'react';
+import React, { Component } from 'react';
-import { EuiFieldPassword, EuiSpacer } from '../../../../src/components';
+import { EuiFieldPassword } from '../../../../src/components';
+import { DisplayToggles } from './display_toggles';
export default class extends Component {
constructor(props) {
@@ -19,64 +20,15 @@ export default class extends Component {
render() {
return (
-
+ /* DisplayToggles wrapper for Docs only */
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
);
}
}
diff --git a/src-docs/src/views/form_controls/field_search.js b/src-docs/src/views/form_controls/field_search.js
index 2224b22e9a1..a08729a6eb2 100644
--- a/src-docs/src/views/form_controls/field_search.js
+++ b/src-docs/src/views/form_controls/field_search.js
@@ -1,6 +1,7 @@
-import React, { Component, Fragment } from 'react';
+import React, { Component } from 'react';
-import { EuiFieldSearch, EuiSpacer } from '../../../../src/components';
+import { EuiFieldSearch } from '../../../../src/components';
+import { DisplayToggles } from './display_toggles';
export default class extends Component {
constructor(props) {
@@ -19,64 +20,15 @@ export default class extends Component {
render() {
return (
-
+ /* DisplayToggles wrapper for Docs only */
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
);
}
}
diff --git a/src-docs/src/views/form_controls/field_text.js b/src-docs/src/views/form_controls/field_text.js
index 125dc557928..8ee88c5c430 100644
--- a/src-docs/src/views/form_controls/field_text.js
+++ b/src-docs/src/views/form_controls/field_text.js
@@ -1,6 +1,7 @@
-import React, { Component, Fragment } from 'react';
+import React, { Component } from 'react';
-import { EuiFieldText, EuiSpacer } from '../../../../src/components';
+import { EuiFieldText } from '../../../../src/components';
+import { DisplayToggles } from './display_toggles';
export default class extends Component {
constructor(props) {
@@ -19,64 +20,16 @@ export default class extends Component {
render() {
return (
-
+ /* DisplayToggles wrapper for Docs only */
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
);
}
}
diff --git a/src-docs/src/views/form_controls/file_picker.js b/src-docs/src/views/form_controls/file_picker.js
index 68f7acd2799..d57ee542bf3 100644
--- a/src-docs/src/views/form_controls/file_picker.js
+++ b/src-docs/src/views/form_controls/file_picker.js
@@ -1,4 +1,5 @@
import React, { Component, Fragment } from 'react';
+import { DisplayToggles } from './display_toggles';
import {
EuiFilePicker,
@@ -6,6 +7,7 @@ import {
EuiFlexItem,
EuiText,
EuiSpacer,
+ EuiSwitch,
} from '../../../../src/components';
export class FilePicker extends Component {
@@ -13,6 +15,7 @@ export class FilePicker extends Component {
super(props);
this.state = {
files: {},
+ large: true,
};
}
@@ -45,15 +48,30 @@ export class FilePicker extends Component {
return (
-
- {
- this.onChange(files);
- }}
- />
+
+ {/* DisplayToggles wrapper for Docs only */}
+ {
+ this.setState({ large: e.target.checked });
+ }}
+ />,
+ ]}>
+ {
+ this.onChange(files);
+ }}
+ display={this.state.large ? 'large' : 'default'}
+ />
+
+
@@ -62,30 +80,6 @@ export class FilePicker extends Component {
-
-
-
-
-
-
-
- {
- this.onChange(files);
- }}
- />
-
-
-
- {
- this.onChange(files);
- }}
- />
);
}
diff --git a/src-docs/src/views/form_controls/form_controls_example.js b/src-docs/src/views/form_controls/form_controls_example.js
index 9d186929cd1..cad4de36cfc 100644
--- a/src-docs/src/views/form_controls/form_controls_example.js
+++ b/src-docs/src/views/form_controls/form_controls_example.js
@@ -87,38 +87,38 @@ export const FormControlsExample = {
title: 'Form controls',
sections: [
{
- title: 'Search field',
+ title: 'Text field',
source: [
{
type: GuideSectionTypes.JS,
- code: fieldSearchSource,
+ code: fieldTextSource,
},
{
type: GuideSectionTypes.HTML,
- code: fieldSearchHtml,
+ code: fieldTextHtml,
},
],
props: {
- EuiFieldSearch,
+ EuiFieldText,
},
- demo: ,
+ demo: ,
},
{
- title: 'Text field',
+ title: 'Search field',
source: [
{
type: GuideSectionTypes.JS,
- code: fieldTextSource,
+ code: fieldSearchSource,
},
{
type: GuideSectionTypes.HTML,
- code: fieldTextHtml,
+ code: fieldSearchHtml,
},
],
props: {
- EuiFieldText,
+ EuiFieldSearch,
},
- demo: ,
+ demo: ,
},
{
title: 'Number field',
@@ -154,6 +154,34 @@ export const FormControlsExample = {
},
demo: ,
},
+ {
+ title: 'Select',
+ source: [
+ {
+ type: GuideSectionTypes.JS,
+ code: selectSource,
+ },
+ {
+ type: GuideSectionTypes.HTML,
+ code: selectHtml,
+ },
+ ],
+ text: (
+
+ This component renders a basic HTML <select>
{' '}
+ element. If you need more customization for how the options and/or
+ selected values render, use the{' '}
+ EuiSuperSelect. Another option is
+ to use the EuiComboBox, which has
+ search and multi-select capabilities, but also has restrictions on how
+ items are rendered.
+
+ ),
+ props: {
+ EuiSelect,
+ },
+ demo: ,
+ },
{
title: 'Textarea',
source: [
@@ -202,34 +230,6 @@ export const FormControlsExample = {
demo: ,
props: { EuiFilePicker },
},
- {
- title: 'Select',
- source: [
- {
- type: GuideSectionTypes.JS,
- code: selectSource,
- },
- {
- type: GuideSectionTypes.HTML,
- code: selectHtml,
- },
- ],
- text: (
-
- This component renders a basic HTML <select>
{' '}
- element. If you need more customization for how the options and/or
- selected values render, use the{' '}
- EuiSuperSelect. Another option is
- to use the EuiComboBox, which has
- search and multi-select capabilities, but also has restrictions on how
- items are rendered.
-
- ),
- props: {
- EuiSelect,
- },
- demo: ,
- },
{
title: 'Checkbox',
source: [
diff --git a/src-docs/src/views/form_controls/radio_group.js b/src-docs/src/views/form_controls/radio_group.js
index 1e4cfb4f672..e727f684893 100644
--- a/src-docs/src/views/form_controls/radio_group.js
+++ b/src-docs/src/views/form_controls/radio_group.js
@@ -60,21 +60,6 @@ export default class extends Component {
onChange={this.onChange}
disabled
/>
-
-
-
-
- Compressed
-
-
-
-
-
);
}
diff --git a/src-docs/src/views/form_controls/select.js b/src-docs/src/views/form_controls/select.js
index 1c7774d55c5..2017aae2096 100644
--- a/src-docs/src/views/form_controls/select.js
+++ b/src-docs/src/views/form_controls/select.js
@@ -1,6 +1,7 @@
-import React, { Component, Fragment } from 'react';
+import React, { Component } from 'react';
-import { EuiSelect, EuiSpacer } from '../../../../src/components';
+import { EuiSelect } from '../../../../src/components';
+import { DisplayToggles } from './display_toggles';
export default class extends Component {
constructor(props) {
@@ -25,54 +26,16 @@ export default class extends Component {
render() {
return (
-
+ /* DisplayToggles wrapper for Docs only */
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
);
}
}
diff --git a/src-docs/src/views/form_controls/text_area.js b/src-docs/src/views/form_controls/text_area.js
index 43f04395d50..779627bd991 100644
--- a/src-docs/src/views/form_controls/text_area.js
+++ b/src-docs/src/views/form_controls/text_area.js
@@ -1,6 +1,7 @@
-import React, { Component, Fragment } from 'react';
+import React, { Component } from 'react';
-import { EuiTextArea, EuiSpacer } from '../../../../src/components';
+import { EuiTextArea } from '../../../../src/components';
+import { DisplayToggles } from './display_toggles';
export default class extends Component {
constructor(props) {
@@ -19,43 +20,15 @@ export default class extends Component {
render() {
return (
-
+ /* DisplayToggles wrapper for Docs only */
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
);
}
}
diff --git a/src-docs/src/views/form_layouts/form_compressed.js b/src-docs/src/views/form_layouts/form_compressed.js
deleted file mode 100644
index 8ab9ba27cb8..00000000000
--- a/src-docs/src/views/form_layouts/form_compressed.js
+++ /dev/null
@@ -1,181 +0,0 @@
-import React, { Component } from 'react';
-
-import {
- EuiButton,
- EuiCheckboxGroup,
- EuiComboBox,
- EuiFieldText,
- EuiForm,
- EuiFormRow,
- EuiFilePicker,
- EuiRange,
- EuiSelect,
- EuiSpacer,
- EuiSwitch,
- EuiPanel,
-} from '../../../../src/components';
-
-import makeId from '../../../../src/components/form/form_row/make_id';
-
-export default class extends Component {
- constructor(props) {
- super(props);
-
- const idPrefix = makeId();
-
- this.state = {
- isSwitchChecked: false,
- checkboxes: [
- {
- id: `${idPrefix}0`,
- label: 'Option one',
- },
- {
- id: `${idPrefix}1`,
- label: 'Option two is checked by default',
- },
- {
- id: `${idPrefix}2`,
- label: 'Option three',
- },
- ],
- checkboxIdToSelectedMap: {
- [`${idPrefix}1`]: true,
- },
- radios: [
- {
- id: `${idPrefix}4`,
- label: 'Option one',
- },
- {
- id: `${idPrefix}5`,
- label: 'Option two is selected by default',
- },
- {
- id: `${idPrefix}6`,
- label: 'Option three',
- },
- ],
- radioIdSelected: `${idPrefix}5`,
- comboBoxSelectionOptions: [],
- value: '20',
- };
- }
-
- onRangeChange = e => {
- this.setState({
- value: e.target.value,
- });
- };
-
- onSwitchChange = () => {
- this.setState({
- isSwitchChecked: !this.state.isSwitchChecked,
- });
- };
-
- onCheckboxChange = optionId => {
- const newCheckboxIdToSelectedMap = {
- ...this.state.checkboxIdToSelectedMap,
- ...{
- [optionId]: !this.state.checkboxIdToSelectedMap[optionId],
- },
- };
-
- this.setState({
- checkboxIdToSelectedMap: newCheckboxIdToSelectedMap,
- });
- };
-
- onRadioChange = optionId => {
- this.setState({
- radioIdSelected: optionId,
- });
- };
-
- render() {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- this.setState({ comboBoxSelectionOptions })
- }
- />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Save form
-
-
-
- );
- }
-}
diff --git a/src-docs/src/views/form_layouts/form_layouts_example.js b/src-docs/src/views/form_layouts/form_layouts_example.js
index 47bb218318a..75570fda683 100644
--- a/src-docs/src/views/form_layouts/form_layouts_example.js
+++ b/src-docs/src/views/form_layouts/form_layouts_example.js
@@ -35,10 +35,6 @@ import InlinePopover from './inline_popover';
const inlinePopoverSource = require('!!raw-loader!./inline_popover');
const inlinePopoverHtml = renderToHtml(InlinePopover);
-import FormCompressed from './form_compressed';
-const formCompressedSource = require('!!raw-loader!./form_compressed');
-const formCompressedHtml = renderToHtml(FormCompressed);
-
export const FormLayoutsExample = {
title: 'Form layouts',
sections: [
@@ -107,49 +103,6 @@ export const FormLayoutsExample = {
`,
},
- {
- title: 'Compressed and horizontal',
- source: [
- {
- type: GuideSectionTypes.JS,
- code: formCompressedSource,
- },
- {
- type: GuideSectionTypes.HTML,
- code: formCompressedHtml,
- },
- ],
- text: (
-
- If the particular form is in an area with a small amount of real
- estate, you can pass{' '}
- display="rowCompressed" to the{' '}
- EuiFormRow s but you will also need to pass{' '}
- compressed=true to the form controls themselves.
- For editor style controls, pass{' '}
- display="columnCompressed" to align the
- labels and inputs horizontally.
-
- ),
- props: {
- EuiFormRow,
- },
- demo:
,
- snippet: [
- `
-
- `,
- `
-
- `,
- ],
- },
{
title: 'Described form groups',
source: [
diff --git a/src-docs/src/views/form_layouts/inline_sizing.js b/src-docs/src/views/form_layouts/inline_sizing.js
index d66e8da3c98..56f70f5bc54 100644
--- a/src-docs/src/views/form_layouts/inline_sizing.js
+++ b/src-docs/src/views/form_layouts/inline_sizing.js
@@ -29,7 +29,7 @@ export default () => (
- Save
+ Save
diff --git a/src-docs/src/views/super_select/super_select.js b/src-docs/src/views/super_select/super_select.js
index b356b870072..329fca0b554 100644
--- a/src-docs/src/views/super_select/super_select.js
+++ b/src-docs/src/views/super_select/super_select.js
@@ -1,6 +1,7 @@
-import React, { Component, Fragment } from 'react';
+import React, { Component } from 'react';
-import { EuiSuperSelect, EuiSpacer } from '../../../../src/components';
+import { EuiSuperSelect } from '../../../../src/components';
+import { DisplayToggles } from '../form_controls/display_toggles';
export default class extends Component {
constructor(props) {
@@ -40,68 +41,14 @@ export default class extends Component {
render() {
return (
-
+ /* DisplayToggles wrapper for Docs only */
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
);
}
}
diff --git a/src/components/color_picker/color_picker_swatch.tsx b/src/components/color_picker/color_picker_swatch.tsx
index 5ad759b12c9..f67fb53ef84 100644
--- a/src/components/color_picker/color_picker_swatch.tsx
+++ b/src/components/color_picker/color_picker_swatch.tsx
@@ -15,16 +15,18 @@ export type EuiColorPickerSwatchProps = CommonProps &
export const EuiColorPickerSwatch: FunctionComponent<
EuiColorPickerSwatchProps
-> = forwardRef(({ className, color, ...rest }, ref: Ref
) => {
- const classes = classNames('euiColorPickerSwatch', className);
+> = forwardRef(
+ ({ className, color, style, ...rest }, ref: Ref) => {
+ const classes = classNames('euiColorPickerSwatch', className);
- return (
-
- );
-});
+ return (
+
+ );
+ }
+);
diff --git a/src/components/date_picker/super_date_picker/date_popover/_absolute_tab.scss b/src/components/date_picker/super_date_picker/date_popover/_absolute_tab.scss
new file mode 100644
index 00000000000..8fc06622454
--- /dev/null
+++ b/src/components/date_picker/super_date_picker/date_popover/_absolute_tab.scss
@@ -0,0 +1,3 @@
+.euiSuperDatePicker__absoluteDateFormRow {
+ padding: 0 $euiSizeS $euiSizeS !important; // override compressed form row
+}
diff --git a/src/components/date_picker/super_date_picker/date_popover/_index.scss b/src/components/date_picker/super_date_picker/date_popover/_index.scss
index d8a2dc7d5a5..e184170cbc1 100644
--- a/src/components/date_picker/super_date_picker/date_popover/_index.scss
+++ b/src/components/date_picker/super_date_picker/date_popover/_index.scss
@@ -1,2 +1,3 @@
+@import 'absolute_tab';
@import 'date_popover_button';
@import 'date_popover_content';
diff --git a/src/components/date_picker/super_date_picker/date_popover/absolute_tab.js b/src/components/date_picker/super_date_picker/date_popover/absolute_tab.js
index 30269280f05..51f17a14514 100644
--- a/src/components/date_picker/super_date_picker/date_popover/absolute_tab.js
+++ b/src/components/date_picker/super_date_picker/date_popover/absolute_tab.js
@@ -62,7 +62,7 @@ export class EuiAbsoluteTab extends Component {
onChange={this.handleChange}
/>
= 0' : null}>
-
-
-
+
@@ -113,6 +113,7 @@ export class EuiRelativeTab extends Component {
/>
-
-
-
+ hasNoInitialSelection={false}
+ isLoading={false}
+ onChange={[Function]}
+ options={
+ Array [
+ Object {
+ "text": "Last",
+ "value": "last",
+ },
+ Object {
+ "text": "Next",
+ "value": "next",
+ },
+ ]
+ }
+ value="last"
+ />
-
-
-
+ isLoading={false}
+ onChange={[Function]}
+ value={15}
+ />
-
-
-
+ hasNoInitialSelection={false}
+ isLoading={false}
+ onChange={[Function]}
+ options={
+ Array [
+ Object {
+ "text": "seconds",
+ "value": "s",
+ },
+ Object {
+ "text": "minutes",
+ "value": "m",
+ },
+ Object {
+ "text": "hours",
+ "value": "h",
+ },
+ Object {
+ "text": "days",
+ "value": "d",
+ },
+ Object {
+ "text": "weeks",
+ "value": "w",
+ },
+ Object {
+ "text": "months",
+ "value": "M",
+ },
+ Object {
+ "text": "years",
+ "value": "y",
+ },
+ ]
+ }
+ value="m"
+ />
-
-
- Apply
-
-
+ Apply
+
-
-
-
+ hasNoInitialSelection={false}
+ isLoading={false}
+ onChange={[Function]}
+ options={
+ Array [
+ Object {
+ "text": "Last",
+ "value": "last",
+ },
+ Object {
+ "text": "Next",
+ "value": "next",
+ },
+ ]
+ }
+ value="Next"
+ />
-
-
-
+ isLoading={false}
+ onChange={[Function]}
+ value={32}
+ />
-
-
-
+ hasNoInitialSelection={false}
+ isLoading={false}
+ onChange={[Function]}
+ options={
+ Array [
+ Object {
+ "text": "seconds",
+ "value": "s",
+ },
+ Object {
+ "text": "minutes",
+ "value": "m",
+ },
+ Object {
+ "text": "hours",
+ "value": "h",
+ },
+ Object {
+ "text": "days",
+ "value": "d",
+ },
+ Object {
+ "text": "weeks",
+ "value": "w",
+ },
+ Object {
+ "text": "months",
+ "value": "M",
+ },
+ Object {
+ "text": "years",
+ "value": "y",
+ },
+ ]
+ }
+ value="M"
+ />
-
-
- Apply
-
-
+ Apply
+
-
-
-
+
-
-
-
+
-
-
-
+
-
-
- Apply
-
-
+
+ Apply
+
diff --git a/src/components/date_picker/super_date_picker/quick_select_popover/refresh_interval.js b/src/components/date_picker/super_date_picker/quick_select_popover/refresh_interval.js
index e7f5e52b1cb..4c0f5fcc7bb 100644
--- a/src/components/date_picker/super_date_picker/quick_select_popover/refresh_interval.js
+++ b/src/components/date_picker/super_date_picker/quick_select_popover/refresh_interval.js
@@ -5,7 +5,7 @@ import { timeUnits, timeUnitsPlural } from '../time_units';
import { EuiFlexGroup, EuiFlexItem } from '../../../flex';
import { EuiTitle } from '../../../title';
import { EuiSpacer } from '../../../spacer';
-import { EuiFormRow, EuiSelect, EuiFieldNumber } from '../../../form';
+import { EuiSelect, EuiFieldNumber } from '../../../form';
import { EuiButton } from '../../../button';
const refreshUnitsOptions = Object.keys(timeUnits)
@@ -122,40 +122,34 @@ export class EuiRefreshInterval extends Component {
-
-
-
+
-
-
-
+
-
-
- {this.props.isPaused ? 'Start' : 'Stop'}
-
-
+
+ {this.props.isPaused ? 'Start' : 'Stop'}
+
diff --git a/src/components/form/field_number/__snapshots__/field_number.test.js.snap b/src/components/form/field_number/__snapshots__/field_number.test.js.snap
index 15a4aa9df41..ea8bcf26f2b 100644
--- a/src/components/form/field_number/__snapshots__/field_number.test.js.snap
+++ b/src/components/form/field_number/__snapshots__/field_number.test.js.snap
@@ -5,6 +5,7 @@ exports[`EuiFieldNumber is rendered 1`] = `
compressed="false"
fullwidth="false"
icon="alert"
+ inputid="1"
isloading="false"
>
diff --git a/src/components/form/field_number/field_number.js b/src/components/form/field_number/field_number.js
index 1adb63f0408..3509ef0dcab 100644
--- a/src/components/form/field_number/field_number.js
+++ b/src/components/form/field_number/field_number.js
@@ -41,7 +41,8 @@ export const EuiFieldNumber = ({
compressed={compressed}
readOnly={readOnly}
prepend={prepend}
- append={append}>
+ append={append}
+ inputId={id}>
diff --git a/src/components/form/field_text/field_text.js b/src/components/form/field_text/field_text.js
index 25c240f279f..34ab574a2d7 100644
--- a/src/components/form/field_text/field_text.js
+++ b/src/components/form/field_text/field_text.js
@@ -39,7 +39,8 @@ export const EuiFieldText = ({
compressed={compressed}
readOnly={readOnly}
prepend={prepend}
- append={append}>
+ append={append}
+ inputId={id}>
`;
-exports[`EuiFormControlLayout props one append is rendered 1`] = `
+exports[`EuiFormControlLayout props one append node is rendered 1`] = `
@@ -240,7 +240,22 @@ exports[`EuiFormControlLayout props one append is rendered 1`] = `
`;
-exports[`EuiFormControlLayout props one prepend is rendered 1`] = `
+exports[`EuiFormControlLayout props one append string is rendered 1`] = `
+
+`;
+
+exports[`EuiFormControlLayout props one prepend node is rendered 1`] = `
@@ -255,6 +270,21 @@ exports[`EuiFormControlLayout props one prepend is rendered 1`] = `
`;
+exports[`EuiFormControlLayout props one prepend string is rendered 1`] = `
+
+`;
+
exports[`EuiFormControlLayout props readOnly is rendered 1`] = `
`;
@@ -55,6 +57,14 @@ exports[`EuiDualRange is rendered 1`] = `
`;
exports[`EuiDualRange props compressed should render 1`] = `
`;
@@ -116,23 +119,6 @@ exports[`EuiDualRange props custom ticks should render 1`] = `
class="euiRangeTrack"
style="margin-right:0.6em"
>
-
-
@@ -157,6 +143,24 @@ exports[`EuiDualRange props custom ticks should render 1`] = `
100kb
+
+
`;
@@ -168,24 +172,25 @@ exports[`EuiDualRange props disabled should render 1`] = `
`;
@@ -197,23 +202,24 @@ exports[`EuiDualRange props fullWidth should render 1`] = `
`;
@@ -244,6 +250,14 @@ exports[`EuiDualRange props inputs should render 1`] = `
-
-
@@ -362,6 +352,74 @@ exports[`EuiDualRange props levels should render 1`] = `
style="width:80%"
/>
+
+
+
+
+`;
+
+exports[`EuiDualRange props only input should render 1`] = `
+
`;
@@ -373,23 +431,24 @@ exports[`EuiDualRange props range should render 1`] = `
`;
@@ -402,23 +461,6 @@ exports[`EuiDualRange props ticks should render 1`] = `
class="euiRangeTrack"
style="margin-right:0.6em"
>
-
-
+
+
`;
diff --git a/src/components/form/range/__snapshots__/range.test.js.snap b/src/components/form/range/__snapshots__/range.test.js.snap
index 32d5d964d35..6d2a528f324 100644
--- a/src/components/form/range/__snapshots__/range.test.js.snap
+++ b/src/components/form/range/__snapshots__/range.test.js.snap
@@ -9,6 +9,7 @@ exports[`EuiRange allows value prop to accept a number 1`] = `
>
`;
@@ -142,6 +146,7 @@ exports[`EuiRange props disabled should render 1`] = `
`;
+exports[`EuiRange props input only should render 1`] = `
+
+`;
+
exports[`EuiRange props input should render 1`] = `
`;
@@ -278,14 +318,6 @@ exports[`EuiRange props range should render 1`] = `
`;
@@ -306,13 +347,6 @@ exports[`EuiRange props ticks should render 1`] = `
class="euiRangeTrack"
style="margin-right:0.6em"
>
-
+
`;
@@ -385,6 +427,7 @@ exports[`EuiRange props value should render 1`] = `
>
.euiFormControlLayout { /* 1 */
width: auto;
}
diff --git a/src/components/form/range/_variables.scss b/src/components/form/range/_variables.scss
index ce6a5cfd8e6..623e58acce8 100644
--- a/src/components/form/range/_variables.scss
+++ b/src/components/form/range/_variables.scss
@@ -12,3 +12,5 @@ $euiRangeTrackBorderColor: $euiRangeTrackColor !default;
$euiRangeTrackRadius: $euiBorderRadius !default;
$euiRangeDisabledOpacity: .25;
+
+$euiRangeHighlightHeight: $euiSizeXS;
diff --git a/src/components/form/range/dual_range.js b/src/components/form/range/dual_range.js
index 3d3a63f4dc6..8e0b3131bbb 100644
--- a/src/components/form/range/dual_range.js
+++ b/src/components/form/range/dual_range.js
@@ -4,6 +4,9 @@ import classNames from 'classnames';
import { keyCodes } from '../../../services';
import { isWithinRange } from '../../../services/number';
+import { EuiInputPopover } from '../../popover';
+import { EuiFormControlLayoutDelimited } from '../form_control_layout';
+import makeId from '../form_row/make_id';
import { EuiRangeHighlight } from './range_highlight';
import { EuiRangeInput } from './range_input';
@@ -15,15 +18,21 @@ import { EuiRangeWrapper } from './range_wrapper';
export class EuiDualRange extends Component {
state = {
+ id: this.props.id || makeId(),
hasFocus: false,
rangeSliderRefAvailable: false,
+ isPopoverOpen: false,
+ rangeWidth: null,
};
+ maxNode = null;
+ minNode = null;
rangeSliderRef = null;
handleRangeSliderRefUpdate = ref => {
this.rangeSliderRef = ref;
this.setState({
rangeSliderRefAvailable: !!ref,
+ rangeWidth: !!ref ? ref.clientWidth : null,
});
};
@@ -201,7 +210,7 @@ export class EuiDualRange extends Component {
this._handleOnChange(this.lowerValue, upper, e);
};
- calculateThumbPositionStyle = value => {
+ calculateThumbPositionStyle = (value, width) => {
// Calculate the left position based on value
const decimal =
(value - this.props.min) / (this.props.max - this.props.min);
@@ -210,7 +219,11 @@ export class EuiDualRange extends Component {
valuePosition = valuePosition >= 0 ? valuePosition : 0;
const EUI_THUMB_SIZE = 16;
- const thumbToTrackRatio = EUI_THUMB_SIZE / this.rangeSliderRef.clientWidth;
+ const trackWidth =
+ this.props.showInput === 'only' && !!width
+ ? width
+ : this.rangeSliderRef.clientWidth;
+ const thumbToTrackRatio = EUI_THUMB_SIZE / trackWidth;
const trackPositionScale = (1 - thumbToTrackRatio) * 100;
return { left: `${valuePosition * trackPositionScale}%` };
};
@@ -221,13 +234,56 @@ export class EuiDualRange extends Component {
});
};
+ onInputFocus = () => {
+ this.setState({
+ isPopoverOpen: true,
+ });
+ };
+
+ onInputBlur = e => {
+ // Firefox returns `relatedTarget` as `null` for security reasons, but provides a proprietary `explicitOriginalTarget`
+ const relatedTarget = e.relatedTarget || e.explicitOriginalTarget;
+ if (!relatedTarget || relatedTarget.id !== this.state.id) {
+ this.closePopover();
+ }
+ };
+
+ closePopover = () => {
+ this.setState({
+ isPopoverOpen: false,
+ });
+ };
+
+ onResize = width => {
+ this.setState({
+ rangeWidth: width,
+ });
+ };
+
+ inputRef = (node, ref) => {
+ if (!this.props.showInput !== 'inputWithPopover') return;
+
+ // IE11 doesn't support the `relatedTarget` event property for blur events
+ // but does add it for focusout. React doesn't support `onFocusOut` so here we are.
+ if (this[ref] != null) {
+ this[ref].removeEventListener('focusout', this.onInputBlur);
+ }
+
+ this[ref] = node;
+
+ if (this[ref]) {
+ this[ref].addEventListener('focusout', this.onInputBlur);
+ }
+ };
+
render() {
const {
className,
compressed,
disabled,
fullWidth,
- id,
+ readOnly,
+ id: propsId,
max,
min,
name,
@@ -245,34 +301,78 @@ export class EuiDualRange extends Component {
...rest
} = this.props;
- const classes = classNames('euiDualRange', className);
+ const { id } = this.state;
+
const digitTolerance = Math.max(String(min).length, String(max).length);
+ const showInputOnly = showInput === 'inputWithPopover';
+ const canShowDropdown = showInputOnly && !readOnly && !disabled;
- return (
-
- {showInput && (
-
- )}
+ const minInput = !!showInput ? (
+ this.inputRef(node, 'minNode')}
+ />
+ ) : (
+ undefined
+ );
+
+ const maxInput = !!showInput ? (
+ this.inputRef(node, 'maxNode')}
+ />
+ ) : (
+ undefined
+ );
+
+ const classes = classNames('euiDualRange', className);
+ const theRange = (
+
+ {!showInputOnly && minInput}
{showLabels && (
{min}
)}
+ {showRange && this.isValid && (
+
+ )}
+
this.toggleHasFocus(true)}
onBlur={() => this.toggleHasFocus(false)}
- style={this.calculateThumbPositionStyle(this.lowerValue || min)}
+ style={this.calculateThumbPositionStyle(
+ this.lowerValue || min,
+ this.state.rangeWidth
+ )}
aria-describedby={this.props['aria-describedby']}
aria-label={this.props['aria-label']}
/>
@@ -324,48 +440,50 @@ export class EuiDualRange extends Component {
value={this.upperValue}
disabled={disabled}
showTicks={showTicks}
- showInput={showInput}
+ showInput={!!showInput}
onKeyDown={this.handleUpperKeyDown}
onFocus={() => this.toggleHasFocus(true)}
onBlur={() => this.toggleHasFocus(false)}
- style={this.calculateThumbPositionStyle(this.upperValue || max)}
+ style={this.calculateThumbPositionStyle(
+ this.upperValue || max,
+ this.state.rangeWidth
+ )}
aria-describedby={this.props['aria-describedby']}
aria-label={this.props['aria-label']}
/>
)}
-
- {showRange && this.isValid && (
-
- )}
{showLabels && {max} }
- {showInput && (
-
+ );
+
+ const thePopover = showInputOnly ? (
+
- )}
-
+ }
+ fullWidth={fullWidth}
+ isOpen={this.state.isPopoverOpen}
+ closePopover={this.closePopover}
+ disableFocusTrap={true}
+ onPanelResize={this.onResize}>
+ {theRange}
+
+ ) : (
+ undefined
);
+
+ return thePopover || theRange;
}
}
@@ -384,14 +502,16 @@ EuiDualRange.propTypes = {
fullWidth: PropTypes.bool,
compressed: PropTypes.bool,
disabled: PropTypes.bool,
+ readOnly: PropTypes.bool,
/**
* Shows static min/max labels on the sides of the range slider
*/
showLabels: PropTypes.bool,
/**
- * Displays a input controls for direct manipulation
+ * Pass `true` to displays an extra input control for direct manipulation.
+ * Pass `'inputWithPopover'` to only show the input but show the range in a dropdown.
*/
- showInput: PropTypes.bool,
+ showInput: PropTypes.oneOf([true, false, 'inputWithPopover']),
/**
* Shows clickable tick marks and labels at the given interval (`step`/`tickInterval`)
*/
diff --git a/src/components/form/range/dual_range.test.js b/src/components/form/range/dual_range.test.js
index cc010c8b06d..03c9a822023 100644
--- a/src/components/form/range/dual_range.test.js
+++ b/src/components/form/range/dual_range.test.js
@@ -4,6 +4,8 @@ import { requiredProps } from '../../../test/required_props';
import { EuiDualRange } from './dual_range';
+jest.mock('../form_row/make_id', () => () => 'generated-id');
+
describe('EuiDualRange', () => {
test('is rendered', () => {
const component = render(
@@ -86,6 +88,23 @@ describe('EuiDualRange', () => {
expect(component).toMatchSnapshot();
});
+ test('only input should render', () => {
+ const component = render(
+ {}}
+ showInput="inputWithPopover"
+ {...requiredProps}
+ />
+ );
+
+ expect(component).toMatchSnapshot();
+ });
+
test('levels should render', () => {
const component = render(
{
const isValid = isWithinRange(
this.props.min,
@@ -26,13 +38,50 @@ export class EuiRange extends Component {
return isWithinRange(this.props.min, this.props.max, this.props.value);
}
+ onInputFocus = () => {
+ this.setState({
+ isPopoverOpen: true,
+ });
+ };
+
+ onInputBlur = e => {
+ // Firefox returns `relatedTarget` as `null` for security reasons, but provides a proprietary `explicitOriginalTarget`
+ const relatedTarget = e.relatedTarget || e.explicitOriginalTarget;
+ if (!relatedTarget || relatedTarget.id !== this.state.id) {
+ this.closePopover();
+ }
+ };
+
+ closePopover = () => {
+ this.setState({
+ isPopoverOpen: false,
+ });
+ };
+
+ inputRef = node => {
+ if (!this.props.showInput !== 'inputWithPopover') return;
+
+ // IE11 and Safar don't support the `relatedTarget` event property for blur events
+ // but do add it for focusout. React doesn't support `onFocusOut` so here we are.
+ if (this.inputNode != null) {
+ this.inputNode.removeEventListener('focusout', this.onInputBlur);
+ }
+
+ this.inputNode = node;
+
+ if (this.inputNode) {
+ this.inputNode.addEventListener('focusout', this.onInputBlur);
+ }
+ };
+
render() {
const {
className,
compressed,
disabled,
fullWidth,
- id,
+ readOnly,
+ id: propsId,
max,
min,
name,
@@ -54,11 +103,41 @@ export class EuiRange extends Component {
...rest
} = this.props;
- const classes = classNames('euiRange', className);
+ const { id } = this.state;
+
const digitTolerance = Math.max(String(min).length, String(max).length);
+ const showInputOnly = showInput === 'inputWithPopover';
+ const canShowDropdown = showInputOnly && !readOnly && !disabled;
+
+ const theInput = !!showInput ? (
+
+ ) : (
+ undefined
+ );
- return (
-
+ const classes = classNames('euiRange', className);
+
+ const theRange = (
+
{showLabels && (
{min}
@@ -66,6 +145,7 @@ export class EuiRange extends Component {
)}
+ {showRange && this.isValid && (
+
+ )}
+
{showValue && !!String(value).length && (
)}
-
- {showRange && this.isValid && (
-
- )}
{showLabels && (
{max}
)}
- {showInput && (
-
- )}
+ {!showInputOnly && theInput}
);
+
+ const thePopover = showInputOnly ? (
+
+ {theRange}
+
+ ) : (
+ undefined
+ );
+
+ return thePopover ? thePopover : theRange;
}
}
@@ -152,9 +238,10 @@ EuiRange.propTypes = {
*/
showLabels: PropTypes.bool,
/**
- * Displays an extra input control for direct manipulation
+ * Pass `true` to displays an extra input control for direct manipulation.
+ * Pass `'inputWithPopover'` to only show the input but show the range in a dropdown.
*/
- showInput: PropTypes.bool,
+ showInput: PropTypes.oneOf([true, false, 'inputWithPopover']),
/**
* Shows clickable tick marks and labels at the given interval (`step`/`tickInterval`)
*/
diff --git a/src/components/form/range/range.test.js b/src/components/form/range/range.test.js
index 652a6c104be..a9c113e1b16 100644
--- a/src/components/form/range/range.test.js
+++ b/src/components/form/range/range.test.js
@@ -4,6 +4,8 @@ import { requiredProps } from '../../../test/required_props';
import { EuiRange } from './range';
+jest.mock('../form_row/make_id', () => () => 'generated-id');
+
describe('EuiRange', () => {
test('is rendered', () => {
const component = render(
@@ -99,6 +101,23 @@ describe('EuiRange', () => {
expect(component).toMatchSnapshot();
});
+ test('input only should render', () => {
+ const component = render(
+ {}}
+ showInput="inputWithPopover"
+ {...requiredProps}
+ />
+ );
+
+ expect(component).toMatchSnapshot();
+ });
+
test('levels should render', () => {
const component = render(
= ({
upperValue,
max,
min,
+ compressed,
}) => {
// Calculate the width the range based on value
// const rangeWidth = (value - min) / (max - min);
@@ -29,6 +31,7 @@ export const EuiRangeHighlight: FunctionComponent = ({
const classes = classNames('euiRangeHighlight', {
'euiRangeHighlight--hasTicks': showTicks,
+ 'euiRangeHighlight--compressed': compressed,
});
const progressClasses = classNames('euiRangeHighlight__progress', {
diff --git a/src/components/form/range/range_input.js b/src/components/form/range/range_input.js
index 732a28b5541..d7e240f9411 100644
--- a/src/components/form/range/range_input.js
+++ b/src/components/form/range/range_input.js
@@ -14,12 +14,16 @@ export const EuiRangeInput = ({
name,
side,
digitTolerance,
+ fullWidth,
+ autoSize,
...rest
}) => {
// Chrome will properly size the input based on the max value, but FF & IE do not.
// Calculate the width of the input based on highest number of characters.
// Add 2 to accomodate for input stepper
- const widthStyle = { width: `${digitTolerance / 1.25 + 2}em` };
+ const widthStyle = autoSize
+ ? { width: `${digitTolerance / 1.25 + 2}em` }
+ : undefined;
return (
);
@@ -48,7 +53,11 @@ EuiRangeInput.propTypes = {
name: PropTypes.string,
digitTolerance: PropTypes.number.isRequired,
side: PropTypes.oneOf(['min', 'max']),
+ fullWidth: PropTypes.bool,
+ autoSize: PropTypes.bool,
+ inputRef: PropTypes.func,
};
EuiRangeInput.defaultProps = {
side: 'max',
+ autoSize: true,
};
diff --git a/src/components/form/range/range_levels.tsx b/src/components/form/range/range_levels.tsx
index b59c63cf852..c607b100aa4 100644
--- a/src/components/form/range/range_levels.tsx
+++ b/src/components/form/range/range_levels.tsx
@@ -21,6 +21,7 @@ export interface EuiRangeLevelsProps {
max: number;
min: number;
showTicks?: boolean;
+ compressed?: boolean;
}
export const EuiRangeLevels: FunctionComponent = ({
@@ -28,6 +29,7 @@ export const EuiRangeLevels: FunctionComponent = ({
max,
min,
showTicks,
+ compressed,
}) => {
const validateLevelIsInRange = (level: EuiRangeLevel) => {
if (level.min < min) {
@@ -44,6 +46,7 @@ export const EuiRangeLevels: FunctionComponent = ({
const classes = classNames('euiRangeLevels', {
'euiRangeLevels--hasTicks': showTicks,
+ 'euiRangeLevels--compressed': compressed,
});
return (
diff --git a/src/components/form/range/range_slider.tsx b/src/components/form/range/range_slider.tsx
index a9120f0fc74..4c16e277000 100644
--- a/src/components/form/range/range_slider.tsx
+++ b/src/components/form/range/range_slider.tsx
@@ -16,6 +16,7 @@ export type EuiRangeSliderProps = InputHTMLAttributes &
min: number;
max: number;
step?: number;
+ compressed?: boolean;
hasFocus?: boolean;
showRange?: boolean;
showTicks?: boolean;
@@ -43,6 +44,7 @@ export const EuiRangeSlider: FunctionComponent<
showTicks,
showRange,
hasFocus,
+ compressed,
...rest
},
ref: Ref
@@ -53,6 +55,7 @@ export const EuiRangeSlider: FunctionComponent<
'euiRangeSlider--hasTicks': showTicks,
'euiRangeSlider--hasFocus': hasFocus,
'euiRangeSlider--hasRange': showRange,
+ 'euiRangeSlider--compressed': compressed,
},
className
);
diff --git a/src/components/form/range/range_ticks.tsx b/src/components/form/range/range_ticks.tsx
index 545707c5d54..d8d63ffc322 100644
--- a/src/components/form/range/range_ticks.tsx
+++ b/src/components/form/range/range_ticks.tsx
@@ -24,6 +24,7 @@ export type EuiRangeTicksProps = Omit<
value?: number | string | Array;
min: number;
max: number;
+ compressed?: boolean;
interval?: number;
disabled?: boolean;
onChange?: MouseEventHandler;
@@ -38,6 +39,7 @@ export const EuiRangeTicks: FunctionComponent = ({
max,
min,
interval = 1,
+ compressed,
}) => {
// Calculate the width of each tick mark
const percentageWidth = (interval / (max - min + interval)) * 100;
@@ -48,8 +50,12 @@ export const EuiRangeTicks: FunctionComponent = ({
? undefined
: { margin: `0 ${percentageWidth / -2}%`, left: 0, right: 0 };
+ const classes = classNames('euiRangeTicks', {
+ 'euiRangeTicks--compressed': compressed,
+ });
+
return (
-
+
{tickSequence.map(tickValue => {
const tickStyle: { left?: string; width?: string } = {};
let customTick;
diff --git a/src/components/form/range/range_tooltip.tsx b/src/components/form/range/range_tooltip.tsx
index 2795deacf3e..73b40f710a9 100644
--- a/src/components/form/range/range_tooltip.tsx
+++ b/src/components/form/range/range_tooltip.tsx
@@ -9,6 +9,7 @@ export interface EuiRangeTooltipProps {
min: number;
name?: string;
showTicks?: boolean;
+ compressed?: boolean;
}
export const EuiRangeTooltip: FunctionComponent
= ({
@@ -19,7 +20,12 @@ export const EuiRangeTooltip: FunctionComponent = ({
min,
name,
showTicks,
+ compressed,
}) => {
+ const classes = classNames('euiRangeTooltip', {
+ 'euiRangeTooltip--compressed': compressed,
+ });
+
// Calculate the left position based on value
let val = 0;
if (typeof value === 'number') {
@@ -52,7 +58,7 @@ export const EuiRangeTooltip: FunctionComponent = ({
);
return (
-
+
;
+ compressed?: boolean;
disabled?: boolean;
showTicks?: boolean;
tickInterval?: number;
@@ -117,6 +118,7 @@ export class EuiRangeTrack extends Component {
levels,
onChange,
value,
+ compressed,
} = this.props;
// TODO: Move these to only re-calculate if no-value props have changed
@@ -147,9 +149,9 @@ export class EuiRangeTrack extends Component {
return (
- {children}
{levels && !!levels.length && (
{
{tickSequence && (
{
interval={tickInterval || step}
/>
)}
+ {children}
);
}
diff --git a/src/components/form/range/range_wrapper.tsx b/src/components/form/range/range_wrapper.tsx
index 78cb6783f21..8179bab0239 100644
--- a/src/components/form/range/range_wrapper.tsx
+++ b/src/components/form/range/range_wrapper.tsx
@@ -4,17 +4,20 @@ import classNames from 'classnames';
export interface EuiRangeWrapperProps {
className?: string;
fullWidth?: boolean;
+ compressed?: boolean;
}
export const EuiRangeWrapper: FunctionComponent = ({
children,
className,
fullWidth,
+ compressed,
}) => {
const classes = classNames(
'euiRangeWrapper',
{
'euiRangeWrapper--fullWidth': fullWidth,
+ 'euiRangeWrapper--compressed': compressed,
},
className
);
diff --git a/src/components/popover/input_popover.tsx b/src/components/popover/input_popover.tsx
index 6659708b0aa..a9f4f2df543 100644
--- a/src/components/popover/input_popover.tsx
+++ b/src/components/popover/input_popover.tsx
@@ -15,9 +15,11 @@ import { cascadingMenuKeyCodes } from '../../services';
interface EuiInputPopoverProps
extends Omit {
+ disableFocusTrap?: boolean;
fullWidth?: boolean;
input: EuiPopoverProps['button'];
inputRef?: EuiPopoverProps['buttonRef'];
+ onPanelResize?: (width?: number) => void;
}
type Props = CommonProps &
@@ -27,8 +29,10 @@ type Props = CommonProps &
export const EuiInputPopover: FunctionComponent = ({
children,
className,
+ disableFocusTrap = false,
input,
fullWidth = false,
+ onPanelResize,
...props
}) => {
const [inputEl, setInputEl] = useState();
@@ -42,6 +46,9 @@ export const EuiInputPopover: FunctionComponent = ({
if (panelEl && (!!inputElWidth || !!width)) {
const newWidth = !!width ? width : inputElWidth;
panelEl.style.width = `${newWidth}px`;
+ if (onPanelResize) {
+ onPanelResize(newWidth);
+ }
}
};
const onResize = () => {
@@ -68,8 +75,9 @@ export const EuiInputPopover: FunctionComponent = ({
);
});
if (
- tabbableItems.length &&
- tabbableItems[tabbableItems.length - 1] === document.activeElement
+ disableFocusTrap ||
+ (tabbableItems.length &&
+ tabbableItems[tabbableItems.length - 1] === document.activeElement)
) {
props.closePopover();
}
@@ -96,7 +104,7 @@ export const EuiInputPopover: FunctionComponent = ({
panelRef={panelRef}
className={classes}
{...props}>
-
+
{children}
From 60a5362b89e9eade815b8e16ea56de5e5752642c Mon Sep 17 00:00:00 2001
From: cchaos
Date: Tue, 10 Sep 2019 15:47:46 -0400
Subject: [PATCH 09/20] Added some display toggles for ranges and ranges with
dropdowns to the complex example
Has issues
---
.../views/form_compressed/complex_example.js | 77 +++++++++++--------
src-docs/src/views/range/input_only.js | 62 ++++++---------
src-docs/src/views/range/states.js | 73 ++++++++----------
3 files changed, 101 insertions(+), 111 deletions(-)
diff --git a/src-docs/src/views/form_compressed/complex_example.js b/src-docs/src/views/form_compressed/complex_example.js
index 5ca9da1b1f7..1a36d667a80 100644
--- a/src-docs/src/views/form_compressed/complex_example.js
+++ b/src-docs/src/views/form_compressed/complex_example.js
@@ -48,12 +48,24 @@ export default class extends Component {
opacityValue: '20',
buttonGroupIdSelected: `${idPrefix}1`,
color: '#DB1374',
+ borderValue: 3,
+ popoverSliderValues: 16,
};
this.selectTooltipContent =
'Otherwise use an EuiToolTip around the label of the form row.';
}
+ onPopoverSliderValueChange = e => {
+ this.setState({
+ popoverSliderValues: e.target.value,
+ });
+ };
+
+ onBorderChange = e => {
+ this.setState({ borderValue: e.target.value });
+ };
+
onColorChange = value => {
this.setState({ color: value });
};
@@ -88,18 +100,16 @@ export default class extends Component {
compressed
prepend="Zoom levels"
startControl={
-
}
endControl={
-
}
@@ -116,10 +126,12 @@ export default class extends Component {
compressed
value={this.state.opacityValue}
onChange={this.onRangeChange}
- // append="%"
+ append="%"
/>
+
+
{this.selectTooltipContent}
@@ -153,31 +165,32 @@ export default class extends Component {
/>
-
+
+
+
+
+
- }
- append="px"
- />
-
-
-
- ,
+ 'kibana_sample_ecommerce_data',
]}
- compressed
+ append="px"
/>
@@ -200,11 +213,12 @@ export default class extends Component {
/>
-
-
-
diff --git a/src-docs/src/views/range/input_only.js b/src-docs/src/views/range/input_only.js
index f6e1cd08463..65cf3a7084e 100644
--- a/src-docs/src/views/range/input_only.js
+++ b/src-docs/src/views/range/input_only.js
@@ -2,6 +2,8 @@ import React, { Component, Fragment } from 'react';
import { EuiRange, EuiSpacer, EuiDualRange } from '../../../../src/components';
+import { DisplayToggles } from '../form_controls/display_toggles';
+
import makeId from '../../../../src/components/form/form_row/make_id';
export default class extends Component {
@@ -42,48 +44,30 @@ export default class extends Component {
render() {
return (
-
-
-
-
-
-
-
-
-
+
+
+
-
+
+
+
);
}
diff --git a/src-docs/src/views/range/states.js b/src-docs/src/views/range/states.js
index 926f58bb189..fc97f01f8ab 100644
--- a/src-docs/src/views/range/states.js
+++ b/src-docs/src/views/range/states.js
@@ -1,11 +1,7 @@
import React, { Component, Fragment } from 'react';
-import {
- EuiRange,
- EuiSpacer,
- EuiFormHelpText,
- EuiDualRange,
-} from '../../../../src/components';
+import { EuiRange, EuiSpacer, EuiDualRange } from '../../../../src/components';
+import { DisplayToggles } from '../form_controls/display_toggles';
import makeId from '../../../../src/components/form/form_row/make_id';
@@ -47,45 +43,38 @@ export default class extends Component {
render() {
return (
-
-
- Recommended levels are {this.levels[1].min} and above.
-
+
+
+
-
-
- Recommended size is {this.levels[1].min}kb and above.
-
+
+
+
);
}
From cfb4a3604d222d92bfa5d0ea3f23bb556f6a1258 Mon Sep 17 00:00:00 2001
From: cchaos
Date: Tue, 10 Sep 2019 17:13:48 -0400
Subject: [PATCH 10/20] Fix console errors
---
src-docs/src/views/range/states.js | 4 ++--
.../form/form_control_layout/form_control_layout.tsx | 9 +++++----
src/components/form/range/dual_range.js | 6 ++++++
src/components/form/range/range.js | 4 ++++
4 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/src-docs/src/views/range/states.js b/src-docs/src/views/range/states.js
index fc97f01f8ab..39b20e48929 100644
--- a/src-docs/src/views/range/states.js
+++ b/src-docs/src/views/range/states.js
@@ -43,7 +43,7 @@ export default class extends Component {
render() {
return (
-
+
-
+
& {
/**
* Creates an input group with element(s) coming before children
*/
- prepend?: string | ReactElements;
+ prepend?: PrependAppendType;
/**
* Creates an input group with element(s) coming after children
*/
- append?: string | ReactElements;
+ append?: PrependAppendType;
children?: ReactNode;
icon?: EuiFormControlLayoutIconsProps['icon'];
clear?: EuiFormControlLayoutIconsProps['clear'];
@@ -95,7 +96,7 @@ export class EuiFormControlLayout extends Component {
renderSideNode(
side: 'append' | 'prepend',
- nodes?: string | ReactElements,
+ nodes?: PrependAppendType,
inputId?: string
) {
if (!nodes) {
diff --git a/src/components/form/range/dual_range.js b/src/components/form/range/dual_range.js
index 8e0b3131bbb..8d9905b4fcd 100644
--- a/src/components/form/range/dual_range.js
+++ b/src/components/form/range/dual_range.js
@@ -298,6 +298,8 @@ export class EuiDualRange extends Component {
showRange,
value,
style,
+ isLoading,
+ isInvalid,
...rest
} = this.props;
@@ -326,6 +328,8 @@ export class EuiDualRange extends Component {
readOnly={readOnly}
autoSize={!showInputOnly}
fullWidth={!!showInputOnly && fullWidth}
+ isLoading={!!showInputOnly && isLoading}
+ isInvalid={isInvalid}
controlOnly={showInputOnly}
inputRef={node => this.inputRef(node, 'minNode')}
/>
@@ -352,7 +356,9 @@ export class EuiDualRange extends Component {
readOnly={readOnly}
autoSize={!showInputOnly}
fullWidth={!!showInputOnly && fullWidth}
+ isLoading={!!showInputOnly && isLoading}
controlOnly={showInputOnly}
+ isInvalid={isInvalid}
inputRef={node => this.inputRef(node, 'maxNode')}
/>
) : (
diff --git a/src/components/form/range/range.js b/src/components/form/range/range.js
index 2de1b30db00..7fb313b2b23 100644
--- a/src/components/form/range/range.js
+++ b/src/components/form/range/range.js
@@ -80,6 +80,7 @@ export class EuiRange extends Component {
compressed,
disabled,
fullWidth,
+ isLoading,
readOnly,
id: propsId,
max,
@@ -100,6 +101,7 @@ export class EuiRange extends Component {
value,
style,
tabIndex,
+ isInvalid,
...rest
} = this.props;
@@ -123,6 +125,8 @@ export class EuiRange extends Component {
name={name}
onFocus={canShowDropdown ? this.onInputFocus : undefined}
fullWidth={showInputOnly && fullWidth}
+ isLoading={showInputOnly && isLoading}
+ isInvalid={isInvalid}
autoSize={!showInputOnly}
inputRef={this.inputRef}
{...rest}
From 21fa2c67abfe0051b8e633e572ab9fc2bbe370cb Mon Sep 17 00:00:00 2001
From: cchaos
Date: Tue, 10 Sep 2019 17:44:35 -0400
Subject: [PATCH 11/20] Some fixes
- Ranges use div spacers between slider and input instead of margin
- Pre/Appends are restrictred to 50% width and truncated
---
.../views/form_compressed/complex_example.js | 2 +-
.../_form_control_layout.scss | 2 +
.../__snapshots__/dual_range.test.js.snap | 72 +++++++++++++++++++
.../range/__snapshots__/range.test.js.snap | 39 ++++++++++
src/components/form/range/_index.scss | 1 +
src/components/form/range/_range.scss | 3 +
src/components/form/range/_range_input.scss | 8 ---
src/components/form/range/dual_range.js | 14 +++-
src/components/form/range/range.js | 7 +-
9 files changed, 136 insertions(+), 12 deletions(-)
create mode 100644 src/components/form/range/_range.scss
diff --git a/src-docs/src/views/form_compressed/complex_example.js b/src-docs/src/views/form_compressed/complex_example.js
index 1a36d667a80..262613869b5 100644
--- a/src-docs/src/views/form_compressed/complex_example.js
+++ b/src-docs/src/views/form_compressed/complex_example.js
@@ -264,7 +264,7 @@ export default class extends Component {
Border
-
+
+
@@ -18,6 +21,9 @@ exports[`EuiDualRange allows value prop to accept empty strings 1`] = `
type="range"
/>
+
`;
@@ -25,6 +31,9 @@ exports[`EuiDualRange allows value prop to accept numbers 1`] = `
+
@@ -47,6 +56,9 @@ exports[`EuiDualRange allows value prop to accept numbers 1`] = `
type="range"
/>
+
`;
@@ -54,6 +66,9 @@ exports[`EuiDualRange is rendered 1`] = `
+
@@ -79,6 +94,9 @@ exports[`EuiDualRange is rendered 1`] = `
type="range"
/>
+
`;
@@ -86,6 +104,9 @@ exports[`EuiDualRange props compressed should render 1`] = `
+
@@ -108,6 +129,9 @@ exports[`EuiDualRange props compressed should render 1`] = `
type="range"
/>
+
`;
@@ -115,6 +139,9 @@ exports[`EuiDualRange props custom ticks should render 1`] = `
+
`;
@@ -169,6 +199,9 @@ exports[`EuiDualRange props disabled should render 1`] = `
+
@@ -192,6 +225,9 @@ exports[`EuiDualRange props disabled should render 1`] = `
type="range"
/>
+
`;
@@ -199,6 +235,9 @@ exports[`EuiDualRange props fullWidth should render 1`] = `
+
@@ -221,6 +260,9 @@ exports[`EuiDualRange props fullWidth should render 1`] = `
type="range"
/>
+
`;
@@ -247,6 +289,9 @@ exports[`EuiDualRange props inputs should render 1`] = `
/>
+
@@ -272,6 +317,9 @@ exports[`EuiDualRange props inputs should render 1`] = `
type="range"
/>
+
`;
diff --git a/src/components/form/range/__snapshots__/range.test.js.snap b/src/components/form/range/__snapshots__/range.test.js.snap
index 6d2a528f324..f9dcab2eeb3 100644
--- a/src/components/form/range/__snapshots__/range.test.js.snap
+++ b/src/components/form/range/__snapshots__/range.test.js.snap
@@ -27,6 +27,9 @@ exports[`EuiRange allows value prop to accept a number 1`] = `
+
`;
@@ -47,6 +50,9 @@ exports[`EuiRange allows value prop to accept empty string 1`] = `
value=""
/>
+
`;
@@ -70,6 +76,9 @@ exports[`EuiRange is rendered 1`] = `
value="8"
/>
+
`;
@@ -89,6 +98,9 @@ exports[`EuiRange props compressed should render 1`] = `
type="range"
/>
+
`;
@@ -133,6 +145,9 @@ exports[`EuiRange props custom ticks should render 1`] = `
type="range"
/>
+
`;
@@ -153,6 +168,9 @@ exports[`EuiRange props disabled should render 1`] = `
type="range"
/>
+
`;
@@ -172,6 +190,9 @@ exports[`EuiRange props fullWidth should render 1`] = `
type="range"
/>
+
`;
@@ -228,6 +249,9 @@ exports[`EuiRange props input should render 1`] = `
value="8"
/>
+
`;
@@ -308,6 +335,9 @@ exports[`EuiRange props levels should render 1`] = `
type="range"
/>
+
`;
@@ -336,6 +366,9 @@ exports[`EuiRange props range should render 1`] = `
value="8"
/>
+
`;
@@ -415,6 +448,9 @@ exports[`EuiRange props ticks should render 1`] = `
type="range"
/>
+
`;
@@ -445,5 +481,8 @@ exports[`EuiRange props value should render 1`] = `
+
`;
diff --git a/src/components/form/range/_index.scss b/src/components/form/range/_index.scss
index b118aebe3d7..b8d4204e060 100644
--- a/src/components/form/range/_index.scss
+++ b/src/components/form/range/_index.scss
@@ -1,6 +1,7 @@
@import 'variables';
@import 'mixins';
+@import 'range';
@import 'range_highlight';
@import 'range_input';
@import 'range_label';
diff --git a/src/components/form/range/_range.scss b/src/components/form/range/_range.scss
new file mode 100644
index 00000000000..3e94f34ce31
--- /dev/null
+++ b/src/components/form/range/_range.scss
@@ -0,0 +1,3 @@
+.euiRange__horizontalSpacer {
+ width: $euiSize;
+}
diff --git a/src/components/form/range/_range_input.scss b/src/components/form/range/_range_input.scss
index e4954a325c8..0de7fda4ef9 100644
--- a/src/components/form/range/_range_input.scss
+++ b/src/components/form/range/_range_input.scss
@@ -2,14 +2,6 @@
width: auto;
min-width: $euiSize * 4;
- &--min {
- margin-right: $euiSize;
- }
-
- &--max {
- margin-left: $euiSize;
- }
-
.euiRange__popover & {
// sass-lint:disable no-important
margin: 0 !important;
diff --git a/src/components/form/range/dual_range.js b/src/components/form/range/dual_range.js
index 8d9905b4fcd..2839c88e154 100644
--- a/src/components/form/range/dual_range.js
+++ b/src/components/form/range/dual_range.js
@@ -371,7 +371,12 @@ export class EuiDualRange extends Component {
className={classes}
fullWidth={fullWidth}
compressed={compressed}>
- {!showInputOnly && minInput}
+ {!showInputOnly && (
+ <>
+ {minInput}
+
+ >
+ )}
{showLabels && (
{min}
@@ -461,7 +466,12 @@ export class EuiDualRange extends Component {
)}
{showLabels && {max} }
- {!showInputOnly && maxInput}
+ {!showInputOnly && (
+ <>
+
+ {maxInput}
+ >
+ )}
);
diff --git a/src/components/form/range/range.js b/src/components/form/range/range.js
index 7fb313b2b23..5150201c17c 100644
--- a/src/components/form/range/range.js
+++ b/src/components/form/range/range.js
@@ -205,7 +205,12 @@ export class EuiRange extends Component {
{max}
)}
- {!showInputOnly && theInput}
+ {!showInputOnly && (
+ <>
+
+ {theInput}
+ >
+ )}
);
From c96f483686dd559213472d12f7f973163232f1ef Mon Sep 17 00:00:00 2001
From: Greg Thompson
Date: Tue, 10 Sep 2019 17:01:33 -0500
Subject: [PATCH 12/20] [feature/compressed-editor-controls] EuiRange +
EuiFormRow (#2321)
* focus management
* add euiformrow to some examples
* use prevention flag
* Revert "add euiformrow to some examples"
This reverts commit f93ef4e36d426fe7b5fcc02d308b3d89365baa11.
* clean up
---
src/components/form/range/dual_range.js | 86 +++++++++++++++----------
src/components/form/range/range.js | 55 ++++++++--------
2 files changed, 82 insertions(+), 59 deletions(-)
diff --git a/src/components/form/range/dual_range.js b/src/components/form/range/dual_range.js
index 8e0b3131bbb..d2ae35537e6 100644
--- a/src/components/form/range/dual_range.js
+++ b/src/components/form/range/dual_range.js
@@ -25,8 +25,7 @@ export class EuiDualRange extends Component {
rangeWidth: null,
};
- maxNode = null;
- minNode = null;
+ preventPopoverClose = false;
rangeSliderRef = null;
handleRangeSliderRefUpdate = ref => {
this.rangeSliderRef = ref;
@@ -234,21 +233,48 @@ export class EuiDualRange extends Component {
});
};
- onInputFocus = () => {
+ onThumbFocus = e => {
+ if (this.props.onFocus) {
+ this.props.onFocus(e);
+ }
+ this.toggleHasFocus(true);
+ };
+
+ onThumbBlur = e => {
+ if (this.props.onBlur) {
+ this.props.onBlur(e);
+ }
+ this.toggleHasFocus(false);
+ };
+
+ onInputFocus = e => {
+ if (this.props.onFocus) {
+ this.props.onFocus(e);
+ }
+ this.preventPopoverClose = true;
this.setState({
isPopoverOpen: true,
});
};
- onInputBlur = e => {
- // Firefox returns `relatedTarget` as `null` for security reasons, but provides a proprietary `explicitOriginalTarget`
- const relatedTarget = e.relatedTarget || e.explicitOriginalTarget;
- if (!relatedTarget || relatedTarget.id !== this.state.id) {
+ onInputBlur = e =>
+ setTimeout(() => {
+ // Safari does not recognize any focus-related eventing for input[type=range]
+ // making it impossible to capture its state using active/focus/relatedTarget
+ // Instead, a prevention flag is set on mousedown, with a waiting period here.
+ // Mousedown is viable because in the popover case, it is inaccessable via keyboard (intentionally)
+ if (this.preventPopoverClose) {
+ this.preventPopoverClose = false;
+ return;
+ }
+ if (this.props.onBlur) {
+ this.props.onBlur(e);
+ }
this.closePopover();
- }
- };
+ }, 200);
closePopover = () => {
+ this.preventPopoverClose = false;
this.setState({
isPopoverOpen: false,
});
@@ -260,22 +286,6 @@ export class EuiDualRange extends Component {
});
};
- inputRef = (node, ref) => {
- if (!this.props.showInput !== 'inputWithPopover') return;
-
- // IE11 doesn't support the `relatedTarget` event property for blur events
- // but does add it for focusout. React doesn't support `onFocusOut` so here we are.
- if (this[ref] != null) {
- this[ref].removeEventListener('focusout', this.onInputBlur);
- }
-
- this[ref] = node;
-
- if (this[ref]) {
- this[ref].addEventListener('focusout', this.onInputBlur);
- }
- };
-
render() {
const {
className,
@@ -294,7 +304,9 @@ export class EuiDualRange extends Component {
tickInterval,
ticks,
levels,
+ onBlur,
onChange,
+ onFocus,
showRange,
value,
style,
@@ -322,12 +334,15 @@ export class EuiDualRange extends Component {
name={`${name}-minValue`}
aria-describedby={this.props['aria-describedby']}
aria-label={this.props['aria-label']}
- onFocus={canShowDropdown ? this.onInputFocus : undefined}
+ onFocus={canShowDropdown ? this.onInputFocus : onFocus}
+ onBlur={canShowDropdown ? this.onInputBlur : onBlur}
readOnly={readOnly}
autoSize={!showInputOnly}
fullWidth={!!showInputOnly && fullWidth}
controlOnly={showInputOnly}
- inputRef={node => this.inputRef(node, 'minNode')}
+ onMouseDown={
+ showInputOnly ? () => (this.preventPopoverClose = true) : null
+ }
/>
) : (
undefined
@@ -348,12 +363,15 @@ export class EuiDualRange extends Component {
name={`${name}-maxValue`}
aria-describedby={this.props['aria-describedby']}
aria-label={this.props['aria-label']}
- onFocus={canShowDropdown ? this.onInputFocus : undefined}
+ onFocus={canShowDropdown ? this.onInputFocus : onFocus}
+ onBlur={canShowDropdown ? this.onInputBlur : onBlur}
readOnly={readOnly}
autoSize={!showInputOnly}
fullWidth={!!showInputOnly && fullWidth}
controlOnly={showInputOnly}
- inputRef={node => this.inputRef(node, 'maxNode')}
+ onMouseDown={
+ showInputOnly ? () => (this.preventPopoverClose = true) : null
+ }
/>
) : (
undefined
@@ -412,6 +430,8 @@ export class EuiDualRange extends Component {
aria-hidden={true}
tabIndex={-1}
showRange={showRange}
+ onFocus={onFocus}
+ onBlur={onBlur}
{...rest}
/>
@@ -425,8 +445,8 @@ export class EuiDualRange extends Component {
showTicks={showTicks}
showInput={!!showInput}
onKeyDown={this.handleLowerKeyDown}
- onFocus={() => this.toggleHasFocus(true)}
- onBlur={() => this.toggleHasFocus(false)}
+ onFocus={this.onThumbFocus}
+ onBlur={this.onThumbBlur}
style={this.calculateThumbPositionStyle(
this.lowerValue || min,
this.state.rangeWidth
@@ -442,8 +462,8 @@ export class EuiDualRange extends Component {
showTicks={showTicks}
showInput={!!showInput}
onKeyDown={this.handleUpperKeyDown}
- onFocus={() => this.toggleHasFocus(true)}
- onBlur={() => this.toggleHasFocus(false)}
+ onFocus={this.onThumbFocus}
+ onBlur={this.onThumbBlur}
style={this.calculateThumbPositionStyle(
this.upperValue || max,
this.state.rangeWidth
diff --git a/src/components/form/range/range.js b/src/components/form/range/range.js
index 2de1b30db00..13c71f5827f 100644
--- a/src/components/form/range/range.js
+++ b/src/components/form/range/range.js
@@ -22,7 +22,7 @@ export class EuiRange extends Component {
isPopoverOpen: false,
};
- this.inputNode = null;
+ this.preventPopoverClose = false;
}
handleOnChange = e => {
@@ -38,42 +38,38 @@ export class EuiRange extends Component {
return isWithinRange(this.props.min, this.props.max, this.props.value);
}
- onInputFocus = () => {
+ onInputFocus = e => {
+ if (this.props.onFocus) {
+ this.props.onFocus(e);
+ }
this.setState({
isPopoverOpen: true,
});
};
- onInputBlur = e => {
- // Firefox returns `relatedTarget` as `null` for security reasons, but provides a proprietary `explicitOriginalTarget`
- const relatedTarget = e.relatedTarget || e.explicitOriginalTarget;
- if (!relatedTarget || relatedTarget.id !== this.state.id) {
+ onInputBlur = e =>
+ setTimeout(() => {
+ // Safari does not recognize any focus-related eventing for input[type=range]
+ // making it impossible to capture its state using active/focus/relatedTarget
+ // Instead, a prevention flag is set on mousedown, with a waiting period here.
+ // Mousedown is viable because in the popover case, it is inaccessable via keyboard (intentionally)
+ if (this.preventPopoverClose) {
+ this.preventPopoverClose = false;
+ return;
+ }
+ if (this.props.onBlur) {
+ this.props.onBlur(e);
+ }
this.closePopover();
- }
- };
+ }, 200);
closePopover = () => {
+ this.preventPopoverClose = false;
this.setState({
isPopoverOpen: false,
});
};
- inputRef = node => {
- if (!this.props.showInput !== 'inputWithPopover') return;
-
- // IE11 and Safar don't support the `relatedTarget` event property for blur events
- // but do add it for focusout. React doesn't support `onFocusOut` so here we are.
- if (this.inputNode != null) {
- this.inputNode.removeEventListener('focusout', this.onInputBlur);
- }
-
- this.inputNode = node;
-
- if (this.inputNode) {
- this.inputNode.addEventListener('focusout', this.onInputBlur);
- }
- };
-
render() {
const {
className,
@@ -96,7 +92,9 @@ export class EuiRange extends Component {
showValue,
valueAppend,
valuePrepend,
+ onBlur,
onChange,
+ onFocus,
value,
style,
tabIndex,
@@ -121,10 +119,10 @@ export class EuiRange extends Component {
compressed={compressed}
onChange={this.handleOnChange}
name={name}
- onFocus={canShowDropdown ? this.onInputFocus : undefined}
+ onFocus={canShowDropdown ? this.onInputFocus : onFocus}
+ onBlur={canShowDropdown ? this.onInputBlur : onBlur}
fullWidth={showInputOnly && fullWidth}
autoSize={!showInputOnly}
- inputRef={this.inputRef}
{...rest}
/>
) : (
@@ -180,6 +178,11 @@ export class EuiRange extends Component {
showTicks={showTicks}
showRange={showRange}
tabIndex={showInput ? -1 : tabIndex || null}
+ onMouseDown={
+ showInputOnly ? () => (this.preventPopoverClose = true) : null
+ }
+ onFocus={showInput === true ? null : onFocus}
+ onBlur={showInputOnly ? this.onInputBlur : onBlur}
{...rest}
/>
From a494d3538cec62bd30c8bce31d01a79e82be3a24 Mon Sep 17 00:00:00 2001
From: cchaos
Date: Tue, 10 Sep 2019 20:15:33 -0400
Subject: [PATCH 13/20] Cleanup
---
src-docs/src/views/combo_box/combo_box.js | 2 +-
.../views/form_compressed/complex_example.js | 26 +++----
.../views/form_compressed/form_compressed.js | 21 -----
.../views/form_compressed/form_horizontal.js | 55 -------------
.../form_compressed/form_horizontal_help.js | 77 +++++++------------
.../views/form_controls/display_toggles.js | 9 ++-
.../src/views/form_controls/field_text.js | 1 -
src-docs/src/views/range/input_only.js | 2 +-
src/components/combo_box/_combo_box.scss | 1 -
.../combo_box_input/_combo_box_pill.scss | 2 +-
.../date_popover/_absolute_tab.scss | 2 +-
.../form/file_picker/_file_picker.scss | 2 +-
.../_form_control_layout.scss | 2 +-
.../__snapshots__/dual_range.test.js.snap | 72 ++++++++---------
.../range/__snapshots__/range.test.js.snap | 64 +++++++--------
.../form/range/_range_highlight.scss | 1 -
src/components/form/range/dual_range.js | 7 +-
src/components/form/range/dual_range.test.js | 2 +-
src/components/form/range/range.test.js | 2 +-
19 files changed, 127 insertions(+), 223 deletions(-)
diff --git a/src-docs/src/views/combo_box/combo_box.js b/src-docs/src/views/combo_box/combo_box.js
index e2144f9db1b..973334206d4 100644
--- a/src-docs/src/views/combo_box/combo_box.js
+++ b/src-docs/src/views/combo_box/combo_box.js
@@ -84,7 +84,7 @@ export default class extends Component {
const { selectedOptions } = this.state;
return (
/* DisplayToggles wrapper for Docs only */
-
+
{
- this.setState({
- radioIdSelected: optionId,
- });
- };
-
render() {
return (
diff --git a/src-docs/src/views/form_compressed/form_horizontal.js b/src-docs/src/views/form_compressed/form_horizontal.js
index 63f00966b13..559015f8654 100644
--- a/src-docs/src/views/form_compressed/form_horizontal.js
+++ b/src-docs/src/views/form_compressed/form_horizontal.js
@@ -11,48 +11,12 @@ import {
EuiPanel,
} from '../../../../src/components';
-import makeId from '../../../../src/components/form/form_row/make_id';
-
export default class extends Component {
constructor(props) {
super(props);
- const idPrefix = makeId();
-
this.state = {
isSwitchChecked: false,
- checkboxes: [
- {
- id: `${idPrefix}0`,
- label: 'Option one',
- },
- {
- id: `${idPrefix}1`,
- label: 'Option two is checked by default',
- },
- {
- id: `${idPrefix}2`,
- label: 'Option three',
- },
- ],
- checkboxIdToSelectedMap: {
- [`${idPrefix}1`]: true,
- },
- radios: [
- {
- id: `${idPrefix}4`,
- label: 'Option one',
- },
- {
- id: `${idPrefix}5`,
- label: 'Option two is selected by default',
- },
- {
- id: `${idPrefix}6`,
- label: 'Option three',
- },
- ],
- radioIdSelected: `${idPrefix}5`,
comboBoxSelectionOptions: [],
value: '20',
};
@@ -70,25 +34,6 @@ export default class extends Component {
});
};
- onCheckboxChange = optionId => {
- const newCheckboxIdToSelectedMap = {
- ...this.state.checkboxIdToSelectedMap,
- ...{
- [optionId]: !this.state.checkboxIdToSelectedMap[optionId],
- },
- };
-
- this.setState({
- checkboxIdToSelectedMap: newCheckboxIdToSelectedMap,
- });
- };
-
- onRadioChange = optionId => {
- this.setState({
- radioIdSelected: optionId,
- });
- };
-
render() {
return (
diff --git a/src-docs/src/views/form_compressed/form_horizontal_help.js b/src-docs/src/views/form_compressed/form_horizontal_help.js
index 9cdc912c92d..b97b4b2ac66 100644
--- a/src-docs/src/views/form_compressed/form_horizontal_help.js
+++ b/src-docs/src/views/form_compressed/form_horizontal_help.js
@@ -1,4 +1,4 @@
-import React, { Component } from 'react';
+import React from 'react';
import {
EuiFieldText,
@@ -9,51 +9,32 @@ import {
} from '../../../../src/components';
import { EuiToolTip } from '../../../../src/components/tool_tip';
-export default class extends Component {
- constructor(props) {
- super(props);
+export default () => (
+
+
+
+
- this.state = {
- isSwitchChecked: false,
- value: '20',
- };
- }
-
- onSwitchChange = () => {
- this.setState({
- isSwitchChecked: !this.state.isSwitchChecked,
- });
- };
-
- render() {
- return (
-
-
-
-
-
-
-
- Label
-
-
- }
- display="columnCompressed">
-
-
-
- );
- }
-}
+
+
+ Label
+
+
+ }
+ display="columnCompressed">
+
+
+
+);
diff --git a/src-docs/src/views/form_controls/display_toggles.js b/src-docs/src/views/form_controls/display_toggles.js
index aa9206c2b3f..b7cb8dea9a1 100644
--- a/src-docs/src/views/form_controls/display_toggles.js
+++ b/src-docs/src/views/form_controls/display_toggles.js
@@ -39,6 +39,7 @@ export class DisplayToggles extends Component {
render() {
const {
+ canIsDisabled,
canDisabled,
canReadOnly,
canLoading,
@@ -49,12 +50,11 @@ export class DisplayToggles extends Component {
canInvalid,
children,
extras,
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- onUpdate,
} = this.props;
const canProps = {};
if (canDisabled) canProps.disabled = this.state.disabled;
+ if (canIsDisabled) canProps.isDisabled = this.state.disabled;
if (canReadOnly) canProps.readOnly = this.state.readOnly;
if (canLoading) canProps.isLoading = this.state.loading;
if (canFullWidth) canProps.fullWidth = this.state.fullWidth;
@@ -84,7 +84,7 @@ export class DisplayToggles extends Component {
}>
- {canDisabled && (
+ {(canDisabled || canIsDisabled) && (
);
diff --git a/src-docs/src/views/range/input_only.js b/src-docs/src/views/range/input_only.js
index 65cf3a7084e..dc8da0f16fd 100644
--- a/src-docs/src/views/range/input_only.js
+++ b/src-docs/src/views/range/input_only.js
@@ -56,7 +56,7 @@ export default class extends Component {
-
+
`;
-exports[`EuiDualRange props only input should render 1`] = `
+exports[`EuiDualRange props range should render 1`] = `
+
+`;
+
+exports[`EuiDualRange props slider should display in popover 1`] = `
@@ -484,41 +519,6 @@ exports[`EuiDualRange props only input should render 1`] = `
`;
-exports[`EuiDualRange props range should render 1`] = `
-
-`;
-
exports[`EuiDualRange props ticks should render 1`] = `
`;
-exports[`EuiRange props input only should render 1`] = `
-
-`;
-
exports[`EuiRange props input should render 1`] = `
`;
+exports[`EuiRange props slider should display in popover 1`] = `
+
+`;
+
exports[`EuiRange props ticks should render 1`] = `
}
fullWidth={fullWidth}
diff --git a/src/components/form/range/dual_range.test.js b/src/components/form/range/dual_range.test.js
index 03c9a822023..fad041a3a4f 100644
--- a/src/components/form/range/dual_range.test.js
+++ b/src/components/form/range/dual_range.test.js
@@ -88,7 +88,7 @@ describe('EuiDualRange', () => {
expect(component).toMatchSnapshot();
});
- test('only input should render', () => {
+ test('slider should display in popover', () => {
const component = render(
{
expect(component).toMatchSnapshot();
});
- test('input only should render', () => {
+ test('slider should display in popover', () => {
const component = render(
Date: Tue, 10 Sep 2019 22:42:39 -0400
Subject: [PATCH 14/20] Add `controlOnly` prop to EuiFieldText
---
.../__snapshots__/field_text.test.js.snap | 9 +++++
src/components/form/field_text/field_text.js | 38 ++++++++++++-------
.../form/field_text/field_text.test.js | 6 +++
3 files changed, 40 insertions(+), 13 deletions(-)
diff --git a/src/components/form/field_text/__snapshots__/field_text.test.js.snap b/src/components/form/field_text/__snapshots__/field_text.test.js.snap
index 3e67debb490..f927679d823 100644
--- a/src/components/form/field_text/__snapshots__/field_text.test.js.snap
+++ b/src/components/form/field_text/__snapshots__/field_text.test.js.snap
@@ -23,6 +23,15 @@ exports[`EuiFieldText is rendered 1`] = `
`;
+exports[`EuiFieldText props controlOnly is rendered 1`] = `
+
+
+
+`;
+
exports[`EuiFieldText props fullWidth is rendered 1`] = `
{
const classes = classNames('euiFieldText', className, {
@@ -31,6 +32,24 @@ export const EuiFieldText = ({
'euiFieldText-isLoading': isLoading,
});
+ const control = (
+
+
+
+ );
+
+ if (controlOnly) return control;
+
return (
-
-
-
+ {control}
);
};
@@ -87,6 +94,11 @@ EuiFieldText.propTypes = {
PropTypes.node,
PropTypes.arrayOf(PropTypes.node),
]),
+ /**
+ * Completely removes form control layout wrapper and ignores
+ * icon, prepend, and append. Best used inside EuiFormControlLayoutDelimited.
+ */
+ controlOnly: PropTypes.bool,
};
EuiFieldText.defaultProps = {
diff --git a/src/components/form/field_text/field_text.test.js b/src/components/form/field_text/field_text.test.js
index 3694e82731d..1797eb54dc2 100644
--- a/src/components/form/field_text/field_text.test.js
+++ b/src/components/form/field_text/field_text.test.js
@@ -57,5 +57,11 @@ describe('EuiFieldText', () => {
expect(component).toMatchSnapshot();
});
+
+ test('controlOnly is rendered', () => {
+ const component = render( );
+
+ expect(component).toMatchSnapshot();
+ });
});
});
From 15694a98d2252a2e33198f2e7717f6dbfed08379 Mon Sep 17 00:00:00 2001
From: cchaos
Date: Tue, 10 Sep 2019 22:58:34 -0400
Subject: [PATCH 15/20] Update TS defs
---
src/components/form/field_number/index.d.ts | 1 +
src/components/form/field_text/index.d.ts | 1 +
src/components/form/form_row/index.d.ts | 8 +++++++-
src/components/form/range/index.d.ts | 3 ++-
4 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/src/components/form/field_number/index.d.ts b/src/components/form/field_number/index.d.ts
index 24d0f9eb28c..a90e7123c38 100644
--- a/src/components/form/field_number/index.d.ts
+++ b/src/components/form/field_number/index.d.ts
@@ -18,6 +18,7 @@ declare module '@elastic/eui' {
prepend?: ReactNode | ReactNode[];
append?: ReactNode | ReactNode[];
inputRef?: Ref;
+ controlOnly?: boolean;
}
export const EuiFieldNumber: FunctionComponent<
diff --git a/src/components/form/field_text/index.d.ts b/src/components/form/field_text/index.d.ts
index 61b118436bc..c88d2f18840 100644
--- a/src/components/form/field_text/index.d.ts
+++ b/src/components/form/field_text/index.d.ts
@@ -17,6 +17,7 @@ declare module '@elastic/eui' {
prepend?: React.ReactNode;
append?: React.ReactNode;
compressed?: boolean;
+ controlOnly?: boolean;
}
export const EuiFieldText: FunctionComponent<
diff --git a/src/components/form/form_row/index.d.ts b/src/components/form/form_row/index.d.ts
index 76c08290f4c..564e4f58742 100644
--- a/src/components/form/form_row/index.d.ts
+++ b/src/components/form/form_row/index.d.ts
@@ -21,7 +21,13 @@ declare module '@elastic/eui' {
labelAppend?: ReactNode;
describedByIds?: string[];
compressed?: boolean;
- display?: 'row' | 'rowCompressed' | 'columnCompressed';
+ display?:
+ | 'row'
+ | 'rowCompressed'
+ | 'columnCompressed'
+ | 'center'
+ | 'centerCompressed'
+ | 'columnCompressedSwitch';
displayOnly?: boolean;
};
diff --git a/src/components/form/range/index.d.ts b/src/components/form/range/index.d.ts
index 14cacd52569..c2fed6e2ef9 100644
--- a/src/components/form/range/index.d.ts
+++ b/src/components/form/range/index.d.ts
@@ -33,6 +33,7 @@ declare module '@elastic/eui' {
export interface EuiRangeProps {
compressed?: boolean;
+ readOnly?: boolean;
fullWidth?: boolean;
id?: string;
levels?: EuiRangeLevel[];
@@ -43,7 +44,7 @@ declare module '@elastic/eui' {
// The spec allows string values for `step` but the component requires
// a number.
step?: number;
- showInput?: boolean;
+ showInput?: boolean | 'inputWithPopover';
showLabels?: boolean;
showRange?: boolean;
showTicks?: boolean;
From 8ba88c0b0583b33a7422854fd918daa228f2c24b Mon Sep 17 00:00:00 2001
From: cchaos
Date: Wed, 11 Sep 2019 11:29:03 -0400
Subject: [PATCH 16/20] Some docs fixes
---
src-docs/src/views/expression/expression.js | 8 ++++++--
src-docs/src/views/modal/modal.js | 3 +++
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/src-docs/src/views/expression/expression.js b/src-docs/src/views/expression/expression.js
index 04b0aa4f6ed..37e167e0034 100644
--- a/src-docs/src/views/expression/expression.js
+++ b/src-docs/src/views/expression/expression.js
@@ -101,6 +101,7 @@ export default class extends Component {
When
-
+
@@ -160,7 +163,7 @@ export default class extends Component {
isOpen={this.state.example1.isOpen}
closePopover={this.closeExample1}
ownFocus
- withTitle
+ panelPaddingSize="s"
anchorPosition="downLeft">
{this.renderPopover1()}
@@ -169,6 +172,7 @@ export default class extends Component {
+
+
{'Title '}
From 69beef776cc9a1e3ab5d67f5bac208f93ed9adbe Mon Sep 17 00:00:00 2001
From: cchaos
Date: Wed, 11 Sep 2019 11:53:35 -0400
Subject: [PATCH 17/20] Fix inherit screen reader ability of EuiRange
By moving the id to the input if it exists
---
src/components/form/range/__snapshots__/range.test.js.snap | 3 ++-
src/components/form/range/range.js | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/components/form/range/__snapshots__/range.test.js.snap b/src/components/form/range/__snapshots__/range.test.js.snap
index fb48f07460b..b231d8aadb5 100644
--- a/src/components/form/range/__snapshots__/range.test.js.snap
+++ b/src/components/form/range/__snapshots__/range.test.js.snap
@@ -207,7 +207,6 @@ exports[`EuiRange props input should render 1`] = `
aria-label="aria-label"
class="euiRangeSlider"
data-test-subj="test subject string"
- id="id"
max="10"
min="1"
name="name"
@@ -230,6 +229,7 @@ exports[`EuiRange props input should render 1`] = `
aria-label="aria-label"
class="euiFieldNumber euiRangeInput euiRangeInput--max"
data-test-subj="test subject string"
+ id="id"
max="10"
min="1"
name="name"
@@ -358,6 +358,7 @@ exports[`EuiRange props slider should display in popover 1`] = `
aria-label="aria-label"
class="euiFieldNumber euiRangeInput euiRangeInput--max"
data-test-subj="test subject string"
+ id="id"
max="10"
min="1"
name="name"
diff --git a/src/components/form/range/range.js b/src/components/form/range/range.js
index 577e4e117fd..8dbfcfe41d1 100644
--- a/src/components/form/range/range.js
+++ b/src/components/form/range/range.js
@@ -111,6 +111,7 @@ export class EuiRange extends Component {
const theInput = !!showInput ? (
Date: Wed, 11 Sep 2019 12:00:29 -0400
Subject: [PATCH 18/20] Add dual range to complex example
---
.../views/form_compressed/complex_example.js | 31 +++++++++----------
src-docs/src/views/range/input_only.js | 2 --
2 files changed, 15 insertions(+), 18 deletions(-)
diff --git a/src-docs/src/views/form_compressed/complex_example.js b/src-docs/src/views/form_compressed/complex_example.js
index 96616e5d310..baf94c29ba9 100644
--- a/src-docs/src/views/form_compressed/complex_example.js
+++ b/src-docs/src/views/form_compressed/complex_example.js
@@ -4,11 +4,11 @@ import {
EuiButtonIcon,
EuiColorPicker,
EuiColorPickerSwatch,
+ EuiDualRange,
EuiFieldNumber,
EuiFieldText,
EuiFlexGroup,
EuiFlexItem,
- EuiFormControlLayoutDelimited,
EuiFormLabel,
EuiFormRow,
EuiHorizontalRule,
@@ -50,6 +50,7 @@ export default class extends Component {
color: '#DB1374',
borderValue: 3,
popoverSliderValues: 16,
+ dualValue: [5, 10],
};
this.selectTooltipContent =
@@ -88,6 +89,12 @@ export default class extends Component {
});
};
+ onDualChange = value => {
+ this.setState({
+ dualValue: value,
+ });
+ };
+
render() {
return (
@@ -96,23 +103,15 @@ export default class extends Component {
-
- }
- endControl={
-
- }
/>
diff --git a/src-docs/src/views/range/input_only.js b/src-docs/src/views/range/input_only.js
index dc8da0f16fd..dfb832dbd08 100644
--- a/src-docs/src/views/range/input_only.js
+++ b/src-docs/src/views/range/input_only.js
@@ -61,11 +61,9 @@ export default class extends Component {
id={makeId()}
value={this.state.dualValue}
onChange={this.onDualChange}
- compressed
showInput="inputWithPopover"
showLabels
levels={this.levels}
- readOnly
/>
From b3d66316cf82ce115d984ec3fa586b95d1199645 Mon Sep 17 00:00:00 2001
From: cchaos
Date: Wed, 11 Sep 2019 13:39:56 -0400
Subject: [PATCH 19/20] Quick fix for IE
---
src-docs/src/views/form_compressed/complex_example.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src-docs/src/views/form_compressed/complex_example.js b/src-docs/src/views/form_compressed/complex_example.js
index baf94c29ba9..cdbf81ede3b 100644
--- a/src-docs/src/views/form_compressed/complex_example.js
+++ b/src-docs/src/views/form_compressed/complex_example.js
@@ -263,7 +263,7 @@ export default class extends Component {
Border
-
+
-
+
Date: Wed, 11 Sep 2019 14:05:11 -0400
Subject: [PATCH 20/20] cl
---
CHANGELOG.md | 34 +++++++++++++++++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 01f5eb929c0..2d76d690142 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,38 @@
## [`master`](https://github.com/elastic/eui/tree/master)
-No public interface changes since `13.8.1`.
+### Feature: Compressed Form Controls ([#2167](https://github.com/elastic/eui/pull/2167))
+
+- Altered the look of `compressed` form controls to look more subtle
+- Created `EuiFormControlLayoutDelimited` for dual inputs indicating a range
+- Added compressed and column style layouts to `EuiFormRow` via `display` prop
+- Reduced overall height of `compressed` `EuiRange` and `EuiDualRange`
+- Added `showInput = 'inputWithPopover'` option for `compressed` `EuiRange` and `EuiDualRange` to display the slider in a popover
+
+- Made all inputs in the `EuiSuperDatePicker` popover `compressed`
+- Added `controlOnly` prop to `EuiFieldText` and `EuiFieldNumber`
+- Allow `style` prop to be passed down in `EuiColorPickerSwatch`
+- `EuiFilePicker` now has `default` and `large` display sizes that both have `compressed` alternatives
+- Allow strings to be passed as `append`/`prepend` props and added a11y support
+- Added a max height with overflow to `EuiSuperSelect`
+
+**Bug fixes**
+
+- Fixed `EuiColorPicker` padding on right to accomodate down caret
+- Fixed sizings of `EuiComboBox` and pills
+- Fixed truncation on `EuiContextMenuItem`
+- Fixed style of more `append`/`prepend` options of `EuiFormControlLayout`
+
+**Deprecations**
+
+- `EuiFormRow`'s `compressed` prop deprecated in favor of `display: rowCompressed`
+- `EuiFormRow`'s `displayOnly` prop deprecated in favor of `display: center`
+
+**Breaking changes**
+
+- SASS mixin `euiTextOverflowWrap()` has been removed in favor of `euiTextBreakWord()`
+- `EuiFormLabel` no longer has a bottom margin
+- `EuiFormRow` no longer has bottom padding, nor does it add margin to any `+ *` siblings only sibling `EuiFormRow`s
+
## [`13.8.1`](https://github.com/elastic/eui/tree/v13.8.1)