summaryrefslogtreecommitdiffstats
path: root/toolkit/content/widgets/moz-button
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:13:33 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:13:33 +0000
commit086c044dc34dfc0f74fbe41f4ecb402b2cd34884 (patch)
treea4f824bd33cb075dd5aa3eb5a0a94af221bbe83a /toolkit/content/widgets/moz-button
parentAdding debian version 124.0.1-1. (diff)
downloadfirefox-086c044dc34dfc0f74fbe41f4ecb402b2cd34884.tar.xz
firefox-086c044dc34dfc0f74fbe41f4ecb402b2cd34884.zip
Merging upstream version 125.0.1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/content/widgets/moz-button')
-rw-r--r--toolkit/content/widgets/moz-button/moz-button.css142
-rw-r--r--toolkit/content/widgets/moz-button/moz-button.mjs90
-rw-r--r--toolkit/content/widgets/moz-button/moz-button.stories.mjs100
3 files changed, 332 insertions, 0 deletions
diff --git a/toolkit/content/widgets/moz-button/moz-button.css b/toolkit/content/widgets/moz-button/moz-button.css
new file mode 100644
index 0000000000..47567df41d
--- /dev/null
+++ b/toolkit/content/widgets/moz-button/moz-button.css
@@ -0,0 +1,142 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+
+:host {
+ display: inline-block;
+}
+
+button {
+ appearance: none;
+ min-height: var(--button-min-height);
+ color: var(--button-text-color);
+ border: var(--button-border);
+ border-radius: var(--button-border-radius);
+ background-color: var(--button-background-color);
+ padding: var(--button-padding);
+ /* HTML button gets `font: -moz-button` from UA styles,
+ * but we want it to match the root font styling. */
+ font: inherit;
+ font-weight: var(--button-font-weight);
+ /* Ensure font-size isn't overridden by widget styling (e.g. in forms.css) */
+ font-size: var(--button-font-size);
+ width: 100%;
+
+ &[size=small] {
+ min-height: var(--button-min-height-small);
+ font-size: var(--button-font-size-small);
+ }
+
+ &:hover {
+ background-color: var(--button-background-color-hover);
+ border-color: var(--button-border-color-hover);
+ color: var(--button-text-color-hover);
+ }
+
+ &:hover:active {
+ background-color: var(--button-background-color-active);
+ border-color: var(--button-border-color-active);
+ color: var(--button-text-color-active);
+ }
+
+ &:disabled {
+ background-color: var(--button-background-color-disabled);
+ border-color: var(--button-border-color-disabled);
+ color: var(--button-text-color-disabled);
+ opacity: var(--button-opacity-disabled);
+ }
+
+ &:focus-visible {
+ outline: var(--focus-outline);
+ outline-offset: var(--focus-outline-offset);
+ }
+
+ &[type="primary"] {
+ background-color: var(--button-background-color-primary);
+ border-color: var(--button-border-color-primary);
+ color: var(--button-text-color-primary);
+
+ &:hover {
+ background-color: var(--button-background-color-primary-hover);
+ border-color: var(--button-border-color-primary-hover);
+ color: var(--button-text-color-primary-hover);
+ }
+
+ &:hover:active {
+ background-color: var(--button-background-color-primary-active);
+ border-color: var(--button-border-color-primary-active);
+ color: var(--button-text-color-primary-active);
+ }
+
+ &:disabled {
+ background-color: var(--button-background-color-primary-disabled);
+ border-color: var(--button-border-color-primary-disabled);
+ color: var(--button-text-color-primary-disabled);
+ }
+ }
+
+ &[type="destructive"] {
+ background-color: var(--button-background-color-destructive);
+ border-color: var(--button-border-color-destructive);
+ color: var(--button-text-color-destructive);
+
+ &:hover {
+ background-color: var(--button-background-color-destructive-hover);
+ border-color: var(--button-border-color-destructive-hover);
+ color: var(--button-text-color-destructive-hover);
+ }
+
+ &:hover:active {
+ background-color: var(--button-background-color-destructive-active);
+ border-color: var(--button-border-color-destructive-active);
+ color: var(--button-text-color-destructive-active);
+ }
+
+ &:disabled {
+ background-color: var(--button-background-color-destructive-disabled);
+ border-color: var(--button-border-color-destructive-disabled);
+ color: var(--button-text-color-destructive-disabled);
+ }
+ }
+
+ &[type~=ghost] {
+ background-color: var(--button-background-color-ghost);
+ border-color: var(--button-border-color-ghost);
+ color: var(--button-text-color-ghost);
+
+ &:hover {
+ background-color: var(--button-background-color-ghost-hover);
+ border-color: var(--button-border-color-ghost-hover);
+ color: var(--button-text-color-ghost-hover);
+ }
+
+ &:hover:active {
+ background-color: var(--button-background-color-ghost-active);
+ border-color: var(--button-border-color-ghost-active);
+ color: var(--button-text-color-ghost-active);
+ }
+
+ &:disabled {
+ background-color: var(--button-background-color-ghost-disabled);
+ border-color: var(--button-border-color-ghost-disabled);
+ color: var(--button-text-color-ghost-disabled);
+ }
+ }
+
+ &[type~=icon] {
+ background-size: var(--icon-size-default);
+ background-position: center;
+ background-repeat: no-repeat;
+ -moz-context-properties: fill, stroke;
+ fill: currentColor;
+ stroke: currentColor;
+ width: var(--button-size-icon);
+ height: var(--button-size-icon);
+ padding: var(--button-padding-icon);
+
+ &[size=small] {
+ width: var(--button-size-icon-small);
+ height: var(--button-size-icon-small);
+ }
+ }
+}
diff --git a/toolkit/content/widgets/moz-button/moz-button.mjs b/toolkit/content/widgets/moz-button/moz-button.mjs
new file mode 100644
index 0000000000..3e7c151e61
--- /dev/null
+++ b/toolkit/content/widgets/moz-button/moz-button.mjs
@@ -0,0 +1,90 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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 { MozLitElement } from "../lit-utils.mjs";
+
+/**
+ * A button with multiple types and two sizes.
+ *
+ * @tagname moz-button
+ * @property {string} label - The button's label, will be overridden by slotted content.
+ * @property {string} type - The button type.
+ * Options: default, primary, destructive, icon, icon ghost, ghost.
+ * @property {string} size - The button size.
+ * Options: default, small.
+ * @property {boolean} disabled - The disabled state.
+ * @property {string} title - The button's title attribute, used in shadow DOM and therefore not as an attribute on moz-button.
+ * @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} ariaLabelAttribute - Internal, map aria-label attribute to the ariaLabel JS property.
+ * @property {HTMLButtonElement} buttonEl - The internal button element in the shadow DOM.
+ * @slot default - The button's content, overrides label property.
+ * @fires click - The click event.
+ */
+export default class MozButton extends MozLitElement {
+ static shadowRootOptions = {
+ ...MozLitElement.shadowRootOptions,
+ delegatesFocus: true,
+ };
+
+ static properties = {
+ label: { type: String, reflect: true },
+ type: { type: String, reflect: true },
+ size: { type: String, reflect: true },
+ disabled: { type: Boolean, reflect: true },
+ title: { type: String, state: true },
+ titleAttribute: { type: String, attribute: "title", reflect: true },
+ tooltipText: { type: String },
+ ariaLabelAttribute: {
+ type: String,
+ attribute: "aria-label",
+ reflect: true,
+ },
+ ariaLabel: { type: String, state: true },
+ };
+
+ static queries = {
+ buttonEl: "button",
+ };
+
+ constructor() {
+ super();
+ this.type = "default";
+ this.size = "default";
+ this.disabled = false;
+ }
+
+ willUpdate(changes) {
+ if (changes.has("titleAttribute")) {
+ this.title = this.titleAttribute;
+ this.titleAttribute = null;
+ }
+ if (changes.has("ariaLabelAttribute")) {
+ this.ariaLabel = this.ariaLabelAttribute;
+ this.ariaLabelAttribute = null;
+ }
+ }
+
+ render() {
+ return html`
+ <link
+ rel="stylesheet"
+ href="chrome://global/content/elements/moz-button.css"
+ />
+ <button
+ type=${this.type}
+ size=${this.size}
+ ?disabled=${this.disabled}
+ title=${ifDefined(this.title || this.tooltipText)}
+ aria-label=${ifDefined(this.ariaLabel)}
+ part="button"
+ >
+ <slot>${this.label}</slot>
+ </button>
+ `;
+ }
+}
+customElements.define("moz-button", MozButton);
diff --git a/toolkit/content/widgets/moz-button/moz-button.stories.mjs b/toolkit/content/widgets/moz-button/moz-button.stories.mjs
new file mode 100644
index 0000000000..52a459e807
--- /dev/null
+++ b/toolkit/content/widgets/moz-button/moz-button.stories.mjs
@@ -0,0 +1,100 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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";
+// eslint-disable-next-line import/no-unassigned-import
+import "./moz-button.mjs";
+
+export default {
+ title: "UI Widgets/Moz Button",
+ component: "moz-button",
+ argTypes: {
+ l10nId: {
+ options: [
+ "moz-button-labelled",
+ "moz-button-titled",
+ "moz-button-aria-labelled",
+ ],
+ control: { type: "select" },
+ },
+ size: {
+ options: ["default", "small"],
+ control: { type: "radio" },
+ },
+ },
+ parameters: {
+ actions: {
+ handles: ["click"],
+ },
+ status: "in-development",
+ fluent: `
+moz-button-labelled = Button
+moz-button-primary = Primary
+moz-button-destructive = Destructive
+moz-button-titled =
+ .title = View logins
+moz-button-aria-labelled =
+ .aria-label = View logins
+`,
+ },
+};
+
+const Template = ({ type, size, l10nId, iconUrl, disabled }) => html`
+ <style>
+ moz-button[type~="icon"]::part(button) {
+ background-image: url("${iconUrl}");
+ }
+ </style>
+ <moz-button
+ data-l10n-id=${l10nId}
+ type=${type}
+ size=${size}
+ ?disabled=${disabled}
+ ></moz-button>
+`;
+
+export const Default = Template.bind({});
+Default.args = {
+ type: "default",
+ size: "default",
+ l10nId: "moz-button-labelled",
+ iconUrl: "chrome://global/skin/icons/more.svg",
+ disabled: false,
+};
+export const DefaultSmall = Template.bind({});
+DefaultSmall.args = {
+ type: "default",
+ size: "small",
+ l10nId: "moz-button-labelled",
+ iconUrl: "chrome://global/skin/icons/more.svg",
+ disabled: false,
+};
+export const Primary = Template.bind({});
+Primary.args = {
+ ...Default.args,
+ type: "primary",
+ l10nId: "moz-button-primary",
+};
+export const Destructive = Template.bind({});
+Destructive.args = {
+ ...Default.args,
+ type: "destructive",
+ l10nId: "moz-button-destructive",
+};
+export const Icon = Template.bind({});
+Icon.args = {
+ ...Default.args,
+ type: "icon",
+ l10nId: "moz-button-titled",
+};
+export const IconSmall = Template.bind({});
+IconSmall.args = {
+ ...Icon.args,
+ size: "small",
+};
+export const IconGhost = Template.bind({});
+IconGhost.args = {
+ ...Icon.args,
+ type: "icon ghost",
+};