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

Selectable EuiCards #1895

Merged
merged 12 commits into from
May 1, 2019
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- Added `isLoading` prop to `EuiStat` ([#1848](https://github.com/elastic/eui/pull/1848))
- Added `roundUp` prop to relative tab of `EuiSuperDatePicker` ([#1827](https://github.com/elastic/eui/pull/1827))
- Changed position of `EuiSwitch` for date rounding used at relative tab of `EuiSuperDatePicker` ([#1827](https://github.com/elastic/eui/pull/1827))
- Added `selectable` prop to `EuiCard` ([#1895](https://github.com/elastic/eui/pull/1895))

**Bug fixes**

Expand Down
56 changes: 51 additions & 5 deletions src-docs/src/views/card/card_example.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { Fragment } from 'react';

import { renderToHtml } from '../../services';

Expand All @@ -12,6 +12,10 @@ import {
EuiCallOut,
} from '../../../../src/components';

import {
EuiCardSelect
} from '../../../../src/components/card/card_select';

import Card from './card';
const cardSource = require('!!raw-loader!./card');
const cardHtml = renderToHtml(Card);
Expand All @@ -32,6 +36,10 @@ import CardLayout from './card_layout';
const cardLayoutSource = require('!!raw-loader!./card_layout');
const cardLayoutHtml = renderToHtml(CardLayout);

import CardSelectable from './card_selectable';
const cardSelectableSource = require('!!raw-loader!./card_selectable');
const cardSelectableHtml = renderToHtml(CardSelectable);

export const CardExample = {
title: 'Card',
sections: [{
Expand Down Expand Up @@ -90,7 +98,7 @@ export const CardExample = {
/>
</div>
),
components: { EuiCard },
props: { EuiCard },
demo: <CardLayout />,
},
{
Expand All @@ -117,7 +125,7 @@ export const CardExample = {
/>
</div>
),
components: { EuiCard },
props: { EuiCard },
demo: <CardImage />,
},
{
Expand Down Expand Up @@ -156,7 +164,45 @@ export const CardExample = {
change the title of the tooltip, supply a <EuiCode>betaBadgeTitle</EuiCode> prop.
</p>
),
components: { EuiCard },
props: { EuiCard },
demo: <CardBeta />,
}],
},
{
title: 'Selectable',
source: [{
type: GuideSectionTypes.JS,
code: cardSelectableSource,
}, {
type: GuideSectionTypes.HTML,
code: cardSelectableHtml,
}],
text: (
<Fragment>
<p>
When you have a list of cards that can be selected but <strong>do not navigate anywhere</strong>, you
can add the <EuiCode>selectable</EuiCode> prop. The prop is an object that requires an <EuiCode>onClick</EuiCode>.
It will apply the button as seen below, and passing <EuiCode>selectable.isSelected = true</EuiCode> will alter the
styles of the card and button to look selected.
</p>
<p>
The select button is essentially an EuiButtonEmpty and so the <EuiCode>selectable</EuiCode> object can
also accept any props that EuiButtonEmpty can.
</p>
</Fragment>
),
props: { EuiCardSelect },
demo: <CardSelectable />,
snippet: `<EuiCard
icon={<EuiIcon />}
title="Title"
description="Example of a short card description."
footer={cardFooterContent}
selectable={{
onClick: this.cardClicked,
isSelected: this.state.cardIsSelected,
isDisabled: this.state.cardIsDisabled,
}}
/>`
},
],
};
217 changes: 217 additions & 0 deletions src-docs/src/views/card/card_selectable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
import React, { Component } from 'react';

import {
EuiButtonEmpty,
EuiCard,
EuiIcon,
EuiFlexGroup,
EuiFlexItem,
} from '../../../../src/components';

export default class extends Component {
constructor(props) {
super(props);

this.state = {
card1Selected: true,
card2Selected: false,
};
}

card1Clicked = () => {
this.setState({
card1Selected: !this.state.card1Selected,
});
}

card2Clicked = () => {
this.setState({
card2Selected: !this.state.card2Selected,
});
}

render() {
const cardFooterContent = (
<EuiButtonEmpty
iconType="iInCircle"
size="xs"
>
More details
</EuiButtonEmpty>
);

return (
<div>
<EuiFlexGroup gutterSize="l">
<EuiFlexItem>
<EuiCard
icon={<EuiIcon size="xxl" type="logoSketch" />}
title="Sketch"
description="Example of a short card description."
footer={cardFooterContent}
selectable={{
onClick: this.card1Clicked,
isSelected: this.state.card1Selected,
}}
/>
</EuiFlexItem>
<EuiFlexItem>
<EuiCard
icon={<EuiIcon size="xxl" type="logoGCP" />}
title="Google"
description="Example of a longer card description. See how the footers stay lined up."
footer={cardFooterContent}
selectable={{
onClick: this.card2Clicked,
isSelected: this.state.card2Selected,
}}
/>
</EuiFlexItem>
<EuiFlexItem>
<EuiCard
icon={<EuiIcon size="xxl" type="logoAerospike" />}
title="Not Adobe"
description="Example of a short card description."
footer={cardFooterContent}
selectable={{
onClick: () => {},
isDisabled: true,
}}
/>
</EuiFlexItem>
</EuiFlexGroup>
<EuiFlexGroup gutterSize="l">
<EuiFlexItem>
<EuiCard
icon={<EuiIcon size="xxl" type="logoSketch" />}
title="Sketch"
description="Example of a short card description."
footer={cardFooterContent}
selectable={{
onClick: this.card1Clicked,
isSelected: this.state.card1Selected,
color: 'danger'
}}
/>
</EuiFlexItem>
<EuiFlexItem>
<EuiCard
icon={<EuiIcon size="xxl" type="logoGCP" />}
title="Google"
description="Example of a longer card description. See how the footers stay lined up."
footer={cardFooterContent}
selectable={{
onClick: this.card2Clicked,
isSelected: this.state.card2Selected,
color: 'danger',
children: 'Custom text and icon',
iconType: 'bell'
}}
/>
</EuiFlexItem>
<EuiFlexItem>
<EuiCard
icon={<EuiIcon size="xxl" type="logoAerospike" />}
title="Not Adobe"
description="Example of a short card description."
footer={cardFooterContent}
selectable={{
onClick: () => {},
isDisabled: true,
color: 'danger',
iconType: 'minusInCircle'
}}
/>
</EuiFlexItem>
</EuiFlexGroup>
<EuiFlexGroup gutterSize="l">
<EuiFlexItem>
<EuiCard
icon={<EuiIcon size="xxl" type="logoSketch" />}
title="Sketch"
description="Example of a short card description."
footer={cardFooterContent}
selectable={{
onClick: this.card1Clicked,
isSelected: this.state.card1Selected,
color: 'primary'
}}
/>
</EuiFlexItem>
<EuiFlexItem>
<EuiCard
icon={<EuiIcon size="xxl" type="logoGCP" />}
title="Google"
description="Example of a longer card description. See how the footers stay lined up."
footer={cardFooterContent}
selectable={{
onClick: this.card2Clicked,
isSelected: this.state.card2Selected,
color: 'primary',
children: 'Custom text, and className',
className: 'eui-textAlignLeft'
}}
/>
</EuiFlexItem>
<EuiFlexItem>
<EuiCard
icon={<EuiIcon size="xxl" type="logoAerospike" />}
title="Not Adobe"
description="Example of a short card description."
footer={cardFooterContent}
selectable={{
onClick: () => {},
isDisabled: true,
color: 'primary',
}}
/>
</EuiFlexItem>
</EuiFlexGroup>
<EuiFlexGroup gutterSize="l">
<EuiFlexItem>
<EuiCard
icon={<EuiIcon size="xxl" type="logoSketch" />}
title="Sketch"
description="Example of a short card description."
footer={cardFooterContent}
selectable={{
onClick: this.card1Clicked,
isSelected: this.state.card1Selected,
color: 'ghost'
}}
/>
</EuiFlexItem>
<EuiFlexItem>
<EuiCard
icon={<EuiIcon size="xxl" type="logoGCP" />}
title="Google"
description="Example of a longer card description. See how the footers stay lined up."
footer={cardFooterContent}
selectable={{
onClick: this.card2Clicked,
isSelected: this.state.card2Selected,
color: 'ghost',
children: 'Custom text and style tag',
style: { textTransform: 'uppercase' }
}}
/>
</EuiFlexItem>
<EuiFlexItem>
<EuiCard
icon={<EuiIcon size="xxl" type="logoAerospike" />}
title="Not Adobe"
description="Example of a short card description."
footer={cardFooterContent}
selectable={{
onClick: () => {},
isDisabled: true,
children: 'Custom disabled text',
color: 'ghost'
}}
/>
</EuiFlexItem>
</EuiFlexGroup>
</div>
);
}
}
13 changes: 9 additions & 4 deletions src/components/button/button_empty/_button_empty.scss
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,15 @@ $buttonTypes: (
// Create button modifiders based upon the map.
@each $name, $color in $buttonTypes {
.euiButtonEmpty--#{$name} {
color: $color;

.euiButtonEmpty__icon {
fill: $color;
@if ($name == 'ghost') {
// Ghost is unique and ALWAYS sits against a dark background.
color: $color;
} @else if ($name == 'text') {
// The default color is lighter than the normal text color, make the it the text color
color: $euiTextColor;
} @else {
// Other colors need to check their contrast against the page background color.
color: makeHighContrastColor($color, $euiColorEmptyShade);
}

&:focus {
Expand Down
Loading