diff options
Diffstat (limited to 'toolkit/content/widgets/moz-button')
-rw-r--r-- | toolkit/content/widgets/moz-button/moz-button.css | 26 | ||||
-rw-r--r-- | toolkit/content/widgets/moz-button/moz-button.mjs | 21 | ||||
-rw-r--r-- | toolkit/content/widgets/moz-button/moz-button.stories.mjs | 29 |
3 files changed, 58 insertions, 18 deletions
diff --git a/toolkit/content/widgets/moz-button/moz-button.css b/toolkit/content/widgets/moz-button/moz-button.css index 71d57ea93a..4eb6839e06 100644 --- a/toolkit/content/widgets/moz-button/moz-button.css +++ b/toolkit/content/widgets/moz-button/moz-button.css @@ -23,6 +23,10 @@ button { /* Ensure font-size isn't overridden by widget styling (e.g. in forms.css) */ font-size: var(--button-font-size); width: 100%; + display: flex; + justify-content: center; + align-items: center; + gap: var(--space-small); &[size=small] { min-height: var(--button-min-height-small); @@ -125,21 +129,33 @@ button { } } - &[type~=icon] { + &[type~=icon]:not(.labelled) { background-size: var(--icon-size-default); background-position: center; background-repeat: no-repeat; - -moz-context-properties: fill, stroke; - fill: currentColor; - stroke: currentColor; + } + + &[type~=icon]:not(.labelled), + &:not(.labelled):has(img) { width: var(--button-size-icon); height: var(--button-size-icon); padding: var(--button-padding-icon); - color: var(--icon-color); &[size=small] { width: var(--button-size-icon-small); height: var(--button-size-icon-small); } } + + img, + &[type~=icon]:not(.labelled) { + -moz-context-properties: fill, fill-opacity, stroke; + fill: currentColor; + stroke: currentColor; + } + + img { + width: var(--icon-size-default); + height: var(--icon-size-default); + } } diff --git a/toolkit/content/widgets/moz-button/moz-button.mjs b/toolkit/content/widgets/moz-button/moz-button.mjs index a951dbf5d8..9a239d4e56 100644 --- a/toolkit/content/widgets/moz-button/moz-button.mjs +++ b/toolkit/content/widgets/moz-button/moz-button.mjs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { html, ifDefined } from "../vendor/lit.all.mjs"; +import { html, ifDefined, classMap } from "../vendor/lit.all.mjs"; import { MozLitElement } from "../lit-utils.mjs"; /** @@ -19,8 +19,11 @@ import { MozLitElement } from "../lit-utils.mjs"; * @property {string} titleAttribute - Internal, map title attribute to the title JS property. * @property {string} tooltipText - Set the title property, the title attribute will be used first. * @property {string} ariaLabel - The button's arial-label attribute, used in shadow DOM and therefore not as an attribute on moz-button. + * @property {string} iconSrc - Path to the icon that should be displayed in the button. * @property {string} ariaLabelAttribute - Internal, map aria-label attribute to the ariaLabel JS property. + * @property {string} hasVisibleLabel - Internal, tracks whether or not the button has a visible label. * @property {HTMLButtonElement} buttonEl - The internal button element in the shadow DOM. + * @property {HTMLButtonElement} slotEl - The internal slot element in the shadow DOM. * @slot default - The button's content, overrides label property. * @fires click - The click event. */ @@ -44,10 +47,13 @@ export default class MozButton extends MozLitElement { reflect: true, }, ariaLabel: { type: String, state: true }, + iconSrc: { type: String }, + hasVisibleLabel: { type: Boolean, state: true }, }; static queries = { buttonEl: "button", + slotEl: "slot", }; constructor() { @@ -55,6 +61,7 @@ export default class MozButton extends MozLitElement { this.type = "default"; this.size = "default"; this.disabled = false; + this.hasVisibleLabel = !!this.label; } willUpdate(changes) { @@ -73,6 +80,12 @@ export default class MozButton extends MozLitElement { this.buttonEl.click(); } + checkForLabelText() { + this.hasVisibleLabel = this.slotEl + .assignedNodes() + .some(node => node.textContent.trim()); + } + render() { return html` <link @@ -86,8 +99,12 @@ export default class MozButton extends MozLitElement { title=${ifDefined(this.title || this.tooltipText)} aria-label=${ifDefined(this.ariaLabel)} part="button" + class=${classMap({ labelled: this.label || this.hasVisibleLabel })} > - <slot>${this.label}</slot> + ${this.iconSrc + ? html`<img src=${this.iconSrc} role="presentation" />` + : ""} + <slot @slotchange=${this.checkForLabelText}>${this.label}</slot> </button> `; } diff --git a/toolkit/content/widgets/moz-button/moz-button.stories.mjs b/toolkit/content/widgets/moz-button/moz-button.stories.mjs index 52a459e807..dd8d6369db 100644 --- a/toolkit/content/widgets/moz-button/moz-button.stories.mjs +++ b/toolkit/content/widgets/moz-button/moz-button.stories.mjs @@ -2,7 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { html } from "../vendor/lit.all.mjs"; +import { html, ifDefined } from "../vendor/lit.all.mjs"; // eslint-disable-next-line import/no-unassigned-import import "./moz-button.mjs"; @@ -22,6 +22,10 @@ export default { options: ["default", "small"], control: { type: "radio" }, }, + type: { + options: ["default", "primary", "destructive", "icon", "icon ghost"], + control: { type: "select" }, + }, }, parameters: { actions: { @@ -40,17 +44,13 @@ moz-button-aria-labelled = }, }; -const Template = ({ type, size, l10nId, iconUrl, disabled }) => html` - <style> - moz-button[type~="icon"]::part(button) { - background-image: url("${iconUrl}"); - } - </style> +const Template = ({ type, size, l10nId, iconSrc, disabled }) => html` <moz-button data-l10n-id=${l10nId} type=${type} size=${size} ?disabled=${disabled} + iconSrc=${ifDefined(iconSrc)} ></moz-button> `; @@ -59,7 +59,7 @@ Default.args = { type: "default", size: "default", l10nId: "moz-button-labelled", - iconUrl: "chrome://global/skin/icons/more.svg", + iconSrc: "", disabled: false, }; export const DefaultSmall = Template.bind({}); @@ -67,7 +67,7 @@ DefaultSmall.args = { type: "default", size: "small", l10nId: "moz-button-labelled", - iconUrl: "chrome://global/skin/icons/more.svg", + iconSrc: "", disabled: false, }; export const Primary = Template.bind({}); @@ -85,7 +85,7 @@ Destructive.args = { export const Icon = Template.bind({}); Icon.args = { ...Default.args, - type: "icon", + iconSrc: "chrome://global/skin/icons/more.svg", l10nId: "moz-button-titled", }; export const IconSmall = Template.bind({}); @@ -96,5 +96,12 @@ IconSmall.args = { export const IconGhost = Template.bind({}); IconGhost.args = { ...Icon.args, - type: "icon ghost", + type: "ghost", +}; +export const IconText = Template.bind({}); +IconText.args = { + type: "default", + size: "default", + iconSrc: "chrome://global/skin/icons/edit-copy.svg", + l10nId: "moz-button-labelled", }; |