diff --git a/.changeset/chilled-peaches-enjoy.md b/.changeset/chilled-peaches-enjoy.md new file mode 100644 index 00000000000..f7a8def296a --- /dev/null +++ b/.changeset/chilled-peaches-enjoy.md @@ -0,0 +1,27 @@ +--- +"@spectrum-css/actionbutton": major +--- + +Action button now uses Spectrum 2 tokens and design specifications. A few notable changes: + +- Medium is now the default size and `.spectrum-ActionButton--sizeM` has been removed. +- Includes the Spectrum 2 down state transform. +- The component border was not removed and its color was changed to `transparent` in order to continue support for Windows High Contrast / forced colors, which still shows a border. The mod custom properties for border were removed to avoid interference with Windows High Contrast / forced colors accessibility. +- Some selectors to target the icon + text button and the icon-only button have been simplified using `:has`. This removes some overly complex `calc()` functions used for inline spacing, uses the design tokens more directly, and removes the previously documented need for the component's child elements to use a specific source order. +- Background and content colors were updated. +- Mod custom properties have been adjusted: + - Renamed: + - `--mod-line-height-100` renamed to `--mod-actionbutton-line-height`. + - `--mod-sans-font-family-stack` renamed to `--mod-button-font-family`. + - `--mod-animation-duration-100` renamed to `--mod-button-animation-duration`. + - Removed: + - `--mod-actionbutton-border-color-default` + - `--mod-actionbutton-border-color-disabled` + - `--mod-actionbutton-border-color-down` + - `--mod-actionbutton-border-color-focus` + - `--mod-actionbutton-border-color-hover` + - `--mod-actionbutton-border-width` + - `--mod-actionbutton-static-content-color` + - New: + - `--mod-actionbutton-font-weight` + - `--mod-actionbutton-font-style` diff --git a/components/actionbutton/dist/metadata.json b/components/actionbutton/dist/metadata.json index 06487511be1..655e8bdff1f 100644 --- a/components/actionbutton/dist/metadata.json +++ b/components/actionbutton/dist/metadata.json @@ -2,37 +2,29 @@ "sourceFile": "index.css", "selectors": [ ".spectrum-ActionButton", + ".spectrum-ActionButton .spectrum-ActionButton-hold", + ".spectrum-ActionButton .spectrum-ActionButton-icon", + ".spectrum-ActionButton .spectrum-ActionButton-label", ".spectrum-ActionButton--sizeL", ".spectrum-ActionButton--sizeS", ".spectrum-ActionButton--sizeXL", ".spectrum-ActionButton--sizeXS", ".spectrum-ActionButton-hold", - ".spectrum-ActionButton-hold + .spectrum-ActionButton-icon", ".spectrum-ActionButton-icon", - ".spectrum-ActionButton-icon:only-child", ".spectrum-ActionButton-label", ".spectrum-ActionButton-label:empty", ".spectrum-ActionButton.is-disabled", ".spectrum-ActionButton.is-selected", - ".spectrum-ActionButton.is-selected .is-disabled.spectrum-ActionButton--staticBlack", - ".spectrum-ActionButton.is-selected .is-disabled.spectrum-ActionButton--staticWhite", - ".spectrum-ActionButton.is-selected .spectrum-ActionButton-hold", - ".spectrum-ActionButton.is-selected .spectrum-ActionButton-icon", - ".spectrum-ActionButton.is-selected .spectrum-ActionButton-label", - ".spectrum-ActionButton.is-selected.spectrum-ActionButton--emphasized:not(.spectrum-ActionButton--staticBlack, .spectrum-ActionButton--staticWhite)", - ".spectrum-ActionButton.is-selected.spectrum-ActionButton--staticBlack:disabled", - ".spectrum-ActionButton.is-selected.spectrum-ActionButton--staticWhite:disabled", + ".spectrum-ActionButton.is-selected.spectrum-ActionButton--emphasized", + ".spectrum-ActionButton.is-selected.spectrum-ActionButton--staticBlack", + ".spectrum-ActionButton.is-selected.spectrum-ActionButton--staticWhite", ".spectrum-ActionButton.spectrum-ActionButton--quiet", - ".spectrum-ActionButton.spectrum-ActionButton--quiet.is-disabled:not(.is-selected)", + ".spectrum-ActionButton.spectrum-ActionButton--quiet.is-selected", ".spectrum-ActionButton.spectrum-ActionButton--quiet:disabled:not(.is-selected)", ".spectrum-ActionButton.spectrum-ActionButton--staticBlack", - ".spectrum-ActionButton.spectrum-ActionButton--staticBlack .is-disabled", ".spectrum-ActionButton.spectrum-ActionButton--staticBlack.spectrum-ActionButton--quiet", - ".spectrum-ActionButton.spectrum-ActionButton--staticBlack:disabled", ".spectrum-ActionButton.spectrum-ActionButton--staticWhite", - ".spectrum-ActionButton.spectrum-ActionButton--staticWhite .is-disabled", ".spectrum-ActionButton.spectrum-ActionButton--staticWhite.spectrum-ActionButton--quiet", - ".spectrum-ActionButton.spectrum-ActionButton--staticWhite:disabled", ".spectrum-ActionButton::-moz-focus-inner", ".spectrum-ActionButton:active", ".spectrum-ActionButton:after", @@ -41,29 +33,41 @@ ".spectrum-ActionButton:focus", ".spectrum-ActionButton:focus-visible", ".spectrum-ActionButton:focus-visible:after", + ".spectrum-ActionButton:has(.spectrum-ActionButton-icon)", ".spectrum-ActionButton:hover", + ".spectrum-ActionButton:not(:has(.spectrum-ActionButton-label))", "[dir=\"rtl\"] .spectrum-ActionButton", "a.spectrum-ActionButton" ], "modifiers": [ "--mod-actionbutton-animation-duration", "--mod-actionbutton-background-color-default", + "--mod-actionbutton-background-color-default-selected", + "--mod-actionbutton-background-color-default-selected-emphasized", "--mod-actionbutton-background-color-disabled", "--mod-actionbutton-background-color-down", + "--mod-actionbutton-background-color-down-selected", + "--mod-actionbutton-background-color-down-selected-emphasized", "--mod-actionbutton-background-color-focus", + "--mod-actionbutton-background-color-focus-selected", + "--mod-actionbutton-background-color-focus-selected-emphasized", "--mod-actionbutton-background-color-hover", - "--mod-actionbutton-border-color-default", - "--mod-actionbutton-border-color-disabled", - "--mod-actionbutton-border-color-down", - "--mod-actionbutton-border-color-focus", - "--mod-actionbutton-border-color-hover", + "--mod-actionbutton-background-color-hover-selected", + "--mod-actionbutton-background-color-hover-selected-emphasized", "--mod-actionbutton-border-radius", - "--mod-actionbutton-border-width", "--mod-actionbutton-content-color-default", + "--mod-actionbutton-content-color-default-selected", + "--mod-actionbutton-content-color-default-selected-emphasized", "--mod-actionbutton-content-color-disabled", "--mod-actionbutton-content-color-down", + "--mod-actionbutton-content-color-down-selected", + "--mod-actionbutton-content-color-down-selected-emphasized", "--mod-actionbutton-content-color-focus", + "--mod-actionbutton-content-color-focus-selected", + "--mod-actionbutton-content-color-focus-selected-emphasized", "--mod-actionbutton-content-color-hover", + "--mod-actionbutton-content-color-hover-selected", + "--mod-actionbutton-content-color-hover-selected-emphasized", "--mod-actionbutton-edge-to-hold-icon", "--mod-actionbutton-edge-to-text", "--mod-actionbutton-edge-to-visual", @@ -71,13 +75,16 @@ "--mod-actionbutton-focus-indicator-border-radius", "--mod-actionbutton-focus-indicator-color", "--mod-actionbutton-focus-indicator-gap", + "--mod-actionbutton-focus-indicator-thickness", + "--mod-actionbutton-font-size", + "--mod-actionbutton-font-style", + "--mod-actionbutton-font-weight", "--mod-actionbutton-height", "--mod-actionbutton-icon-size", "--mod-actionbutton-label-color", + "--mod-actionbutton-line-height", "--mod-actionbutton-min-width", - "--mod-actionbutton-text-to-visual", - "--mod-disabled-background-color", - "--mod-disabled-content-color" + "--mod-actionbutton-text-to-visual" ], "component": [ "--spectrum-action-button-edge-to-hold-icon-extra-large", @@ -91,16 +98,7 @@ "--spectrum-actionbutton-background-color-down", "--spectrum-actionbutton-background-color-focus", "--spectrum-actionbutton-background-color-hover", - "--spectrum-actionbutton-background-color-selected", - "--spectrum-actionbutton-background-color-selected-disabled", - "--spectrum-actionbutton-background-color-selected-down", - "--spectrum-actionbutton-background-color-selected-focus", - "--spectrum-actionbutton-background-color-selected-hover", - "--spectrum-actionbutton-border-color-default", - "--spectrum-actionbutton-border-color-disabled", - "--spectrum-actionbutton-border-color-down", - "--spectrum-actionbutton-border-color-focus", - "--spectrum-actionbutton-border-color-hover", + "--spectrum-actionbutton-border-color", "--spectrum-actionbutton-border-radius", "--spectrum-actionbutton-border-width", "--spectrum-actionbutton-content-color-default", @@ -108,7 +106,7 @@ "--spectrum-actionbutton-content-color-down", "--spectrum-actionbutton-content-color-focus", "--spectrum-actionbutton-content-color-hover", - "--spectrum-actionbutton-content-color-selected", + "--spectrum-actionbutton-downstate-perspective", "--spectrum-actionbutton-edge-to-hold-icon", "--spectrum-actionbutton-edge-to-text", "--spectrum-actionbutton-edge-to-visual", @@ -118,8 +116,11 @@ "--spectrum-actionbutton-focus-indicator-gap", "--spectrum-actionbutton-focus-indicator-thickness", "--spectrum-actionbutton-font-size", + "--spectrum-actionbutton-font-style", + "--spectrum-actionbutton-font-weight", "--spectrum-actionbutton-height", "--spectrum-actionbutton-icon-size", + "--spectrum-actionbutton-line-height", "--spectrum-actionbutton-min-width", "--spectrum-actionbutton-text-to-visual" ], @@ -129,6 +130,7 @@ "--spectrum-accent-background-color-hover", "--spectrum-accent-background-color-key-focus", "--spectrum-animation-duration-100", + "--spectrum-black", "--spectrum-border-width-100", "--spectrum-component-edge-to-text-100", "--spectrum-component-edge-to-text-200", @@ -150,14 +152,23 @@ "--spectrum-component-height-300", "--spectrum-component-height-50", "--spectrum-component-height-75", + "--spectrum-component-size-difference-down", + "--spectrum-component-size-minimum-perspective-down", + "--spectrum-component-size-width-ratio-down", "--spectrum-corner-radius-medium-size-extra-large", "--spectrum-corner-radius-medium-size-extra-small", "--spectrum-corner-radius-medium-size-large", "--spectrum-corner-radius-medium-size-medium", "--spectrum-corner-radius-medium-size-small", + "--spectrum-default-font-style", "--spectrum-disabled-background-color", - "--spectrum-disabled-border-color", "--spectrum-disabled-content-color", + "--spectrum-disabled-static-black-background-color", + "--spectrum-disabled-static-black-content-color", + "--spectrum-disabled-static-white-background-color", + "--spectrum-disabled-static-white-content-color", + "--spectrum-downstate-height", + "--spectrum-downstate-width", "--spectrum-focus-indicator-color", "--spectrum-focus-indicator-gap", "--spectrum-focus-indicator-thickness", @@ -169,12 +180,9 @@ "--spectrum-gray-100", "--spectrum-gray-200", "--spectrum-gray-25", - "--spectrum-gray-400", - "--spectrum-gray-50", - "--spectrum-gray-500", - "--spectrum-gray-600", "--spectrum-line-height-100", "--spectrum-logical-rotation", + "--spectrum-medium-font-weight", "--spectrum-neutral-background-color-selected-default", "--spectrum-neutral-background-color-selected-down", "--spectrum-neutral-background-color-selected-hover", @@ -193,14 +201,14 @@ "--spectrum-text-to-visual-75", "--spectrum-transparent-black-100", "--spectrum-transparent-black-200", - "--spectrum-transparent-black-500", - "--spectrum-transparent-black-600", - "--spectrum-transparent-black-700", + "--spectrum-transparent-black-25", + "--spectrum-transparent-black-800", + "--spectrum-transparent-black-900", "--spectrum-transparent-white-100", "--spectrum-transparent-white-200", - "--spectrum-transparent-white-500", - "--spectrum-transparent-white-600", - "--spectrum-transparent-white-700", + "--spectrum-transparent-white-25", + "--spectrum-transparent-white-800", + "--spectrum-transparent-white-900", "--spectrum-white", "--spectrum-workflow-icon-size-100", "--spectrum-workflow-icon-size-200", @@ -214,20 +222,12 @@ "--mod-button-line-height" ], "high-contrast": [ + "--highcontrast-actionbutton-animation-duration", "--highcontrast-actionbutton-background-color-default", "--highcontrast-actionbutton-background-color-disabled", - "--highcontrast-actionbutton-background-color-down", - "--highcontrast-actionbutton-background-color-focus", - "--highcontrast-actionbutton-background-color-hover", - "--highcontrast-actionbutton-border-color-default", - "--highcontrast-actionbutton-border-color-disabled", - "--highcontrast-actionbutton-border-color-down", - "--highcontrast-actionbutton-border-color-focus", - "--highcontrast-actionbutton-border-color-hover", + "--highcontrast-actionbutton-border-color", "--highcontrast-actionbutton-content-color-default", "--highcontrast-actionbutton-content-color-disabled", - "--highcontrast-actionbutton-content-color-down", - "--highcontrast-actionbutton-content-color-focus", - "--highcontrast-actionbutton-content-color-hover" + "--highcontrast-actionbutton-focus-indicator-color" ] } diff --git a/components/actionbutton/index.css b/components/actionbutton/index.css index bcf9af21804..e08737894eb 100644 --- a/components/actionbutton/index.css +++ b/components/actionbutton/index.css @@ -1,461 +1,416 @@ /*! - * Copyright 2024 Adobe. All rights reserved. - * - * This file is licensed to you under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. You may obtain a copy - * of the License at - * - * Unless required by applicable law or agreed to in writing, software distributed under - * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS - * OF ANY KIND, either express or implied. See the License for the specific language - * governing permissions and limitations under the License. - */ +Copyright 2025 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +@import "@spectrum-css/commons/basebutton.css"; .spectrum-ActionButton { - --spectrum-actionbutton-background-color-default: var(--highcontrast-actionbutton-background-color-default, var(--mod-actionbutton-background-color-default, var(--spectrum-gray-50))); - --spectrum-actionbutton-background-color-hover: var(--highcontrast-actionbutton-background-color-hover, var(--mod-actionbutton-background-color-hover, var(--spectrum-gray-100))); - --spectrum-actionbutton-background-color-down: var(--highcontrast-actionbutton-background-color-down, var(--mod-actionbutton-background-color-down, var(--spectrum-gray-200))); - --spectrum-actionbutton-background-color-focus: var(--highcontrast-actionbutton-background-color-focus, var(--mod-actionbutton-background-color-focus, var(--spectrum-gray-100))); - --spectrum-actionbutton-background-color-selected-disabled: var(--spectrum-transparent-black-100); - - --spectrum-actionbutton-background-color-selected: var(--spectrum-neutral-background-color-selected-default); - --spectrum-actionbutton-background-color-selected-hover: var(--spectrum-neutral-background-color-selected-hover); - --spectrum-actionbutton-background-color-selected-down: var(--spectrum-neutral-background-color-selected-down); - --spectrum-actionbutton-background-color-selected-focus: var(--spectrum-neutral-background-color-selected-key-focus); - - --spectrum-actionbutton-border-color-default: var(--highcontrast-actionbutton-border-color-default, var(--mod-actionbutton-border-color-default, var(--spectrum-gray-400))); - --spectrum-actionbutton-border-color-hover: var(--highcontrast-actionbutton-border-color-hover, var(--mod-actionbutton-border-color-hover, var(--spectrum-gray-500))); - --spectrum-actionbutton-border-color-down: var(--highcontrast-actionbutton-border-color-down, var(--mod-actionbutton-border-color-down, var(--spectrum-gray-600))); - --spectrum-actionbutton-border-color-focus: var(--highcontrast-actionbutton-border-color-focus, var(--mod-actionbutton-border-color-focus, var(--spectrum-gray-500))); - --spectrum-actionbutton-border-color-disabled: var(--spectrum-disabled-border-color); - - --spectrum-actionbutton-content-color-selected: var(--spectrum-gray-25); - --spectrum-actionbutton-content-color-disabled: var(--mod-disabled-content-color, var(--spectrum-disabled-content-color)); - --spectrum-actionbutton-background-color-disabled: var(--mod-disabled-background-color, var(--spectrum-disabled-background-color)); - - --spectrum-actionbutton-animation-duration: var(--mod-actionbutton-animation-duration, var(--spectrum-animation-duration-100)); - --spectrum-actionbutton-border-radius: var(--mod-actionbutton-border-radius, var(--spectrum-corner-radius-medium-size-medium)); - --spectrum-actionbutton-border-width: var(--mod-actionbutton-border-width, var(--spectrum-border-width-100)); - - --spectrum-actionbutton-content-color-default: var(--highcontrast-actionbutton-content-color-default, var(--mod-actionbutton-content-color-default, var(--spectrum-neutral-content-color-default))); - --spectrum-actionbutton-content-color-hover: var(--highcontrast-actionbutton-content-color-hover, var(--mod-actionbutton-content-color-hover, var(--spectrum-neutral-content-color-hover))); - --spectrum-actionbutton-content-color-down: var(--highcontrast-actionbutton-content-color-down, var(--mod-actionbutton-content-color-down, var(--spectrum-neutral-content-color-down))); - --spectrum-actionbutton-content-color-focus: var(--highcontrast-actionbutton-content-color-focus, var(--mod-actionbutton-content-color-focus, var(--spectrum-neutral-content-color-key-focus))); - - --spectrum-actionbutton-focus-indicator-gap: var(--mod-actionbutton-focus-indicator-gap, var(--spectrum-focus-indicator-gap)); + --spectrum-actionbutton-animation-duration: var(--spectrum-animation-duration-100); + --spectrum-actionbutton-border-radius: var(--spectrum-corner-radius-medium-size-medium); + --spectrum-actionbutton-border-width: var(--spectrum-border-width-100); + --spectrum-actionbutton-border-color: transparent; + + --spectrum-actionbutton-content-color-default: var(--spectrum-neutral-content-color-default); + --spectrum-actionbutton-content-color-hover: var(--spectrum-neutral-content-color-hover); + --spectrum-actionbutton-content-color-down: var(--spectrum-neutral-content-color-down); + --spectrum-actionbutton-content-color-focus: var(--spectrum-neutral-content-color-key-focus); + --spectrum-actionbutton-content-color-disabled: var(--spectrum-disabled-content-color); + + --spectrum-actionbutton-background-color-default: var(--spectrum-gray-100); + --spectrum-actionbutton-background-color-hover: var(--spectrum-gray-200); + --spectrum-actionbutton-background-color-down: var(--spectrum-gray-200); + --spectrum-actionbutton-background-color-focus: var(--spectrum-gray-200); + --spectrum-actionbutton-background-color-disabled: var(--spectrum-disabled-background-color); + + --spectrum-actionbutton-focus-indicator-gap: var(--spectrum-focus-indicator-gap); --spectrum-actionbutton-focus-indicator-thickness: var(--spectrum-focus-indicator-thickness); --spectrum-actionbutton-focus-indicator-color: var(--spectrum-focus-indicator-color); + --spectrum-actionbutton-focus-indicator-border-radius: calc(var(--spectrum-actionbutton-border-radius) + var(--spectrum-actionbutton-focus-indicator-gap)); - --spectrum-actionbutton-min-width: var(--mod-actionbutton-min-width, calc((var(--spectrum-component-edge-to-visual-only-100) * 2) + var(--spectrum-workflow-icon-size-100))); + --spectrum-actionbutton-min-width: calc((var(--spectrum-component-edge-to-visual-only-100) * 2) + var(--spectrum-workflow-icon-size-100)); --spectrum-actionbutton-height: var(--spectrum-component-height-100); --spectrum-actionbutton-icon-size: var(--spectrum-workflow-icon-size-100); --spectrum-actionbutton-font-size: var(--spectrum-font-size-100); + --spectrum-actionbutton-font-weight: var(--spectrum-medium-font-weight); + --spectrum-actionbutton-font-style: var(--spectrum-default-font-style); + + /* Take up full component height for line-height, in order to help prevent characters from being cut off in some languages (e.g. Thai). */ + --spectrum-actionbutton-line-height: var(--spectrum-actionbutton-height); + --spectrum-actionbutton-text-to-visual: var(--spectrum-text-to-visual-100); - --spectrum-actionbutton-edge-to-hold-icon: var(--mod-actionbutton-edge-to-hold-icon, var(--spectrum-action-button-edge-to-hold-icon-medium)); + --spectrum-actionbutton-edge-to-hold-icon: var(--spectrum-action-button-edge-to-hold-icon-medium); + --spectrum-actionbutton-edge-to-visual: var(--spectrum-component-edge-to-visual-100); + --spectrum-actionbutton-edge-to-text: var(--spectrum-component-edge-to-text-100); + --spectrum-actionbutton-edge-to-visual-only: var(--spectrum-component-edge-to-visual-only-100); - --spectrum-actionbutton-edge-to-visual: var(--mod-actionbutton-edge-to-visual, calc(var(--spectrum-component-edge-to-visual-100) - var(--spectrum-actionbutton-border-width))); - --spectrum-actionbutton-edge-to-text: var(--mod-actionbutton-edge-to-text, calc(var(--spectrum-component-edge-to-text-100) - var(--spectrum-actionbutton-border-width))); - --spectrum-actionbutton-edge-to-visual-only: var(--mod-actionbutton-edge-to-visual-only, calc(var(--spectrum-component-edge-to-visual-only-100) - var(--spectrum-actionbutton-border-width))); + /* stylelint-disable-next-line spectrum-tools/no-unknown-custom-properties -- height and width are set by implementations */ + --spectrum-actionbutton-downstate-perspective: max(var(--spectrum-downstate-height), var(--spectrum-downstate-width) * var(--spectrum-component-size-width-ratio-down)); &:dir(rtl) { --spectrum-logical-rotation: matrix(-1, 0, 0, 1, 0, 0); } &.spectrum-ActionButton--quiet { - --mod-actionbutton-border-color-default: transparent; - - --mod-actionbutton-background-color-default: transparent; - --mod-actionbutton-background-color-hover: var(--spectrum-gray-100); - --mod-actionbutton-background-color-down: var(--spectrum-gray-200); - --mod-actionbutton-background-color-focus: var(--spectrum-gray-100); + --spectrum-actionbutton-background-color-default: transparent; + --spectrum-actionbutton-background-color-hover: var(--spectrum-gray-200); + --spectrum-actionbutton-background-color-down: var(--spectrum-gray-200); + --spectrum-actionbutton-background-color-focus: var(--spectrum-gray-200); + --spectrum-actionbutton-background-color-disabled: transparent; - &:disabled:not(.is-selected), - &.is-disabled:not(.is-selected) { - --mod-actionbutton-border-color-disabled: transparent; - --mod-actionbutton-background-color-disabled: transparent; + &.is-selected { + --spectrum-actionbutton-background-color-disabled: var(--spectrum-disabled-background-color); } } &.spectrum-ActionButton--staticBlack { - --mod-actionbutton-background-color-default: transparent; + --spectrum-actionbutton-background-color-default: var(--spectrum-transparent-black-100); + --spectrum-actionbutton-background-color-hover: var(--spectrum-transparent-black-200); + --spectrum-actionbutton-background-color-down: var(--spectrum-transparent-black-200); + --spectrum-actionbutton-background-color-focus: var(--spectrum-transparent-black-200); + --spectrum-actionbutton-background-color-disabled: var(--spectrum-disabled-static-black-background-color); - --mod-actionbutton-border-color-default: var(--spectrum-transparent-black-500); - --mod-actionbutton-border-color-hover: var(--spectrum-transparent-black-600); - --mod-actionbutton-border-color-down: var(--spectrum-transparent-black-700); - --mod-actionbutton-border-color-focus: var(--spectrum-transparent-black-600); + --spectrum-actionbutton-content-color-default: var(--spectrum-transparent-black-800); + --spectrum-actionbutton-content-color-hover: var(--spectrum-transparent-black-900); + --spectrum-actionbutton-content-color-down: var(--spectrum-transparent-black-900); + --spectrum-actionbutton-content-color-focus: var(--spectrum-transparent-black-900); + --spectrum-actionbutton-content-color-disabled: var(--spectrum-disabled-static-black-content-color); - --mod-actionbutton-focus-indicator-color: var(--spectrum-static-black-focus-indicator-color); - - --spectrum-actionbutton-background-color-disabled: transparent; - --spectrum-actionbutton-background-color-selected-disabled: var(--spectrum-transparent-black-200); - - &:disabled, - .is-disabled { - --mod-disabled-content-color: var(--spectrum-transparent-black-500); - --mod-actionbutton-border-color-disabled: var(--spectrum-transparent-black-500); - } + --spectrum-actionbutton-focus-indicator-color: var(--spectrum-static-black-focus-indicator-color); &.spectrum-ActionButton--quiet { - --mod-actionbutton-border-color-default: transparent; + --spectrum-actionbutton-background-color-default: transparent; + --spectrum-actionbutton-background-color-hover: var(--spectrum-transparent-black-200); + --spectrum-actionbutton-background-color-down: var(--spectrum-transparent-black-200); + --spectrum-actionbutton-background-color-focus: var(--spectrum-transparent-black-200); + --spectrum-actionbutton-background-color-disabled: var(--spectrum-transparent-black-25); } } &.spectrum-ActionButton--staticWhite { - --mod-actionbutton-background-color-default: transparent; + --spectrum-actionbutton-background-color-default: var(--spectrum-transparent-white-100); + --spectrum-actionbutton-background-color-hover: var(--spectrum-transparent-white-200); + --spectrum-actionbutton-background-color-down: var(--spectrum-transparent-white-200); + --spectrum-actionbutton-background-color-focus: var(--spectrum-transparent-white-200); + --spectrum-actionbutton-background-color-disabled: var(--spectrum-disabled-static-white-background-color); - --mod-actionbutton-border-color-default: var(--spectrum-transparent-white-500); - --mod-actionbutton-border-color-hover: var(--spectrum-transparent-white-600); - --mod-actionbutton-border-color-down: var(--spectrum-transparent-white-700); - --mod-actionbutton-border-color-focus: var(--spectrum-transparent-white-600); + --spectrum-actionbutton-content-color-default: var(--spectrum-transparent-white-800); + --spectrum-actionbutton-content-color-hover: var(--spectrum-transparent-white-900); + --spectrum-actionbutton-content-color-down: var(--spectrum-transparent-white-900); + --spectrum-actionbutton-content-color-focus: var(--spectrum-transparent-white-900); + --spectrum-actionbutton-content-color-disabled: var(--spectrum-disabled-static-white-content-color); - --mod-actionbutton-focus-indicator-color: var(--spectrum-static-white-focus-indicator-color); - - --spectrum-actionbutton-background-color-disabled: transparent; - --spectrum-actionbutton-background-color-selected-disabled: var(--spectrum-transparent-white-200); - - &:disabled, - .is-disabled { - --mod-disabled-content-color: var(--spectrum-transparent-white-500); - --mod-actionbutton-border-color-disabled: var(--spectrum-transparent-white-500); - } + --spectrum-actionbutton-focus-indicator-color: var(--spectrum-static-white-focus-indicator-color); &.spectrum-ActionButton--quiet { - --mod-actionbutton-border-color-default: transparent; + --spectrum-actionbutton-background-color-default: transparent; + --spectrum-actionbutton-background-color-hover: var(--spectrum-transparent-white-200); + --spectrum-actionbutton-background-color-down: var(--spectrum-transparent-white-200); + --spectrum-actionbutton-background-color-focus: var(--spectrum-transparent-white-200); + --spectrum-actionbutton-background-color-disabled: var(--spectrum-transparent-white-25); } } &.is-selected { - --mod-actionbutton-background-color-default: var(--spectrum-actionbutton-background-color-selected); - --mod-actionbutton-background-color-hover: var(--spectrum-actionbutton-background-color-selected-hover); - --mod-actionbutton-background-color-down: var(--spectrum-actionbutton-background-color-selected-down); - --mod-actionbutton-background-color-focus: var(--spectrum-actionbutton-background-color-selected-focus); - --mod-actionbutton-background-color-disabled: var(--spectrum-actionbutton-background-color-selected-disabled); - - --mod-actionbutton-border-color-default: transparent; - --mod-actionbutton-border-color-hover: transparent; - --mod-actionbutton-border-color-down: transparent; - --mod-actionbutton-border-color-focus: transparent; - --mod-actionbutton-border-color-disabled: transparent; - - --mod-actionbutton-content-color-default: var(--spectrum-actionbutton-content-color-selected); - --mod-actionbutton-content-color-hover: var(--spectrum-actionbutton-content-color-selected); - --mod-actionbutton-content-color-down: var(--spectrum-actionbutton-content-color-selected); - --mod-actionbutton-content-color-focus: var(--spectrum-actionbutton-content-color-selected); - - &.spectrum-ActionButton--emphasized:not(.spectrum-ActionButton--staticBlack, .spectrum-ActionButton--staticWhite) { - --mod-actionbutton-background-color-default: var(--spectrum-accent-background-color-default); - --mod-actionbutton-background-color-hover: var(--spectrum-accent-background-color-hover); - --mod-actionbutton-background-color-down: var(--spectrum-accent-background-color-down); - --mod-actionbutton-background-color-focus: var(--spectrum-accent-background-color-key-focus); - - --mod-actionbutton-content-color-default: var(--spectrum-white); - --mod-actionbutton-content-color-hover: var(--spectrum-white); - --mod-actionbutton-content-color-down: var(--spectrum-white); - --mod-actionbutton-content-color-focus: var(--spectrum-white); + --mod-actionbutton-background-color-default: var(--mod-actionbutton-background-color-default-selected, var(--spectrum-neutral-background-color-selected-default)); + --mod-actionbutton-background-color-hover: var(--mod-actionbutton-background-color-hover-selected, var(--spectrum-neutral-background-color-selected-hover)); + --mod-actionbutton-background-color-down: var(--mod-actionbutton-background-color-down-selected, var(--spectrum-neutral-background-color-selected-down)); + --mod-actionbutton-background-color-focus: var(--mod-actionbutton-background-color-focus-selected, var(--spectrum-neutral-background-color-selected-key-focus)); + + --mod-actionbutton-content-color-default: var(--mod-actionbutton-content-color-default-selected, var(--spectrum-gray-25)); + --mod-actionbutton-content-color-hover: var(--mod-actionbutton-content-color-hover-selected, var(--spectrum-gray-25)); + --mod-actionbutton-content-color-down: var(--mod-actionbutton-content-color-down-selected, var(--spectrum-gray-25)); + --mod-actionbutton-content-color-focus: var(--mod-actionbutton-content-color-focus-selected, var(--spectrum-gray-25)); + + &.spectrum-ActionButton--emphasized { + --mod-actionbutton-background-color-default: var(--mod-actionbutton-background-color-default-selected-emphasized, var(--spectrum-accent-background-color-default)); + --mod-actionbutton-background-color-hover: var(--mod-actionbutton-background-color-hover-selected-emphasized, var(--spectrum-accent-background-color-hover)); + --mod-actionbutton-background-color-down: var(--mod-actionbutton-background-color-down-selected-emphasized, var(--spectrum-accent-background-color-down)); + --mod-actionbutton-background-color-focus: var(--mod-actionbutton-background-color-focus-selected-emphasized, var(--spectrum-accent-background-color-key-focus)); + + --mod-actionbutton-content-color-default: var(--mod-actionbutton-content-color-default-selected-emphasized, var(--spectrum-white)); + --mod-actionbutton-content-color-hover: var(--mod-actionbutton-content-color-hover-selected-emphasized, var(--spectrum-white)); + --mod-actionbutton-content-color-down: var(--mod-actionbutton-content-color-down-selected-emphasized, var(--spectrum-white)); + --mod-actionbutton-content-color-focus: var(--mod-actionbutton-content-color-focus-selected-emphasized, var(--spectrum-white)); } - &:disabled, - .is-disabled { - &.spectrum-ActionButton--staticBlack { - --mod-disabled-content-color: var(--spectrum-transparent-black-500); - --mod-disabled-background-color: var(--spectrum-transparent-black-100); - } + &.spectrum-ActionButton--staticWhite { + --spectrum-actionbutton-background-color-default: var(--spectrum-transparent-white-800); + --spectrum-actionbutton-background-color-hover: var(--spectrum-transparent-white-900); + --spectrum-actionbutton-background-color-down: var(--spectrum-transparent-white-900); + --spectrum-actionbutton-background-color-focus: var(--spectrum-transparent-white-900); + --spectrum-actionbutton-background-color-disabled: var(--spectrum-disabled-static-white-background-color); + + --spectrum-actionbutton-content-color-default: var(--spectrum-black); + --spectrum-actionbutton-content-color-hover: var(--spectrum-black); + --spectrum-actionbutton-content-color-down: var(--spectrum-black); + --spectrum-actionbutton-content-color-focus: var(--spectrum-black); + } - &.spectrum-ActionButton--staticWhite { - --mod-disabled-content-color: var(--spectrum-transparent-white-500); - --mod-disabled-background-color: var(--spectrum-transparent-white-100); - } + &.spectrum-ActionButton--staticBlack { + --spectrum-actionbutton-background-color-default: var(--spectrum-transparent-black-800); + --spectrum-actionbutton-background-color-hover: var(--spectrum-transparent-black-900); + --spectrum-actionbutton-background-color-down: var(--spectrum-transparent-black-900); + --spectrum-actionbutton-background-color-focus: var(--spectrum-transparent-black-900); + --spectrum-actionbutton-background-color-disabled: var(--spectrum-disabled-static-black-background-color); + + --spectrum-actionbutton-content-color-default: var(--spectrum-white); + --spectrum-actionbutton-content-color-hover: var(--spectrum-white); + --spectrum-actionbutton-content-color-down: var(--spectrum-white); + --spectrum-actionbutton-content-color-focus: var(--spectrum-white); } } } .spectrum-ActionButton--sizeXS { - --spectrum-actionbutton-border-radius: var(--mod-actionbutton-border-radius, var(--spectrum-corner-radius-medium-size-extra-small)); + --spectrum-actionbutton-border-radius: var(--spectrum-corner-radius-medium-size-extra-small); - --spectrum-actionbutton-min-width: var(--mod-actionbutton-min-width, calc((var(--spectrum-component-edge-to-visual-only-50) * 2) + var(--spectrum-workflow-icon-size-50))); + --spectrum-actionbutton-min-width: calc((var(--spectrum-component-edge-to-visual-only-50) * 2) + var(--spectrum-workflow-icon-size-50)); --spectrum-actionbutton-height: var(--spectrum-component-height-50); --spectrum-actionbutton-icon-size: var(--spectrum-workflow-icon-size-50); --spectrum-actionbutton-font-size: var(--spectrum-font-size-50); --spectrum-actionbutton-text-to-visual: var(--spectrum-text-to-visual-50); - --spectrum-actionbutton-edge-to-hold-icon: var(--mod-actionbutton-edge-to-hold-icon, var(--spectrum-action-button-edge-to-hold-icon-extra-small)); - --spectrum-actionbutton-edge-to-visual: var(--mod-actionbutton-edge-to-visual, calc(var(--spectrum-component-edge-to-visual-50) - var(--spectrum-actionbutton-border-width))); - --spectrum-actionbutton-edge-to-text: var(--mod-actionbutton-edge-to-text, calc(var(--spectrum-component-edge-to-text-50) - var(--spectrum-actionbutton-border-width))); - --spectrum-actionbutton-edge-to-visual-only: var(--mod-actionbutton-edge-to-visual-only, calc(var(--spectrum-component-edge-to-visual-only-50) - var(--spectrum-actionbutton-border-width))); + --spectrum-actionbutton-edge-to-hold-icon: var(--spectrum-action-button-edge-to-hold-icon-extra-small); + --spectrum-actionbutton-edge-to-visual: var(--spectrum-component-edge-to-visual-50); + --spectrum-actionbutton-edge-to-text: var(--spectrum-component-edge-to-text-50); + --spectrum-actionbutton-edge-to-visual-only: var(--spectrum-component-edge-to-visual-only-50); + + --spectrum-actionbutton-downstate-perspective: var(--spectrum-component-size-minimum-perspective-down); } .spectrum-ActionButton--sizeS { - --spectrum-actionbutton-border-radius: var(--mod-actionbutton-border-radius, var(--spectrum-corner-radius-medium-size-small)); + --spectrum-actionbutton-border-radius: var(--spectrum-corner-radius-medium-size-small); - --spectrum-actionbutton-min-width: var(--mod-actionbutton-min-width, calc((var(--spectrum-component-edge-to-visual-only-75) * 2) + var(--spectrum-workflow-icon-size-75))); + --spectrum-actionbutton-min-width: calc((var(--spectrum-component-edge-to-visual-only-75) * 2) + var(--spectrum-workflow-icon-size-75)); --spectrum-actionbutton-height: var(--spectrum-component-height-75); --spectrum-actionbutton-icon-size: var(--spectrum-workflow-icon-size-75); --spectrum-actionbutton-font-size: var(--spectrum-font-size-75); --spectrum-actionbutton-text-to-visual: var(--spectrum-text-to-visual-75); - --spectrum-actionbutton-edge-to-hold-icon: var(--mod-actionbutton-edge-to-hold-icon, var(--spectrum-action-button-edge-to-hold-icon-small)); - --spectrum-actionbutton-edge-to-visual: var(--mod-actionbutton-edge-to-visual, calc(var(--spectrum-component-edge-to-visual-75) - var(--spectrum-actionbutton-border-width))); - --spectrum-actionbutton-edge-to-text: var(--mod-actionbutton-edge-to-text, calc(var(--spectrum-component-edge-to-text-75) - var(--spectrum-actionbutton-border-width))); - --spectrum-actionbutton-edge-to-visual-only: var(--mod-actionbutton-edge-to-visual-only, calc(var(--spectrum-component-edge-to-visual-only-75) - var(--spectrum-actionbutton-border-width))); + --spectrum-actionbutton-edge-to-hold-icon: var(--spectrum-action-button-edge-to-hold-icon-small); + --spectrum-actionbutton-edge-to-visual: var(--spectrum-component-edge-to-visual-75); + --spectrum-actionbutton-edge-to-text: var(--spectrum-component-edge-to-text-75); + --spectrum-actionbutton-edge-to-visual-only: var(--spectrum-component-edge-to-visual-only-75); + + --spectrum-actionbutton-downstate-perspective: var(--spectrum-component-size-minimum-perspective-down); } .spectrum-ActionButton--sizeL { - --spectrum-actionbutton-border-radius: var(--mod-actionbutton-border-radius, var(--spectrum-corner-radius-medium-size-large)); + --spectrum-actionbutton-border-radius: var(--spectrum-corner-radius-medium-size-large); - --spectrum-actionbutton-min-width: var(--mod-actionbutton-min-width, calc((var(--spectrum-component-edge-to-visual-only-200) * 2) + var(--spectrum-workflow-icon-size-200))); + --spectrum-actionbutton-min-width: calc((var(--spectrum-component-edge-to-visual-only-200) * 2) + var(--spectrum-workflow-icon-size-200)); --spectrum-actionbutton-height: var(--spectrum-component-height-200); --spectrum-actionbutton-icon-size: var(--spectrum-workflow-icon-size-200); --spectrum-actionbutton-font-size: var(--spectrum-font-size-200); --spectrum-actionbutton-text-to-visual: var(--spectrum-text-to-visual-200); - --spectrum-actionbutton-edge-to-hold-icon: var(--mod-actionbutton-edge-to-hold-icon, var(--spectrum-action-button-edge-to-hold-icon-large)); - --spectrum-actionbutton-edge-to-visual: var(--mod-actionbutton-edge-to-visual, calc(var(--spectrum-component-edge-to-visual-200) - var(--spectrum-actionbutton-border-width))); - --spectrum-actionbutton-edge-to-text: var(--mod-actionbutton-edge-to-text, calc(var(--spectrum-component-edge-to-text-200) - var(--spectrum-actionbutton-border-width))); - --spectrum-actionbutton-edge-to-visual-only: var(--mod-actionbutton-edge-to-visual-only, calc(var(--spectrum-component-edge-to-visual-only-200) - var(--spectrum-actionbutton-border-width))); + --spectrum-actionbutton-edge-to-hold-icon: var(--spectrum-action-button-edge-to-hold-icon-large); + --spectrum-actionbutton-edge-to-visual: var(--spectrum-component-edge-to-visual-200); + --spectrum-actionbutton-edge-to-text: var(--spectrum-component-edge-to-text-200); + --spectrum-actionbutton-edge-to-visual-only: var(--spectrum-component-edge-to-visual-only-200); } .spectrum-ActionButton--sizeXL { - --spectrum-actionbutton-border-radius: var(--mod-actionbutton-border-radius, var(--spectrum-corner-radius-medium-size-extra-large)); + --spectrum-actionbutton-border-radius: var(--spectrum-corner-radius-medium-size-extra-large); - --spectrum-actionbutton-min-width: var(--mod-actionbutton-min-width, calc((var(--spectrum-component-edge-to-visual-only-300) * 2) + var(--spectrum-workflow-icon-size-300))); + --spectrum-actionbutton-min-width: calc((var(--spectrum-component-edge-to-visual-only-300) * 2) + var(--spectrum-workflow-icon-size-300)); --spectrum-actionbutton-height: var(--spectrum-component-height-300); --spectrum-actionbutton-icon-size: var(--spectrum-workflow-icon-size-300); --spectrum-actionbutton-font-size: var(--spectrum-font-size-300); --spectrum-actionbutton-text-to-visual: var(--spectrum-text-to-visual-300); - --spectrum-actionbutton-edge-to-hold-icon: var(--mod-actionbutton-edge-to-hold-icon, var(--spectrum-action-button-edge-to-hold-icon-extra-large)); - --spectrum-actionbutton-edge-to-visual: var(--mod-actionbutton-edge-to-visual, calc(var(--spectrum-component-edge-to-visual-300) - var(--spectrum-actionbutton-border-width))); - --spectrum-actionbutton-edge-to-text: var(--mod-actionbutton-edge-to-text, calc(var(--spectrum-component-edge-to-text-300) - var(--spectrum-actionbutton-border-width))); - --spectrum-actionbutton-edge-to-visual-only: var(--mod-actionbutton-edge-to-visual-only, calc(var(--spectrum-component-edge-to-visual-only-300) - var(--spectrum-actionbutton-border-width))); + --spectrum-actionbutton-edge-to-hold-icon: var(--spectrum-action-button-edge-to-hold-icon-extra-large); + --spectrum-actionbutton-edge-to-visual: var(--spectrum-component-edge-to-visual-300); + --spectrum-actionbutton-edge-to-text: var(--spectrum-component-edge-to-text-300); + --spectrum-actionbutton-edge-to-visual-only: var(--spectrum-component-edge-to-visual-only-300); } .spectrum-ActionButton { - --spectrum-actionbutton-focus-indicator-border-radius: var(--mod-actionbutton-focus-indicator-border-radius, calc(var(--spectrum-actionbutton-border-radius) + var(--spectrum-actionbutton-focus-indicator-gap))); - - cursor: pointer; - user-select: none; - - /* Contain halo */ + @extend %spectrum-BaseButton; position: relative; - /* Show the button overflow in Edge. */ - overflow: visible; - display: inline-flex; - align-items: center; - justify-content: center; - - box-sizing: border-box; - - /* Remove button the margin in Firefox and Safari. */ - margin: 0; - - font-family: var(--mod-button-font-family, var(--spectrum-sans-font-family-stack)); - - /* Adjacent buttons should be aligned correctly */ - vertical-align: top; - - -webkit-font-smoothing: antialiased; - - /* Font smoothing for Firefox */ - -moz-osx-font-smoothing: grayscale; - - line-height: var(--mod-button-line-height, var(--spectrum-line-height-100)); - text-decoration: none; - - /* Remove the inheritance of text transform on button in Edge, Firefox, and IE. */ - text-transform: none; - - /* stylelint-disable-next-line property-no-vendor-prefix -- Correct the inability to style clickable types in iOS and Safari (normalize). */ - -webkit-appearance: button; - - border-style: solid; - - transition: - background var(--mod-button-animation-duration, var(--spectrum-animation-duration-100)) ease-out, - border-color var(--mod-actionbutton-animation-duration, var(--spectrum-animation-duration-100)) ease-in-out, - color var(--mod-button-animation-duration, var(--spectrum-animation-duration-100)) ease-out, - box-shadow var(--mod-button-animation-duration, var(--spectrum-animation-duration-100)) ease-out; - - min-inline-size: var(--spectrum-actionbutton-min-width); + min-inline-size: var(--mod-actionbutton-min-width, var(--spectrum-actionbutton-min-width)); block-size: var(--mod-actionbutton-height, var(--spectrum-actionbutton-height)); + line-height: var(--mod-actionbutton-line-height, var(--spectrum-actionbutton-line-height)); - border-radius: var(--spectrum-actionbutton-border-radius); + border-radius: var(--mod-actionbutton-border-radius, var(--spectrum-actionbutton-border-radius)); border-width: var(--spectrum-actionbutton-border-width); + border-color: var(--highcontrast-actionbutton-border-color, var(--spectrum-actionbutton-border-color)); + border-style: solid; - gap: calc(var(--mod-actionbutton-text-to-visual, var(--spectrum-actionbutton-text-to-visual)) + (var(--spectrum-actionbutton-edge-to-text) - var(--spectrum-actionbutton-edge-to-visual-only))); - - /* Start with text-only padding */ - padding-inline: var(--spectrum-actionbutton-edge-to-text); - - background: var(--spectrum-actionbutton-background-color-default); - border-color: var(--spectrum-actionbutton-border-color-default); - color: var(--spectrum-actionbutton-content-color-default); - - &::after { - position: absolute; - inset: 0; - - margin: calc((var(--spectrum-actionbutton-focus-indicator-gap) + var(--spectrum-actionbutton-border-width)) * -1); - - border-radius: var(--spectrum-actionbutton-focus-indicator-border-radius); + gap: var(--mod-actionbutton-text-to-visual, var(--spectrum-actionbutton-text-to-visual)); + padding-inline: calc(var(--mod-actionbutton-edge-to-text, var(--spectrum-actionbutton-edge-to-text)) - var(--spectrum-actionbutton-border-width)); - transition: box-shadow var(--spectrum-actionbutton-animation-duration) ease-in-out; - - pointer-events: none; - content: ""; - } + background-color: var(--highcontrast-actionbutton-background-color-default, var(--mod-actionbutton-background-color-default, var(--spectrum-actionbutton-background-color-default))); + color: var(--highcontrast-actionbutton-content-color-default, var(--mod-actionbutton-content-color-default, var(--spectrum-actionbutton-content-color-default))); &:hover { - background: var(--spectrum-actionbutton-background-color-hover); - border-color: var(--spectrum-actionbutton-border-color-hover); - color: var(--spectrum-actionbutton-content-color-hover); - } - - /* Fix Firefox */ - &::-moz-focus-inner { - margin-block-start: -2px; - margin-block-end: -2px; - padding: 0; - border: 0; - - /* Remove the inner border and padding for button in Firefox. */ - border-style: none; + background-color: var(--highcontrast-actionbutton-background-color-default, var(--mod-actionbutton-background-color-hover, var(--spectrum-actionbutton-background-color-hover))); + color: var(--highcontrast-actionbutton-content-color-default, var(--mod-actionbutton-content-color-hover, var(--spectrum-actionbutton-content-color-hover))); } - &:focus, &:focus-visible { - /* kill the default ring */ - box-shadow: none; - outline: none; - } - - &:focus-visible { - background: var(--spectrum-actionbutton-background-color-focus); - border-color: var(--spectrum-actionbutton-border-color-focus); - color: var(--spectrum-actionbutton-content-color-focus); - - &::after { - box-shadow: 0 0 0 var(--spectrum-actionbutton-focus-indicator-thickness) var(--spectrum-actionbutton-focus-indicator-color); - } + background-color: var(--highcontrast-actionbutton-background-color-default, var(--mod-actionbutton-background-color-focus, var(--spectrum-actionbutton-background-color-focus))); + color: var(--highcontrast-actionbutton-content-color-default, var(--mod-actionbutton-content-color-focus, var(--spectrum-actionbutton-content-color-focus))); } &:active { - background: var(--spectrum-actionbutton-background-color-down); - border-color: var(--spectrum-actionbutton-border-color-down); - color: var(--spectrum-actionbutton-content-color-down); + background-color: var(--highcontrast-actionbutton-background-color-default, var(--mod-actionbutton-background-color-down, var(--spectrum-actionbutton-background-color-down))); + color: var(--highcontrast-actionbutton-content-color-default, var(--mod-actionbutton-content-color-down, var(--spectrum-actionbutton-content-color-down))); + transform: perspective(var(--spectrum-actionbutton-downstate-perspective)) translateZ(var(--spectrum-component-size-difference-down)); } &:disabled, &.is-disabled { - cursor: default; - - background: var(--highcontrast-actionbutton-background-color-disabled, var(--mod-actionbutton-background-color-disabled, var(--spectrum-actionbutton-background-color-disabled))); - border-color: var(--highcontrast-actionbutton-border-color-disabled, var(--mod-actionbutton-border-color-disabled, var(--spectrum-actionbutton-border-color-disabled))); + background-color: var(--highcontrast-actionbutton-background-color-disabled, var(--mod-actionbutton-background-color-disabled, var(--spectrum-actionbutton-background-color-disabled))); color: var(--highcontrast-actionbutton-content-color-disabled, var(--mod-actionbutton-content-color-disabled, var(--spectrum-actionbutton-content-color-disabled))); } } a.spectrum-ActionButton { - /* Make link text not selectable */ - user-select: none; - - /* stylelint-disable-next-line property-no-vendor-prefix -- Remove appearance for clickable types in iOS and Safari. */ - -webkit-appearance: none; + @extend %spectrum-AnchorButton; } -/* Nested sub-component: Icon */ .spectrum-ActionButton-icon { - flex-shrink: 0; + @extend %spectrum-ButtonIcon; inline-size: var(--mod-actionbutton-icon-size, var(--spectrum-actionbutton-icon-size)); block-size: var(--mod-actionbutton-icon-size, var(--spectrum-actionbutton-icon-size)); - max-block-size: 100%; - - /* adjust icon positioning to match UI kit */ - margin-inline-start: calc(var(--spectrum-actionbutton-edge-to-visual) - var(--spectrum-actionbutton-edge-to-text)); - margin-inline-end: calc(var(--spectrum-actionbutton-edge-to-visual-only) - var(--spectrum-actionbutton-edge-to-text)); - color: inherit; - - /* Augment the margin correction for the icon only scenario */ - .spectrum-ActionButton-hold + &, - &:only-child { - margin-inline-start: calc(var(--spectrum-actionbutton-edge-to-visual-only) - var(--spectrum-actionbutton-edge-to-text)); - } } -.spectrum-ActionButton-label { - align-self: center; - justify-self: center; +/* Icon and label text */ +.spectrum-ActionButton:has(.spectrum-ActionButton-icon) { + padding-inline-start: calc(var(--mod-actionbutton-edge-to-visual, var(--spectrum-actionbutton-edge-to-visual)) - var(--spectrum-actionbutton-border-width)); +} - /* Fixes horizontal alignment of text in anchor buttons */ - text-align: center; +/* Icon only */ +.spectrum-ActionButton:not(:has(.spectrum-ActionButton-label)) { + padding-inline: calc(var(--mod-actionbutton-edge-to-visual-only, var(--spectrum-actionbutton-edge-to-visual-only)) - var(--spectrum-actionbutton-border-width)); +} +.spectrum-ActionButton-label { + @extend %spectrum-ButtonLabel; pointer-events: none; - line-height: var(--spectrum-actionbutton-height); - font-size: var(--spectrum-actionbutton-font-size); + font-size: var(--mod-actionbutton-font-size, var(--spectrum-actionbutton-font-size)); + font-weight: var(--mod-actionbutton-font-weight, var(--spectrum-actionbutton-font-weight)); + font-style: var(--mod-actionbutton-font-style, var(--spectrum-actionbutton-font-style)); white-space: nowrap; color: var(--mod-actionbutton-label-color, inherit); text-overflow: ellipsis; overflow: hidden; - - &:empty { - display: none; - } } .spectrum-ActionButton-hold { position: absolute; - inset-inline-end: calc(var(--spectrum-actionbutton-edge-to-hold-icon) - var(--spectrum-actionbutton-border-width)); - inset-block-end: calc(var(--spectrum-actionbutton-edge-to-hold-icon) - var(--spectrum-actionbutton-border-width)); - + inset-inline-end: calc(var(--mod-actionbutton-edge-to-hold-icon, var(--spectrum-actionbutton-edge-to-hold-icon)) - var(--spectrum-actionbutton-border-width)); + inset-block-end: calc(var(--mod-actionbutton-edge-to-hold-icon, var(--spectrum-actionbutton-edge-to-hold-icon)) - var(--spectrum-actionbutton-border-width)); color: inherit; - - transform: var(--spectrum-logical-rotation,); + transform: var(--spectrum-logical-rotation); } -.spectrum-ActionButton-hold + .spectrum-ActionButton-icon, -.spectrum-ActionButton-icon:only-child { - /* Augment the margin correction for the icon only scenario */ - margin-inline-start: calc(var(--spectrum-actionbutton-edge-to-visual-only) - var(--spectrum-actionbutton-edge-to-text)); +/* Focus indicator */ +.spectrum-ActionButton { + transition: border-color var(--highcontrast-actionbutton-animation-duration, var(--mod-actionbutton-animation-duration, var(--spectrum-actionbutton-animation-duration))) ease-in-out; + + &::after { + position: absolute; + inset: 0; + margin: calc((var(--mod-actionbutton-focus-indicator-gap, var(--spectrum-actionbutton-focus-indicator-gap)) + var(--spectrum-actionbutton-border-width)) * -1); + border-radius: var(--mod-actionbutton-focus-indicator-border-radius, var(--spectrum-actionbutton-focus-indicator-border-radius)); + transition: box-shadow var(--highcontrast-actionbutton-animation-duration, var(--mod-actionbutton-animation-duration, var(--spectrum-actionbutton-animation-duration))) ease-in-out; + pointer-events: none; + content: ""; + } + + &:focus-visible { + box-shadow: none; + outline: none; + + &::after { + box-shadow: 0 0 0 var(--mod-actionbutton-focus-indicator-thickness, var(--spectrum-actionbutton-focus-indicator-thickness)) var(--highcontrast-actionbutton-focus-indicator-color, var(--mod-actionbutton-focus-indicator-color, var(--spectrum-actionbutton-focus-indicator-color))); + } + } } @media (forced-colors: active) { .spectrum-ActionButton { + /** + * Default + * - Uses "Button*" system color pairings. + * - Focus indicator is outside the element and should contrast with its background (default of Canvas). + */ + --highcontrast-actionbutton-border-color: ButtonBorder; + --highcontrast-actionbutton-background-color-default: ButtonFace; + --highcontrast-actionbutton-content-color-default: ButtonText; + + --highcontrast-actionbutton-background-color-disabled: ButtonFace; + --highcontrast-actionbutton-content-color-disabled: GrayText; + + --highcontrast-actionbutton-focus-indicator-color: CanvasText; + + /** + * Avoid performance and rendering issues with transitions between system colors. + * Fixes bug in Windows High Contrast where border flashes the wrong color after hover (quiet). + */ + --highcontrast-actionbutton-animation-duration: 0; + &::after { - /* make sure focus indicator renders */ + /* Make sure the box-shadow for the focus indicator renders. */ forced-color-adjust: none; } - &.is-selected { - --highcontrast-actionbutton-background-color-default: Highlight; - --highcontrast-actionbutton-background-color-hover: Highlight; - --highcontrast-actionbutton-background-color-focus: Highlight; - --highcontrast-actionbutton-background-color-down: Highlight; - --highcontrast-actionbutton-background-color-disabled: ButtonFace; + .spectrum-ActionButton-icon, + .spectrum-ActionButton-hold, + .spectrum-ActionButton-label { + /* Removes the extra unwanted background on label ("readability backplate") that can cause text to be unreadable. */ + forced-color-adjust: none; + } - --highcontrast-actionbutton-border-color-default: HighlightText; - --highcontrast-actionbutton-border-color-hover: HighlightText; - --highcontrast-actionbutton-border-color-focus: HighlightText; - --highcontrast-actionbutton-border-color-down: HighlightText; - --highcontrast-actionbutton-border-color-disabled: GrayText; + /** + * Quiet + * - Default blends in with background and has no border. + * - Quiet + disabled does not show border unless selected. + */ + &.spectrum-ActionButton--quiet { + --highcontrast-actionbutton-border-color: Canvas; + --highcontrast-actionbutton-background-color-default: Canvas; + --highcontrast-actionbutton-background-color-disabled: Canvas; + --highcontrast-actionbutton-content-color-default: CanvasText; - --highcontrast-actionbutton-content-color-default: HighlightText; - --highcontrast-actionbutton-content-color-hover: HighlightText; - --highcontrast-actionbutton-content-color-focus: HighlightText; - --highcontrast-actionbutton-content-color-down: HighlightText; - --highcontrast-actionbutton-content-color-disabled: GrayText; - - .spectrum-ActionButton-icon, - .spectrum-ActionButton-hold, - .spectrum-ActionButton-label { - /* ensure custom text colors from above get applied */ - /* it seems like this shouldn't have to be done, but colors are wrong without it */ - forced-color-adjust: none; + &:disabled:not(.is-selected) { + --highcontrast-actionbutton-border-color: Canvas; } } + + /* Interaction shows a change in border color. */ + &:hover, + &:active, + &:focus-visible { + --highcontrast-actionbutton-border-color: Highlight; + } + + /* Selected always shows as a solid highlighted color. */ + &.is-selected { + --highcontrast-actionbutton-border-color: Highlight; + --highcontrast-actionbutton-background-color-default: Highlight; + --highcontrast-actionbutton-content-color-default: HighlightText; + } + + /* Disabled has a GrayText border and content color. */ + &:disabled { + --highcontrast-actionbutton-border-color: GrayText; + } } } diff --git a/components/actionbutton/stories/actionbutton.stories.js b/components/actionbutton/stories/actionbutton.stories.js index a08f0f7bbfc..e1bd38463d7 100644 --- a/components/actionbutton/stories/actionbutton.stories.js +++ b/components/actionbutton/stories/actionbutton.stories.js @@ -1,22 +1,18 @@ import { default as IconStories } from "@spectrum-css/icon/stories/icon.stories.js"; -import { Sizes } from "@spectrum-css/preview/decorators"; +import { Sizes, withDownStateDimensionCapture } from "@spectrum-css/preview/decorators"; import { disableDefaultModes } from "@spectrum-css/preview/modes"; import { isActive, isDisabled, isEmphasized, isFocused, isHovered, isQuiet, isSelected, size, staticColor } from "@spectrum-css/preview/types"; import metadata from "../dist/metadata.json"; import packageJson from "../package.json"; import { ActionButtonGroup } from "./actionbutton.test.js"; -import { ActionButtonsWithIconOptions, IconOnlyOption, TreatmentTemplate } from "./template.js"; +import { ActionButtonsWithIconOptions, IconOnlyOption, Template, TreatmentTemplate } from "./template.js"; /** * The action button component represents an action a user can take. * * ## Usage notes * - * For action buttons that only contain an icon with no label, do not include the element with the `.spectrum-ActionButton-label` class in the markup. If an icon and a label are both used, ensure that the element with the `.spectrum-ActionButton-label` class comes after the `.spectrum-Icon` element. - * - * If the hold icon is used, ensure that the element with the `.spectrum-ActionButton-hold` class comes before the `.spectrum-Icon` element. - * - * When using `.spectrum-ActionButton--staticWhite` or `.spectrum-ActionButton--staticBlack`, use the `--mod-actionbutton-content-color-default` custom property to set the text color when selected. + * For action buttons that only contain an icon with no label, do not include the element with the `.spectrum-ActionButton-label` class in the markup. */ export default { title: "Action button", @@ -25,6 +21,7 @@ export default { size: size(["xs", "s", "m", "l", "xl"]), iconName: { ...(IconStories?.argTypes?.iconName ?? {}), + name: "Workflow icon", if: false, }, label: { @@ -37,9 +34,15 @@ export default { control: { type: "text" }, }, isQuiet, - isEmphasized, + isEmphasized: { + ...isEmphasized, + if: { arg: "staticColor", truthy: false }, + }, isDisabled, - isSelected, + isSelected: { + ...isSelected, + description: "An optional state used when treating the action button as a toggle.", + }, isHovered, isFocused, isActive, @@ -63,7 +66,10 @@ export default { control: "select", options: ["true", "menu", "listbox", "tree", "grid", "dialog", "false"], }, - staticColor, + staticColor: { + ...staticColor, + if: { arg: "isEmphasized", truthy: false }, + }, }, args: { rootClass: "spectrum-ActionButton", @@ -88,6 +94,9 @@ export default { type: "figma", url: "https://www.figma.com/design/Mngz9H7WZLbrCvGQf3GnsY/S2-%2F-Desktop?node-id=702-2877", }, + downState: { + selectors: [".spectrum-ActionButton:not(:disabled)"], + }, packageJson, metadata, docs: { @@ -96,6 +105,9 @@ export default { }, } }, + decorators: [ + withDownStateDimensionCapture, + ], }; export const Default = ActionButtonGroup.bind({}); @@ -106,7 +118,9 @@ Default.tags = ["!autodocs"]; /** * Action buttons should always have a label, unless they are only using an icon that is universally understood and accessible. They can have an optional icon, but it should not be used for decoration. Use an icon only when necessary and when it has a strong association with the label text. * - * The label can be hidden to create an icon-only action button. If the label is hidden, an icon is required, and the label will appear in a tooltip on hover. + * The label can be hidden to create an icon-only action button. If the label is hidden, an icon is required, and the implementation should show the label with a tooltip on hover. + * + * Action buttons can be used as toggles instead of for taking direct action. The optional "selected" state displayed below is used for when the action button is toggleable. */ export const Standard = TreatmentTemplate.bind({}); Standard.args = Default.args; @@ -117,7 +131,9 @@ Standard.parameters = { Standard.storyName = "Default"; /** - * The emphasized action button has a blue background for its selected state in order to provide a visual prominence. This is optimal for when the selection should call attention, such as within a tool bar. + * The emphasized action button has a blue background for its selected state in order to provide a visual prominence. + * This is optimal for when the selection should call attention, such as within a tool bar. + * For this variant, the `.spectrum-ActionButton--emphasized` class is applied to `.spectrum-ActionButton`. */ export const Emphasized = TreatmentTemplate.bind({}); Emphasized.tags = ["!dev"]; @@ -130,9 +146,6 @@ Emphasized.parameters = { }, }; -/** - * Adding the `.spectrum-ActionButton--emphasized` class to a quiet action button can be effective in calling attention. - */ export const EmphasizedQuiet = TreatmentTemplate.bind({}); EmphasizedQuiet.tags = ["!dev"]; EmphasizedQuiet.args = { @@ -144,7 +157,7 @@ EmphasizedQuiet.parameters = { disableSnapshot: true, }, }; -EmphasizedQuiet.storyName = "Emphasized (quiet)"; +EmphasizedQuiet.storyName = "Quiet, emphasized"; /** * Quiet action buttons have no visible background until they’re interacted with. This style works best when a clear layout (vertical stack, table, grid) makes it easy to parse the buttons. Too many quiet components in a small space can be hard to read. @@ -161,7 +174,10 @@ Quiet.parameters = { }; /** - * An action button can have a hold icon (a small corner triangle). This icon indicates that holding down the action button for a short amount of time can reveal a popover menu, which can be used, for example, to switch between related actions. Because of the way padding is calculated, the hold icon must be placed before the workflow icon in the markup. + * An action button can have a hold icon (a small corner triangle). This icon indicates that holding down the action button for a + * short amount of time can reveal a [popover](/docs/components-popover--docs) menu, which can be used, for example, to switch + * between related actions. Note that this popover menu is not demonstrated here—this would be handled by the implementation. + * Because of the way padding is calculated, the hold icon must be placed before the workflow icon in the markup. */ export const HoldIcon = IconOnlyOption.bind({}); HoldIcon.tags = ["!dev"]; @@ -190,6 +206,14 @@ StaticWhiteQuiet.parameters = { chromatic: { disableSnapshot: true } }; +/** + * When an action button needs to be placed on top of a color background or a visual, use the static color + * option. Use static black on light color or image backgrounds, and static white on dark color or image + * backgrounds, regardless of the color theme. For more info, see the + * [design guidelines](https://spectrum.adobe.com/page/action-button/#Static-color). + * + * Emphasized is not supported for the static black and static white variants. + */ export const StaticBlackDocs = TreatmentTemplate.bind({}); StaticBlackDocs.tags = ["!dev"]; StaticBlackDocs.args = { @@ -226,6 +250,28 @@ Sizing.parameters = { chromatic: { disableSnapshot: true }, }; +/** + * When the action button text is too long for the available horizontal space, it truncates at the end. + * To demonstrate what this looks like, this example sets a maximum width on the button. + * + * Implementations should also reveal the full text on hover, per this component's + * [design guidelines on text overflow](https://spectrum.adobe.com/page/action-button/#Text-overflow). + * This is not demonstrated here. + */ +export const TextOverflowBehavior = Template.bind({}); +TextOverflowBehavior.tags = ["!dev"]; +TextOverflowBehavior.args = { + label: "This is extra long text that will cause text truncation", + customStyles: { + "max-inline-size": "120px", + }, +}; +TextOverflowBehavior.parameters = { + chromatic: { + disableSnapshot: true, + }, +}; + // ********* VRT ONLY ********* // export const WithForcedColors = ActionButtonGroup.bind({}); WithForcedColors.args = Default.args; diff --git a/components/actionbutton/stories/actionbutton.test.js b/components/actionbutton/stories/actionbutton.test.js index fb37fdc910f..4a26724f80b 100644 --- a/components/actionbutton/stories/actionbutton.test.js +++ b/components/actionbutton/stories/actionbutton.test.js @@ -62,11 +62,6 @@ export const ActionButtonGroup = Variants({ testHeading: "Static black", staticColor: "black", }, - { - testHeading: "Static black - emphasized", - staticColor: "black", - isEmphasized: true, - }, { testHeading: "Static black - quiet", staticColor: "black", @@ -76,11 +71,6 @@ export const ActionButtonGroup = Variants({ testHeading: "Static white", staticColor: "white", }, - { - testHeading: "Static white - emphasized", - staticColor: "white", - isEmphasized: true, - }, { testHeading: "Static white - quiet", staticColor: "white", diff --git a/components/actionbutton/stories/template.js b/components/actionbutton/stories/template.js index 3b3cb8930c2..942c3bccefa 100644 --- a/components/actionbutton/stories/template.js +++ b/components/actionbutton/stories/template.js @@ -67,7 +67,6 @@ export const Template = ({ role = "button", } = {}, context = {}) => { const { updateArgs } = context; - return html`