Skip to content

Commit

Permalink
Add display, descriptionWidth, textWrap and isInvalid props to EuiExp…
Browse files Browse the repository at this point in the history
…ression (elastic#3467)

* added prop

* added test and updated example

* add cl

* added description to tooltip

* renamed prop, turned into enum

* example is function component

* update snippet

* make the example more like alerting

* new styles

* basic combobox working

* more progress on example

* added align right

* removed truncate

* renamed column prop

* cleanup

* updated tests and added handling of color

* remove unneeded line

* Review updates

* update test

* re-added textWrap prop

* update cl

* PR feedback

Co-authored-by: cchaos <[email protected]>
  • Loading branch information
2 people authored and daveyholler committed Jun 3, 2020
1 parent c79d09b commit ed9d7b7
Show file tree
Hide file tree
Showing 10 changed files with 654 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- Added `left-start` popover placement to `EuiDatePicker` ([#3511](https://github.com/elastic/eui/pull/3511))
- Added `theme` prop to `EuiHeader` ([#3524](https://github.com/elastic/eui/pull/3524))
- Added `.euiHeaderLink-isActive` class to `EuiHeaderLink` when `isActive` ([#3524](https://github.com/elastic/eui/pull/3524))
- Added `display`, `descriptionWidth`, `textWrap` and `isInvalid` props to `EuiExpression` ([#3467](https://github.com/elastic/eui/pull/3467))

**Bug Fixes**

Expand Down
202 changes: 202 additions & 0 deletions src-docs/src/views/expression/columns.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
import React, { useState, Fragment } from 'react';

import {
EuiPopoverTitle,
EuiPopover,
EuiSelect,
EuiComboBox,
EuiExpression,
EuiTitle,
EuiSpacer,
} from '../../../../src/components';

export default () => {
const [example1, setExample1] = useState({
isOpen: false,
value: (
<Fragment>
<p>.kibana_task_manager,</p>
<p>kibana_sample_data_ecommerce</p>
</Fragment>
),
});

const [example2, setExample2] = useState({
isOpen: false,
value: 'count()',
});

const options = [
{
label: '.kibana_task_manager',
},
{
label: 'kibana_sample_data_ecommerce',
},
{
label: '.kibana-event-log-8.0.0-000001',
},
{
label: 'kibana_sample_data_flights',
},
{
label: '.kibana-event-log-8.0.0',
},
];

const [selectedOptions, setSelected] = useState([options[0], options[1]]);

const openExample1 = () => {
setExample1({
...example1,
isOpen: !example1.isOpen,
});
};

const closeExample1 = () => {
setExample1({
...example1,
isOpen: false,
});
};

const openExample2 = () => {
setExample2({
...example2,
isOpen: !example2.isOpen,
});
};

const closeExample2 = () => {
setExample2({
...example2,
isOpen: false,
});
};

const changeExample2 = e => {
setExample2({
value: e.target.value,
isOpen: false,
});
};

const onChange = selectedOptions => {
setSelected(selectedOptions);
const indices = selectedOptions.map((s, index) => {
return (
<p key={index}>
{s.label}
{index < selectedOptions.length - 1 ? ',' : null}
</p>
);
});
setExample1({
...example1,
value: indices,
});
};

const renderPopover1 = () => (
<div style={{ width: 300 }}>
<EuiPopoverTitle>INDICES</EuiPopoverTitle>
<EuiComboBox
placeholder="Select one or more indices"
options={options}
selectedOptions={selectedOptions}
onChange={onChange}
isClearable={true}
data-test-subj="demoComboBox"
/>
</div>
);

const renderPopover2 = () => (
<div style={{ width: 150 }}>
<EuiPopoverTitle>WHEN</EuiPopoverTitle>
<EuiSelect
compressed
value={example2.value}
onChange={changeExample2}
options={[
{
value: 'count()',
text: 'count()',
},
{
value: 'sum()',
text: 'sum()',
},
{
value: 'min()',
text: 'min()',
},
{ value: 'max()', text: 'max()' },
]}
/>
</div>
);

return (
<div style={{ maxWidth: 500 }}>
<EuiPopover
id="columnsPopover1"
button={
<EuiExpression
description="indices"
display="columns"
value={example1.value}
isInvalid={
selectedOptions && selectedOptions.length > 0 ? false : true
}
isActive={example1.isOpen}
onClick={openExample1}
/>
}
isOpen={example1.isOpen}
closePopover={closeExample1}
ownFocus
display="block"
panelPaddingSize="s"
anchorPosition="downLeft">
{renderPopover1()}
</EuiPopover>

<EuiPopover
id="columnsPopover2"
panelPaddingSize="s"
button={
<EuiExpression
description="when"
display="columns"
value={example2.value}
isActive={example2.isOpen}
onClick={openExample2}
/>
}
isOpen={example2.isOpen}
closePopover={closeExample2}
ownFocus
display="block"
anchorPosition="downLeft">
{renderPopover2()}
</EuiPopover>
<EuiExpression
display="columns"
description="Except"
value="kibana_sample_data_ky_counties"
/>
<EuiSpacer />
<EuiTitle size="xxs">
<h3>Description width at 50px</h3>
</EuiTitle>
<EuiExpression
description="join"
display="columns"
descriptionWidth={50}
value="kibana_sample_data_ky_avl"
onClick={() => {}}
/>
</div>
);
};
119 changes: 115 additions & 4 deletions src-docs/src/views/expression/expression_example.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Expression from './expression';
const expressionSource = require('!!raw-loader!./expression');
const expressionHtml = renderToHtml(Expression);
const expressionSnippet = `<EuiExpression
description="description"
description={description}
value={value}
isActive={isActive}
onClick={handleClick}
Expand All @@ -22,7 +22,7 @@ import Colors from './colors';
const colorSource = require('!!raw-loader!./colors');
const colorHtml = renderToHtml(Colors);
const colorSnippet = `<EuiExpression
description="description"
description={description}
value={value}
color="primary"
/>`;
Expand All @@ -32,17 +32,44 @@ const stringingSource = require('!!raw-loader!./stringing');
const stringingHtml = renderToHtml(Stringing);
const stringingSnippet = `<div>
<EuiExpression
description="description1"
description={description1}
value={value1}
onClick={handleClick1}
/>
<EuiExpression
description="description2"
description={description2}
value={value2}
onClick={handleClick2}
/>
</div>`;

import Columns from './columns';
const columnsSource = require('!!raw-loader!./columns');
const columnsHtml = renderToHtml(Columns);
const columnsSnippet = `<EuiExpression
description={description}
display="columns"
value={value}
/>`;

import Invalid from './invalid';
const invalidSource = require('!!raw-loader!./invalid');
const invalidHtml = renderToHtml(Invalid);
const invalidSnippet = `<EuiExpression
description={description}
isInvalid
value={value}
/>`;

import Truncate from './truncate';
const truncateSource = require('!!raw-loader!./truncate');
const truncateHtml = renderToHtml(Truncate);
const truncateSnippet = `<EuiExpression
description={description}
value={value}
textWrap="truncate"
/>`;

export const ExpressionExample = {
title: 'Expression',
sections: [
Expand Down Expand Up @@ -114,5 +141,89 @@ export const ExpressionExample = {
snippet: stringingSnippet,
demo: <Stringing />,
},
{
title: 'Column display',
source: [
{
type: GuideSectionTypes.JS,
code: columnsSource,
},
{
type: GuideSectionTypes.HTML,
code: columnsHtml,
},
],
text: (
<div>
<p>
There might be cases where displaying multiple{' '}
<strong>EuiExpression</strong>s in a paragraph is not ideal. For
example, when both the <EuiCode>description</EuiCode> and the{' '}
<EuiCode>value</EuiCode> are variable or when their text is quite
long. To use a column display instead, pass{' '}
<EuiCode language="ts">{'display="columns"'}</EuiCode>.
</p>
<p>
In column display, each expression is its own line and the{' '}
<EuiCode>description</EuiCode> column is aligned to the right. The
default width for the <EuiCode>description</EuiCode> is 20%, but you
can customize this with the
<EuiCode>descriptionWidth</EuiCode> prop. When displaying a group of{' '}
<strong>EuiExpression</strong>s, make sure to set the same width for
all descriptions.
</p>
</div>
),
snippet: columnsSnippet,
demo: <Columns />,
},
{
title: 'Invalid state',
source: [
{
type: GuideSectionTypes.JS,
code: invalidSource,
},
{
type: GuideSectionTypes.HTML,
code: invalidHtml,
},
],
text: (
<p>
Set <EuiCode>isInvalid</EuiCode> to true to display{' '}
<strong>EuiExpression</strong>&apos;s error state. This state will
override the <EuiCode>color</EuiCode> prop with danger.
</p>
),
snippet: invalidSnippet,
demo: <Invalid />,
},
{
title: 'Truncate text',
source: [
{
type: GuideSectionTypes.JS,
code: truncateSource,
},
{
type: GuideSectionTypes.HTML,
code: truncateHtml,
},
],
text: (
<p>
To truncate <strong>EuiExpression</strong>&apos;s content, pass{' '}
<EuiCode language="ts">{'textWrap="truncate"'}</EuiCode>. Text
truncation only works properly if the prop types of{' '}
<EuiCode>description</EuiCode> and <EuiCode>value</EuiCode> are
strings. If you&apos;re using nodes, use the{' '}
<EuiCode>.eui-textTruncate</EuiCode> utility class on all their
sub-children.
</p>
),
snippet: truncateSnippet,
demo: <Truncate />,
},
],
};
24 changes: 24 additions & 0 deletions src-docs/src/views/expression/invalid.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';

import { EuiExpression, EuiSpacer } from '../../../../src/components';

export default () => (
<div>
<EuiExpression
onClick={() => {}}
description="sort by"
value="count"
isInvalid
/>
<EuiSpacer />
<div style={{ maxWidth: 220 }}>
<EuiExpression
description="email"
display="columns"
isInvalid
value="example@mail."
onClick={() => {}}
/>
</div>
</div>
);
2 changes: 2 additions & 0 deletions src-docs/src/views/expression/stringing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export default () => (
description="group by"
value="right.kytccountynmbr"
onClick={() => {}}
color="accent"
/>
<EuiExpression description="sort by" value="count" />
</div>
);
Loading

0 comments on commit ed9d7b7

Please sign in to comment.