Skip to content

Commit

Permalink
fix(menu): focus indicator styles fixed for S2 (#3530)
Browse files Browse the repository at this point in the history
  • Loading branch information
castastrophe authored Jan 30, 2025
1 parent 6c19fcf commit 88bfc5b
Show file tree
Hide file tree
Showing 8 changed files with 99 additions and 64 deletions.
7 changes: 7 additions & 0 deletions .changeset/funny-pants-perform.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@spectrum-css/menu": patch
---

By adding additional system mappings for the menu item, we are able to support box-shadow styling for Spectrum 1 and Express, while updating to outline styles for Spectrum 2 (S2) foundations.

For S2 foundations, a margin is leveraged on the Menu item to leave space for the outline width and outline offset. This is reflected in the padding present for the menu items in the design specifications for S2.
17 changes: 13 additions & 4 deletions components/menu/dist/metadata.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
{
"sourceFile": "index.css",
"selectors": [
".is-selectableMultiple .spectrum-Menu-item",
".is-selectableMultiple .spectrum-Menu-itemCheckbox",
".js-focus-within .spectrum-Menu .spectrum-Menu-item--collapsible.is-open[focus-within]",
".spectrum-Menu",
".spectrum-Menu .spectrum-Menu-backIcon",
Expand Down Expand Up @@ -130,9 +128,10 @@
".spectrum-Menu-sectionHeading",
".spectrum-Menu.is-selectable .spectrum-Menu-item",
".spectrum-Menu.is-selectable .spectrum-Menu-item.is-selected",
".spectrum-Menu.is-selectableMultiple .spectrum-Menu-item",
".spectrum-Menu.is-selectableMultiple .spectrum-Menu-itemCheckbox",
".spectrum-Menu.js-focus-within .spectrum-Menu-item--collapsible.is-open[focus-within]",
".spectrum-Menu.spectrum-Menu--sizeL",
".spectrum-Menu.spectrum-Menu--sizeM",
".spectrum-Menu.spectrum-Menu--sizeS",
".spectrum-Menu.spectrum-Menu--sizeXL",
".spectrum-Menu:lang(ja)",
Expand Down Expand Up @@ -259,8 +258,13 @@
"--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-icon-height",
"--spectrum-menu-item-icon-width",
Expand Down Expand Up @@ -289,6 +293,7 @@
"--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-top-edge-to-text",
"--spectrum-menu-item-top-to-action",
Expand Down Expand Up @@ -379,7 +384,11 @@
"--system-menu-item-background-color-down",
"--system-menu-item-background-color-hover",
"--system-menu-item-background-color-key-focus",
"--system-menu-item-corner-radius"
"--system-menu-item-corner-radius",
"--system-menu-item-focus-indicator-offset",
"--system-menu-item-focus-indicator-outline-style",
"--system-menu-item-focus-indicator-shadow",
"--system-menu-item-spacing-multiplier"
],
"passthroughs": [
"--mod-checkbox-text-to-control",
Expand Down
111 changes: 55 additions & 56 deletions components/menu/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,37 @@
--spectrum-menu-checkmark-display-shown: block;
--spectrum-menu-checkmark-display: var(--spectrum-menu-checkmark-display-shown);

--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-label-font-size: var(--spectrum-font-size-100);
--spectrum-menu-item-label-text-to-visual: var(--spectrum-text-to-visual-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-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-checkmark-height: var(--spectrum-menu-item-checkmark-height-medium);
--spectrum-menu-item-checkmark-width: var(--spectrum-menu-item-checkmark-width-medium);
--spectrum-menu-item-top-to-checkmark: var(--spectrum-menu-item-top-to-selected-icon-medium);

--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)));

--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(--mod-menu-item-focus-indicator-width, var(--spectrum-menu-item-focus-indicator-width)) * var(--spectrum-menu-item-focus-indicator-direction-scalar, 1));

&.spectrum-Menu--sizeS {
--spectrum-menu-item-min-height: var(--spectrum-component-height-75);
--spectrum-menu-item-icon-height: var(--spectrum-workflow-icon-size-75);
Expand Down Expand Up @@ -168,34 +196,6 @@
--spectrum-menu-back-icon-margin: var(--spectrum-navigational-indicator-top-to-back-icon-small);
}

&,
&.spectrum-Menu--sizeM {
--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-label-font-size: var(--spectrum-font-size-100);
--spectrum-menu-item-label-text-to-visual: var(--spectrum-text-to-visual-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-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-checkmark-height: var(--spectrum-menu-item-checkmark-height-medium);
--spectrum-menu-item-checkmark-width: var(--spectrum-menu-item-checkmark-width-medium);
--spectrum-menu-item-top-to-checkmark: var(--spectrum-menu-item-top-to-selected-icon-medium);

--spectrum-menu-back-icon-margin: var(--spectrum-navigational-indicator-top-to-back-icon-medium);
}

&.spectrum-Menu--sizeL {
--spectrum-menu-item-min-height: var(--spectrum-component-height-200);
--spectrum-menu-item-icon-height: var(--spectrum-workflow-icon-size-200);
Expand Down Expand Up @@ -249,7 +249,9 @@

--spectrum-menu-back-icon-margin: var(--spectrum-navigational-indicator-top-to-back-icon-extra-large);
}
}

.spectrum-Menu {
display: inline-block;
inline-size: var(--mod-menu-inline-size, auto);
box-sizing: border-box;
Expand Down Expand Up @@ -283,6 +285,16 @@
}
}

&.is-selectableMultiple {
.spectrum-Menu-item {
align-items: start;
}

.spectrum-Menu-itemCheckbox {
grid-area: checkmarkArea;
}
}

.spectrum-Menu-divider {
--spectrum-menu-divider-thickness: var(--spectrum-divider-thickness-medium);

Expand Down Expand Up @@ -384,7 +396,7 @@
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: 0;
margin: calc((var(--spectrum-menu-item-focus-indicator-offset) + var(--spectrum-menu-item-focus-indicator-border-width)) * var(--spectrum-menu-item-spacing-multiplier));
text-decoration: none;

display: grid;
Expand Down Expand Up @@ -590,17 +602,10 @@

.spectrum-Menu-item:focus-visible,
.spectrum-Menu-back:focus-visible {
box-shadow: inset calc(var(--mod-menu-item-focus-indicator-width, var(--spectrum-menu-item-focus-indicator-width)) * var(--spectrum-menu-item-focus-indicator-direction-scalar, 1)) 0 0 0 var(--highcontrast-menu-item-focus-indicator-color, var(--mod-menu-item-focus-indicator-color, var(--spectrum-menu-item-focus-indicator-color)));
}

.is-selectableMultiple {
.spectrum-Menu-item {
align-items: start;
}

.spectrum-Menu-itemCheckbox {
grid-area: checkmarkArea;
}
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-border-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 {
Expand Down Expand Up @@ -765,26 +770,20 @@
}
}

&:hover {
.spectrum-Menu-chevron {
fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-drillin-icon-color-hover, var(--spectrum-menu-drillin-icon-color-hover)));
color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-drillin-icon-color-hover, var(--spectrum-menu-drillin-icon-color-hover)));
}
&:hover .spectrum-Menu-chevron {
fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-drillin-icon-color-hover, var(--spectrum-menu-drillin-icon-color-hover)));
color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-drillin-icon-color-hover, var(--spectrum-menu-drillin-icon-color-hover)));
}

&:focus,
&.is-focused {
.spectrum-Menu-chevron {
fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-drillin-icon-color-focus, var(--spectrum-menu-drillin-icon-color-focus)));
color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-drillin-icon-color-focus, var(--spectrum-menu-drillin-icon-color-focus)));
}
&:focus .spectrum-Menu-chevron,
&.is-focused .spectrum-Menu-chevron {
fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-drillin-icon-color-focus, var(--spectrum-menu-drillin-icon-color-focus)));
color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-drillin-icon-color-focus, var(--spectrum-menu-drillin-icon-color-focus)));
}

&:active {
.spectrum-Menu-chevron {
fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-drillin-icon-color-down, var(--spectrum-menu-drillin-icon-color-down)));
color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-drillin-icon-color-down, var(--spectrum-menu-drillin-icon-color-down)));
}
&:active .spectrum-Menu-chevron {
fill: var(--highcontrast-menu-item-color-focus, var(--mod-menu-drillin-icon-color-down, var(--spectrum-menu-drillin-icon-color-down)));
color: var(--highcontrast-menu-item-color-focus, var(--mod-menu-drillin-icon-color-down, var(--spectrum-menu-drillin-icon-color-down)));
}
}

Expand Down
6 changes: 4 additions & 2 deletions components/menu/stories/menu.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ Default.args = {
{
label: "Focused menu item",
iconName: "FolderOpen",
isFocused: true
isFocused: true,
isActive: true,
},
{
label: "A menu item with a longer label that causes the text to wrap to the next line",
Expand Down Expand Up @@ -248,7 +249,7 @@ TraySubmenu.parameters = {
docs: {
story: {
inline: false,
height: "400px"
height: "300px",
}
},
viewport: {
Expand Down Expand Up @@ -497,6 +498,7 @@ export const PopoverSubmenu = SubmenuInPopover.bind({});
PopoverSubmenu.storyName = "Submenu in popover";
PopoverSubmenu.tags = ["!dev"];
PopoverSubmenu.parameters = {
layout: "padded",
chromatic: { disableSnapshot: true },
};

Expand Down
5 changes: 5 additions & 0 deletions components/menu/stories/menu.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,11 @@ export const MenuItemGroup = Variants({
testHeading: "Focused",
isFocused: true,
},
{
testHeading: "Focused and active",
isFocused: true,
isActive: true,
},
{
testHeading: "Disabled",
isDisabled: true,
Expand Down
3 changes: 1 addition & 2 deletions components/menu/stories/template.js
Original file line number Diff line number Diff line change
Expand Up @@ -741,8 +741,7 @@ export const SubmenuInPopover = (context) => Popover({
isOpen: true,
position: "end-top",
customStyles: {
"--mod-popover-animation-distance": "-4px",
top: "-105px",
top: "-120px",
"inline-size": "120px",
},
content: [
Expand Down
7 changes: 7 additions & 0 deletions components/menu/themes/spectrum-two.css
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@
--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;
}
}
7 changes: 7 additions & 0 deletions components/menu/themes/spectrum.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@
--spectrum-menu-item-background-color-hover: rgba(var(--spectrum-gray-900-rgb), var(--spectrum-transparent-black-200-opacity));
--spectrum-menu-item-background-color-down: rgba(var(--spectrum-gray-900-rgb), var(--spectrum-transparent-black-200-opacity));
--spectrum-menu-item-background-color-key-focus: rgba(var(--spectrum-gray-900-rgb), var(--spectrum-transparent-black-200-opacity));

--spectrum-menu-item-corner-radius: 0;

/* Focus state styling */
--spectrum-menu-item-focus-indicator-shadow: inset;
--spectrum-menu-item-focus-indicator-offset: 0;
--spectrum-menu-item-spacing-multiplier: 0;
--spectrum-menu-item-focus-indicator-outline-style: none;
}
}

0 comments on commit 88bfc5b

Please sign in to comment.