`;
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 {