From 8351f20999799bd4316fc5270c2759234266c110 Mon Sep 17 00:00:00 2001 From: Jeff Smith <37851214+eljefe223@users.noreply.github.com> Date: Mon, 17 May 2021 23:18:56 -0700 Subject: [PATCH] feat: add support for sub menus to menu (#18233) * feat: style menu for vNext * Change files * updated chnage file --- ...-497df4a8-736a-4c0e-bfed-ca69b00168aa.json | 7 + .../src/menu-item/menu-item.styles.ts | 117 +++++++-- .../src/menu/fixtures/menu.html | 242 ++++++++++++++++-- 3 files changed, 319 insertions(+), 47 deletions(-) create mode 100644 change/@fluentui-web-components-497df4a8-736a-4c0e-bfed-ca69b00168aa.json diff --git a/change/@fluentui-web-components-497df4a8-736a-4c0e-bfed-ca69b00168aa.json b/change/@fluentui-web-components-497df4a8-736a-4c0e-bfed-ca69b00168aa.json new file mode 100644 index 0000000000000..4e861f9478bea --- /dev/null +++ b/change/@fluentui-web-components-497df4a8-736a-4c0e-bfed-ca69b00168aa.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "add support for sub menus to menu", + "packageName": "@fluentui/web-components", + "email": "jes@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/web-components/src/menu-item/menu-item.styles.ts b/packages/web-components/src/menu-item/menu-item.styles.ts index 835c13fd2ac4a..05562dc7d6a8f 100644 --- a/packages/web-components/src/menu-item/menu-item.styles.ts +++ b/packages/web-components/src/menu-item/menu-item.styles.ts @@ -11,6 +11,7 @@ import { cornerRadius, outlineWidth, neutralFocus, + neutralForegroundHint, neutralFillStealthHover, neutralFillStealthActive, disabledOpacity, @@ -19,6 +20,9 @@ import { export const menuItemStyles = (context, definition) => css` ${display('grid')} :host { + contain: layout; + overflow: visible; + font-family: ${bodyFont}; outline: none; box-sizing: border-box; height: calc(${heightNumber} * 1px); @@ -29,17 +33,48 @@ export const menuItemStyles = (context, definition) => padding: 0; margin: 0 calc(${designUnit} * 1px); white-space: nowrap; - overflow: hidden; color: ${neutralForegroundRest}; fill: currentcolor; cursor: pointer; - font-family: ${bodyFont}; font-size: ${typeRampBaseFontSize}; line-height: ${typeRampBaseLineHeight}; border-radius: calc(${cornerRadius} * 1px); border: calc(${outlineWidth} * 1px) solid transparent; } + :host(.indent-0) { + grid-template-columns: auto 1fr minmax(42px, auto); + } + + :host(.indent-0) .content { + grid-column: 1; + grid-row: 1; + margin-inline-start: 10px; + } + + :host(.indent-2) { + grid-template-columns: minmax(42px, auto) minmax(42px, auto) 1fr minmax(42px, auto) minmax(42px, auto); + } + + :host(.indent-2) .content { + grid-column: 3; + grid-row: 1; + margin-inline-start: 10px; + } + + :host(.indent-2) .expand-collapse-glyph-container { + grid-column: 5; + grid-row: 1; + } + + :host(.indent-2) .start { + grid-column: 2; + } + + :host(.indent-2) .end { + grid-column: 4; + } + :host(:${focusVisible}) { border: calc(${outlineWidth} * 1px) solid ${neutralFocus}; box-shadow: 0 0 0 calc((${outlineWidth} - ${outlineWidth}) * 1px) ${neutralFocus}; @@ -49,18 +84,21 @@ export const menuItemStyles = (context, definition) => background: ${neutralFillStealthHover}; } - :host(:active) { + :host([aria-checked="true"]), + :host(:active), + :host(.expanded) { background: ${neutralFillStealthActive}; + color: ${neutralForegroundRest}; } - :host(.disabled) { + :host([disabled]) { cursor: ${disabledCursor}; opacity: ${disabledOpacity}; } - :host(.disabled:hover) .start, - :host(.disabled:hover) .end, - :host(.disabled:hover)::slotted(svg) { + :host([disabled]:hover) .start, + :host([disabled]:hover) .end, + :host([disabled]:hover)::slotted(svg) { fill: currentcolor; } @@ -72,7 +110,11 @@ export const menuItemStyles = (context, definition) => } .start, - .end, + .end { + display: flex; + justify-content: center; + } + ::slotted(svg) { ${ /* Glyph size and margin-left is temporary - @@ -91,41 +133,44 @@ export const menuItemStyles = (context, definition) => fill: ${neutralForegroundRest}; } - - :host([role="menuitemcheckbox"]), - :host([role="menuitemradio"]) { + :host(.indent-1[aria-haspopup="menu"]), + :host(.indent-1[role="menuitemcheckbox"]), + :host(.indent-1[role="menuitemradio"]) { display: grid; - grid-template-columns: auto auto 1fr minmax(42px, auto); + grid-template-columns: minmax(42px, auto) auto 1fr minmax(42px, auto) minmax(42px, auto); align-items: center; min-height: 32px; } - :host .input-container { + :host(.indent-2:not([aria-haspopup="menu"])) .end { + grid-column: 5; + } + + :host .input-container, + :host .expand-collapse-glyph-container { display: none; } + :host([aria-haspopup="menu"]) .expand-collapse-glyph-container, :host([role="menuitemcheckbox"]) .input-container, :host([role="menuitemradio"]) .input-container { display: grid; margin-inline-end: 10px; } - :host([role="menuitemcheckbox"]) .start, - :host([role="menuitemradio"]) .start { - grid-column-start: 2; - margin-inline-end: 10px; - } - + :host([aria-haspopup="menu"]) .content, :host([role="menuitemcheckbox"]) .content, :host([role="menuitemradio"]) .content { grid-column-start: 3; } + :host([aria-haspopup="menu"]) .end, :host([role="menuitemcheckbox"]) .end, :host([role="menuitemradio"]) .end { grid-column-start: 4; } + :host .expand-collapse, :host .checkbox, :host .radio { display: flex; @@ -135,11 +180,15 @@ export const menuItemStyles = (context, definition) => width: 20px; height: 20px; box-sizing: border-box; - border: calc(${outlineWidth} * 1px) solid ${neutralForegroundRest}; outline: none; margin-inline-start: 10px; } + :host .checkbox, + :host .radio { + border: calc(${outlineWidth} * 1px) solid ${neutralForegroundRest}; + } + :host .checkbox { border-radius: calc(${cornerRadius} * 1px); } @@ -155,6 +204,11 @@ export const menuItemStyles = (context, definition) => display: none; } + ::slotted([slot="end"]:not(svg)) { + margin-inline-end: 10px; + color: ${neutralForegroundHint} + } + :host([aria-checked="true"]) .checkbox-indicator, :host([aria-checked="true"]) ::slotted([slot="checkbox-indicator"]) { width: 100%; @@ -201,6 +255,13 @@ export const menuItemStyles = (context, definition) => :host(:active)::slotted(svg) { fill: ${SystemColors.HighlightText}; } + + :host(.expanded) { + background: ${SystemColors.Highlight}; + border-color: ${SystemColors.Highlight}; + color: ${SystemColors.HighlightText}; + } + :host(:${focusVisible}) { background: ${SystemColors.Highlight}; border-color: ${SystemColors.ButtonText}; @@ -208,19 +269,21 @@ export const menuItemStyles = (context, definition) => color: ${SystemColors.HighlightText}; fill: currentcolor; } - :host(.disabled), - :host(.disabled:hover), - :host(.disabled:hover) .start, - :host(.disabled:hover) .end, - :host(.disabled:hover)::slotted(svg) { + + :host([disabled]), + :host([disabled]:hover), + :host([disabled]:hover) .start, + :host([disabled]:hover) .end, + :host([disabled]:hover)::slotted(svg) { background: ${SystemColors.Canvas}; color: ${SystemColors.GrayText}; fill: currentcolor; opacity: 1; } + :host .expanded-toggle, :host .checkbox, - :host .radio{ + :host .radio { border-color: ${SystemColors.ButtonText}; background: ${SystemColors.HighlightText}; } @@ -231,8 +294,10 @@ export const menuItemStyles = (context, definition) => border-color: ${SystemColors.HighlightText}; } + :host(:hover) .expanded-toggle, :host(:hover) .checkbox, :host(:hover) .radio, + :host(:${focusVisible}) .expanded-toggle, :host(:${focusVisible}) .checkbox, :host(:${focusVisible}) .radio, :host([checked="true"]:hover) .checkbox, diff --git a/packages/web-components/src/menu/fixtures/menu.html b/packages/web-components/src/menu/fixtures/menu.html index 384d7b5ee36fe..5085fc9368e47 100644 --- a/packages/web-components/src/menu/fixtures/menu.html +++ b/packages/web-components/src/menu/fixtures/menu.html @@ -3,11 +3,81 @@

Default

Menu item 1 Menu item 2 - Menu item 3 Disabled - Menu item 4 + Menu item 3 + + Menu item 4 +
+ Shortcut text +
+
+
+ +

With start, end and nested submenus

+ + Menu item 1 + Menu item 2 + Menu item 3 + + + + + Menu item 4 + + + + + + + + Checkbox 1 + Nested Menu item 1.1 + Nested Menu item 1.2 + Nested Menu item 1.3 + + + + +

With start, end slot with text and nested submenus

+ + Menu item 1 + + Menu item 2 +
+ Shortcut text +
+
+ Menu item 3 + + + + + Menu item 4 +
+ Shortcut text +
+ + + + + Checkbox 1 + Nested Menu item 1.1 + Nested Menu item 1.2 + Nested Menu item 1.3 + +
-

With Separator

+

With seperator

Menu item 1 Menu item 2 @@ -28,7 +98,154 @@

With Separator

-

With radio buttons and checkboxes

+

With nested submenus

+ + + + + + Menu item 1 + + + + + + Menu item 2 + + + + + Checkbox 1 + Nested Menu item 1.1 + Nested Menu item 1.2 + Nested Menu item 1.3 + + + + + + + Menu item 3 +
+ Shortcut text +
+
+ + Menu item 4 + + + + + Nested Menu item 4.1 + Nested Menu item 4.2 + Nested Menu item 4.3 + + + + Menu item 5 + + + + + Checkbox 1 + + Nested Menu item 5.1 + + + + + Checkbox 1 + Nested Menu item 5.1.1 + Nested Menu item 5.1.2 + Nested Menu item 5.1.3 + + + + Nested Menu item 5.2 + + + + + Nested Menu item 5.2.1 + Nested Menu item 5.2.2 + Nested Menu item 5.2.3 + + + + Nested Menu item 5.3 + + + + + Nested Menu item 5.3.1 + Nested Menu item 5.3.2 + Nested Menu item 5.3.3 + + + + +
+ +

With standard elements

+ +
Menu item 1
+
Menu item 2
+
Menu item 3
+
+ +

With fluent buttons and anchors

+ + + Menu item 1 + + + Menu item 2 + + + Menu item 3 + + + Menu item 4 + + + +

With radio buttons and checkboxes

Menu item 1 Menu item 2 @@ -49,11 +266,6 @@

With radio buttons and checkboxes

Radio 2.1 - - - With radio buttons and checkboxes d="M6.5,7.7h-1v-1h1V7.7z M10.6,7.7h-1v-1h1V7.7z M14.7,6.7v2.1h-1v2.6c0,0.2,0,0.4-0.1,0.6c-0.1,0.2-0.2,0.4-0.3,0.5c-0.1,0.1-0.3,0.3-0.5,0.3c-0.2,0.1-0.4,0.1-0.6,0.1H10l-3.5,3v-3H3.9c-0.2,0-0.4,0-0.6-0.1c-0.2-0.1-0.4-0.2-0.5-0.3c-0.1-0.1-0.3-0.3-0.3-0.5c-0.1-0.2-0.1-0.4-0.1-0.6V8.8h-1V6.7h1V5.2c0-0.2,0-0.4,0.1-0.6c0.1-0.2,0.2-0.4,0.3-0.5c0.1-0.1,0.3-0.3,0.5-0.3c0.2-0.1,0.4-0.1,0.6-0.1h3.6V1.9C7.3,1.8,7.2,1.7,7.1,1.5C7,1.4,7,1.2,7,1C7,0.9,7,0.8,7,0.6c0.1-0.1,0.1-0.2,0.2-0.3c0.1-0.1,0.2-0.2,0.3-0.2C7.7,0,7.9,0,8,0c0.1,0,0.3,0,0.4,0.1c0.1,0.1,0.2,0.1,0.3,0.2C8.8,0.4,8.9,0.5,9,0.6C9,0.8,9,0.9,9,1c0,0.2,0,0.4-0.1,0.5C8.8,1.7,8.7,1.8,8.5,1.9v1.7h3.6c0.2,0,0.4,0,0.6,0.1c0.2,0.1,0.4,0.2,0.5,0.3c0.1,0.1,0.3,0.3,0.3,0.5c0.1,0.2,0.1,0.4,0.1,0.6v1.5H14.7z M12.6,5.2c0-0.1-0.1-0.3-0.2-0.4c-0.1-0.1-0.2-0.2-0.4-0.2H3.9c-0.1,0-0.3,0.1-0.4,0.2C3.4,4.9,3.4,5,3.4,5.2v6.2c0,0.1,0.1,0.3,0.2,0.4c0.1,0.1,0.2,0.2,0.4,0.2h3.6v1.8l2.1-1.8h2.5c0.1,0,0.3-0.1,0.4-0.2c0.1-0.1,0.2-0.2,0.2-0.4V5.2z M5.8,8.9c0.3,0.3,0.6,0.5,1,0.7C7.2,9.7,7.6,9.8,8,9.8s0.8-0.1,1.2-0.2c0.4-0.2,0.7-0.4,1-0.7l0.7,0.7c-0.4,0.4-0.8,0.7-1.4,0.9c-0.5,0.2-1,0.3-1.6,0.3s-1.1-0.1-1.6-0.3c-0.5-0.2-1-0.5-1.3-0.9L5.8,8.9z" /> - - -
- -

With standard elements

- -
Menu item 1
-
Menu item 2
-
Menu item 3
-