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(toggle-button): add toggle button #1922

Merged
merged 4 commits into from
Jun 21, 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
1 change: 1 addition & 0 deletions ds-versions.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
"textbox": "1.1.0",
"toast": "2.1.0",
"toast-dialog": "2.1.0",
"toggle-button": "1.0.0",
"tooltip": "1.0.0",
"tourtip": "1.0.0",
"typography": "1.1.0"
Expand Down
Empty file.
9 changes: 9 additions & 0 deletions src/components/ebay-toggle-button/browser.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"requireRemap": [
{
"from": "./style",
"to": "../../common/empty",
"if-flag": "ebayui-no-skin"
}
]
}
13 changes: 13 additions & 0 deletions src/components/ebay-toggle-button/component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export default class {
onInput(input) {
this.state = { pressed: input.pressed };
}

handleClick(ev) {
this.state.pressed = !this.state.pressed;
this.emit("toggle", {
originalEvent: ev,
pressed: this.state.pressed,
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<ebay-toggle-button title="Title" layoutType="list" ...input onToggle("emit", "toggle")>
<@subtitle>
<p>Subtitle 1</p>
<p>Subtitle 2</p>
</@subtitle>
</ebay-toggle-button>
3 changes: 3 additions & 0 deletions src/components/ebay-toggle-button/examples/with-icon.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<ebay-toggle-button title="Title" subtitle="Subtitle" layoutType="list" ...input onToggle("emit", "toggle")>
<@icon><ebay-archive-24-icon/></@icon>
</ebay-toggle-button>
4 changes: 4 additions & 0 deletions src/components/ebay-toggle-button/examples/with-image.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
$ const { src, alt, fillPlacement, ...buttonInput } = input
<ebay-toggle-button title="Title" subtitle="Subtitle" layoutType="list" ...buttonInput onToggle("emit", "toggle")>
<@img src=src alt=alt fillPlacement=fillPlacement />
</ebay-toggle-button>
59 changes: 59 additions & 0 deletions src/components/ebay-toggle-button/index.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { processHtmlAttributes } from "../../common/html-attributes";

static var ignoredAttributes = [
"class",
"title",
"subtitle",
"pressed"
];

<button
type="button"
class=[
"toggle-button",
input.layoutType && `toggle-button--${input.layoutType}-layout`,
input.class
]
aria-pressed=state.pressed && "true"
ArtBlue marked this conversation as resolved.
Show resolved Hide resolved
...processHtmlAttributes(input, ignoredAttributes)
onClick("handleClick")>
<if(input.icon)>
<span class="toggle-button__icon">
<${input.icon}/>
</span>
</if>
<else-if(input.img)>
<span class="toggle-button__image-container">
<if(input.img.fillPlacement)>
<span
role="img"
aria-label=input.img.alt
class="toggle-button__image"
style={
backgroundImage: `url(${input.img.src})`,
backgroundPosition: input.img.fillPlacement || "center",
backgroundSize: "cover",
backgroundRepeat: "no-repeat",
} />
</if>
<else>
<span class="toggle-button__image">
<img src=input.img.src alt=input.img.alt />
</span>
</else>
</span>
</else-if>
<span class="toggle-button__content">
<span class="toggle-button__title">${input.title}</span>
<if(input.subtitle)>
<span class="toggle-button__subtitle">
<if(typeof input.subtitle === "string")>
${input.subtitle}
</if>
<else>
<${input.subtitle}/>
</else>
</span>
</if>
</span>
</button>
33 changes: 33 additions & 0 deletions src/components/ebay-toggle-button/marko-tag.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"attribute-groups": ["html-attributes"],
"@*": {
"targetProperty": null,
"type": "expression"
},
"@html-attributes": "expression",
"@pressed": "boolean",
"@title": "string",
"@subtitle <subtitle>": {
"@*": {
"targetProperty": null,
"type": "expression"
},
"@html-attributes": "expression"
},
"@icon <icon>": {
"@*": {
"targetProperty": null,
"type": "expression"
},
"@html-attributes": "expression"
},
"@img <img>": {
"@*": {
"targetProperty": null,
"type": "expression"
},
"@html-attributes": "expression",
"@src": "string",
"@size": "string"
}
}
1 change: 1 addition & 0 deletions src/components/ebay-toggle-button/style.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require("@ebay/skin/toggle-button");
161 changes: 161 additions & 0 deletions src/components/ebay-toggle-button/toggle-button.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import { tagToString } from "../../../.storybook/storybook-code-source";
import { addRenderBodies } from "../../../.storybook/utils";
import readme from "./README.md";
import component from "./index.marko";
import WithIconTemplate from "./examples/with-icon.marko";
import WithIconCode from "./examples/with-icon.marko?raw";
import WithImageTemplate from "./examples/with-image.marko";
import WithImageCode from "./examples/with-image.marko?raw";
import MultilineSubtitleTemplate from "./examples/multiline-subtitle.marko";
import MultilineSubtitleCode from "./examples/multiline-subtitle.marko?raw";

const Template = (args) => ({
input: addRenderBodies(args),
});

export default {
title: "buttons/ebay-toggle-button",
component,
parameters: {
docs: {
description: {
component: readme,
},
},
},
argTypes: {
renderBody: {},
layoutType: {
type: "string",
control: { type: "select" },
options: [undefined, "list", "gallery"],
description:
'Enforced layout type of the button. May be `undefined` (minimal default), `"list"`, or `"gallery"`. Gallery layout may only be used when there is also an icon or an image.',
},
pressed: {
type: "boolean",
control: { type: "boolean" },
description: "Pressed state of the button",
},
title: {
type: "string",
control: { type: "text" },
description: "Title attribute for the button",
},
subtitle: {
type: "string|@subtitle",
control: { type: "text" },
description: "Subtitle attribute for the button",
},
icon: {
name: "@icon",
description: "An `<ebay-[name]-icon>` to show as the button's icon",
table: {
category: "@attribute tags",
},
},
img: {
name: "@img",
description: "An `<img>` to show as the button's image",
table: {
category: "@attribute tags",
},
},
subtitleTag: {
name: "@subtitle",
description:
"May be used instead of the `subtitle` attribute for more control. Should contain no more than two brief lines of text",
table: {
category: "@attribute tags",
},
},
src: {
table: {
category: "@img attributes",
},
control: { type: "text" },
description: "Link to the image source",
},
alt: {
table: {
category: "@img attributes",
},
control: { type: "text" },
description: "Alt text for the image",
},
fillPlacement: {
LuLaValva marked this conversation as resolved.
Show resolved Hide resolved
table: {
category: "@img attributes",
},
control: { type: "text" },
ArtBlue marked this conversation as resolved.
Show resolved Hide resolved
description:
"Placement of the image within the given bounds using the CSS `background-position` property. Options include [keywords, lengths, and edge distances](https://developer.mozilla.org/en-US/docs/Web/CSS/background-position). Using this property will switch the image fit from `contain` to `cover`",
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice!

},
onToggle: {
action: "on-toggle",
description: "Triggered when the button is toggled",
table: {
category: "Events",
defaultValue: {
summary: "{ originalEvent, pressed }",
},
},
},
},
};

export const Default = Template.bind({});
Default.args = {
LuLaValva marked this conversation as resolved.
Show resolved Hide resolved
title: "Title",
};

Default.parameters = {
docs: {
source: {
code: tagToString("ebay-toggle-button", Default.args),
},
},
};

export const WithIcon = (args) => ({
input: args,
component: WithIconTemplate,
});
WithIcon.args = {};
WithIcon.parameters = {
docs: {
source: {
code: WithIconCode,
},
},
};

export const WithImage = (args) => ({
input: args,
component: WithImageTemplate,
});
WithImage.args = {
layoutType: "gallery",
src: "https://cloudfront.slrlounge.com/wp-content/uploads/2012/07/01-SLRLounge-Holding-Standing-Wrong.jpg",
fillPlacement: "top",
};
WithImage.parameters = {
docs: {
source: {
code: WithImageCode,
},
},
};

export const MultilineSubtitle = (args) => ({
input: args,
component: MultilineSubtitleTemplate,
});
MultilineSubtitle.args = {};
MultilineSubtitle.parameters = {
docs: {
source: {
code: MultilineSubtitleCode,
},
},
};