Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add display, descriptionWidth, textWrap and isInvalid props to EuiExpression #3467

Merged
merged 33 commits into from
Jun 2, 2020
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
c4d93cd
added truncate example, pending prop
andreadelrio May 12, 2020
faaa6ad
added prop
andreadelrio May 12, 2020
23dad35
added test and updated example
andreadelrio May 13, 2020
f03e8fe
add cl
andreadelrio May 13, 2020
0f13450
remove unneeded line
andreadelrio May 13, 2020
1bf1d04
added description to tooltip
andreadelrio May 13, 2020
60fa604
fix conflict
andreadelrio May 13, 2020
efe0e00
renamed prop, turned into enum
andreadelrio May 13, 2020
eb52280
example is function component
andreadelrio May 13, 2020
72b2918
Merge remote-tracking branch 'upstream/master' into expression-truncate
andreadelrio May 13, 2020
dfc860a
update snippet
andreadelrio May 13, 2020
89d3992
make the example more like alerting
andreadelrio May 18, 2020
d256cc7
new styles
andreadelrio May 27, 2020
cb0d1aa
fix conflict
andreadelrio May 27, 2020
cb9ebd1
basic combobox working
andreadelrio May 28, 2020
c4e396b
more progress on example
andreadelrio May 28, 2020
1caac1a
added align right
andreadelrio May 28, 2020
a392e3e
removed truncate
andreadelrio May 28, 2020
6e7585b
will rename column prop
andreadelrio May 28, 2020
1c1b811
renamed column prop
andreadelrio May 28, 2020
36bb3ec
cleanup
andreadelrio May 29, 2020
b1e01dc
updated tests and added handling of color
andreadelrio May 29, 2020
fc1ddf7
remove unneeded line
andreadelrio May 29, 2020
4128407
Review updates
May 29, 2020
b606ecc
Merge pull request #10 from cchaos/andreadelrio/expression-truncate
andreadelrio May 29, 2020
5cc964a
added invalid example
andreadelrio Jun 1, 2020
4e583f8
update test
andreadelrio Jun 1, 2020
f6d39f2
re-added textWrap prop =D
andreadelrio Jun 1, 2020
d15a4b4
update cl
andreadelrio Jun 1, 2020
52dec78
PR feedback
andreadelrio Jun 1, 2020
3e21df3
tiny styling fix
andreadelrio Jun 2, 2020
e0209b0
update CL
andreadelrio Jun 2, 2020
85b20b6
nits
andreadelrio Jun 2, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,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
208 changes: 208 additions & 0 deletions src-docs/src/views/expression/columns.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
import React, { useState } from 'react';

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

export default () => {
const [example1, setExample1] = useState({
isOpen: false,
value: (
<div>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need this div, but if you do, it gets removed if you change the selected options, so you need to add it to the onChange function as well. You can simply change it to a fragment <></>

<p>.kibana_task_manager,</p>
<p>kibana_sample_data_ecommerce</p>
</div>
),
});

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,
});
setExample2({
...example2,
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
setExample2({
...example2,
});

};

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

const openExample2 = () => {
setExample1({
...example1,
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
setExample1({
...example1,
});

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>truncate</EuiCode> to the <EuiCode>textWrap</EuiCode> prop.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<EuiCode>truncate</EuiCode> to the <EuiCode>textWrap</EuiCode> prop.
<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>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
<EuiCode>.eui-textTruncate</EuiCode>
<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>
);
Loading