Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DTRA-1047] henry/dtra-1047/feat: snackbar UI #56

Merged
merged 18 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions lib/components/Snackbar/SnackbarWrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { StandalonePlaceholderRegularIcon } from "@deriv/quill-icons/Standalone";
import { Snackbar } from ".";
import React, { useState } from "react";

export const SnackbarWrapper = () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's weird but i couldn't find the place where this component is used..

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its just a wrapper to pass functions into the component to work for now. For the next task it'll be used.

const [isOpen, setIsOpen] = useState(false);

const handleActionClick = () => {
console.log("clicked");
henry-deriv marked this conversation as resolved.
Show resolved Hide resolved
handleClose();
kate-deriv marked this conversation as resolved.
Show resolved Hide resolved
};

const handleOpen = () => {
setIsOpen(true);
};

const handleClose = () => {
setTimeout(() => {
henry-deriv marked this conversation as resolved.
Show resolved Hide resolved
setIsOpen(false);
}, 1000);
};

return (
<div>
<button onClick={handleOpen} style={{ color: "white" }}>
henry-deriv marked this conversation as resolved.
Show resolved Hide resolved
Click me
</button>
<Snackbar
icon={
<StandalonePlaceholderRegularIcon
fill="#ffffff"
iconSize="sm"
/>
}
message="Unable to upload selected photos. \n The app will retry in 5 seconds."
henry-deriv marked this conversation as resolved.
Show resolved Hide resolved
actionText="Action"
onActionClick={handleActionClick}
isOpen={isOpen}
onClose={handleClose}
/>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Snackbar calls onActionClick when action button is clicked 1`] = `
<div>
<div
class="snackbar fast-animation"
>
<div
class="snackbar__message--container"
>
<p
class="quill-typography__body-text__size--sm__weight--regular__decoration--default quill-typography__color--default snackbar__message"
>
Test message
</p>
</div>
<button
style="color: rgb(255, 255, 255); padding: 4px;"
type="button"
>
Action
</button>
<button
style="color: rgb(255, 255, 255); padding: 4px;"
type="button"
>
x
</button>
</div>
</div>
`;

exports[`Snackbar calls onClose after a certain duration when Snackbar is open 1`] = `
<div>
<div
class="snackbar slow-animation"
>
<div
class="snackbar__message--container"
>
<p
class="quill-typography__body-text__size--sm__weight--regular__decoration--default quill-typography__color--default snackbar__message"
>
Test message
</p>
</div>
<button
style="color: rgb(255, 255, 255); padding: 4px;"
type="button"
>
x
</button>
</div>
</div>
`;

exports[`Snackbar calls onClose when close button is clicked 1`] = `
<div>
<div
class="snackbar fast-animation"
>
<div
class="snackbar__message--container"
>
<p
class="quill-typography__body-text__size--sm__weight--regular__decoration--default quill-typography__color--default snackbar__message"
>
Test message
</p>
</div>
<button
style="color: rgb(255, 255, 255); padding: 4px;"
type="button"
>
x
</button>
</div>
</div>
`;

exports[`Snackbar renders correctly with custom icon 1`] = `
<div>
<div
class="snackbar slow-animation"
>
<div
class="snackbar__icon--container"
>
<img
alt="Custom Icon"
data-testid="custom-icon"
src="custom-icon.svg"
/>
</div>
<div
class="snackbar__message--container"
>
<p
class="quill-typography__body-text__size--sm__weight--regular__decoration--default quill-typography__color--default snackbar__message"
>
Test message
</p>
</div>
<button
style="color: rgb(255, 255, 255); padding: 4px;"
type="button"
>
x
</button>
</div>
</div>
`;

exports[`Snackbar renders correctly without action button 1`] = `
<div>
<div
class="snackbar slow-animation"
>
<div
class="snackbar__message--container"
>
<p
class="quill-typography__body-text__size--sm__weight--regular__decoration--default quill-typography__color--default snackbar__message"
>
Test message
</p>
</div>
<button
style="color: rgb(255, 255, 255); padding: 4px;"
type="button"
>
x
</button>
</div>
</div>
`;

exports[`Snackbar renders correctly without close button 1`] = `
<div>
<div
class="snackbar slow-animation"
>
<div
class="snackbar__message--container"
>
<p
class="quill-typography__body-text__size--sm__weight--regular__decoration--default quill-typography__color--default snackbar__message"
>
Test message
</p>
</div>
</div>
</div>
`;

exports[`Snackbar renders with default props 1`] = `
<div>
<div
class="snackbar slow-animation"
>
<div
class="snackbar__message--container"
>
<p
class="quill-typography__body-text__size--sm__weight--regular__decoration--default quill-typography__color--default snackbar__message"
>
Test message
</p>
</div>
<button
style="color: rgb(255, 255, 255); padding: 4px;"
type="button"
>
x
</button>
</div>
</div>
`;
109 changes: 109 additions & 0 deletions lib/components/Snackbar/__tests__/snackbar.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { render, screen, fireEvent } from "@testing-library/react";
import { Snackbar } from "..";

describe("Snackbar", () => {
it("renders with default props", () => {
const { container } = render(
<Snackbar
message="Test message"
henry-deriv marked this conversation as resolved.
Show resolved Hide resolved
isOpen={true}
onClose={jest.fn()}
/>,
);
expect(screen.getByText("Test message")).toBeInTheDocument();
henry-deriv marked this conversation as resolved.
Show resolved Hide resolved
expect(container).toMatchSnapshot();
});
it("calls onActionClick when action button is clicked", () => {
const onActionClickMock = jest.fn();
const { container } = render(
<Snackbar
message="Test message"
actionText="Action"
isOpen={true}
onActionClick={onActionClickMock}
onClose={jest.fn()}
/>,
);

fireEvent.click(screen.getByText("Action"));
henry-deriv marked this conversation as resolved.
Show resolved Hide resolved
expect(onActionClickMock).toHaveBeenCalled();
expect(container).toMatchSnapshot();
});
it("calls onClose when close button is clicked", () => {
const onCloseMock = jest.fn();
const { container } = render(
<Snackbar
message="Test message"
isOpen={true}
onClose={onCloseMock}
/>,
);

fireEvent.click(screen.getByText("x"));
expect(onCloseMock).toHaveBeenCalled();
expect(container).toMatchSnapshot();
});
it("calls onClose after a certain duration when Snackbar is open", async () => {
jest.useFakeTimers();

const onCloseMock = jest.fn();
const { container } = render(
<Snackbar
message="Test message"
isOpen={true}
onClose={onCloseMock}
/>,
);

jest.advanceTimersByTime(3000);
expect(onCloseMock).toHaveBeenCalled();
expect(container).toMatchSnapshot();

jest.useRealTimers();
henry-deriv marked this conversation as resolved.
Show resolved Hide resolved
});
it("renders correctly with custom icon", () => {
const customIcon = (
<img
src="custom-icon.svg"
alt="Custom Icon"
data-testid="custom-icon"
/>
);
const { container } = render(
<Snackbar
icon={customIcon}
message="Test message"
isOpen={true}
onClose={jest.fn()}
/>,
);

expect(screen.getByTestId("custom-icon")).toBeInTheDocument();
expect(container).toMatchSnapshot();
});
it("renders correctly without action button", () => {
const { container } = render(
<Snackbar
message="Test message"
isOpen={true}
onClose={() => {}}
/>,
);

expect(screen.queryByText("Action")).toBeNull();
henry-deriv marked this conversation as resolved.
Show resolved Hide resolved
expect(container).toMatchSnapshot();
});
it("renders correctly without close button", () => {
const { container } = render(
<Snackbar
message="Test message"
isOpen={true}
onClose={jest.fn()}
hasCloseButton={false}
/>,
);

expect(screen.queryByText("x")).toBeNull();
henry-deriv marked this conversation as resolved.
Show resolved Hide resolved
expect(container).toMatchSnapshot();
});
});
Loading