Skip to content

Commit

Permalink
feat(toast): add new <bq-toast> component (#301)
Browse files Browse the repository at this point in the history
  • Loading branch information
endv-bogdanb authored and dgonzalezr committed Jul 3, 2023
1 parent 3bf70c8 commit 5c22cc7
Show file tree
Hide file tree
Showing 12 changed files with 786 additions and 0 deletions.
70 changes: 70 additions & 0 deletions packages/bee-q/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { TSpinnerSize, TSpinnerTextPosition } from "./components/spinner/bq-spin
import { TStatusType } from "./components/status/bq-status.types";
import { TSwitchInnerLabel, TSwitchJustifyContent } from "./components/switch/bq-swithc.types";
import { TTabSize } from "./components/tab/bq-tab.types";
import { TToastPlacement, TToastType } from "./components/toast/bq-toast.types";
import { FloatingUIPlacement } from "./services/interfaces";
export { TAvatarShape, TAvatarSize } from "./components/avatar/bq-avatar.types";
export { TBadgeSize } from "./components/badge/bq-badge.types";
Expand All @@ -34,6 +35,7 @@ export { TSpinnerSize, TSpinnerTextPosition } from "./components/spinner/bq-spin
export { TStatusType } from "./components/status/bq-status.types";
export { TSwitchInnerLabel, TSwitchJustifyContent } from "./components/switch/bq-swithc.types";
export { TTabSize } from "./components/tab/bq-tab.types";
export { TToastPlacement, TToastType } from "./components/toast/bq-toast.types";
export { FloatingUIPlacement } from "./services/interfaces";
export namespace Components {
/**
Expand Down Expand Up @@ -596,6 +598,31 @@ export namespace Components {
*/
"value": string;
}
interface BqToast {
"hide": () => Promise<void>;
/**
* If true will hide toast icon
*/
"hideIcon": boolean;
/**
* If true, the toast will be shown
*/
"open": boolean;
/**
* Placement of toast
*/
"placement": TToastPlacement;
"show": () => Promise<void>;
/**
* The length of time, in milliseconds, after which the toast will close itself
*/
"time": number;
"toast": () => Promise<void>;
/**
* Type of toast
*/
"type": TToastType;
}
interface BqTooltip {
/**
* Set the action when the tooltip should be displayed, on hover (default) or click
Expand Down Expand Up @@ -680,6 +707,10 @@ export interface BqTabGroupCustomEvent<T> extends CustomEvent<T> {
detail: T;
target: HTMLBqTabGroupElement;
}
export interface BqToastCustomEvent<T> extends CustomEvent<T> {
detail: T;
target: HTMLBqToastElement;
}
declare global {
/**
* An avatar represents an object made of different pieces of information, in a way that is understandable at a glance.
Expand Down Expand Up @@ -805,6 +836,12 @@ declare global {
prototype: HTMLBqTabGroupElement;
new (): HTMLBqTabGroupElement;
};
interface HTMLBqToastElement extends Components.BqToast, HTMLStencilElement {
}
var HTMLBqToastElement: {
prototype: HTMLBqToastElement;
new (): HTMLBqToastElement;
};
interface HTMLBqTooltipElement extends Components.BqTooltip, HTMLStencilElement {
}
var HTMLBqTooltipElement: {
Expand All @@ -830,6 +867,7 @@ declare global {
"bq-switch": HTMLBqSwitchElement;
"bq-tab": HTMLBqTabElement;
"bq-tab-group": HTMLBqTabGroupElement;
"bq-toast": HTMLBqToastElement;
"bq-tooltip": HTMLBqTooltipElement;
}
}
Expand Down Expand Up @@ -1454,6 +1492,36 @@ declare namespace LocalJSX {
*/
"value"?: string;
}
interface BqToast {
/**
* If true will hide toast icon
*/
"hideIcon"?: boolean;
/**
* Callback handler to be called when the notification is hidden
*/
"onBqHide"?: (event: BqToastCustomEvent<HTMLBqToastElement>) => void;
/**
* Callback handler to be called when the notification is shown
*/
"onBqShow"?: (event: BqToastCustomEvent<HTMLBqToastElement>) => void;
/**
* If true, the toast will be shown
*/
"open"?: boolean;
/**
* Placement of toast
*/
"placement"?: TToastPlacement;
/**
* The length of time, in milliseconds, after which the toast will close itself
*/
"time"?: number;
/**
* Type of toast
*/
"type"?: TToastType;
}
interface BqTooltip {
/**
* Set the action when the tooltip should be displayed, on hover (default) or click
Expand Down Expand Up @@ -1496,6 +1564,7 @@ declare namespace LocalJSX {
"bq-switch": BqSwitch;
"bq-tab": BqTab;
"bq-tab-group": BqTabGroup;
"bq-toast": BqToast;
"bq-tooltip": BqTooltip;
}
}
Expand Down Expand Up @@ -1537,6 +1606,7 @@ declare module "@stencil/core" {
"bq-switch": LocalJSX.BqSwitch & JSXBase.HTMLAttributes<HTMLBqSwitchElement>;
"bq-tab": LocalJSX.BqTab & JSXBase.HTMLAttributes<HTMLBqTabElement>;
"bq-tab-group": LocalJSX.BqTabGroup & JSXBase.HTMLAttributes<HTMLBqTabGroupElement>;
"bq-toast": LocalJSX.BqToast & JSXBase.HTMLAttributes<HTMLBqToastElement>;
"bq-tooltip": LocalJSX.BqTooltip & JSXBase.HTMLAttributes<HTMLBqTooltipElement>;
}
}
Expand Down
2 changes: 2 additions & 0 deletions packages/bee-q/src/components/icon/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Icons are simplified images that graphically explain the meaning of an object on
- [bq-dialog](../dialog)
- [bq-notification](../notification)
- [bq-switch](../switch)
- [bq-toast](../toast)

### Graph
```mermaid
Expand All @@ -48,6 +49,7 @@ graph TD;
bq-dialog --> bq-icon
bq-notification --> bq-icon
bq-switch --> bq-icon
bq-toast --> bq-icon
style bq-icon fill:#f9f,stroke:#333,stroke-width:4px
```

Expand Down
100 changes: 100 additions & 0 deletions packages/bee-q/src/components/toast/__tests__/bq-toast.e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { newE2EPage } from '@stencil/core/testing';

import { computedStyle } from '../../../shared/test-utils/computedStyle';

describe('bq-toast', () => {
it('should render', async () => {
const page = await newE2EPage();
await page.setContent('<bq-toast></bq-toast>');

const element = await page.find('bq-toast');

expect(element).toHaveClass('hydrated');
});

it('should have shadow root', async () => {
const page = await newE2EPage();
await page.setContent('<bq-toast></bq-toast>');

const element = await page.find('bq-toast');

expect(element.shadowRoot).not.toBeNull();
});

it('should display text', async () => {
const page = await newE2EPage();
await page.setContent('<bq-toast>Text</bq-toast>');

const element = await page.find('bq-toast');

expect(element).toEqualText('Text');
});

it('should display info icon by default', async () => {
const page = await newE2EPage();
await page.setContent('<bq-toast>Text</bq-toast>');

const iconWrapper = await page.find('bq-toast >>> bq-icon');

expect(iconWrapper).toEqualAttribute('name', 'info');
});

it('should display success icon', async () => {
const page = await newE2EPage();
await page.setContent('<bq-toast type="success">Text</bq-toast>');

const iconWrapper = await page.find('bq-toast >>> bq-icon');

expect(iconWrapper).toEqualAttribute('name', 'check-circle');
});

it('should display custom icon', async () => {
const page = await newE2EPage();
await page.setContent(`
<bq-toast>
Text
<bq-icon slot="icon" size="24" weight="bold" name="star"></bq-icon>
</bq-toast>
`);

const iconWrapperName = await page.$eval('bq-toast', (element) => {
const slotElement = element.shadowRoot.querySelector<HTMLSlotElement>('slot[name="icon"]');

const assignedElements = slotElement.assignedElements({ flatten: true })[0];

return assignedElements.getAttribute('name');
});

expect(iconWrapperName).toEqualText('star');
});

it('should respect design style', async () => {
const page = await newE2EPage();
await page.setContent(`<bq-toast>Text</bq-toast>`);

const styleProps = ['padding', 'borderRadius', 'gap'] as const;

const style = await computedStyle(page, 'bq-toast >>> [part="wrapper"]', styleProps);

expect(style).toEqual({ padding: '12px 16px', borderRadius: '8px', gap: '8px' });
});

it('should call methods', async () => {
const page = await newE2EPage();
await page.setContent('<bq-toast>Test</bq-toast>');

const element = await page.find('bq-toast');

await element.callMethod('show');
await page.waitForChanges();

expect(element).toEqualAttribute('aria-hidden', 'false');
expect(element).toEqualAttribute('hidden', 'false');

await element.callMethod('hide');
await page.waitForChanges();

expect(element).toEqualAttribute('aria-hidden', 'true');
expect(element).toEqualAttribute('hidden', 'true');
});
});
19 changes: 19 additions & 0 deletions packages/bee-q/src/components/toast/_storybook/bq-toast.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { ArgTypes, Title, Subtitle } from '@storybook/addon-docs';

<Title>Toast</Title>

The Toast Component is a UI element used to provide short, non-interruptive notifications to users.

<Subtitle>Usage</Subtitle>

Toasts are typically displayed briefly at the bottom of the screen and disappear after a short amount of time. Toasts are commonly used to provide confirmation messages, error messages, or progress updates.

<Subtitle>👍 When to use</Subtitle>

- Providing confirmation messages for actions, such as confirming the successful submission of a form or successful completion of a task.
- Displaying error messages for issues or problems, such as indicating a required field is missing or a network error has occurred.
- Presenting progress updates for long-running actions, such as indicating the status of a download or the progress of a task

<Title>Properties</Title>

<ArgTypes of="bq-toast" />
Loading

0 comments on commit 5c22cc7

Please sign in to comment.