From 9af9e40697957d9f62199c66ea0f49bb18749555 Mon Sep 17 00:00:00 2001 From: Filipp Baranovskii Date: Fri, 22 Mar 2019 12:09:45 +0300 Subject: [PATCH 1/5] adds support to pass descriptionID to bind a button and a description inside a card component --- src-docs/src/views/card/card_example.js | 294 +++++++++++++----------- src-docs/src/views/card/card_footer.js | 11 +- src/components/card/card.js | 30 +-- 3 files changed, 183 insertions(+), 152 deletions(-) diff --git a/src-docs/src/views/card/card_example.js b/src-docs/src/views/card/card_example.js index 4a22edc672c..7a32a64697f 100644 --- a/src-docs/src/views/card/card_example.js +++ b/src-docs/src/views/card/card_example.js @@ -2,15 +2,9 @@ import React from 'react'; import { renderToHtml } from '../../services'; -import { - GuideSectionTypes, -} from '../../components'; +import { GuideSectionTypes } from '../../components'; -import { - EuiCode, - EuiCard, - EuiCallOut, -} from '../../../../src/components'; +import { EuiCode, EuiCard, EuiCallOut } from '../../../../src/components'; import Card from './card'; const cardSource = require('!!raw-loader!./card'); @@ -34,129 +28,167 @@ const cardLayoutHtml = renderToHtml(CardLayout); export const CardExample = { title: 'Card', - sections: [{ - title: 'Basic Card', - source: [{ - type: GuideSectionTypes.JS, - code: cardSource, - }, { - type: GuideSectionTypes.HTML, - code: cardHtml, - }], - text: ( -
+ sections: [ + { + title: 'Basic Card', + source: [ + { + type: GuideSectionTypes.JS, + code: cardSource, + }, + { + type: GuideSectionTypes.HTML, + code: cardHtml, + }, + ], + text: ( +
+

+ At its core an EuiCard should contain a{' '} + title,description, and an{' '} + icon. You can make the whole card clickable by + giving it an onClick handler. +

+

+ By default a card's title element is a span. + This can be changed via the titleElement prop. + However, if an onClick function is also passed, + the title element will be forced back to a span. +

+

+ By default a card's content is center aligned. To change the + alignment set textAlign to{' '} + left or right. +

+
+ ), + props: { EuiCard }, + demo: , + }, + { + title: 'Layout', + source: [ + { + type: GuideSectionTypes.JS, + code: cardLayoutSource, + }, + { + type: GuideSectionTypes.HTML, + code: cardLayoutHtml, + }, + ], + text: ( +
+

+ Most of the time, cards should read from top to bottom (vertical). + However, in some cases, you may want the icon to be to the left of + the content. In this case, add the prop{' '} + layout="horizontal". +

+ + Horizontal layouts do not work with images, + footers, or textAlign. Therefore, these + properties will be ignored. + + } + /> +
+ ), + components: { EuiCard }, + demo: , + }, + { + title: 'Images', + source: [ + { + type: GuideSectionTypes.JS, + code: cardImageSource, + }, + { + type: GuideSectionTypes.HTML, + code: cardImageHtml, + }, + ], + text: ( +
+

+ Images can be added in place of, or in conjuction with, icons. Just + pass a url into the image prop and it will expand + to the edges of the card. +

+ + Make sure that all images are the{' '} + same proportions when used in a singular row. + + } + /> +
+ ), + components: { EuiCard }, + demo: , + }, + { + title: 'Footer', + source: [ + { + type: GuideSectionTypes.JS, + code: cardFooterSource, + }, + { + type: GuideSectionTypes.HTML, + code: cardFooterHtml, + }, + ], + text: ( +
+

+ Footers can contain any number of elements and will always align to + the bottom of the card. However, if you supply a footer containing a{' '} + EuiButton you must not also give + it an onClick. +

+ + You can bind a button and a description for Screen Reader by + providing descriptionId + + } + /> +
+ ), + components: { EuiCard }, + demo: , + }, + { + title: 'Beta badge', + source: [ + { + type: GuideSectionTypes.JS, + code: cardBetaSource, + }, + { + type: GuideSectionTypes.HTML, + code: cardBetaHtml, + }, + ], + text: (

- At its core an EuiCard should contain a title, - description, and an icon. You can make the whole card - clickable by giving it an onClick handler. + If the card links to or references a module that is not GA (beta, lab, + etc), you can add a betaBadgeLabel and{' '} + betaBadgeTooltipContent to the card and it will + properly create and position an EuiBetaBadge. If + you want to change the title of the tooltip, supply a{' '} + betaBadgeTitle prop.

-

- By default a card's title element is a span. This can be changed via - the titleElement prop. However, if an onClick function is - also passed, the title element will be forced back to a span. -

-

- By default a card's content is center aligned. To change the alignment - set textAlign to left or right. -

-
- ), - props: { EuiCard }, - demo: , - }, - { - title: 'Layout', - source: [{ - type: GuideSectionTypes.JS, - code: cardLayoutSource, - }, { - type: GuideSectionTypes.HTML, - code: cardLayoutHtml, - }], - text: ( -
-

- Most of the time, cards should read from top to bottom (vertical). However, in some cases, you may - want the icon to be to the left of the content. In this case, add - the prop layout="horizontal". -

- Horizontal layouts do not work with images, - footers, or textAlign. Therefore, these properties will be ignored. - - } - /> -
- ), - components: { EuiCard }, - demo: , - }, - { - title: 'Images', - source: [{ - type: GuideSectionTypes.JS, - code: cardImageSource, - }, { - type: GuideSectionTypes.HTML, - code: cardImageHtml, - }], - text: ( -
-

- Images can be added in place of, or in conjuction with, icons. - Just pass a url into the image prop and it will expand to the edges of the card. -

- Make sure that all images are the same proportions when - used in a singular row. - - } - /> -
- ), - components: { EuiCard }, - demo: , - }, - { - title: 'Footer', - source: [{ - type: GuideSectionTypes.JS, - code: cardFooterSource, - }, { - type: GuideSectionTypes.HTML, - code: cardFooterHtml, - }], - text: ( -

- Footers can contain any number of elements and will always align to the bottom of the card. - However, if you supply a footer containing a EuiButton you must not also - give it an onClick. -

- ), - components: { EuiCard }, - demo: , - }, - { - title: 'Beta badge', - source: [{ - type: GuideSectionTypes.JS, - code: cardBetaSource, - }, { - type: GuideSectionTypes.HTML, - code: cardBetaHtml, - }], - text: ( -

- If the card links to or references a module that is not GA (beta, lab, etc), - you can add a betaBadgeLabel and betaBadgeTooltipContent to - the card and it will properly create and position an EuiBetaBadge. If you want to - change the title of the tooltip, supply a betaBadgeTitle prop. -

- ), - components: { EuiCard }, - demo: , - }], + ), + components: { EuiCard }, + demo: , + }, + ], }; diff --git a/src-docs/src/views/card/card_footer.js b/src-docs/src/views/card/card_footer.js index 61876756252..255272ffefd 100644 --- a/src-docs/src/views/card/card_footer.js +++ b/src-docs/src/views/card/card_footer.js @@ -13,10 +13,14 @@ import { const cardFooterContent = (
- Go for it - + + Go for it + + -

Or try this

+

+ Or try this +

); @@ -28,6 +32,7 @@ export default () => ( icon={} title="Developers Tools" description="Example of a short card description." + descriptionId="example.cards.developerTools.screenReader" footer={cardFooterContent} /> diff --git a/src/components/card/card.js b/src/components/card/card.js index d8b6d1d5a89..6a376cf2ba0 100644 --- a/src/components/card/card.js +++ b/src/components/card/card.js @@ -39,6 +39,7 @@ const cardLayout = (props, propName, componentName, ...rest) => { export const EuiCard = ({ className, description, + descriptionId, title, titleElement, icon, @@ -55,7 +56,7 @@ export const EuiCard = ({ betaBadgeTitle, layout, bottomGraphic, - ...rest, + ...rest }) => { const classes = classNames( 'euiCard', @@ -67,7 +68,7 @@ export const EuiCard = ({ 'euiCard--hasIcon': icon, 'euiCard--hasBottomGraphic': bottomGraphic, }, - className, + className ); let secureRel; @@ -77,17 +78,14 @@ export const EuiCard = ({ let imageNode; if (image && layout === 'vertical') { - imageNode = ( - - ); + imageNode = ; } let iconNode; if (icon) { - iconNode = React.cloneElement( - icon, - { className: classNames(icon.props.className, 'euiCard__icon') } - ); + iconNode = React.cloneElement(icon, { + className: classNames(icon.props.className, 'euiCard__icon'), + }); } let OuterElement = 'div'; @@ -129,9 +127,7 @@ export const EuiCard = ({ let optionalBottomGraphic; if (bottomGraphic) { optionalBottomGraphic = ( - - {bottomGraphic} - + {bottomGraphic} ); } @@ -154,15 +150,13 @@ export const EuiCard = ({ -

{description}

+

{description}

- {layout === 'vertical' && - - {footer} - - } + {layout === 'vertical' && ( + {footer} + )} {optionalBottomGraphic} From e024a714535aaa2e8c5bcc8b9c27316edb833f2f Mon Sep 17 00:00:00 2001 From: Filipp Baranovskii Date: Fri, 22 Mar 2019 12:23:32 +0300 Subject: [PATCH 2/5] updated CHANGELOG with 1758 pull request info --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a9a610820c..09d5a10fdf1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - Converted `EuiCardGraphic` to TS ([#1751](https://github.com/elastic/eui/pull/1751)) - Enhanced the build process to emit TypeScript types for the variables extracted from the themes ([#1750](https://github.com/elastic/eui/pull/1750)) +- Added support for passing descriptionID to bind a button to a description inside a card component ([#1758](https://github.com/elastic/eui/pull/1758)) ## [`9.5.0`](https://github.com/elastic/eui/tree/v9.5.0) From ae9dbfbee284071653e19c9f66c25942ea9efd59 Mon Sep 17 00:00:00 2001 From: Filipp Baranovskii Date: Fri, 22 Mar 2019 17:58:42 +0300 Subject: [PATCH 3/5] adds prop type for card component doc --- src/components/card/card.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/card/card.js b/src/components/card/card.js index 6a376cf2ba0..01956b21b87 100644 --- a/src/components/card/card.js +++ b/src/components/card/card.js @@ -172,6 +172,11 @@ EuiCard.propTypes = { */ titleElement: PropTypes.oneOf(['h2', 'h3', 'h4', 'h5', 'h6', 'span']), description: PropTypes.node.isRequired, + /** + * Allows you to bind a button from `footer` value to a description + * to make ScreenReader able to explain where that button refers. + */ + descriptionId: PropTypes.string, /** * Requires a node From 5bf6237b93a44c6cbdc410305dede989454ad3b7 Mon Sep 17 00:00:00 2001 From: Filipp Baranovskii Date: Fri, 22 Mar 2019 18:00:05 +0300 Subject: [PATCH 4/5] card component: remove callout --- src-docs/src/views/card/card_example.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src-docs/src/views/card/card_example.js b/src-docs/src/views/card/card_example.js index 7a32a64697f..1142a012183 100644 --- a/src-docs/src/views/card/card_example.js +++ b/src-docs/src/views/card/card_example.js @@ -152,14 +152,6 @@ export const CardExample = { EuiButton you must not also give it an onClick.

- - You can bind a button and a description for Screen Reader by - providing descriptionId - - } - /> ), components: { EuiCard }, From 397dc1b635a0c2681454adfabf9857ccc670bf62 Mon Sep 17 00:00:00 2001 From: Filipp Baranovskii Date: Fri, 22 Mar 2019 18:11:31 +0300 Subject: [PATCH 5/5] card component: remove descriptionId example --- src-docs/src/views/card/card_footer.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src-docs/src/views/card/card_footer.js b/src-docs/src/views/card/card_footer.js index 255272ffefd..eff38f3ab19 100644 --- a/src-docs/src/views/card/card_footer.js +++ b/src-docs/src/views/card/card_footer.js @@ -13,7 +13,7 @@ import { const cardFooterContent = (
- + Go for it @@ -32,7 +32,6 @@ export default () => ( icon={} title="Developers Tools" description="Example of a short card description." - descriptionId="example.cards.developerTools.screenReader" footer={cardFooterContent} />