Skip to content

Commit

Permalink
feat(banner): Update close() to use CloseReason and provide programma…
Browse files Browse the repository at this point in the history
…tic way of closing

BREAKING CHANGE: Updated adapter to use CloseReason types

PiperOrigin-RevId: 327517664
  • Loading branch information
EstebanG23 authored and copybara-github committed Aug 19, 2020
1 parent b2e80a5 commit ff88df6
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 38 deletions.
2 changes: 1 addition & 1 deletion packages/mdc-banner/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ Event name | `event.detail` | Description
Method Signature | Description
--- | ---
`open() => void` | Opens the banner.
`close(reason: CloseReason|string = '') => void` | Closes the banner, optionally with the specified action indicating why it was closed.
`close(reason: CloseReason) => void` | Closes the banner, with the specified action indicating why it was closed.
`isOpen() => boolean` | Returns whether the banner is open.
`getText() => string` | Gets the text of the banner.
`setText(text: string) => void` | Sets the text of the banner.
Expand Down
6 changes: 4 additions & 2 deletions packages/mdc-banner/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
* THE SOFTWARE.
*/

import {CloseReason} from './constants';

/**
* Defines the shape of the adapter expected by the foundation.
* Implement this adapter for your framework of choice to delegate updates to
Expand All @@ -42,12 +44,12 @@ export interface MDCBannerAdapter {
/**
* Broadcasts an event denoting that the banner has finished closing.
*/
notifyClosed(reason: string): void;
notifyClosed(reason: CloseReason): void;

/**
* Broadcasts an event denoting that the banner has just started closing.
*/
notifyClosing(reason: string): void;
notifyClosing(reason: CloseReason): void;

/**
* Broadcasts an event denoting that the banner has finished opening.
Expand Down
12 changes: 5 additions & 7 deletions packages/mdc-banner/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ export class MDCBanner extends MDCComponent<MDCBannerFoundation> {
* @param reason Why the banner was closed. Value will be passed to
* events.CLOSING and events.CLOSED via the `event.detail.reason`
* property. Standard values are CloseReason.PRIMARY and
* CloseReason.SECONDARY, but custom client-specific values may also be
* used if desired.
* CloseReason.SECONDARY, but CloseReason.UNSPECIFIED is provided for
* custom handling of programmatic closing of the banner.
*/
close(reason: CloseReason|string = '') {
close(reason: CloseReason) {
this.foundation.close(reason);
}

Expand All @@ -103,12 +103,10 @@ export class MDCBanner extends MDCComponent<MDCBannerFoundation> {
return this.contentEl.offsetHeight;
},
notifyClosed: (reason) => {
this.emit<MDCBannerCloseEventDetail>(
events.CLOSED, reason ? {reason} : {});
this.emit<MDCBannerCloseEventDetail>(events.CLOSED, {reason});
},
notifyClosing: (reason) => {
this.emit<MDCBannerCloseEventDetail>(
events.CLOSING, reason ? {reason} : {});
this.emit<MDCBannerCloseEventDetail>(events.CLOSING, {reason});
},
notifyOpened: () => {
this.emit(events.OPENED, {});
Expand Down
9 changes: 6 additions & 3 deletions packages/mdc-banner/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,15 @@ export const selectors = {
/** Reason as to why the banner was closed. */
export enum CloseReason {
// Indicates the banner was closed via primary action button.
PRIMARY = 'primary',
PRIMARY,
// Indicates the banner was closed via secondary action button.
SECONDARY = 'secondary',
SECONDARY,
// Will never be used by the component. Provided for custom handling of
// programmatic closing of the banner.
UNSPECIFIED,
}

/** Interface for the detail of the closing and closed events emitted. */
export interface MDCBannerCloseEventDetail {
reason?: CloseReason|string;
reason: CloseReason;
}
9 changes: 5 additions & 4 deletions packages/mdc-banner/foundation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,12 @@ export class MDCBannerFoundation extends MDCFoundation<MDCBannerAdapter> {

/**
* @param reason Why the banner was closed. Value will be passed to
* CLOSING_EVENT and CLOSED_EVENT via the `event.detail.reason` property.
* Standard values are CloseReason.PRIMARY and CloseReason.SECONDARY,
* but custom client-specific values may also be used if desired.
* events.CLOSING and events.CLOSED via the `event.detail.reason`
* property. Standard values are CloseReason.PRIMARY and
* CloseReason.SECONDARY, but CloseReason.UNSPECIFIED is provided for
* custom handling of programmatic closing of the banner.
*/
close(reason: CloseReason|string = '') {
close(reason: CloseReason) {
if (!this.isOpened) {
// Avoid redundant close calls (and events), e.g. repeated interactions as
// the banner is animating closed
Expand Down
4 changes: 2 additions & 2 deletions packages/mdc-banner/test/component.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ describe('MDCBanner', () => {

component.listen(events.CLOSING, closingHandler);
component.listen(events.CLOSED, closedHandler);
component.close();
component.close(CloseReason.UNSPECIFIED);
expect(closingHandler).toHaveBeenCalled();
expect(fixture.classList.contains(cssClasses.CLOSING)).toBe(true);
expect(fixture.classList.contains(cssClasses.OPEN)).toBe(false);
Expand All @@ -195,7 +195,7 @@ describe('MDCBanner', () => {
const {component} = setupTest(fixture);
component.open();

component.close();
component.close(CloseReason.UNSPECIFIED);
expect(fixture.offsetHeight).toEqual(0);
});

Expand Down
29 changes: 10 additions & 19 deletions packages/mdc-banner/test/foundation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ describe('MDCBannerFoundation', () => {
const {foundation, mockAdapter} = setupTest();

foundation.open();
foundation.close();
foundation.close(CloseReason.UNSPECIFIED);

expect(mockAdapter.removeClass).toHaveBeenCalledWith(cssClasses.OPEN);
});
Expand All @@ -80,7 +80,7 @@ describe('MDCBannerFoundation', () => {
const {foundation, mockAdapter} = setupTest();

foundation.open();
foundation.close();
foundation.close(CloseReason.UNSPECIFIED);

jasmine.clock().tick(1);
expect(mockAdapter.addClass).not.toHaveBeenCalledWith(cssClasses.OPEN);
Expand Down Expand Up @@ -108,7 +108,7 @@ describe('MDCBannerFoundation', () => {
jasmine.clock().tick(numbers.BANNER_ANIMATION_OPEN_TIME_MS);
expect(mockAdapter.removeClass).toHaveBeenCalledWith(cssClasses.CLOSING);
expect(mockAdapter.removeClass).toHaveBeenCalledTimes(1);
foundation.close();
foundation.close(CloseReason.UNSPECIFIED);

expect(mockAdapter.addClass).toHaveBeenCalledWith(cssClasses.CLOSING);
jasmine.clock().tick(numbers.BANNER_ANIMATION_CLOSE_TIME_MS);
Expand All @@ -131,30 +131,21 @@ describe('MDCBannerFoundation', () => {

foundation.open();
jasmine.clock().tick(numbers.BANNER_ANIMATION_OPEN_TIME_MS);
foundation.close();
foundation.close(CloseReason.UNSPECIFIED);

expect(mockAdapter.notifyClosing).toHaveBeenCalledWith('');
expect(mockAdapter.notifyClosing)
.toHaveBeenCalledWith(CloseReason.UNSPECIFIED);
expect(mockAdapter.notifyClosing).toHaveBeenCalledTimes(1);
jasmine.clock().tick(numbers.BANNER_ANIMATION_CLOSE_TIME_MS);
expect(mockAdapter.notifyClosed).toHaveBeenCalledWith('');
expect(mockAdapter.notifyClosed)
.toHaveBeenCalledWith(CloseReason.UNSPECIFIED);
expect(mockAdapter.notifyClosed).toHaveBeenCalledTimes(1);

foundation.open();
jasmine.clock().tick(numbers.BANNER_ANIMATION_OPEN_TIME_MS);

const reason = 'reason';
foundation.close(reason);
expect(mockAdapter.notifyClosing).toHaveBeenCalledWith(reason);
expect(mockAdapter.notifyClosing).toHaveBeenCalledTimes(2);
jasmine.clock().tick(numbers.BANNER_ANIMATION_CLOSE_TIME_MS);
expect(mockAdapter.notifyClosed).toHaveBeenCalledWith(reason);
expect(mockAdapter.notifyClosed).toHaveBeenCalledTimes(2);
});

it('#close does nothing if the banner is already closed', () => {
const {foundation, mockAdapter} = setupTest();

foundation.close();
foundation.close(CloseReason.UNSPECIFIED);
jasmine.clock().tick(1);
jasmine.clock().tick(numbers.BANNER_ANIMATION_CLOSE_TIME_MS);
expect(mockAdapter.removeClass).not.toHaveBeenCalledWith(cssClasses.OPEN);
Expand Down Expand Up @@ -182,7 +173,7 @@ describe('MDCBannerFoundation', () => {
const {foundation} = setupTest();

foundation.open();
foundation.close();
foundation.close(CloseReason.UNSPECIFIED);

expect(foundation.isOpen()).toBe(false);
});
Expand Down

0 comments on commit ff88df6

Please sign in to comment.