diff --git a/.changeset/breezy-trees-cough.md b/.changeset/breezy-trees-cough.md new file mode 100644 index 000000000..ba058f0ee --- /dev/null +++ b/.changeset/breezy-trees-cough.md @@ -0,0 +1,5 @@ +--- +"@ebay/ebayui-core": patch +--- + +docs(snackbar): updated docs to support @action diff --git a/src/components/ebay-snackbar-dialog/README.md b/src/components/ebay-snackbar-dialog/README.md index 20492726e..1c3265fb7 100644 --- a/src/components/ebay-snackbar-dialog/README.md +++ b/src/components/ebay-snackbar-dialog/README.md @@ -3,7 +3,7 @@ ebay-snackbar-dialog </span> <span style='font-weight: normal; font-size: medium; margin-bottom: -15px;'> - DS v1.0.0 + DS v2.0.0 </span> </h1> diff --git a/src/components/ebay-snackbar-dialog/examples/action.marko b/src/components/ebay-snackbar-dialog/examples/action.marko index f4781cdf7..f100de2e2 100644 --- a/src/components/ebay-snackbar-dialog/examples/action.marko +++ b/src/components/ebay-snackbar-dialog/examples/action.marko @@ -1,10 +1,10 @@ class { declare state: { open: boolean; - } + }; onCreate() { - this.state = {open: false}; + this.state = { open: false }; } handleOpen() { @@ -13,20 +13,21 @@ class { handleClose() { this.state.open = false; - } - - handleAction() { - //do API call, other action here - alert("action") + this.emit("close"); } } - <ebay-button on-click("handleOpen")> Open Action Snackbar </ebay-button> -<ebay-snackbar-dialog open=state.open on-close('handleClose') on-action("handleAction")> +<ebay-snackbar-dialog + open=state.open + on-close("handleClose") + on-open("emit", "open") + on-action("emit", "action") + ...input +> <@action accessKey="U"> Undo </@action> - This is the action snackbar + This 'snackbar' text should be 1-2 lines. </ebay-snackbar-dialog> diff --git a/src/components/ebay-snackbar-dialog/examples/default.marko b/src/components/ebay-snackbar-dialog/examples/default.marko index ac9433cd3..53e1e5aee 100644 --- a/src/components/ebay-snackbar-dialog/examples/default.marko +++ b/src/components/ebay-snackbar-dialog/examples/default.marko @@ -24,5 +24,5 @@ class { Open Default Snackbar </ebay-button> <ebay-snackbar-dialog open=state.open on-close('handleClose') on-open('emit', 'open') ...input > - ${input.snacktext} + This 'snackbar' text should be 1-2 lines. </ebay-snackbar-dialog> diff --git a/src/components/ebay-snackbar-dialog/snackbar-dialog.stories.ts b/src/components/ebay-snackbar-dialog/snackbar-dialog.stories.ts index 14d166d3b..e47f0d70e 100644 --- a/src/components/ebay-snackbar-dialog/snackbar-dialog.stories.ts +++ b/src/components/ebay-snackbar-dialog/snackbar-dialog.stories.ts @@ -1,6 +1,14 @@ import Readme from "./README.md"; -import Component from "./examples/default.marko"; -import code from "./examples/default.marko?raw"; +import component from "./index.marko"; +import { + addRenderBodies, + buildExtensionTemplate, +} from "../../../.storybook/utils"; + +import defaultTemplate from "./examples/default.marko"; +import defaultTemplateCode from "./examples/default.marko?raw"; +import withActionTemplate from "./examples/action.marko"; +import withActionTemplateCode from "./examples/action.marko?raw"; const Template = (args) => ({ input: { @@ -15,7 +23,7 @@ const Template = (args) => ({ export default { title: "dialogs/ebay-snackbar-dialog", - component: Component, + component, parameters: { docs: { description: { @@ -37,9 +45,12 @@ export default { control: { type: "radio" }, options: ["row", "column"], }, - snacktext: { - control: { type: "text" }, - description: "for demo only", + action: { + name: "@action", + description: "If present, shows an action button on snackbar", + table: { + category: "@attribute tags", + }, }, onOpen: { action: "on-open", @@ -74,14 +85,12 @@ export default { }, }; -export const Standard = Template.bind({}); -Standard.args = { - snacktext: "This is the snackbar", -}; -Standard.parameters = { - docs: { - source: { - code, - }, - }, -}; +export const Default = buildExtensionTemplate( + defaultTemplate, + defaultTemplateCode, +); + +export const WithAction = buildExtensionTemplate( + withActionTemplate, + withActionTemplateCode, +); diff --git a/src/components/ebay-snackbar-dialog/test/__snapshots__/renders-basic-version.expected.txt b/src/components/ebay-snackbar-dialog/test/__snapshots__/renders-basic-version.expected.txt new file mode 100644 index 000000000..7b6c882a8 --- /dev/null +++ b/src/components/ebay-snackbar-dialog/test/__snapshots__/renders-basic-version.expected.txt @@ -0,0 +1,29 @@ +[36m<DocumentFragment>[39m + [36m<button[39m + [33mclass[39m=[32m"btn btn--secondary"[39m + [33mdata-ebayui[39m=[32m""[39m + [33mtype[39m=[32m"button"[39m + [36m>[39m + [0mOpen Default Snackbar[0m + [36m</button>[39m + [36m<div[39m + [33maria-live[39m=[32m"polite"[39m + [33maria-modal[39m=[32m"true"[39m + [33mclass[39m=[32m"snackbar-dialog snackbar-dialog--transition"[39m + [33mhidden[39m=[32m""[39m + [33mrole[39m=[32m"dialog"[39m + [36m>[39m + [36m<div[39m + [33mclass[39m=[32m"snackbar-dialog__window"[39m + [36m>[39m + [36m<div[39m + [33mclass[39m=[32m"snackbar-dialog__header"[39m + [36m/>[39m + [36m<div[39m + [33mclass[39m=[32m"snackbar-dialog__main"[39m + [36m>[39m + [0mThis 'snackbar' text should be 1-2 lines.[0m + [36m</div>[39m + [36m</div>[39m + [36m</div>[39m +[36m</DocumentFragment>[39m \ No newline at end of file diff --git a/src/components/ebay-snackbar-dialog/test/__snapshots__/renders-in-open-state.expected.txt b/src/components/ebay-snackbar-dialog/test/__snapshots__/renders-in-open-state.expected.txt new file mode 100644 index 000000000..940e3af7d --- /dev/null +++ b/src/components/ebay-snackbar-dialog/test/__snapshots__/renders-in-open-state.expected.txt @@ -0,0 +1,28 @@ +[36m<DocumentFragment>[39m + [36m<button[39m + [33mclass[39m=[32m"btn btn--secondary"[39m + [33mdata-ebayui[39m=[32m""[39m + [33mtype[39m=[32m"button"[39m + [36m>[39m + [0mOpen Default Snackbar[0m + [36m</button>[39m + [36m<div[39m + [33maria-live[39m=[32m"polite"[39m + [33maria-modal[39m=[32m"true"[39m + [33mclass[39m=[32m"snackbar-dialog snackbar-dialog--transition"[39m + [33mrole[39m=[32m"dialog"[39m + [36m>[39m + [36m<div[39m + [33mclass[39m=[32m"snackbar-dialog__window"[39m + [36m>[39m + [36m<div[39m + [33mclass[39m=[32m"snackbar-dialog__header"[39m + [36m/>[39m + [36m<div[39m + [33mclass[39m=[32m"snackbar-dialog__main"[39m + [36m>[39m + [0mThis 'snackbar' text should be 1-2 lines.[0m + [36m</div>[39m + [36m</div>[39m + [36m</div>[39m +[36m</DocumentFragment>[39m \ No newline at end of file diff --git a/src/components/ebay-snackbar-dialog/test/__snapshots__/renders-with-action-version.expected.txt b/src/components/ebay-snackbar-dialog/test/__snapshots__/renders-with-action-version.expected.txt new file mode 100644 index 000000000..386c451dc --- /dev/null +++ b/src/components/ebay-snackbar-dialog/test/__snapshots__/renders-with-action-version.expected.txt @@ -0,0 +1,45 @@ +[36m<DocumentFragment>[39m + [36m<button[39m + [33mclass[39m=[32m"btn btn--secondary"[39m + [33mdata-ebayui[39m=[32m""[39m + [33mtype[39m=[32m"button"[39m + [36m>[39m + [0mOpen Action Snackbar[0m + [36m</button>[39m + [36m<div[39m + [33maria-live[39m=[32m"polite"[39m + [33maria-modal[39m=[32m"true"[39m + [33mclass[39m=[32m"snackbar-dialog snackbar-dialog--transition"[39m + [33mhidden[39m=[32m""[39m + [33mrole[39m=[32m"dialog"[39m + [36m>[39m + [36m<div[39m + [33mclass[39m=[32m"snackbar-dialog__window"[39m + [36m>[39m + [36m<div[39m + [33mclass[39m=[32m"snackbar-dialog__header"[39m + [36m/>[39m + [36m<div[39m + [33mclass[39m=[32m"snackbar-dialog__main"[39m + [36m>[39m + [0mThis 'snackbar' text should be 1-2 lines.[0m + [36m</div>[39m + [36m<span[39m + [33mclass[39m=[32m"snackbar-dialog__actions"[39m + [36m>[39m + [36m<button[39m + [33mclass[39m=[32m"fake-link"[39m + [33mdata-ebayui[39m=[32m""[39m + [33mtype[39m=[32m"button"[39m + [36m>[39m + [0mUndo[0m + [36m<span[39m + [33mclass[39m=[32m"clipped"[39m + [36m>[39m + [0m- Access Key: U[0m + [36m</span>[39m + [36m</button>[39m + [36m</span>[39m + [36m</div>[39m + [36m</div>[39m +[36m</DocumentFragment>[39m \ No newline at end of file diff --git a/src/components/ebay-snackbar-dialog/test/__snapshots__/renders-without-handle.expected.txt b/src/components/ebay-snackbar-dialog/test/__snapshots__/renders-without-handle.expected.txt new file mode 100644 index 000000000..b5ef6be32 --- /dev/null +++ b/src/components/ebay-snackbar-dialog/test/__snapshots__/renders-without-handle.expected.txt @@ -0,0 +1,29 @@ +[36m<DocumentFragment>[39m + [36m<button[39m + [33mclass[39m=[32m"btn btn--secondary"[39m + [33mdata-ebayui[39m=[32m""[39m + [33mtype[39m=[32m"button"[39m + [36m>[39m + [0mOpen Default Snackbar[0m + [36m</button>[39m + [36m<div[39m + [33maria-live[39m=[32m"polite"[39m + [33maria-modal[39m=[32m"true"[39m + [33mclass[39m=[32m"snackbar-dialog snackbar-dialog--transition"[39m + [33mhidden[39m=[32m""[39m + [33mrole[39m=[32m"dialog"[39m + [36m>[39m + [36m<div[39m + [33mclass[39m=[32m"snackbar-dialog__window snackbar-dialog__window--column"[39m + [36m>[39m + [36m<div[39m + [33mclass[39m=[32m"snackbar-dialog__header"[39m + [36m/>[39m + [36m<div[39m + [33mclass[39m=[32m"snackbar-dialog__main"[39m + [36m>[39m + [0mThis 'snackbar' text should be 1-2 lines.[0m + [36m</div>[39m + [36m</div>[39m + [36m</div>[39m +[36m</DocumentFragment>[39m \ No newline at end of file diff --git a/src/components/ebay-snackbar-dialog/test/mock/index.js b/src/components/ebay-snackbar-dialog/test/mock/index.js deleted file mode 100644 index cd9f2d04a..000000000 --- a/src/components/ebay-snackbar-dialog/test/mock/index.js +++ /dev/null @@ -1,24 +0,0 @@ -/* eslint camelcase: "off" */ -import { createRenderBody } from "../../../../common/test-utils/shared"; - -export const Snackbar = { - a11yCloseText: "close", - header: { - renderBody: createRenderBody("head content"), - }, - footer: { - renderBody: createRenderBody("footer content"), - }, - action: { - renderBody: createRenderBody("action content"), - }, - renderBody: createRenderBody("body content"), -}; - -export const Snackbar_Open = Object.assign({}, Snackbar, { - open: true, -}); - -export const Snackbar_Closed = Object.assign({}, Snackbar, { - open: false, -}); diff --git a/src/components/ebay-snackbar-dialog/test/test.browser.js b/src/components/ebay-snackbar-dialog/test/test.browser.js index 80be60d91..4dc6501cc 100644 --- a/src/components/ebay-snackbar-dialog/test/test.browser.js +++ b/src/components/ebay-snackbar-dialog/test/test.browser.js @@ -1,9 +1,11 @@ import { expect, use } from "chai"; +import { composeStories } from "@storybook/marko"; import chaiDom from "chai-dom"; +import sinon from "sinon/pkg/sinon"; import { render, fireEvent, cleanup, waitFor } from "@marko/testing-library"; import { fastAnimations } from "../../../common/test-utils/browser"; -import template from ".."; -import * as mock from "./mock"; +import * as stories from "../snackbar-dialog.stories"; // import all stories from the stories file +const { Default, WithAction } = composeStories(stories); use(chaiDom); before(() => { @@ -19,12 +21,16 @@ afterEach(() => { /** @type import("@marko/testing-library").RenderResult */ let component; +let clock; describe("given an open snackbar", () => { - const input = mock.Snackbar_Open; - beforeEach(async () => { - component = await render(template, input); + component = await render(WithAction, { open: true }); + clock = sinon.useFakeTimers(); + }); + + afterEach(() => { + clock.restore(); }); it("then it is not hidden in the DOM", () => { @@ -33,7 +39,7 @@ describe("given an open snackbar", () => { describe("clicking on action icon emits action", () => { it("action emitted", async () => { - await fireEvent.click(component.getByText(/action/i)); + await fireEvent.click(component.getByText(/Undo/i)); expect(component.emitted("action")).has.length(1); }); }); @@ -41,22 +47,21 @@ describe("given an open snackbar", () => { describe("focus and mouseenter prevent closing it until all events", () => { it("is not closed", async () => { await fireEvent.mouseEnter( - component.getByText(/action/i).parentElement, + component.getByText(/Undo/i).parentElement, ); - await fireEvent.focus(component.getByText(/action/i).parentElement); - await fireEvent.blur(component.getByText(/action/i).parentElement); + await fireEvent.focus(component.getByText(/Undo/i).parentElement); + await fireEvent.blur(component.getByText(/Undo/i).parentElement); + clock.tick(7000); await waitFor(() => { expect(component.emitted("close")).has.length(0); - }, 7000); + }); }); }); }); describe("given a closed snackbar", () => { - const input = mock.Snackbar_Closed; - beforeEach(async () => { - component = await render(template, input); + component = await render(Default); }); it("then it is hidden in the DOM", () => { diff --git a/src/components/ebay-snackbar-dialog/test/test.server.js b/src/components/ebay-snackbar-dialog/test/test.server.js index c2b5904ea..b34c2dca6 100644 --- a/src/components/ebay-snackbar-dialog/test/test.server.js +++ b/src/components/ebay-snackbar-dialog/test/test.server.js @@ -1,35 +1,26 @@ -import { expect, use } from "chai"; -import { render } from "@marko/testing-library"; -import template from ".."; -import * as mock from "./mock"; - -use(require("chai-dom")); +import { composeStories } from "@storybook/marko"; +import { testPassThroughAttributes } from "../../../common/test-utils/server"; +import { snapshotHTML } from "../../../common/test-utils/snapshots"; +import * as stories from "../snackbar-dialog.stories"; // import all stories from the stories file +const { Default, WithAction } = composeStories(stories); +const htmlSnap = snapshotHTML(__dirname); describe("snackbar-dialog", () => { it("renders basic version", async () => { - const input = mock.Snackbar; - const { getByRole, getByText } = await render(template, input); - const dialog = getByRole("dialog", { hidden: true }); + await htmlSnap(Default); + }); - expect(dialog).has.attr("hidden"); - expect(dialog).has.class("snackbar-dialog"); - expect(dialog).has.class("snackbar-dialog--transition"); - expect(getByText(input.renderBody.text)).has.class( - "snackbar-dialog__main", - ); - expect(getByText(input.header.renderBody.text).parentElement).has.class( - "snackbar-dialog__header", - ); - expect(getByText(input.action.renderBody.text).parentElement).has.class( - "snackbar-dialog__actions", - ); - expect(getByRole("button", { hidden: "true" })).has.class("fake-link"); - expect(dialog.childNodes[0]).has.class("snackbar-dialog__window"); + it("renders without handle ", async () => { + await htmlSnap(Default, { layout: "column" }); }); it("renders in open state", async () => { - const input = mock.Snackbar_Open; - const { getByRole } = await render(template, input); - expect(getByRole("dialog")).does.not.have.attr("hidden"); + await htmlSnap(Default, { open: true }); }); + + it("renders with action version", async () => { + await htmlSnap(WithAction); + }); + + testPassThroughAttributes(Default); });