Skip to content

Commit

Permalink
[card] Revert change to footer button alignment, add new footerAction…
Browse files Browse the repository at this point in the history
…Alignment prop (left | right), default to right for backwards compat
  • Loading branch information
qq99 committed Nov 26, 2019
1 parent c8d836d commit 0cf759c
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 9 deletions.
5 changes: 3 additions & 2 deletions UNRELEASED.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- Added `ariaHaspopup` prop to `Popover` ([#2248](https://github.com/Shopify/polaris-react/pull/2248))
- Fixed an accessibility issue where the `Form` implicit submit was still accessible via keyboard ([#2447](https://github.com/Shopify/polaris-react/pull/2447))
- Moved `Button` styles from the `Buttongroup` CSS file to the `Button` CSS file ([#2441](https://github.com/Shopify/polaris-react/pull/2441))
- Added `footerActionAlignment` prop to control `<Card>` footer action alignment, defaults to `'right'`

### Bug fixes

Expand All @@ -17,10 +18,10 @@
- Fixed an issue where the dropzone component jumped from an extra-large layout to a layout based on the width of its container ([#2412](https://github.com/Shopify/polaris-react/pull/2412))
- Fixed an issue which caused HSL colors to not display in Edge ([#2418](https://github.com/Shopify/polaris-react/pull/2418))
- Changed Button's `disclosure` prop to be `boolean | "up" | "down"`, allowing greater control over the direction the disclosure caret faces ([#2431](https://github.com/Shopify/polaris-react/pull/2431))
- Fixed an issue where the dropzone component jumped from an extra-large layout to a layout based on the width of it's container ([#2412](https://github.com/Shopify/polaris-react/pull/2412))
- Fixed a race condition in DatePicker ([#2373](https://github.com/Shopify/polaris-react/pull/2373))
- Added the top bar height to the `Topbar` in `Frame` to ensure the `Sticky` components get the correct top position ([2415](https://github.com/Shopify/polaris-react/pull/2415))
- Added the top bar height to the `Topbar` in `Frame` to ensure the `Sticky` components get the correct top position ([#2415](https://github.com/Shopify/polaris-react/pull/2415))
- Fixed `merge` mutating its arguments ([#2317](https://github.com/Shopify/polaris-react/pull/2317))
- Updated `Card` footer actions to be right aligned by default again ([#2407](https://github.com/Shopify/polaris-react/pull/2407))

### Documentation

Expand Down
6 changes: 5 additions & 1 deletion src/components/Card/Card.scss
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,17 @@

.Footer {
display: flex;
justify-content: flex-start;
justify-content: flex-end;
padding: 0 spacing() spacing();

@include page-content-when-not-fully-condensed {
padding: 0 spacing(loose) spacing(loose);
}

&.LeftJustified {
justify-content: flex-start;
}

.Section-subdued + & {
border-top: border();
padding: spacing(loose);
Expand Down
25 changes: 20 additions & 5 deletions src/components/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export interface CardProps {
secondaryFooterActions?: ComplexAction[];
/** The content of the disclosure button rendered when there is more than one secondary footer action */
secondaryFooterActionsDisclosureText?: string;
/** Alignment of the footer actions on the card, defaults to right */
footerActionAlignment?: 'right' | 'left';
}

// TypeScript can't generate types that correctly infer the typing of
Expand All @@ -49,6 +51,7 @@ export const Card: React.FunctionComponent<CardProps> & {
primaryFooterAction,
secondaryFooterActions,
secondaryFooterActionsDisclosureText,
footerActionAlignment = 'right',
}: CardProps) {
const i18n = useI18n();

Expand Down Expand Up @@ -94,11 +97,23 @@ export const Card: React.FunctionComponent<CardProps> & {

const footerMarkup =
primaryFooterActionMarkup || secondaryFooterActionsMarkup ? (
<div className={styles.Footer}>
<ButtonGroup>
{secondaryFooterActionsMarkup}
{primaryFooterActionMarkup}
</ButtonGroup>
<div
className={classNames(
styles.Footer,
footerActionAlignment === 'left' && styles.LeftJustified,
)}
>
{footerActionAlignment === 'right' ? (
<ButtonGroup>
{secondaryFooterActionsMarkup}
{primaryFooterActionMarkup}
</ButtonGroup>
) : (
<ButtonGroup>
{primaryFooterActionMarkup}
{secondaryFooterActionsMarkup}
</ButtonGroup>
)}
</div>
) : null;

Expand Down
2 changes: 1 addition & 1 deletion src/components/Card/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ Use for less important card actions, or actions merchants may do before reviewin

<!-- content-for: web -->

Use footer actions for a card’s most important actions, or actions merchants should do after reviewing the contents of the card. For example, merchants should review the contents of a shipment before an important action like adding tracking information.
Use footer actions for a card’s most important actions, or actions merchants should do after reviewing the contents of the card. For example, merchants should review the contents of a shipment before an important action like adding tracking information. Footer actions can be left or right aligned with the `footerActionAlignment` prop.

<!-- /content-for -->

Expand Down
50 changes: 50 additions & 0 deletions src/components/Card/tests/Card.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
trigger,
findByTestID,
} from 'test-utilities/legacy';
import {mountWithApp} from 'test-utilities';
import {Card, Badge, Button, Popover, ActionList} from 'components';
import {WithinContentContext} from '../../../utilities/within-content-context';
import {Section} from '../components';
Expand Down Expand Up @@ -74,6 +75,55 @@ describe('<Card />', () => {
expect(card.find(Card.Header)).toHaveLength(1);
});

describe('footerActionAlignment prop', () => {
it('renders right-aligned if not supplied', () => {
const card = mountWithApp(
<Card
primaryFooterAction={{content: 'primary action'}}
secondaryFooterActions={[{content: 'secondary action'}]}
>
<p>Some card content.</p>
</Card>,
);

const buttons = card.findAll(Button);
expect(buttons[0].prop('children')).toBe('secondary action');
expect(buttons[1].prop('children')).toBe('primary action');
});

it('renders right-aligned if set to "right"', () => {
const card = mountWithApp(
<Card
primaryFooterAction={{content: 'primary action'}}
secondaryFooterActions={[{content: 'secondary action'}]}
footerActionAlignment="right"
>
<p>Some card content.</p>
</Card>,
);

const buttons = card.findAll(Button);
expect(buttons[0].prop('children')).toBe('secondary action');
expect(buttons[1].prop('children')).toBe('primary action');
});

it('renders left-aligned if set to "left"', () => {
const card = mountWithApp(
<Card
primaryFooterAction={{content: 'primary action'}}
secondaryFooterActions={[{content: 'secondary action'}]}
footerActionAlignment="left"
>
<p>Some card content.</p>
</Card>,
);

const buttons = card.findAll(Button);
expect(buttons[0].prop('children')).toBe('primary action');
expect(buttons[1].prop('children')).toBe('secondary action');
});
});

it('renders a primary footer action', () => {
const card = mountWithAppProvider(
<Card primaryFooterAction={{content: 'test action'}}>
Expand Down

0 comments on commit 0cf759c

Please sign in to comment.