diff --git a/packages/react-core/src/components/Card/examples/Card.md b/packages/react-core/src/components/Card/examples/Card.md index 2aa78dd2c0f..07e1f608cf4 100644 --- a/packages/react-core/src/components/Card/examples/Card.md +++ b/packages/react-core/src/components/Card/examples/Card.md @@ -6,7 +6,7 @@ propComponents: ['Card', 'CardHeaderMain', 'CardTitle', 'CardBody', 'CardFooter' ouia: true --- -import pfLogo from './pfLogo.svg'; +import pfLogo from './pfLogo.svg'; ## Examples ### Basic @@ -24,8 +24,8 @@ import { Card, CardTitle, CardBody, CardFooter } from '@patternfly/react-core'; ### With image and actions ```js import React from 'react'; -import { Brand, Card, CardHeader, CardHeaderMain, CardActions, CardTitle, CardBody, CardFooter, Checkbox, Dropdown, DropdownToggle, DropdownItem, DropdownSeparator, DropdownPosition, DropdownDirection, KebabToggle } from '@patternfly/react-core'; -import pfLogo from './pfLogo.svg'; +import { Brand, Card, CardHeader, CardHeaderMain, CardActions, CardTitle, CardBody, CardFooter, Checkbox, Dropdown, DropdownToggle, DropdownItem, DropdownSeparator, KebabToggle } from '@patternfly/react-core'; +import pfLogo from './pfLogo.svg'; class KebabDropdown extends React.Component { constructor(props) { @@ -45,11 +45,11 @@ class KebabDropdown extends React.Component { }); }; this.onClick = (checked, event) => { - const target = event.target; - const value = target.type === 'checkbox' ? target.checked : target.value; - const name = target.name; - this.setState({ [name]: value }); - }; + const target = event.target; + const value = target.type === 'checkbox' ? target.checked : target.value; + const name = target.name; + this.setState({ [name]: value }); + }; } render() { @@ -107,7 +107,7 @@ class KebabDropdown extends React.Component { ### Card header in card head ```js import React from 'react'; -import { Card, CardHeader, CardActions, CardTitle, CardBody, CardFooter, Checkbox, Dropdown, DropdownToggle, DropdownItem, DropdownSeparator, DropdownPosition, DropdownDirection, KebabToggle } from '@patternfly/react-core'; +import { Card, CardHeader, CardActions, CardTitle, CardBody, CardFooter, Checkbox, Dropdown, DropdownToggle, DropdownItem, DropdownSeparator, KebabToggle } from '@patternfly/react-core'; class KebabDropdown extends React.Component { constructor(props) { @@ -127,11 +127,11 @@ class KebabDropdown extends React.Component { }); }; this.onClick = (checked, event) => { - const target = event.target; - const value = target.type === 'checkbox' ? target.checked : target.value; - const name = target.name; - this.setState({ [name]: value }); - }; + const target = event.target; + const value = target.type === 'checkbox' ? target.checked : target.value; + const name = target.name; + this.setState({ [name]: value }); + }; } render() { @@ -186,7 +186,7 @@ class KebabDropdown extends React.Component { ### Only actions in card head (no header/footer) ```js import React from 'react'; -import { Checkbox, Dropdown, DropdownToggle, DropdownItem, DropdownSeparator, DropdownPosition, DropdownDirection, KebabToggle, Card, CardHeader, CardActions, CardTitle, CardBody } from '@patternfly/react-core'; +import { Checkbox, Dropdown, DropdownToggle, DropdownItem, DropdownSeparator, KebabToggle, Card, CardHeader, CardActions, CardTitle, CardBody } from '@patternfly/react-core'; class KebabDropdown extends React.Component { constructor(props) { @@ -206,11 +206,11 @@ class KebabDropdown extends React.Component { }); }; this.onClick = (checked, event) => { - const target = event.target; - const value = target.type === 'checkbox' ? target.checked : target.value; - const name = target.name; - this.setState({ [name]: value }); - }; + const target = event.target; + const value = target.type === 'checkbox' ? target.checked : target.value; + const name = target.name; + this.setState({ [name]: value }); + }; } render() { @@ -270,7 +270,7 @@ import { Brand, Card, CardBody, CardFooter, CardHeader, CardHeaderMain, CardTitl - + Header Body Footer @@ -280,7 +280,7 @@ import { Brand, Card, CardBody, CardFooter, CardHeader, CardHeaderMain, CardTitl ### With no footer ```js import React from 'react'; -import { Card, CardTitle, CardBody, CardFooter } from '@patternfly/react-core'; +import { Card, CardTitle, CardBody } from '@patternfly/react-core'; Header @@ -291,7 +291,7 @@ import { Card, CardTitle, CardBody, CardFooter } from '@patternfly/react-core'; ### With no header ```js import React from 'react'; -import { Card, CardTitle, CardBody, CardFooter } from '@patternfly/react-core'; +import { Card, CardBody, CardFooter } from '@patternfly/react-core'; This card has no header @@ -302,7 +302,7 @@ import { Card, CardTitle, CardBody, CardFooter } from '@patternfly/react-core'; ### With only a content section ```js import React from 'react'; -import { Card, CardTitle, CardBody, CardFooter } from '@patternfly/react-core'; +import { Card, CardBody } from '@patternfly/react-core'; Body @@ -364,7 +364,7 @@ import { Card, CardTitle, CardBody, CardFooter } from '@patternfly/react-core'; ### Selectable and selected ```js import React from 'react'; -import { Card, CardHeader, CardActions, CardTitle, CardBody, Dropdown, DropdownToggle, DropdownItem, DropdownSeparator, DropdownPosition, DropdownDirection, KebabToggle, } from '@patternfly/react-core'; +import { Card, CardHeader, CardActions, CardTitle, CardBody, Dropdown, DropdownToggle, DropdownItem, DropdownSeparator, KebabToggle, } from '@patternfly/react-core'; class SelectableCard extends React.Component { constructor(props) { @@ -388,7 +388,7 @@ class SelectableCard extends React.Component { this.setState({ selected: newSelected }) - }; + }; this.onToggle = (isOpen, event) => { event.stopPropagation() this.setState({ diff --git a/packages/react-integration/cypress/integration/card.spec.ts b/packages/react-integration/cypress/integration/card.spec.ts index 69e867c5576..bd9c2efa479 100644 --- a/packages/react-integration/cypress/integration/card.spec.ts +++ b/packages/react-integration/cypress/integration/card.spec.ts @@ -37,8 +37,16 @@ describe('Card Demo Test', () => { }); it('Verify card is flat', () => { - cy.get('article') - .last() - .should('have.class', 'pf-m-flat'); + cy.get('#flatCard').should('have.class', 'pf-m-flat'); + }); + + it('Verify that selectable card can be selected and unselected with keyboard input', () => { + cy.get('#selectableCard').focus(); + cy.focused().should('have.class', 'pf-m-selectable'); + cy.focused().should('not.have.class', 'pf-m-selected'); + cy.focused().type('{enter}'); + cy.focused().should('have.class', 'pf-m-selected'); + cy.focused().type('{enter}'); + cy.focused().should('not.have.class', 'pf-m-selected'); }); }); diff --git a/packages/react-integration/demo-app-ts/src/components/demos/CardDemo/CardDemo.tsx b/packages/react-integration/demo-app-ts/src/components/demos/CardDemo/CardDemo.tsx index 767c6cc15cd..a6103fb8592 100644 --- a/packages/react-integration/demo-app-ts/src/components/demos/CardDemo/CardDemo.tsx +++ b/packages/react-integration/demo-app-ts/src/components/demos/CardDemo/CardDemo.tsx @@ -1,8 +1,28 @@ import React from 'react'; import { Card, CardTitle, CardBody, CardFooter } from '@patternfly/react-core'; +interface CardDemoState { + selected: string; +} export class CardDemo extends React.Component { static displayName = 'CardDemo'; + + state: CardDemoState = { + selected: null + }; + + onKeyDown = (event: any) => { + if (event.target !== event.currentTarget) { + return; + } + if ([13, 32].includes(event.keyCode)) { + const newSelected = event.currentTarget.id === this.state.selected ? null : event.currentTarget.id; + this.setState({ + selected: newSelected + }); + } + }; + componentDidMount() { window.scrollTo(0, 0); } @@ -36,7 +56,18 @@ export class CardDemo extends React.Component { Footer

- + + Header + Body + Footer + + + Header Body Footer