diff --git a/.changeset/strong-pianos-work.md b/.changeset/strong-pianos-work.md new file mode 100644 index 00000000000..20e62c598ed --- /dev/null +++ b/.changeset/strong-pianos-work.md @@ -0,0 +1,33 @@ +--- +"@spectrum-css/menu": major +--- + +### Spectrum 2 migration + +Menu now uses Spectrum 2 tokens and specifications. + +Removes custom menu item background color tokens: `@adobe/spectrum-tokens` has been updated to include many tokens relating to the menu component, including some that replace custom tokens that had previously been added. As such, these custom menu item color tokens that are now available from `@adobe/spectrum-tokens` have been removed. + +In addition to other small token and minor style changes, there were several new features that were added to this version of menu, including: + +- A thumbnail can now be used in place of an icon +- A section description can now be included below the menu section heading +- The actions area previously held action switches for multi-select, and in this version, an external link action icon can be included in that area + +### New mods + +- `--mod-menu-item-corner-radius` +- `--mod-menu-item-linkout-icon-height` +- `--mod-menu-item-linkout-icon-width` +- `--mod-menu-item-thumbnail-height` +- `--mod-menu-item-thumbnail-opacity-disabled` +- `--mod-menu-item-thumbnail-to-label` +- `--mod-menu-item-thumbnail-width` +- `--mod-menu-item-top-to-thumbnail` +- `--mod-menu-item-top-to-workflow-icon` +- `--mod-menu-section-description-color` +- `--mod-menu-section-description-font-size` +- `--mod-menu-section-description-font-weight` +- `--mod-menu-section-description-line-height` +- `--mod-menu-section-description-line-height-cjk` +- `--mod-menu-section-header-to-description` diff --git a/components/menu/dist/metadata.json b/components/menu/dist/metadata.json index 3b4f63996b8..819a2b1b560 100644 --- a/components/menu/dist/metadata.json +++ b/components/menu/dist/metadata.json @@ -12,16 +12,17 @@ ".spectrum-Menu .spectrum-Menu-item--collapsible.is-open.is-focused", ".spectrum-Menu .spectrum-Menu-item--collapsible.is-open:active", ".spectrum-Menu .spectrum-Menu-item--collapsible.is-open:focus", - ".spectrum-Menu .spectrum-Menu-item--collapsible.is-open:focus-within", ".spectrum-Menu .spectrum-Menu-item--collapsible.is-open:hover", ".spectrum-Menu .spectrum-Menu-item--drillIn.is-open", ".spectrum-Menu .spectrum-Menu-item:focus .spectrum-Menu-itemCheckbox", ".spectrum-Menu .spectrum-Menu-item:focus .spectrum-Menu-itemSwitch", + ".spectrum-Menu .spectrum-Menu-item:has(> .spectrum-Menu-itemIcon--workflowIcon) .spectrum-Menu-linkout", ".spectrum-Menu .spectrum-Menu-item:hover .spectrum-Menu-itemCheckbox", ".spectrum-Menu .spectrum-Menu-item:hover .spectrum-Menu-itemSwitch", ".spectrum-Menu .spectrum-Menu-itemIcon", ".spectrum-Menu .spectrum-Menu-itemIcon--workflowIcon", - ".spectrum-Menu .spectrum-Menu-itemIcon:not(.spectrum-Menu-chevron, .spectrum-Menu-checkmark)", + ".spectrum-Menu .spectrum-Menu-itemIcon:not(.spectrum-Menu-chevron, .spectrum-Menu-checkmark, .spectrum-Menu-linkout)", + ".spectrum-Menu .spectrum-Menu-linkout", ".spectrum-Menu li:not(.spectrum-Menu-item, .spectrum-Menu-divider)", ".spectrum-Menu-back", ".spectrum-Menu-back .spectrum-Menu-sectionHeading", @@ -60,10 +61,10 @@ ".spectrum-Menu-item--drillIn:active .spectrum-Menu-chevron", ".spectrum-Menu-item--drillIn:focus .spectrum-Menu-chevron", ".spectrum-Menu-item--drillIn:hover .spectrum-Menu-chevron", - ".spectrum-Menu-item.is-disabled", ".spectrum-Menu-item.is-disabled .spectrum-Menu-itemDescription", ".spectrum-Menu-item.is-disabled .spectrum-Menu-itemIcon", ".spectrum-Menu-item.is-disabled .spectrum-Menu-itemLabel", + ".spectrum-Menu-item.is-disabled .spectrum-Menu-itemThumbnail", ".spectrum-Menu-item.is-disabled .spectrum-Menu-itemValue", ".spectrum-Menu-item.is-disabled .spectrum-Menu-sectionHeading", ".spectrum-Menu-item.is-disabled:hover", @@ -72,15 +73,17 @@ ".spectrum-Menu-item.is-disabled:hover .spectrum-Menu-itemLabel", ".spectrum-Menu-item.is-disabled:hover .spectrum-Menu-itemValue", ".spectrum-Menu-item.is-disabled:hover .spectrum-Menu-sectionHeading", - ".spectrum-Menu-item.is-focused", - ".spectrum-Menu-item.is-focused > .spectrum-Menu-checkmark", - ".spectrum-Menu-item.is-focused > .spectrum-Menu-chevron", - ".spectrum-Menu-item.is-focused > .spectrum-Menu-itemDescription", - ".spectrum-Menu-item.is-focused > .spectrum-Menu-itemIcon:not(.spectrum-Menu-chevron, .spectrum-Menu-checkmark)", - ".spectrum-Menu-item.is-focused > .spectrum-Menu-itemLabel", - ".spectrum-Menu-item.is-focused > .spectrum-Menu-itemValue", - ".spectrum-Menu-item.is-focused > .spectrum-Menu-sectionHeading", + ".spectrum-Menu-item.is-focus-visible", + ".spectrum-Menu-item.is-focus-visible .spectrum-Menu-linkout", + ".spectrum-Menu-item.is-focus-visible > .spectrum-Menu-checkmark", + ".spectrum-Menu-item.is-focus-visible > .spectrum-Menu-chevron", + ".spectrum-Menu-item.is-focus-visible > .spectrum-Menu-itemDescription", + ".spectrum-Menu-item.is-focus-visible > .spectrum-Menu-itemIcon:not(.spectrum-Menu-chevron, .spectrum-Menu-checkmark)", + ".spectrum-Menu-item.is-focus-visible > .spectrum-Menu-itemLabel", + ".spectrum-Menu-item.is-focus-visible > .spectrum-Menu-itemValue", + ".spectrum-Menu-item.is-focus-visible > .spectrum-Menu-sectionHeading", ".spectrum-Menu-item:active", + ".spectrum-Menu-item:active .spectrum-Menu-linkout", ".spectrum-Menu-item:active > .spectrum-Menu-checkmark", ".spectrum-Menu-item:active > .spectrum-Menu-chevron", ".spectrum-Menu-item:active > .spectrum-Menu-itemDescription", @@ -88,16 +91,26 @@ ".spectrum-Menu-item:active > .spectrum-Menu-itemLabel", ".spectrum-Menu-item:active > .spectrum-Menu-itemValue", ".spectrum-Menu-item:active > .spectrum-Menu-sectionHeading", - ".spectrum-Menu-item:focus", - ".spectrum-Menu-item:focus > .spectrum-Menu-checkmark", - ".spectrum-Menu-item:focus > .spectrum-Menu-chevron", - ".spectrum-Menu-item:focus > .spectrum-Menu-itemDescription", - ".spectrum-Menu-item:focus > .spectrum-Menu-itemIcon:not(.spectrum-Menu-chevron, .spectrum-Menu-checkmark)", - ".spectrum-Menu-item:focus > .spectrum-Menu-itemLabel", - ".spectrum-Menu-item:focus > .spectrum-Menu-itemValue", - ".spectrum-Menu-item:focus > .spectrum-Menu-sectionHeading", ".spectrum-Menu-item:focus-visible", + ".spectrum-Menu-item:focus-visible .spectrum-Menu-linkout", + ".spectrum-Menu-item:focus-visible > .spectrum-Menu-checkmark", + ".spectrum-Menu-item:focus-visible > .spectrum-Menu-chevron", + ".spectrum-Menu-item:focus-visible > .spectrum-Menu-itemDescription", + ".spectrum-Menu-item:focus-visible > .spectrum-Menu-itemIcon:not(.spectrum-Menu-chevron, .spectrum-Menu-checkmark)", + ".spectrum-Menu-item:focus-visible > .spectrum-Menu-itemLabel", + ".spectrum-Menu-item:focus-visible > .spectrum-Menu-itemValue", + ".spectrum-Menu-item:focus-visible > .spectrum-Menu-sectionHeading", + ".spectrum-Menu-item:has(> .spectrum-Menu-itemThumbnail) > .spectrum-Menu-checkmark", + ".spectrum-Menu-item:has(> .spectrum-Menu-itemThumbnail) > .spectrum-Menu-itemActions", + ".spectrum-Menu-item:has(> .spectrum-Menu-itemThumbnail) > .spectrum-Menu-itemCheckbox", + ".spectrum-Menu-item:has(> .spectrum-Menu-itemThumbnail) > .spectrum-Menu-itemLabel", + ".spectrum-Menu-item:has(> .spectrum-Menu-itemThumbnail) > .spectrum-Menu-itemValue", + ".spectrum-Menu-item:has(> .spectrum-Menu-itemThumbnail):has(> .spectrum-Menu-itemDescription) .spectrum-Menu-itemThumbnail", + ".spectrum-Menu-item:has(> .spectrum-Menu-itemThumbnail):has(> .spectrum-Menu-itemDescription) > .spectrum-Menu-checkmark", + ".spectrum-Menu-item:has(> .spectrum-Menu-itemThumbnail):has(> .spectrum-Menu-itemDescription) > .spectrum-Menu-itemCheckbox", + ".spectrum-Menu-item:has(> .spectrum-Menu-itemThumbnail):has(> .spectrum-Menu-itemDescription) > .spectrum-Menu-itemDescription", ".spectrum-Menu-item:hover", + ".spectrum-Menu-item:hover .spectrum-Menu-linkout", ".spectrum-Menu-item:hover > .spectrum-Menu-checkmark", ".spectrum-Menu-item:hover > .spectrum-Menu-chevron", ".spectrum-Menu-item:hover > .spectrum-Menu-itemDescription", @@ -110,11 +123,12 @@ ".spectrum-Menu-itemLabel", ".spectrum-Menu-itemLabel--truncate", ".spectrum-Menu-itemSelection", + ".spectrum-Menu-itemThumbnail", ".spectrum-Menu-itemValue", - ".spectrum-Menu-item[aria-disabled=\"true\"]", ".spectrum-Menu-item[aria-disabled=\"true\"] .spectrum-Menu-itemDescription", ".spectrum-Menu-item[aria-disabled=\"true\"] .spectrum-Menu-itemIcon", ".spectrum-Menu-item[aria-disabled=\"true\"] .spectrum-Menu-itemLabel", + ".spectrum-Menu-item[aria-disabled=\"true\"] .spectrum-Menu-itemThumbnail", ".spectrum-Menu-item[aria-disabled=\"true\"] .spectrum-Menu-itemValue", ".spectrum-Menu-item[aria-disabled=\"true\"] .spectrum-Menu-sectionHeading", ".spectrum-Menu-item[aria-disabled=\"true\"]:hover", @@ -123,6 +137,7 @@ ".spectrum-Menu-item[aria-disabled=\"true\"]:hover .spectrum-Menu-itemLabel", ".spectrum-Menu-item[aria-disabled=\"true\"]:hover .spectrum-Menu-itemValue", ".spectrum-Menu-item[aria-disabled=\"true\"]:hover .spectrum-Menu-sectionHeading", + ".spectrum-Menu-sectionDescription", ".spectrum-Menu-sectionHeading", ".spectrum-Menu.is-selectable .spectrum-Menu-item", ".spectrum-Menu.is-selectable .spectrum-Menu-item.is-selected", @@ -131,11 +146,9 @@ ".spectrum-Menu.spectrum-Menu--sizeL", ".spectrum-Menu.spectrum-Menu--sizeS", ".spectrum-Menu.spectrum-Menu--sizeXL", - ".spectrum-Menu:dir(rtl)", ".spectrum-Menu:lang(ja)", ".spectrum-Menu:lang(ko)", ".spectrum-Menu:lang(zh)", - "[dir=\"rtl\"] .spectrum-Menu", "[dir=\"rtl\"] .spectrum-Menu .spectrum-Menu-chevron" ], "modifiers": [ @@ -166,6 +179,7 @@ "--mod-menu-item-checkmark-height", "--mod-menu-item-checkmark-width", "--mod-menu-item-collapsible-no-icon-submenu-item-padding-x-start", + "--mod-menu-item-corner-radius", "--mod-menu-item-description-color-default", "--mod-menu-item-description-color-disabled", "--mod-menu-item-description-color-down", @@ -195,17 +209,30 @@ "--mod-menu-item-label-text-to-visual", "--mod-menu-item-label-to-description-spacing", "--mod-menu-item-label-to-value-area-min-spacing", + "--mod-menu-item-linkout-icon-height", + "--mod-menu-item-linkout-icon-width", "--mod-menu-item-min-height", "--mod-menu-item-selectable-edge-to-text-not-selected", "--mod-menu-item-text-to-control", + "--mod-menu-item-thumbnail-height", + "--mod-menu-item-thumbnail-opacity-disabled", + "--mod-menu-item-thumbnail-to-label", + "--mod-menu-item-thumbnail-width", "--mod-menu-item-top-edge-to-text", "--mod-menu-item-top-to-action", "--mod-menu-item-top-to-checkbox", "--mod-menu-item-top-to-checkmark", + "--mod-menu-item-top-to-thumbnail", + "--mod-menu-item-top-to-workflow-icon", "--mod-menu-item-value-color-default", "--mod-menu-item-value-color-down", "--mod-menu-item-value-color-focus", "--mod-menu-item-value-color-hover", + "--mod-menu-section-description-color", + "--mod-menu-section-description-font-size", + "--mod-menu-section-description-font-weight", + "--mod-menu-section-description-line-height", + "--mod-menu-section-description-line-height-cjk", "--mod-menu-section-divider-margin-block", "--mod-menu-section-header-bottom-edge-to-text", "--mod-menu-section-header-color", @@ -214,6 +241,7 @@ "--mod-menu-section-header-line-height", "--mod-menu-section-header-line-height-cjk", "--mod-menu-section-header-min-width", + "--mod-menu-section-header-to-description", "--mod-menu-section-header-top-edge-to-text" ], "component": [ @@ -234,18 +262,12 @@ "--spectrum-menu-item-background-color-default", "--spectrum-menu-item-background-color-down", "--spectrum-menu-item-background-color-hover", - "--spectrum-menu-item-background-color-key-focus", + "--spectrum-menu-item-background-color-keyboard-focus", "--spectrum-menu-item-bottom-edge-to-text", "--spectrum-menu-item-checkmark-height", - "--spectrum-menu-item-checkmark-height-extra-large", - "--spectrum-menu-item-checkmark-height-large", - "--spectrum-menu-item-checkmark-height-medium", - "--spectrum-menu-item-checkmark-height-small", "--spectrum-menu-item-checkmark-width", - "--spectrum-menu-item-checkmark-width-extra-large", - "--spectrum-menu-item-checkmark-width-large", - "--spectrum-menu-item-checkmark-width-medium", - "--spectrum-menu-item-checkmark-width-small", + "--spectrum-menu-item-chevron-height", + "--spectrum-menu-item-chevron-width", "--spectrum-menu-item-collapsible-no-icon-submenu-item-padding-x-start", "--spectrum-menu-item-corner-radius", "--spectrum-menu-item-description-color-default", @@ -256,14 +278,12 @@ "--spectrum-menu-item-description-font-size", "--spectrum-menu-item-description-line-height", "--spectrum-menu-item-description-line-height-cjk", - "--spectrum-menu-item-focus-indicator-border-width", "--spectrum-menu-item-focus-indicator-color", "--spectrum-menu-item-focus-indicator-color-default", - "--spectrum-menu-item-focus-indicator-direction-scalar", "--spectrum-menu-item-focus-indicator-offset", "--spectrum-menu-item-focus-indicator-outline-style", - "--spectrum-menu-item-focus-indicator-shadow", "--spectrum-menu-item-focus-indicator-width", + "--spectrum-menu-item-focus-margin", "--spectrum-menu-item-icon-height", "--spectrum-menu-item-icon-width", "--spectrum-menu-item-label-content-color-default", @@ -282,8 +302,13 @@ "--spectrum-menu-item-label-line-height-cjk", "--spectrum-menu-item-label-text-to-visual", "--spectrum-menu-item-label-to-description", - "--spectrum-menu-item-label-to-description-spacing", + "--spectrum-menu-item-label-to-description-extra-large", + "--spectrum-menu-item-label-to-description-large", + "--spectrum-menu-item-label-to-description-medium", + "--spectrum-menu-item-label-to-description-small", "--spectrum-menu-item-label-to-value-area-min-spacing", + "--spectrum-menu-item-linkout-icon-height", + "--spectrum-menu-item-linkout-icon-width", "--spectrum-menu-item-min-height", "--spectrum-menu-item-section-divider-height", "--spectrum-menu-item-selectable-edge-to-text-not-selected", @@ -291,8 +316,11 @@ "--spectrum-menu-item-selectable-edge-to-text-not-selected-large", "--spectrum-menu-item-selectable-edge-to-text-not-selected-medium", "--spectrum-menu-item-selectable-edge-to-text-not-selected-small", - "--spectrum-menu-item-spacing-multiplier", "--spectrum-menu-item-text-to-control", + "--spectrum-menu-item-thumbnail-height", + "--spectrum-menu-item-thumbnail-opacity-disabled", + "--spectrum-menu-item-thumbnail-to-label", + "--spectrum-menu-item-thumbnail-width", "--spectrum-menu-item-top-edge-to-text", "--spectrum-menu-item-top-to-action", "--spectrum-menu-item-top-to-checkbox", @@ -301,24 +329,46 @@ "--spectrum-menu-item-top-to-selected-icon-large", "--spectrum-menu-item-top-to-selected-icon-medium", "--spectrum-menu-item-top-to-selected-icon-small", + "--spectrum-menu-item-top-to-thumbnail", + "--spectrum-menu-item-top-to-thumbnail-extra-large", + "--spectrum-menu-item-top-to-thumbnail-large", + "--spectrum-menu-item-top-to-thumbnail-medium", + "--spectrum-menu-item-top-to-thumbnail-small", + "--spectrum-menu-item-top-to-workflow-icon", "--spectrum-menu-item-value-color-default", "--spectrum-menu-item-value-color-down", "--spectrum-menu-item-value-color-focus", "--spectrum-menu-item-value-color-hover", + "--spectrum-menu-section-description-color", + "--spectrum-menu-section-description-font-size", + "--spectrum-menu-section-description-font-weight", + "--spectrum-menu-section-description-line-height", + "--spectrum-menu-section-description-line-height-cjk", "--spectrum-menu-section-header-color", "--spectrum-menu-section-header-font-size", "--spectrum-menu-section-header-font-weight", "--spectrum-menu-section-header-line-height", "--spectrum-menu-section-header-line-height-cjk", - "--spectrum-menu-section-header-min-width" + "--spectrum-menu-section-header-min-width", + "--spectrum-menu-section-header-to-description", + "--spectrum-menu-section-header-to-description-extra-large", + "--spectrum-menu-section-header-to-description-large", + "--spectrum-menu-section-header-to-description-medium", + "--spectrum-menu-section-header-to-description-small" ], "global": [ "--spectrum-accent-color-1000", "--spectrum-accent-color-1100", "--spectrum-accent-color-900", - "--spectrum-blue-800", "--spectrum-bold-font-weight", - "--spectrum-border-width-200", + "--spectrum-checkmark-icon-size-100", + "--spectrum-checkmark-icon-size-200", + "--spectrum-checkmark-icon-size-300", + "--spectrum-checkmark-icon-size-75", + "--spectrum-chevron-icon-size-100", + "--spectrum-chevron-icon-size-200", + "--spectrum-chevron-icon-size-300", + "--spectrum-chevron-icon-size-75", "--spectrum-cjk-line-height-100", "--spectrum-component-bottom-to-text-100", "--spectrum-component-bottom-to-text-200", @@ -332,24 +382,38 @@ "--spectrum-component-height-200", "--spectrum-component-height-300", "--spectrum-component-height-75", + "--spectrum-component-size-difference-down", + "--spectrum-component-size-width-ratio-down", "--spectrum-component-top-to-text-100", "--spectrum-component-top-to-text-200", "--spectrum-component-top-to-text-300", "--spectrum-component-top-to-text-75", - "--spectrum-corner-radius-100", + "--spectrum-component-top-to-workflow-icon-100", + "--spectrum-component-top-to-workflow-icon-200", + "--spectrum-component-top-to-workflow-icon-300", + "--spectrum-component-top-to-workflow-icon-75", + "--spectrum-corner-radius-400", + "--spectrum-corner-radius-500", + "--spectrum-corner-radius-600", + "--spectrum-corner-radius-700", "--spectrum-disabled-content-color", "--spectrum-divider-thickness-medium", "--spectrum-divider-thickness-small", + "--spectrum-downstate-height", + "--spectrum-downstate-width", "--spectrum-focus-indicator-color", + "--spectrum-focus-indicator-gap", "--spectrum-focus-indicator-thickness", "--spectrum-font-size-100", "--spectrum-font-size-200", "--spectrum-font-size-300", "--spectrum-font-size-50", "--spectrum-font-size-75", - "--spectrum-gray-1000-rgb", "--spectrum-gray-900", "--spectrum-line-height-100", + "--spectrum-link-out-icon-size-100", + "--spectrum-link-out-icon-size-200", + "--spectrum-link-out-icon-size-75", "--spectrum-navigational-indicator-top-to-back-icon-extra-large", "--spectrum-navigational-indicator-top-to-back-icon-large", "--spectrum-navigational-indicator-top-to-back-icon-medium", @@ -362,6 +426,7 @@ "--spectrum-neutral-subdued-content-color-down", "--spectrum-neutral-subdued-content-color-hover", "--spectrum-neutral-subdued-content-color-key-focus", + "--spectrum-regular-font-weight", "--spectrum-spacing-100", "--spectrum-spacing-50", "--spectrum-text-to-control-100", @@ -371,8 +436,12 @@ "--spectrum-text-to-visual-100", "--spectrum-text-to-visual-200", "--spectrum-text-to-visual-300", + "--spectrum-text-to-visual-400", "--spectrum-text-to-visual-75", - "--spectrum-transparent-black-200-opacity", + "--spectrum-thumbnail-size-500", + "--spectrum-thumbnail-size-700", + "--spectrum-thumbnail-size-800", + "--spectrum-thumbnail-size-900", "--spectrum-workflow-icon-size-100", "--spectrum-workflow-icon-size-200", "--spectrum-workflow-icon-size-300", diff --git a/components/menu/index.css b/components/menu/index.css index c6519dd47d6..7f36a14298f 100644 --- a/components/menu/index.css +++ b/components/menu/index.css @@ -1,5 +1,5 @@ /*! - * Copyright 2024 Adobe. All rights reserved. + * 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 @@ -11,94 +11,12 @@ * governing permissions and limitations under the License. */ -@media (forced-colors: active) { - .spectrum-Menu { - --highcontrast-menu-item-background-color-default: ButtonFace; - --highcontrast-menu-item-color-default: ButtonText; - - --highcontrast-menu-item-background-color-focus: Highlight; - --highcontrast-menu-item-color-focus: HighlightText; - - --highcontrast-menu-checkmark-icon-color-default: Highlight; - - --highcontrast-menu-item-color-disabled: GrayText; - --highcontrast-menu-item-focus-indicator-color: Highlight; - - --highcontrast-menu-item-selected-background-color: Highlight; - --highcontrast-menu-item-selected-color: HighlightText; - - @supports (color: SelectedItem) { - --highcontrast-menu-item-selected-background-color: SelectedItem; - --highcontrast-menu-item-selected-color: SelectedItemText; - } - - .spectrum-Menu-item { - /* Hide unstylable readability backplates. */ - forced-color-adjust: none; - } - - .spectrum-Menu-item:hover, - .spectrum-Menu-item:focus { - .spectrum-Menu-itemCheckbox { - /* @passthrough start */ - --highcontrast-checkbox-highlight-color-hover: ButtonText; - --highcontrast-checkbox-highlight-color-default: ButtonText; - /* @passthrough end */ - } - - .spectrum-Menu-itemSwitch { - /* @passthrough start */ - --highcontrast-switch-handle-border-color-hover: ButtonText; - --highcontrast-switch-handle-border-color-selected-default: ButtonText; - --highcontrast-switch-handle-border-color-selected-hover: ButtonText; - --highcontrast-switch-background-color-selected-default: ButtonText; - --highcontrast-switch-background-color-selected-hover: ButtonText; - /* @passthrough end */ - } - } - - .spectrum-Menu-item--drillIn.is-open { - --highcontrast-menu-item-background-color-default: var(--highcontrast-menu-item-selected-background-color); - --highcontrast-menu-item-color-default: var(--highcontrast-menu-item-selected-color); - } - - .spectrum-Menu-item--collapsible.is-open { - &:hover, - &:focus-within { - box-shadow: var(--spectrum-menu-item-focus-indicator-shadow) var(--spectrum-menu-item-focus-indicator-border-width) 0 0 0 var(--spectrum-menu-item-focus-indicator-color-default); - } - - &:hover, - &:active, - &:focus, - &.is-focused { - --highcontrast-menu-item-color-focus: var(--highcontrast-menu-item-color-default); - } - } - } -} - .spectrum-Menu { - --spectrum-menu-item-background-color-hover: rgba(var(--spectrum-gray-1000-rgb), var(--spectrum-transparent-black-200-opacity)); - --spectrum-menu-item-background-color-down: rgba(var(--spectrum-gray-1000-rgb), var(--spectrum-transparent-black-200-opacity)); - --spectrum-menu-item-background-color-key-focus: rgba(var(--spectrum-gray-1000-rgb), var(--spectrum-transparent-black-200-opacity)); - - --spectrum-menu-item-corner-radius: var(--spectrum-corner-radius-100); - - /* Focus state styling */ - --spectrum-menu-item-focus-indicator-shadow: none; - --spectrum-menu-item-focus-indicator-offset: var(--spectrum-spacing-50); - --spectrum-menu-item-spacing-multiplier: 1; - --spectrum-menu-item-focus-indicator-outline-style: solid; - - --spectrum-menu-item-top-to-action: var(--spectrum-spacing-50); - --spectrum-menu-item-top-to-checkbox: var(--spectrum-spacing-50); + /* Simplified - spec'd for 0% opacity */ + --spectrum-menu-item-background-color-default: var(--highcontrast-menu-item-background-color-default, transparent); --spectrum-menu-item-label-line-height: var(--spectrum-line-height-100); --spectrum-menu-item-label-line-height-cjk: var(--spectrum-cjk-line-height-100); - --spectrum-menu-item-label-to-description-spacing: var(--spectrum-menu-item-label-to-description); - --spectrum-menu-item-focus-indicator-width: var(--mod-menu-item-focus-indicator-width, var(--spectrum-border-width-200)); - --spectrum-menu-item-focus-indicator-color: var(--spectrum-blue-800); --spectrum-menu-item-label-to-value-area-min-spacing: var(--spectrum-spacing-100); --spectrum-menu-item-label-content-color-default: var(--spectrum-neutral-content-color-default); @@ -126,7 +44,17 @@ --spectrum-menu-section-header-line-height: var(--spectrum-line-height-100); --spectrum-menu-section-header-line-height-cjk: var(--spectrum-cjk-line-height-100); --spectrum-menu-section-header-font-weight: var(--spectrum-bold-font-weight); - --spectrum-menu-section-header-color: var(--spectrum-gray-900); + --spectrum-menu-section-header-color: var(--spectrum-neutral-content-color-default); + --spectrum-menu-section-header-font-size: var(--spectrum-font-size-100); + --spectrum-menu-section-header-min-width: var(--spectrum-component-height-100); + + --spectrum-menu-section-description-line-height: var(--spectrum-line-height-100); + --spectrum-menu-section-description-line-height-cjk: var(--spectrum-cjk-line-height-100); + --spectrum-menu-section-description-font-weight: var(--spectrum-regular-font-weight); + --spectrum-menu-section-description-color: var(--spectrum-neutral-subdued-content-color-default); + --spectrum-menu-section-header-to-description: var(--spectrum-menu-section-header-to-description-medium); + --spectrum-menu-item-label-to-description: var(--spectrum-menu-item-label-to-description-medium); + --spectrum-menu-collapsible-icon-color: var(--spectrum-gray-900); --spectrum-menu-checkmark-icon-color-default: var(--spectrum-accent-color-900); @@ -151,33 +79,52 @@ --spectrum-menu-item-min-height: var(--spectrum-component-height-100); --spectrum-menu-item-icon-height: var(--spectrum-workflow-icon-size-100); --spectrum-menu-item-icon-width: var(--spectrum-workflow-icon-size-100); + + --spectrum-menu-item-linkout-icon-height: var(--spectrum-link-out-icon-size-100); + --spectrum-menu-item-linkout-icon-width: var(--spectrum-link-out-icon-size-100); + --spectrum-menu-item-label-font-size: var(--spectrum-font-size-100); --spectrum-menu-item-label-text-to-visual: var(--spectrum-text-to-visual-100); + --spectrum-menu-item-top-to-action: var(--spectrum-spacing-50); + --spectrum-menu-item-top-to-checkbox: var(--spectrum-spacing-50); + --spectrum-menu-item-top-to-workflow-icon: var(--spectrum-component-top-to-workflow-icon-100); + --spectrum-menu-item-label-inline-edge-to-content: var(--spectrum-component-edge-to-text-100); --spectrum-menu-item-top-edge-to-text: var(--spectrum-component-top-to-text-100); --spectrum-menu-item-bottom-edge-to-text: var(--spectrum-component-bottom-to-text-100); - --spectrum-menu-item-text-to-control: var(--spectrum-text-to-control-100); + --spectrum-menu-item-selectable-edge-to-text-not-selected: var(--spectrum-menu-item-selectable-edge-to-text-not-selected-medium); --spectrum-menu-item-description-font-size: var(--spectrum-font-size-75); - --spectrum-menu-section-header-font-size: var(--spectrum-font-size-100); - --spectrum-menu-section-header-min-width: var(--spectrum-component-height-100); - - --spectrum-menu-item-selectable-edge-to-text-not-selected: var(--spectrum-menu-item-selectable-edge-to-text-not-selected-medium); + --spectrum-menu-item-corner-radius: var(--spectrum-corner-radius-500); - --spectrum-menu-item-checkmark-height: var(--spectrum-menu-item-checkmark-height-medium); - --spectrum-menu-item-checkmark-width: var(--spectrum-menu-item-checkmark-width-medium); + --spectrum-menu-item-checkmark-height: var(--spectrum-checkmark-icon-size-100); + --spectrum-menu-item-checkmark-width: var(--spectrum-checkmark-icon-size-100); --spectrum-menu-item-top-to-checkmark: var(--spectrum-menu-item-top-to-selected-icon-medium); + --spectrum-menu-item-chevron-height: var(--spectrum-chevron-icon-size-100); + --spectrum-menu-item-chevron-width: var(--spectrum-chevron-icon-size-100); + + --spectrum-menu-item-top-to-thumbnail: var(--spectrum-menu-item-top-to-thumbnail-medium); + --spectrum-menu-item-thumbnail-to-label: var(--spectrum-text-to-visual-200); + --spectrum-menu-item-thumbnail-height: var(--spectrum-thumbnail-size-700); + --spectrum-menu-item-thumbnail-width: var(--spectrum-thumbnail-size-700); + --spectrum-menu-item-thumbnail-opacity-disabled: 0.3; + --spectrum-menu-back-icon-margin: var(--spectrum-navigational-indicator-top-to-back-icon-medium); /* "no" icon: just the chevron (we're not counting it because it HAS to be there for a collapsible) */ --spectrum-menu-item-collapsible-no-icon-submenu-item-padding-x-start: calc((var(--spectrum-menu-item-label-inline-edge-to-content) + var(--spectrum-menu-item-checkmark-width) + var(--spectrum-menu-item-label-text-to-visual) + var(--spectrum-menu-item-focus-indicator-width))); + /* Focus state styling */ + --spectrum-menu-item-focus-indicator-width: var(--mod-menu-item-focus-indicator-width, var(--spectrum-focus-indicator-thickness)); + --spectrum-menu-item-focus-indicator-color: var(--spectrum-focus-indicator-color); + --spectrum-menu-item-focus-indicator-offset: var(--spectrum-focus-indicator-gap); + --spectrum-menu-item-focus-indicator-outline-style: solid; --spectrum-menu-item-focus-indicator-color-default: var(--highcontrast-menu-item-focus-indicator-color, var(--mod-menu-item-focus-indicator-color, var(--spectrum-menu-item-focus-indicator-color))); - --spectrum-menu-item-focus-indicator-border-width: calc(var(--spectrum-menu-item-focus-indicator-width) * var(--spectrum-menu-item-focus-indicator-direction-scalar, 1)); + --spectrum-menu-item-focus-margin: calc(var(--spectrum-menu-item-focus-indicator-offset) + var(--spectrum-menu-item-focus-indicator-width)); &.spectrum-Menu--sizeS { --spectrum-menu-item-min-height: var(--spectrum-component-height-75); @@ -190,6 +137,8 @@ --spectrum-menu-item-top-edge-to-text: var(--spectrum-component-top-to-text-75); --spectrum-menu-item-bottom-edge-to-text: var(--spectrum-component-bottom-to-text-75); + --spectrum-menu-item-top-to-workflow-icon: var(--spectrum-component-top-to-workflow-icon-75); + --spectrum-menu-item-text-to-control: var(--spectrum-text-to-control-75); --spectrum-menu-item-description-font-size: var(--spectrum-font-size-50); @@ -197,12 +146,29 @@ --spectrum-menu-section-header-font-size: var(--spectrum-font-size-75); --spectrum-menu-section-header-min-width: var(--spectrum-component-height-75); + --spectrum-menu-section-description-font-size: var(--spectrum-font-size-50); + --spectrum-menu-section-header-to-description: var(--spectrum-menu-section-header-to-description-small); + --spectrum-menu-item-label-to-description: var(--spectrum-menu-item-label-to-description-small); + --spectrum-menu-item-selectable-edge-to-text-not-selected: var(--spectrum-menu-item-selectable-edge-to-text-not-selected-small); - --spectrum-menu-item-checkmark-height: var(--spectrum-menu-item-checkmark-height-small); - --spectrum-menu-item-checkmark-width: var(--spectrum-menu-item-checkmark-width-small); + --spectrum-menu-item-checkmark-height: var(--spectrum-checkmark-icon-size-75); + --spectrum-menu-item-checkmark-width: var(--spectrum-checkmark-icon-size-75); --spectrum-menu-item-top-to-checkmark: var(--spectrum-menu-item-top-to-selected-icon-small); + --spectrum-menu-item-chevron-height: var(--spectrum-chevron-icon-size-75); + --spectrum-menu-item-chevron-width: var(--spectrum-chevron-icon-size-75); + + --spectrum-menu-item-linkout-icon-height: var(--spectrum-link-out-icon-size-75); + --spectrum-menu-item-linkout-icon-width: var(--spectrum-link-out-icon-size-75); + + --spectrum-menu-item-corner-radius: var(--spectrum-corner-radius-400); + + --spectrum-menu-item-top-to-thumbnail: var(--spectrum-menu-item-top-to-thumbnail-small); + --spectrum-menu-item-thumbnail-to-label: var(--spectrum-text-to-visual-100); + --spectrum-menu-item-thumbnail-height: var(--spectrum-thumbnail-size-500); + --spectrum-menu-item-thumbnail-width: var(--spectrum-thumbnail-size-500); + --spectrum-menu-back-icon-margin: var(--spectrum-navigational-indicator-top-to-back-icon-small); } @@ -217,6 +183,8 @@ --spectrum-menu-item-top-edge-to-text: var(--spectrum-component-top-to-text-200); --spectrum-menu-item-bottom-edge-to-text: var(--spectrum-component-bottom-to-text-200); + --spectrum-menu-item-top-to-workflow-icon: var(--spectrum-component-top-to-workflow-icon-200); + --spectrum-menu-item-text-to-control: var(--spectrum-text-to-control-200); --spectrum-menu-item-description-font-size: var(--spectrum-font-size-100); @@ -224,12 +192,29 @@ --spectrum-menu-section-header-font-size: var(--spectrum-font-size-200); --spectrum-menu-section-header-min-width: var(--spectrum-component-height-200); + --spectrum-menu-section-description-font-size: var(--spectrum-font-size-100); + --spectrum-menu-section-header-to-description: var(--spectrum-menu-section-header-to-description-large); + --spectrum-menu-item-label-to-description: var(--spectrum-menu-item-label-to-description-large); + --spectrum-menu-item-selectable-edge-to-text-not-selected: var(--spectrum-menu-item-selectable-edge-to-text-not-selected-large); - --spectrum-menu-item-checkmark-height: var(--spectrum-menu-item-checkmark-height-large); - --spectrum-menu-item-checkmark-width: var(--spectrum-menu-item-checkmark-width-large); + --spectrum-menu-item-checkmark-height: var(--spectrum-checkmark-icon-size-200); + --spectrum-menu-item-checkmark-width: var(--spectrum-checkmark-icon-size-200); --spectrum-menu-item-top-to-checkmark: var(--spectrum-menu-item-top-to-selected-icon-large); + --spectrum-menu-item-chevron-height: var(--spectrum-chevron-icon-size-200); + --spectrum-menu-item-chevron-width: var(--spectrum-chevron-icon-size-200); + + --spectrum-menu-item-linkout-icon-height: var(--spectrum-link-out-icon-size-200); + --spectrum-menu-item-linkout-icon-width: var(--spectrum-link-out-icon-size-200); + + --spectrum-menu-item-corner-radius: var(--spectrum-corner-radius-600); + + --spectrum-menu-item-top-to-thumbnail: var(--spectrum-menu-item-top-to-thumbnail-large); + --spectrum-menu-item-thumbnail-to-label: var(--spectrum-text-to-visual-300); + --spectrum-menu-item-thumbnail-height: var(--spectrum-thumbnail-size-800); + --spectrum-menu-item-thumbnail-width: var(--spectrum-thumbnail-size-800); + --spectrum-menu-back-icon-margin: var(--spectrum-navigational-indicator-top-to-back-icon-large); } @@ -244,6 +229,8 @@ --spectrum-menu-item-top-edge-to-text: var(--spectrum-component-top-to-text-300); --spectrum-menu-item-bottom-edge-to-text: var(--spectrum-component-bottom-to-text-300); + --spectrum-menu-item-top-to-workflow-icon: var(--spectrum-component-top-to-workflow-icon-300); + --spectrum-menu-item-text-to-control: var(--spectrum-text-to-control-300); --spectrum-menu-item-description-font-size: var(--spectrum-font-size-200); @@ -251,17 +238,30 @@ --spectrum-menu-section-header-font-size: var(--spectrum-font-size-300); --spectrum-menu-section-header-min-width: var(--spectrum-component-height-300); + --spectrum-menu-section-description-font-size: var(--spectrum-font-size-200); + --spectrum-menu-section-header-to-description: var(--spectrum-menu-section-header-to-description-extra-large); + --spectrum-menu-item-label-to-description: var(--spectrum-menu-item-label-to-description-extra-large); + --spectrum-menu-item-selectable-edge-to-text-not-selected: var(--spectrum-menu-item-selectable-edge-to-text-not-selected-extra-large); - --spectrum-menu-item-checkmark-height: var(--spectrum-menu-item-checkmark-height-extra-large); - --spectrum-menu-item-checkmark-width: var(--spectrum-menu-item-checkmark-width-extra-large); + --spectrum-menu-item-checkmark-height: var(--spectrum-checkmark-icon-size-300); + --spectrum-menu-item-checkmark-width: var(--spectrum-checkmark-icon-size-300); --spectrum-menu-item-top-to-checkmark: var(--spectrum-menu-item-top-to-selected-icon-extra-large); - --spectrum-menu-back-icon-margin: var(--spectrum-navigational-indicator-top-to-back-icon-extra-large); - } + --spectrum-menu-item-chevron-height: var(--spectrum-chevron-icon-size-300); + --spectrum-menu-item-chevron-width: var(--spectrum-chevron-icon-size-300); + + --spectrum-menu-item-linkout-icon-height: var(--spectrum-link-out-icon-size-200); + --spectrum-menu-item-linkout-icon-width: var(--spectrum-link-out-icon-size-200); + + --spectrum-menu-item-corner-radius: var(--spectrum-corner-radius-700); - &:dir(rtl) { - --spectrum-menu-item-focus-indicator-direction-scalar: -1; + --spectrum-menu-item-top-to-thumbnail: var(--spectrum-menu-item-top-to-thumbnail-extra-large); + --spectrum-menu-item-thumbnail-to-label: var(--spectrum-text-to-visual-400); + --spectrum-menu-item-thumbnail-height: var(--spectrum-thumbnail-size-900); + --spectrum-menu-item-thumbnail-width: var(--spectrum-thumbnail-size-900); + + --spectrum-menu-back-icon-margin: var(--spectrum-navigational-indicator-top-to-back-icon-extra-large); } } @@ -280,6 +280,7 @@ --spectrum-menu-item-label-line-height: var(--mod-menu-item-label-line-height-cjk, var(--spectrum-menu-item-label-line-height-cjk)); --spectrum-menu-item-description-line-height: var(--mod-menu-item-description-line-height-cjk, var(--spectrum-menu-item-description-line-height-cjk)); --spectrum-menu-section-header-line-height: var(--mod-menu-section-header-line-height-cjk, var(--spectrum-menu-section-header-line-height-cjk)); + --spectrum-menu-section-description-line-height: var(--mod-menu-section-description-line-height-cjk, var(--spectrum-menu-section-description-line-height-cjk)); } /* Menus with "selectable" menu items. */ @@ -350,8 +351,8 @@ } .spectrum-Menu-chevron { - block-size: var(--spectrum-menu-item-checkmark-height); - inline-size: var(--spectrum-menu-item-checkmark-width); + block-size: var(--spectrum-menu-item-chevron-height); + inline-size: var(--spectrum-menu-item-chevron-width); /* Chevrons (aka collapsibles) have text or an icon directly next to them. */ margin-inline-end: var(--mod-menu-item-text-to-control, var(--spectrum-menu-item-text-to-control)); @@ -374,13 +375,30 @@ .spectrum-Menu-itemIcon--workflowIcon { /* Always provide space at the end of a workflow icon. */ margin-inline-end: var(--mod-menu-item-label-text-to-visual, var(--spectrum-menu-item-label-text-to-visual)); + margin-block-start: calc(var(--mod-menu-item-top-to-workflow-icon, var(--spectrum-menu-item-top-to-workflow-icon)) - var(--mod-menu-item-top-edge-to-text, var(--spectrum-menu-item-top-edge-to-text))); } - .spectrum-Menu-itemIcon:not(.spectrum-Menu-chevron, .spectrum-Menu-checkmark) { + .spectrum-Menu-itemIcon:not(.spectrum-Menu-chevron, .spectrum-Menu-checkmark, .spectrum-Menu-linkout) { block-size: var(--mod-menu-item-icon-height, var(--spectrum-menu-item-icon-height)); inline-size: var(--mod-menu-item-icon-width, var(--spectrum-menu-item-icon-width)); } + .spectrum-Menu-linkout { + block-size: var(--mod-menu-item-linkout-icon-height, var(--spectrum-menu-item-linkout-icon-height)); + inline-size: var(--mod-menu-item-linkout-icon-width, var(--spectrum-menu-item-linkout-icon-width)); + + /* Improve vertical alignment of linkout icon */ + /* TODO: revisit with #1194 when final icon available */ + display: block; + margin-block-start: calc(var(--mod-menu-item-label-font-size, var(--spectrum-menu-item-label-font-size)) - var(--spectrum-menu-item-linkout-icon-height)); + } + + /* Improve vertical alignment of linkout icon */ + /* TODO: revisit with #1194 when final icon available */ + .spectrum-Menu-item:has(> .spectrum-Menu-itemIcon--workflowIcon) .spectrum-Menu-linkout { + margin-block-start: calc(var(--mod-menu-item-label-font-size, var(--spectrum-menu-item-label-font-size)) - var(--mod-menu-item-icon-height, var(--spectrum-menu-item-icon-height) / 2)); + } + /* Presentational list items for sections and dividers. */ li:not(.spectrum-Menu-item, .spectrum-Menu-divider) { display: block; @@ -396,7 +414,7 @@ position: relative; align-items: center; - border-radius: var(--spectrum-menu-item-corner-radius); + border-radius: var(--mod-menu-item-corner-radius, var(--spectrum-menu-item-corner-radius)); box-sizing: border-box; @@ -410,20 +428,45 @@ padding-block-end: var(--mod-menu-item-bottom-edge-to-text, var(--spectrum-menu-item-bottom-edge-to-text)); padding-inline: var(--mod-menu-item-label-inline-edge-to-content, var(--spectrum-menu-item-label-inline-edge-to-content)); - margin: calc((var(--spectrum-menu-item-focus-indicator-offset) + var(--spectrum-menu-item-focus-indicator-width)) * var(--spectrum-menu-item-spacing-multiplier)); + margin: var(--spectrum-menu-item-focus-margin); text-decoration: none; display: grid; grid-template-areas: - ". chevronAreaCollapsible . headingIconArea sectionHeadingArea . . . " - "selectedArea chevronAreaCollapsible checkmarkArea iconArea labelArea valueArea actionsArea chevronAreaDrillIn" - ". . . . descriptionArea . . . " - ". . . . submenuArea . . . "; + ". chevronAreaCollapsible . headingIconArea sectionHeadingArea . . . " + "selectedArea chevronAreaCollapsible checkmarkArea iconArea labelArea valueArea actionsArea chevronAreaDrillIn" + "selectedOverflow . . visualOverflow descriptionArea . . . " + ". . . . submenuArea . . . "; grid-template-columns: auto auto auto auto 1fr auto auto auto; grid-template-rows: 1fr auto; + /* Alignment adjustments if there's a thumbnail */ + &:has(> .spectrum-Menu-itemThumbnail) { + > .spectrum-Menu-itemCheckbox, + > .spectrum-Menu-checkmark, + > .spectrum-Menu-itemActions, + > .spectrum-Menu-itemValue, + > .spectrum-Menu-itemLabel { + align-self: center; + margin-block-start: 0; + } + + &:has(> .spectrum-Menu-itemDescription) { + /* Reduces perceived visual margin between label and description */ + > .spectrum-Menu-itemDescription { + align-self: start; + } + + /* Allows visual centering against the thumbnail */ + > .spectrum-Menu-itemCheckbox, + > .spectrum-Menu-checkmark { + grid-row-end: selectedOverflow; + } + } + } + .spectrum-Menu-itemCheckbox { /* @passthrough start */ --mod-checkbox-top-to-text: 0; @@ -463,10 +506,9 @@ } } - &:focus, - &.is-focused { - background-color: var(--highcontrast-menu-item-background-color-focus, var(--mod-menu-item-background-color-key-focus, var(--spectrum-menu-item-background-color-key-focus))); - outline: none; + &:focus-visible, + &.is-focus-visible { + background-color: var(--highcontrast-menu-item-background-color-focus, var(--mod-menu-item-background-color-key-focus, var(--spectrum-menu-item-background-color-keyboard-focus))); > .spectrum-Menu-itemLabel { color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-label-content-color-focus, var(--spectrum-menu-item-label-content-color-focus))); @@ -484,7 +526,8 @@ color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-value-color-focus, var(--spectrum-menu-item-value-color-focus))); } - > .spectrum-Menu-itemIcon:not(.spectrum-Menu-chevron, .spectrum-Menu-checkmark) { + > .spectrum-Menu-itemIcon:not(.spectrum-Menu-chevron, .spectrum-Menu-checkmark), + .spectrum-Menu-linkout { fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-label-icon-color-focus, var(--spectrum-menu-item-label-icon-color-focus))); color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-label-icon-color-focus, var(--spectrum-menu-item-label-icon-color-focus))); } @@ -519,7 +562,8 @@ color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-value-color-hover, var(--spectrum-menu-item-value-color-hover))); } - > .spectrum-Menu-itemIcon:not(.spectrum-Menu-chevron, .spectrum-Menu-checkmark) { + > .spectrum-Menu-itemIcon:not(.spectrum-Menu-chevron, .spectrum-Menu-checkmark), + .spectrum-Menu-linkout { fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-label-icon-color-hover, var(--spectrum-menu-item-label-icon-color-hover))); color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-label-icon-color-hover, var(--spectrum-menu-item-label-icon-color-hover))); } @@ -538,6 +582,12 @@ &:active { background-color: var(--highcontrast-menu-item-background-color-focus, var(--mod-menu-item-background-color-down, var(--spectrum-menu-item-background-color-down))); + /* The perceived motion can be a bit jarring given the size/complexity of a menu item */ + @media (prefers-reduced-motion: no-preference) { + /* stylelint-disable-next-line spectrum-tools/no-unknown-custom-properties -- height and width are set by implementations */ + transform: perspective(max(var(--spectrum-downstate-height), var(--spectrum-downstate-width) * var(--spectrum-component-size-width-ratio-down))) translateZ(var(--spectrum-component-size-difference-down)); + } + > .spectrum-Menu-itemLabel { color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-label-content-color-down, var(--spectrum-menu-item-label-content-color-down))); } @@ -554,7 +604,8 @@ color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-value-color-down, var(--spectrum-menu-item-value-color-down))); } - > .spectrum-Menu-itemIcon:not(.spectrum-Menu-chevron, .spectrum-Menu-checkmark) { + > .spectrum-Menu-itemIcon:not(.spectrum-Menu-chevron, .spectrum-Menu-checkmark), + .spectrum-Menu-linkout { fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-label-icon-color-down, var(--spectrum-menu-item-label-icon-color-down))); color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-item-label-icon-color-down, var(--spectrum-menu-item-label-icon-color-down))); } @@ -573,8 +624,6 @@ /* Disabled menu items */ &.is-disabled, &[aria-disabled="true"] { - background-color: transparent; - .spectrum-Menu-itemLabel, .spectrum-Menu-sectionHeading, .spectrum-Menu-itemValue { @@ -590,6 +639,10 @@ fill: var(--highcontrast-menu-item-color-disabled, var(--mod-menu-item-label-icon-color-disabled, var(--spectrum-menu-item-label-icon-color-disabled))); } + .spectrum-Menu-itemThumbnail { + opacity: var(--mod-menu-item-thumbnail-opacity-disabled, var(--spectrum-menu-item-thumbnail-opacity-disabled)); + } + &:hover { cursor: default; background-color: transparent; @@ -614,10 +667,8 @@ .spectrum-Menu-item:focus-visible, .spectrum-Menu-back:focus-visible { - box-shadow: var(--spectrum-menu-item-focus-indicator-shadow) var(--spectrum-menu-item-focus-indicator-border-width) 0 0 0 var(--spectrum-menu-item-focus-indicator-color-default); outline: var(--spectrum-menu-item-focus-indicator-width) var(--spectrum-menu-item-focus-indicator-outline-style) var(--spectrum-menu-item-focus-indicator-color-default); outline-offset: var(--spectrum-menu-item-focus-indicator-offset); - border-radius: var(--spectrum-menu-item-corner-radius); } .spectrum-Menu-itemSelection { @@ -665,6 +716,18 @@ padding-block-start: var(--mod-menu-section-header-top-edge-to-text, var(--mod-menu-item-top-edge-to-text, var(--spectrum-menu-item-top-edge-to-text))); padding-block-end: var(--mod-menu-section-header-bottom-edge-to-text, var(--mod-menu-item-bottom-edge-to-text, var(--spectrum-menu-item-bottom-edge-to-text))); padding-inline: var(--mod-menu-item-label-inline-edge-to-content, var(--spectrum-menu-item-label-inline-edge-to-content)); + + /* Keep alignment with menu items */ + margin-inline: var(--spectrum-menu-item-focus-margin); +} + +.spectrum-Menu-sectionDescription { + display: block; + color: var(--mod-menu-section-description-color, var(--spectrum-menu-section-description-color)); + font-weight: var(--mod-menu-section-description-font-weight, var(--spectrum-menu-section-description-font-weight)); + line-height: var(--mod-menu-section-description-line-height, var(--spectrum-menu-section-description-line-height)); + font-size: var(--mod-menu-section-description-font-size, var(--spectrum-menu-section-description-font-size)); + margin-block-start: var(--mod-menu-section-header-to-description, var(--spectrum-menu-section-header-to-description)); } .spectrum-Menu-itemDescription { @@ -673,10 +736,25 @@ font-size: var(--mod-menu-item-description-font-size, var(--spectrum-menu-item-description-font-size)); hyphens: auto; overflow-wrap: break-word; - margin-block-start: var(--mod-menu-item-label-to-description-spacing, var(--spectrum-menu-item-label-to-description-spacing)); + margin-block-start: var(--mod-menu-item-label-to-description-spacing, var(--spectrum-menu-item-label-to-description)); line-height: var(--mod-menu-item-description-line-height, var(--spectrum-menu-item-description-line-height)); } +.spectrum-Menu-itemThumbnail { + grid-area: iconArea; + display: inline-block; + block-size: var(--mod-menu-item-thumbnail-height, var(--spectrum-menu-item-thumbnail-height)); + inline-size: var(--mod-menu-item-thumbnail-width, var(--spectrum-menu-item-thumbnail-width)); + margin-block-start: calc(var(--mod-menu-item-top-to-thumbnail, var(--spectrum-menu-item-top-to-thumbnail)) - var(--mod-menu-item-top-edge-to-text, var(--spectrum-menu-item-top-edge-to-text))); + margin-inline-end: var(--mod-menu-item-thumbnail-to-label, var(--spectrum-menu-item-thumbnail-to-label)); + + /* Span two rows to properly align to description when present */ + .spectrum-Menu-item:has(> &):has(> .spectrum-Menu-itemDescription) & { + grid-row-end: visualOverflow; + align-self: center; + } +} + .spectrum-Menu-itemLabel--truncate { text-overflow: ellipsis; white-space: nowrap; @@ -708,7 +786,7 @@ &.is-open:active, &.is-open:focus, &.is-open.is-focused { - background-color: var(--highcontrast-menu-item-background-color-default, var(--mod-menu-item-background-color-default, var(--spectrum-menu-item-background-color-default))); + background-color: transparent; } .spectrum-Menu-itemIcon { @@ -833,3 +911,65 @@ font-weight: var(--mod-menu-section-header-font-weight, var(--spectrum-menu-section-header-font-weight)); line-height: var(--mod-menu-section-header-line-height, var(--spectrum-menu-section-header-line-height)); } + +@media (forced-colors: active) { + .spectrum-Menu { + --highcontrast-menu-item-background-color-default: ButtonFace; + --highcontrast-menu-item-color-default: ButtonText; + + --highcontrast-menu-item-background-color-focus: Highlight; + --highcontrast-menu-item-color-focus: HighlightText; + + --highcontrast-menu-checkmark-icon-color-default: Highlight; + + --highcontrast-menu-item-color-disabled: GrayText; + --highcontrast-menu-item-focus-indicator-color: Highlight; + + --highcontrast-menu-item-selected-background-color: Highlight; + --highcontrast-menu-item-selected-color: HighlightText; + + @supports (color: SelectedItem) { + --highcontrast-menu-item-selected-background-color: SelectedItem; + --highcontrast-menu-item-selected-color: SelectedItemText; + } + + .spectrum-Menu-item { + /* Hide unstylable readability backplates. */ + forced-color-adjust: none; + } + + .spectrum-Menu-item:hover, + .spectrum-Menu-item:focus { + .spectrum-Menu-itemCheckbox { + /* @passthrough start */ + --highcontrast-checkbox-highlight-color-hover: ButtonText; + --highcontrast-checkbox-highlight-color-default: ButtonText; + /* @passthrough end */ + } + + .spectrum-Menu-itemSwitch { + /* @passthrough start */ + --highcontrast-switch-handle-border-color-hover: ButtonText; + --highcontrast-switch-handle-border-color-selected-default: ButtonText; + --highcontrast-switch-handle-border-color-selected-hover: ButtonText; + --highcontrast-switch-background-color-selected-default: ButtonText; + --highcontrast-switch-background-color-selected-hover: ButtonText; + /* @passthrough end */ + } + } + + .spectrum-Menu-item--drillIn.is-open { + --highcontrast-menu-item-background-color-default: var(--highcontrast-menu-item-selected-background-color); + --highcontrast-menu-item-color-default: var(--highcontrast-menu-item-selected-color); + } + + .spectrum-Menu-item--collapsible.is-open { + &:hover, + &:active, + &:focus, + &.is-focused { + --highcontrast-menu-item-color-focus: var(--highcontrast-menu-item-color-default); + } + } + } +} diff --git a/components/menu/stories/menu.stories.js b/components/menu/stories/menu.stories.js index 23f82bfd300..c7cb764d811 100644 --- a/components/menu/stories/menu.stories.js +++ b/components/menu/stories/menu.stories.js @@ -1,5 +1,5 @@ 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, isFocused, isHovered, isSelected, size } from "@spectrum-css/preview/types"; import metadata from "../dist/metadata.json"; @@ -86,9 +86,16 @@ export default { type: "figma", url: "https://www.figma.com/design/Mngz9H7WZLbrCvGQf3GnsY/S2-%2F-Desktop?node-id=37252-553", }, + downState: { + selectors: [".spectrum-Menu-item:not(.is-disabled)"], + }, packageJson, metadata, }, + decorators: [ + withDownStateDimensionCapture, + ], + tags: ["migrated"], }; export const Default = MenuWithVariants.bind({}); @@ -105,7 +112,7 @@ Default.args = { items: [ { label: "Default menu item", - iconName: "Export" + iconName: "Comment" }, { label: "Focused menu item", @@ -114,12 +121,24 @@ Default.args = { isActive: true, }, { - label: "A menu item with a longer label that causes the text to wrap to the next line", - iconName: "Send", + label: "A menu item with a longer label that causes the text to wrap to the next line" }, { label: "Menu item with no icon", }, + { + label: "Menu item as external link", + hasExternalLink: true, + }, + { + label: "Menu item as external link with icon", + hasExternalLink: true, + iconName: "Data" + }, + { + label: "Menu item with a thumbnail", + thumbnailUrl: "thumbnail.png" + }, { label: "Disabled menu item", iconName: "Share", @@ -131,6 +150,7 @@ Default.args = { { idx: 2, heading: "Menu header - With descriptions and icons", + sectionDescription: "This menu header also has a description", id: "menu-heading-short-desc", items: [ { @@ -142,6 +162,17 @@ Default.args = { description: "This item is checked if single-select or multi-select mode is turned on", isSelected: true, }, + { + label: "Selected item with thumbnail", + isSelected: true, + thumbnailUrl: "thumbnail.png" + }, + { + label: "Selected item with thumbnail", + description: "This item is checked if single-select or multi-select mode is turned on", + isSelected: true, + thumbnailUrl: "thumbnail.png" + }, { label: "Selected item with icon", iconName: "Cloud", @@ -153,7 +184,8 @@ Default.args = { { type: "divider" }, { idx: 3, - heading: "Menu header - With actions, icons, short descriptions, and values and longer header text that wraps", + heading: "Menu header - With actions, icons, thumbnails, short descriptions, and values and longer header text that wraps", + sectionDescription: "This menu header also has a description that is long enough to hopefully just maybe wrap if it's long enough", id: "menu-heading-desc-icon-value", hasActions: true, items: [ @@ -175,11 +207,33 @@ Default.args = { value: "⌘ C", }, { - label: "Disabled menu item with action", - iconName: "Archive", - description: "Disabled menu item with description and icon", + label: "Disabled menu item with thumbnail", + description: "Disabled menu item with description and thumbnail", isDisabled: true, + thumbnailUrl: "thumbnail.png", + }, + { + label: "Menu item with thumbnail and value", + value: "⌘ C", + thumbnailUrl: "thumbnail.png", + }, + { + label: "Menu item with thumbnail and value", + description: "And a description, too", + value: "⌘ C", + thumbnailUrl: "thumbnail.png", }, + { + label: "Menu item with external link action", + description: "Menu item with external link action (does not work in multi-select mode)", + hasExternalLink: true, + }, + { + label: "Disabled menu item with external link action", + description: "Menu item with external link action (does not work in multi-select mode)", + hasExternalLink: true, + isDisabled: true, + } ], }, { @@ -267,6 +321,11 @@ MenuItem.argTypes = { isSelected: { ...isSelected, description: "Used with single or multi-select mode turned on", + if: { arg: "selectionMode", neq: "none" }, + table: { + type: { summary: "boolean" }, + category: "Selection", + }, }, label: { name: "Label", @@ -296,7 +355,7 @@ MenuItem.argTypes = { }, iconName: { ...(IconStories?.argTypes?.iconName ?? {}), - if: false, + if: { arg: "hasThumbnail", truthy: false }, }, hasActions: { name: "Has switches", @@ -309,13 +368,43 @@ MenuItem.argTypes = { control: "boolean", if: { arg: "selectionMode", eq: "multiple" }, }, + hasExternalLink: { + name: "Has external link", + description: "Has external link action", + type: { name: "boolean" }, + table: { + type: { summary: "boolean" }, + category: "Content", + }, + control: "boolean", + }, + hasThumbnail: { + name: "Has thumbnail", + description: "Displays a thumbnail in the label", + type: { name: "boolean" }, + table: { + type: { summary: "boolean" }, + category: "Content", + }, + control: "boolean" + }, + isDrillIn: { + name: "Is drill-in", + description: "Displays drill-in menu indicator", + type: { name: "boolean" }, + table: { + type: { summary: "boolean" }, + category: "Content", + }, + control: "boolean" + }, // These settings are not used in the MenuItem story hasDividers: { table: { disable: true } }, isTraySubmenu: { table: { disable: true } }, }; MenuItem.args = { label: "Start a chat", - iconName: "Chat", + iconName: "Comment", description: "Menu item description", value: "⌘ N", isDisabled: false, @@ -324,6 +413,9 @@ MenuItem.args = { isHovered: false, isSelected: false, hasActions: false, + hasExternalLink: false, + hasThumbnail: false, + isDrillIn: false, }; MenuItem.parameters = { design: { @@ -353,7 +445,7 @@ Collapsible.args = { items: [ { label: "Web Design", - iconName: "DesktopAndMobile", + iconName: "DeviceMultiscreen", isCollapsible: true, isOpen: true, items: [ @@ -408,7 +500,7 @@ Collapsible.args = { }, { label: "Watches", - iconName: "Watch", + iconName: "Clock", isCollapsible: true, items: [ { label: "Defaults to not visible within closed item" }, @@ -463,6 +555,23 @@ Sizing.args = { description: "Short description of menu item", iconName: "Cloud", }, + { + idx: 6, + label: "Menu item as external link", + hasExternalLink: true + }, + { + idx: 7, + label: "Menu item with thumbnail", + value: "Value", + thumbnailUrl: "thumbnail.png" + }, + { + idx: 8, + label: "Menu item with thumbnail", + description: "and description", + thumbnailUrl: "thumbnail.png" + }, ] }; Sizing.parameters = { @@ -548,7 +657,7 @@ TextOverflow.parameters = { }; TextOverflow.args = { customStyles: { - "max-inline-size": "150px", + "max-inline-size": "175px", } }; @@ -578,7 +687,7 @@ WithDividers.args = { /** * Use a section header when a menu section requires a descriptor. Section headers are helpful when two or more - * sections differ in their functionality or relationships. + * sections differ in their functionality or relationships. Section headers can also include an optional description. */ export const WithDividersAndHeaders = Template.bind({}); WithDividersAndHeaders.storyName = "Sections with dividers and headers"; @@ -599,15 +708,15 @@ WithDividersAndHeaders.args = { { label: "Marquee", isSelected: true, - iconName: "Selection", + iconName: "SelectRectangle", }, { label: "Add", - iconName: "SelectAdd", + iconName: "SelectMulti", }, { label: "Subtract", - iconName: "SelectSubtract", + iconName: "SelectNone", }, ] }, @@ -615,12 +724,13 @@ WithDividersAndHeaders.args = { { idx: 2, heading: "Actions", + sectionDescription:"With an optional description", id: "menu-actions", selectionMode: "single", items: [ { label: "Deselect", - iconName: "Deselect", + iconName: "SelectNo", isDisabled: true, } ] diff --git a/components/menu/stories/menu.test.js b/components/menu/stories/menu.test.js index 9c4cc39382c..71165c3c568 100644 --- a/components/menu/stories/menu.test.js +++ b/components/menu/stories/menu.test.js @@ -35,7 +35,7 @@ export const MenuWithVariants = Variants({ items: [ { label: "Web Design", - iconName: "DesktopAndMobile", + iconName: "DeviceMultiscreen", iconSet: "workflow", isCollapsible: true, isOpen: true, @@ -89,7 +89,7 @@ export const MenuWithVariants = Variants({ }, { label: "Watches and longer truncated label that is really really much longer", - iconName: "Watch", + iconName: "Clock", iconSet: "workflow", isCollapsible: true, items: [{ label: "Defaults to not visible within closed item" }], @@ -116,6 +116,7 @@ export const MenuItemGroup = Variants({ { ...args, rootClass: "spectrum-Menu-item", + thumbnailUrl: (args.hasThumbnail && "thumbnail.png") || args.thumbnailUrl, }, context, )} @@ -129,9 +130,18 @@ export const MenuItemGroup = Variants({ testHeading: "No selection", description: undefined, }, + { + testHeading: "No selection, with thumbnails", + description: undefined, + thumbnailUrl: "thumbnail.png" + }, { testHeading: "No selection, with description", }, + { + testHeading: "No selection, with thumbnails, description", + thumbnailUrl: "thumbnail.png" + }, { testHeading: "Single selection: selected", description: undefined, @@ -139,6 +149,14 @@ export const MenuItemGroup = Variants({ selectionMode: "single", isSelected: true, }, + { + testHeading: "Single selection with thumbnails: selected", + description: undefined, + value: undefined, + selectionMode: "single", + isSelected: true, + thumbnailUrl: "thumbnail.png" + }, { testHeading: "Single selection: unselected", description: undefined, @@ -148,6 +166,16 @@ export const MenuItemGroup = Variants({ iconName: "Share", iconSet: "workflow", }, + { + testHeading: "Single selection with thumbnails: unselected", + description: undefined, + value: undefined, + selectionMode: "single", + label: "Share", + iconName: "Share", + iconSet: "workflow", + thumbnailUrl: "thumbnail.png" + }, { testHeading: "Multi-selection: selected", description: undefined, @@ -155,6 +183,14 @@ export const MenuItemGroup = Variants({ selectionMode: "multiple", isSelected: true, }, + { + testHeading: "Multi-selection with thumbnails: selected", + description: undefined, + value: undefined, + selectionMode: "multiple", + isSelected: true, + thumbnailUrl: "thumbnail.png" + }, { testHeading: "Multi-selection: unselected", selectionMode: "multiple", @@ -162,6 +198,14 @@ export const MenuItemGroup = Variants({ iconName: "Share", iconSet: "workflow", }, + { + testHeading: "Multi-selection with thumbnails: unselected", + selectionMode: "multiple", + label: "Share", + iconName: "Share", + iconSet: "workflow", + thumbnailUrl: "thumbnail.png" + }, { testHeading: "Multi-selection: unselected switches", selectionMode: "multiple", @@ -169,6 +213,14 @@ export const MenuItemGroup = Variants({ value: undefined, description: undefined, }, + { + testHeading: "Multi-selection with thumbnails: unselected switches", + selectionMode: "multiple", + hasActions: true, + value: undefined, + description: undefined, + thumbnailUrl: "thumbnail.png" + }, { testHeading: "Multi-selection: selected switches", selectionMode: "multiple", @@ -177,16 +229,37 @@ export const MenuItemGroup = Variants({ description: undefined, isSelected: true, }, + { + testHeading: "Multi-selection with thumbnails: selected switches", + selectionMode: "multiple", + hasActions: true, + value: undefined, + description: undefined, + isSelected: true, + thumbnailUrl: "thumbnail.png" + }, { testHeading: "Multi-selection: switches + labels", selectionMode: "multiple", hasActions: true, label: "Menu item", }, + { + testHeading: "Multi-selection with thumbnails: switches + labels", + selectionMode: "multiple", + hasActions: true, + label: "Menu item", + thumbnailUrl: "thumbnail.png" + }, { testHeading: "Drill-in", isDrillIn: true, }, + { + testHeading: "Drill-in with thumbnails", + isDrillIn: true, + thumbnailUrl: "thumbnail.png" + }, { testHeading: "Truncation", description: "Description will wrap", @@ -197,6 +270,17 @@ export const MenuItemGroup = Variants({ "inline-size": "150px", }, }, + { + testHeading: "Truncation with thumbnails", + description: "Description will wrap", + label: "Longer label will truncate", + shouldTruncate: true, + value: undefined, + customStyles: { + "inline-size": "175px", + }, + thumbnailUrl: "thumbnail.png" + }, { testHeading: "Text wrapping", description: "Description will wrap", @@ -205,6 +289,16 @@ export const MenuItemGroup = Variants({ customStyles: { "inline-size": "150px", }, + }, + { + testHeading: "Text wrapping with thumbnails", + description: "Description will wrap", + label: "Longer label will always wrap", + value: undefined, + customStyles: { + "inline-size": "175px", + }, + thumbnailUrl: "thumbnail.png" } ], stateData: [ @@ -232,11 +326,12 @@ export const MenuItemGroup = Variants({ { testHeading: "Without icon", iconName: undefined, + include: ["No selection", "No selection, with description", "Single selection: selected", "Single selection: unselected", "Multi-selection: selected", "Multi-selection: unselected", "Multi-selection: unselected switches", "Multi-selection: selected switches", "Multi-selection: switches + labels", "Drill-in", "Truncation", "Text wrapping"], }, { testHeading: "Without value", value: undefined, - include: ["No selection", "No selection, with description", "Multi-selection: unselected", "Multi-selection: switches + labels", "Drill-in"], + include: ["No selection", "No selection, with thumbnails", "No selection, with description", "No selection, with thumbnails, description", "Multi-selection: unselected", "Multi-selection with thumbnails: unselected", "Multi-selection: switches + labels", "Multi-selection with thumbnails: switches + labels", "Drill-in", "Drill-in with thumbnails"], }, { testHeading: "Without value or icon", @@ -247,13 +342,13 @@ export const MenuItemGroup = Variants({ { testHeading: "With value", value: "⌘ N", - include: ["Truncation", "Text wrapping"], + include: ["Truncation", "Truncation with thumbnails", "Text wrapping", "Text wrapping with thumbnails"], }, { testHeading: "With multi-select switch", selectionMode: "multiple", hasActions: true, - include: ["Truncation", "Text wrapping"], + include: ["Truncation", "Truncation with thumbnails", "Text wrapping", "Text wrapping with thumbnails"], }, { testHeading: "With value and multi-select switch", @@ -265,8 +360,26 @@ export const MenuItemGroup = Variants({ { testHeading: "Without description", description: undefined, - include: ["Drill-in", "Truncation", "Text wrapping"], + include: ["Drill-in", "Drill-in with thumbnails", "Truncation", "Truncation with thumbnails", "Text wrapping", "Text wrapping with thumbnails"], }, + { + testHeading: "External link", + hasExternalLink: true, + include: ["No selection", "No selection, with thumbnails", "No selection, with description", "No selection, with thumbnails, description", "Truncation", "Truncation with thumbnails", "Text wrapping", "Text wrapping with thumbnails"] + }, + { + testHeading: "External link without value", + hasExternalLink: true, + value: undefined, + include: ["No selection", "No selection, with thumbnails", "No selection, with description", "No selection, with thumbnails, description"] + }, + { + testHeading: "External link without value, icon", + hasExternalLink: true, + value: undefined, + iconName: undefined, + include: ["No selection", "No selection, with description", "Truncation", "Text wrapping"] + } // { // testHeading: "Highlighted", // isHighlighted: true, diff --git a/components/menu/stories/template.js b/components/menu/stories/template.js index 98b765fc520..d77847e629f 100644 --- a/components/menu/stories/template.js +++ b/components/menu/stories/template.js @@ -3,9 +3,11 @@ import { Template as Checkbox } from "@spectrum-css/checkbox/stories/template.js import { Template as Divider } from "@spectrum-css/divider/stories/template.js"; import { Template as Icon } from "@spectrum-css/icon/stories/template.js"; import { Template as Popover } from "@spectrum-css/popover/stories/template.js"; -import { Container, getRandomId } from "@spectrum-css/preview/decorators"; import { Template as Switch } from "@spectrum-css/switch/stories/template.js"; +import { Template as Thumbnail } from "@spectrum-css/thumbnail/stories/template.js"; import { Template as Tray } from "@spectrum-css/tray/stories/template.js"; + +import { Container, getRandomId } from "@spectrum-css/preview/decorators"; import { html } from "lit"; import { classMap } from "lit/directives/class-map.js"; import { ifDefined } from "lit/directives/if-defined.js"; @@ -14,13 +16,223 @@ import { when } from "lit/directives/when.js"; import "../index.css"; +/** + * Get icon name with scale number (defined in design spec). + */ +const iconWithScale = (size = "m", iconName = "ArrowLeft") => { + switch (size) { + case "s": + return `${iconName}75`; + case "l": + return `${iconName}200`; + case "xl": + return `${iconName}300`; + default: + return `${iconName}100`; + } +}; + +const Label = ({ + hasActions = false, + isCollapsible = false, + label, + rootClass, + shouldTruncate = false, +}) => { + if (isCollapsible) { + return html` + ${label} + `; + } + else { + return html` + ${label} + `; + } +}; + +const Visual = ({ + iconName, + iconSet, + rootClass, + size, + thumbnailUrl +}) => { + if (thumbnailUrl) { + return html` + ${Thumbnail({ + imageURL: thumbnailUrl, + altText: "Thumbnail alt text", + size, + customClasses: [`${rootClass}Thumbnail`], + })} + `; + } + else if (iconName) { + return html` + ${Icon({ + iconName, + setName: iconSet, + size, + customClasses: [ + `${rootClass}Icon`, + `${rootClass}Icon--workflowIcon` + ] + })} + `; + } + return; +}; + +const StartAction = ({ + hasActions, + idx, + isCollapsible, + isDisabled, + isSelected, + rootClass, + selectionMode, + size, + context +}) => { + if (isCollapsible || (selectionMode == "single" && isSelected)) { + return html` + ${Icon( + { + iconName: iconWithScale( + size, + isCollapsible ? "ChevronRight" : "Checkmark", + ), + setName: "ui", + useRef: false, + size, + customClasses: [ + `${rootClass}Icon`, + isCollapsible ? "spectrum-Menu-chevron" : "spectrum-Menu-checkmark", + ], + }, + context, + )} + `; + } + else if (selectionMode == "multiple" && !hasActions) { + return html` + ${Checkbox({ + size, + isChecked: isSelected, + isDisabled, + id: `menu-checkbox-${idx}`, + customClasses: [`${rootClass}Checkbox`], + }, + context)}`; + } + return null; +}; + +const EndAction = ({ + hasExternalLink, + hasActions, + idx, + isDisabled, + isDrillIn, + isSelected, + rootClass, + selectionMode, + size, + value, + context +}) => html` + ${when(value, () => html` + + ${value} + + `)} + + ${when( + hasActions && selectionMode == "multiple", + () => html` +