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

feat(listbox): added description element #2020

Merged
merged 1 commit into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
18 changes: 18 additions & 0 deletions src/components/ebay-listbox-button/examples/with-description.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<ebay-listbox-button
prefix-label="Select"
name="formFieldName"
onChange("emit", "change")
onCollapse("emit", "collapse")
onExpand("emit", "expand")
...input
>
<@option selected value="1" text="Option 1">
<@description>Option 1 info</@description>
</@option>
<@option value="2" text="Option 2">
<@description>Option 2 info</@description>
</@option>
<@option value="3" text="Option 3">
<@description>Option 3 info</@description>
</@option>
</ebay-listbox-button>
20 changes: 15 additions & 5 deletions src/components/ebay-listbox-button/listbox-button.stories.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { tagToString } from "../../../.storybook/storybook-code-source";
import { addRenderBodies } from "../../../.storybook/utils";
import {
addRenderBodies,
buildExtensionTemplate,
} from "../../../.storybook/utils";
import Readme from "./README.md";
import Component from "./index.marko";
import WithDescriptionTemplate from "./examples/with-description.marko";
import WithDescriptionTemplateCode from "./examples/with-description.marko?raw";

const Template = (args) => ({
input: addRenderBodies(args),
Expand Down Expand Up @@ -139,8 +144,8 @@ export default {
},
};

export const Standard = Template.bind({});
Standard.args = {
export const Default = Template.bind({});
Default.args = {
prefixLabel: "Selected:",
options: [
{
Expand All @@ -157,12 +162,17 @@ Standard.args = {
},
],
};
Standard.parameters = {
Default.parameters = {
docs: {
source: {
code: tagToString("ebay-listbox-button", Standard.args, {
code: tagToString("ebay-listbox-button", Default.args, {
items: "item",
}),
},
},
};

export const withDescription = buildExtensionTemplate(
WithDescriptionTemplate,
WithDescriptionTemplateCode
);
8 changes: 8 additions & 0 deletions src/components/ebay-listbox-button/marko-tag.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@
"targetProperty": null,
"type": "expression"
},
"@description <description>": {
"attribute-groups": ["html-attributes"],
"@*": {
"targetProperty": null,
"type": "expression"
},
"@html-attributes": "expression"
},
"@html-attributes": "expression",
"@text": "string",
"@selected": "#html-selected",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
<DocumentFragment>
<span
class="listbox-button"
>
<button
aria-haspopup="listbox"
class="listbox-button__control btn btn--form"
type="button"
value="Option 1"
>
<span
class="btn__cell"
>
<span
class="btn__label"
>
Select 
</span>
<span
class="btn__text"
>
Option 1
</span>
<svg
aria-hidden="true"
class="icon icon--chevron-down-16"
focusable="false"
>
<defs>
<symbol
id="icon-chevron-down-16"
viewBox="0 0 16 16"
>
<path
d="M8.707 12.707a1 1 0 0 1-1.414 0l-6-6a1 1 0 0 1 1.414-1.414L8 10.586l5.293-5.293a1 1 0 1 1 1.414 1.414l-6 6Z"
/>
</symbol>
</defs>
<use
href="#icon-chevron-down-16"
/>
</svg>
</span>
</button>
<div
class="listbox__options listbox-button__listbox"
role="listbox"
tabindex="-1"
>
<div
aria-selected="true"
class="listbox__option"
role="option"
>
<span
class="listbox__value"
>
Option 1
</span>
<span
class="listbox__description"
>
Option 1 info
</span>
<svg
aria-hidden="true"
class="icon icon--tick-16"
focusable="false"
>
<defs>
<symbol
id="icon-tick-16"
viewBox="0 0 16 16"
>
<path
clip-rule="evenodd"
d="M13.707 5.707a1 1 0 0 0-1.414-1.414L6 10.586 3.707 8.293a1 1 0 0 0-1.414 1.414l3 3a1 1 0 0 0 1.414 0l7-7Z"
fill-rule="evenodd"
/>
</symbol>
</defs>
<use
href="#icon-tick-16"
/>
</svg>
</div>
<div
class="listbox__option"
role="option"
>
<span
class="listbox__value"
>
Option 2
</span>
<span
class="listbox__description"
>
Option 2 info
</span>
<svg
aria-hidden="true"
class="icon icon--tick-16"
focusable="false"
>
<use
href="#icon-tick-16"
/>
</svg>
</div>
<div
class="listbox__option"
role="option"
>
<span
class="listbox__value"
>
Option 3
</span>
<span
class="listbox__description"
>
Option 3 info
</span>
<svg
aria-hidden="true"
class="icon icon--tick-16"
focusable="false"
>
<use
href="#icon-tick-16"
/>
</svg>
</div>
</div>
<select
class="listbox__native"
hidden=""
name="formFieldName"
>
<option
selected=""
value="1"
/>
<option
value="2"
/>
<option
value="3"
/>
</select>
</span>
</DocumentFragment>
50 changes: 37 additions & 13 deletions src/components/ebay-listbox-button/test/test.browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { render, fireEvent, cleanup } from "@marko/testing-library";
import { pressKey } from "../../../common/test-utils/browser";
import * as stories from "../listbox-button.stories";

const { Standard } = composeStories(stories);
const { Default, withDescription } = composeStories(stories);

const options = [...Standard.args.options];
const options = [...Default.args.options];
options[0] = Object.assign({ selected: true }, options[0]);

use(chaiDom);
Expand All @@ -24,29 +24,29 @@ after(() => document.body.removeChild(form));
describe("given the listbox with 3 items", () => {
beforeEach(async () => {
component = await render(
Standard,
Default,
{
listSelection: "auto",
name: "listbox-name",
buttonName: "listbox-button-name",
},
{
container: form,
}
},
);
});

it("then it should not be expanded", () => {
expect(component.getByRole("button")).has.attr(
"aria-expanded",
"false"
"false",
);
});

it("then it should have button with name attribute", () => {
expect(component.getByRole("button")).has.attr(
"name",
"listbox-button-name"
"listbox-button-name",
);
});

Expand All @@ -67,7 +67,7 @@ describe("given the listbox with 3 items", () => {
it("then it should not expand the listbox", () => {
expect(component.getByRole("button")).has.attr(
"aria-expanded",
"false"
"false",
);
});

Expand All @@ -83,7 +83,7 @@ describe("given the listbox with 3 items", () => {
it("then it should not expand the listbox", () => {
expect(component.getByRole("button")).has.attr(
"aria-expanded",
"false"
"false",
);
});
});
Expand All @@ -101,7 +101,7 @@ describe("given the listbox with 3 items", () => {
it("then it has expanded the listbox", () => {
expect(component.getByRole("button")).has.attr(
"aria-expanded",
"true"
"true",
);
});

Expand All @@ -117,7 +117,7 @@ describe("given the listbox with 3 items", () => {
it("then it has collapsed the listbox", () => {
expect(component.getByRole("button")).has.attr(
"aria-expanded",
"false"
"false",
);
});
});
Expand All @@ -127,11 +127,11 @@ describe("given the listbox with 3 items", () => {
describe("given the listbox is in an expanded state", () => {
beforeEach(async () => {
component = await render(
Standard,
Default,
{ listSelection: "auto", options },
{
container: form,
}
},
);
await fireEvent.click(component.getByRole("button"));
});
Expand Down Expand Up @@ -176,7 +176,7 @@ describe("given the listbox is in an expanded state", () => {

describe("given the listbox is in an expanded state with manual list-selection", () => {
beforeEach(async () => {
component = await render(Standard, { options }, { container: form });
component = await render(Default, { options }, { container: form });
await fireEvent.click(component.getByRole("button"));
});

Expand Down Expand Up @@ -219,6 +219,30 @@ describe("given the listbox is in an expanded state with manual list-selection",
});
});

describe("given the listbox has description", () => {
beforeEach(async () => {
component = await render(withDescription);
await fireEvent.click(component.getByRole("button"));
});

describe("when an option is clicked", () => {
beforeEach(async () => {
await fireEvent.click(component.getByText("Option 2 info"));
});

it("Should trigger listbox change change", () => {
const changeEvents = component.emitted("change");
expect(changeEvents).has.length(1);

const [[changeEvent]] = changeEvents;
expect(changeEvent).has.property("index", 1);
expect(changeEvent)
.has.property("selected")
.and.is.deep.equal(["2"]);
});
});
});

function isVisible(el) {
return !el.hasAttribute("hidden") && !el.closest("[hidden]");
}
Loading
Loading