From 8364e81cc465d4eb4c6979a4d3a28284d05535b1 Mon Sep 17 00:00:00 2001 From: Jenn Diaz Date: Fri, 12 May 2023 16:33:19 -0600 Subject: [PATCH 01/47] chore(sidenav): initial build changes --- components/sidenav/gulpfile.js | 2 +- components/sidenav/package.json | 6 +- components/sidenav/skin.css | 84 -------------------------- components/sidenav/themes/express.css | 12 ++++ components/sidenav/themes/spectrum.css | 12 ++++ 5 files changed, 28 insertions(+), 88 deletions(-) delete mode 100644 components/sidenav/skin.css create mode 100644 components/sidenav/themes/express.css create mode 100644 components/sidenav/themes/spectrum.css diff --git a/components/sidenav/gulpfile.js b/components/sidenav/gulpfile.js index 79fce384ab1..f13104999f1 100644 --- a/components/sidenav/gulpfile.js +++ b/components/sidenav/gulpfile.js @@ -1 +1 @@ -module.exports = require("@spectrum-css/component-builder"); +module.exports = require('@spectrum-css/component-builder-simple'); diff --git a/components/sidenav/package.json b/components/sidenav/package.json index e827a74669b..59484e4cd93 100644 --- a/components/sidenav/package.json +++ b/components/sidenav/package.json @@ -18,12 +18,12 @@ "build": "gulp" }, "peerDependencies": { - "@spectrum-css/vars": ">=9" + "@spectrum-css/tokens": ">=10" }, "devDependencies": { - "@spectrum-css/component-builder": "^4.0.12", "@spectrum-css/icon": "^3.0.50", - "@spectrum-css/vars": "^9.0.8", + "@spectrum-css/component-builder-simple": "^2.0.15", + "@spectrum-css/tokens": "^10.0.0", "gulp": "^4.0.0" }, "publishConfig": { diff --git a/components/sidenav/skin.css b/components/sidenav/skin.css deleted file mode 100644 index f6389a930a2..00000000000 --- a/components/sidenav/skin.css +++ /dev/null @@ -1,84 +0,0 @@ -/*! -Copyright 2023 Adobe. All rights reserved. -This file is licensed to you under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. You may obtain a copy -of the License at http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software distributed under -the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS -OF ANY KIND, either express or implied. See the License for the specific language -governing permissions and limitations under the License. -*/ - -.spectrum-SideNav-item { - &.is-selected { - > .spectrum-SideNav-itemLink { - color: var(--spectrum-sidenav-item-text-color-selected); - background-color: var(--spectrum-sidenav-item-background-color-selected); - } - } - - .is-active { - > .spectrum-SideNav-itemLink { - background-color: var(--spectrum-sidenav-item-background-color-down); - } - } - - &.is-disabled { - /* Disable all children */ - .spectrum-SideNav-itemLink { - background-color: var(--spectrum-sidenav-item-background-color-disabled); - color: var(--spectrum-sidenav-item-text-color-disabled); - - cursor: default; - pointer-events: none; - } - } -} - -.spectrum-SideNav-itemLink { - background-color: var(--spectrum-sidenav-item-background-color); - color: var(--spectrum-sidenav-item-text-color); - - &:hover { - background-color: var(--spectrum-sidenav-item-background-color-hover); - color: var(--spectrum-sidenav-item-text-color-hover); - } - - &:active { - background-color: var(--spectrum-sidenav-item-background-color-down); - } - - &:focus-ring { - background-color: var(--spectrum-sidenav-item-background-color-key-focus); - color: var(--spectrum-sidenav-item-text-color-key-focus); - - &::before { - border-color: var(--spectrum-sidenav-item-border-color-key-focus); - } - } -} - -.spectrum-SideNav-heading { - color: var(--spectrum-sidenav-heading-text-color); -} - -@media (forced-colors: active) { - .spectrum-SideNav-item { - forced-color-adjust: none; - --spectrum-sidenav-item-text-color-selected: HighlightText; - --spectrum-sidenav-item-background-color-selected: Highlight; - --spectrum-sidenav-item-background-color-down: Highlight; - --spectrum-sidenav-item-background-color-disabled: ButtonFace; - --spectrum-sidenav-item-text-color-disabled: GrayText; - --spectrum-sidenav-item-background-color: ButtonFace; - --spectrum-sidenav-item-text-color: ButtonText; - --spectrum-sidenav-item-background-color-hover: ButtonFace; - --spectrum-sidenav-item-text-color-hover: ButtonText; - --spectrum-sidenav-item-background-color-down: ButtonFace; - --spectrum-sidenav-item-background-color-key-focus: ButtonFace; - --spectrum-sidenav-item-text-color-key-focus: ButtonText; - --spectrum-sidenav-item-border-color-key-focus: ButtonText; - --spectrum-sidenav-header-text-color: ButtonText; - } -} diff --git a/components/sidenav/themes/express.css b/components/sidenav/themes/express.css new file mode 100644 index 00000000000..78921ae6a63 --- /dev/null +++ b/components/sidenav/themes/express.css @@ -0,0 +1,12 @@ +/*! +Copyright 2023 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +@container (--system: express) {} diff --git a/components/sidenav/themes/spectrum.css b/components/sidenav/themes/spectrum.css new file mode 100644 index 00000000000..88cfca9b111 --- /dev/null +++ b/components/sidenav/themes/spectrum.css @@ -0,0 +1,12 @@ +/*! +Copyright 2023 Adobe. All rights reserved. +This file is licensed to you under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. You may obtain a copy +of the License at http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS +OF ANY KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. +*/ + +@container (--system: spectrum) {} From 203364c591c6a9b5e7f0cb180539f167536c553c Mon Sep 17 00:00:00 2001 From: Jenn Diaz Date: Fri, 12 May 2023 16:33:46 -0600 Subject: [PATCH 02/47] chore(sidenav)!: wip add new tokens --- components/sidenav/index.css | 138 +++++++++++++++++++++++++++++++---- 1 file changed, 125 insertions(+), 13 deletions(-) diff --git a/components/sidenav/index.css b/components/sidenav/index.css index ccb3a78690c..bc6515e3c40 100644 --- a/components/sidenav/index.css +++ b/components/sidenav/index.css @@ -11,7 +11,46 @@ governing permissions and limitations under the License. */ .spectrum-SideNav { - --spectrum-sidenav-item-padding-y: var(--spectrum-global-dimension-size-65); + /* layout */ + --spectrum-sidenav-min-height: var(--spectrum-component-height-100); + --spectrum-sidenav-width: var(--spectrum-side-navigation-width); + --spectrum-sidenav-min-width: var(--spectrum-side-navigation-minimum-width); + --spectrum-sidenav-max-width: var(--spectrum-side-navigation-maximum-width); + --spectrum-sidenav-border-radius: var(--spectrum-corner-radius-100); + --spectrum-sidenav-icon-size: var(--spectrum-workflow-icon-size-100); + --spectrum-sidenav-icon-spacing: var(--spectrum-text-to-visual-100); + --spectrum-sidenav-inline-padding: var(--spectrum-component-edge-to-text-100); + + /* color */ + --spectrum-sidenav-header-color: var(--spectrum-gray-900); + /* is spectrum-transparent an actual token??? */ + --spectrum-sidenav-disabled-color: var(--spectrum-transparent); + --spectrum-sidenav-label-and-icon-disabled-color: var(--spectrum-disabled-content-color); + --spectrum-sidenav-focus-indicator-color: var(--spectrum-focus-indicator-color); + --spectrum-sidenav-item-background-default: var(--spectrum-transparent); + --spectrum-sidenav-item-background-hover: var(--spectrum-gray-200); + --spectrum-sidenav-item-background-down: var(--spectrum-gray-300); + --spectrum-sidenav-item-background-key-focus: var(--spectrum-gray-200); + --spectrum-sidenav-item-background-default-selected: var(--spectrum-gray-200); + --spectrum-sidenav-item-background-hover-selected: var(--spectrum-gray-300); + --spectrum-sidenav-item-background-down-selected: var(--spectrum-gray-300); + --spectrum-sidenav-item-background-key-focus-selected: var(--spectrum-gray-200); + --spectrum-sidenav-label-and-icon-default: var(--spectrum-neutral-content-color-default); + --spectrum-sidenav-label-and-icon-hover: var(--spectrum-neutral-content-color-hover); + --spectrum-sidenav-label-and-icon-down: var(--spectrum-neutral-content-color-down); + --spectrum-sidenav-label-and-icon-key-focus: var(--spectrum-neutral-content-color-key-focus); + /* WHY ARE THESE THE SAME? --spectrum-sidenav-label-and-icon-default-selected: var(--spectrum-neutral-content-color-default); + --spectrum-sidenav-label-and-icon-hover-selected: var(--spectrum-neutral-content-color-hover); + --spectrum-sidenav-label-and-icon-down-selected: var(--spectrum-neutral-content-color-down); + --spectrum-sidenav-label-and-icon-key-focus-selected: var(--spectrum-neutral-content-color-key-focus); */ + + + + /* typography */ + --spectrum-sidenav-text-font-family: var(--spectrum-sans-serif-font-family); + --spectrum-sidenav-text-font-weight: var(--spectrum-regular-font-weight); + --spectrum-sidenav-text-font-style: var(--spectrum-default-font-style); + } .spectrum-SideNav { @@ -23,8 +62,32 @@ governing permissions and limitations under the License. .spectrum-SideNav-item { list-style-type: none; - margin-block: var(--spectrum-sidenav-item-gap); + margin-block: 4px; /* needs token */ margin-inline: 0; + + &.is-selected { + > .spectrum-SideNav-itemLink { + color: var(--spectrum-sidenav-item-text-color-selected); + background-color: var(--spectrum-sidenav-item-background-color-selected); + } + } + + .is-active { + > .spectrum-SideNav-itemLink { + background-color: var(--spectrum-sidenav-item-background-color-down); + } + } + + &.is-disabled { + /* Disable all children */ + .spectrum-SideNav-itemLink { + background-color: var(--spectrum-sidenav-item-background-color-disabled); + color: var(--spectrum-sidenav-item-text-color-disabled); + + cursor: default; + pointer-events: none; + } + } } .spectrum-SideNav-itemLink { @@ -34,17 +97,21 @@ governing permissions and limitations under the License. justify-content: start; box-sizing: border-box; - inline-size: 100%; - min-block-size: var(--spectrum-sidenav-item-height); + inline-size: var(--spectrum-sidenav-width); + min-inline-size: var(--spectrum-sidenav-min-width); + max-inline-size: var(--spectrum-sidenav-max-width); + min-block-size: var(--spectrum-sidenav-min-height); + + + padding-inline: var(--spectrum-sidenav-inline-padding); - padding-inline: var(--spectrum-sidenav-item-padding-x); - padding-block: var(--spectrum-sidenav-item-padding-y); + border-radius: var(--spectrum-sidenav-border-radius); - border-radius: var(--spectrum-sidenav-item-border-radius); + font-family: var(--spectrum-sidenav-text-font-family); font-size: var(--spectrum-sidenav-item-text-size); - font-weight: var(--spectrum-sidenav-item-text-font-weight); - font-style: normal; + font-weight: var(--spectrum-sidenav-text-font-weight); + font-style: var(--spectrum-sidenav-text-font-style); text-decoration: none; word-break: break-word; @@ -72,8 +139,30 @@ governing permissions and limitations under the License. } .spectrum-SideNav-itemIcon { + inline-size: var(--spectrum-sidenav-icon-size); + block-size: var(--spectrum-sidenav-icon-size); flex-shrink: 0; - margin-inline-end: var(--spectrum-sidenav-icon-gap); + margin-inline-end: var(--spectrum-sidenav-icon-spacing); + } + background-color: var(--spectrum-sidenav-item-background-color); + color: var(--spectrum-sidenav-item-text-color); + + &:hover { + background-color: var(--spectrum-sidenav-item-background-color-hover); + color: var(--spectrum-sidenav-item-text-color-hover); + } + + &:active { + background-color: var(--spectrum-sidenav-item-background-color-down); + } + + &:focus-ring { + background-color: var(--spectrum-sidenav-item-background-color-key-focus); + color: var(--spectrum-sidenav-item-text-color-key-focus); + + &::before { + border-color: var(--spectrum-sidenav-item-border-color-key-focus); + } } } @@ -90,6 +179,7 @@ governing permissions and limitations under the License. border-radius: var(--spectrum-sidenav-heading-border-radius); + color: var(--spectrum-sidenav-header-color); font-size: var(--spectrum-sidenav-heading-text-size); font-weight: var(--spectrum-sidenav-heading-text-font-weight); font-style: normal; @@ -110,19 +200,41 @@ governing permissions and limitations under the License. .spectrum-SideNav-itemLink { font-weight: var(--spectrum-sidenav-item-text-font-weight); + /* needs token var(--spectrum-sidenav-item-padding-x) */ padding-inline-start: calc( var(--spectrum-sidenav-multilevel-item-margin-left) + - var(--spectrum-sidenav-item-padding-x) + 12px ); } - + /* needs token var(--spectrum-sidenav-item-padding-x) */ .spectrum-SideNav { .spectrum-SideNav-itemLink { padding-inline-start: calc( var(--spectrum-sidenav-multilevel-item-margin-left) + - var(--spectrum-sidenav-item-padding-x) + 12px ); } } } } + +@media (forced-colors: active) { + .spectrum-SideNav-item { + forced-color-adjust: none; + --spectrum-sidenav-item-text-color-selected: HighlightText; + --spectrum-sidenav-item-background-color-selected: Highlight; + --spectrum-sidenav-item-background-color-down: Highlight; + --spectrum-sidenav-item-background-color-disabled: ButtonFace; + --spectrum-sidenav-item-text-color-disabled: GrayText; + --spectrum-sidenav-item-background-color: ButtonFace; + --spectrum-sidenav-item-text-color: ButtonText; + --spectrum-sidenav-item-background-color-hover: ButtonFace; + --spectrum-sidenav-item-text-color-hover: ButtonText; + --spectrum-sidenav-item-background-color-down: ButtonFace; + --spectrum-sidenav-item-background-color-key-focus: ButtonFace; + --spectrum-sidenav-item-text-color-key-focus: ButtonText; + --spectrum-sidenav-item-border-color-key-focus: ButtonText; + --spectrum-sidenav-header-text-color: ButtonText; + } +} + From d4381797939dae720bfc10a0d01d68aa12a5aec9 Mon Sep 17 00:00:00 2001 From: Jenn Diaz Date: Thu, 18 May 2023 16:42:17 -0600 Subject: [PATCH 03/47] chore(sidenav)!: wip migrate tokens --- components/sidenav/index.css | 86 +++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 41 deletions(-) diff --git a/components/sidenav/index.css b/components/sidenav/index.css index bc6515e3c40..33924a6d345 100644 --- a/components/sidenav/index.css +++ b/components/sidenav/index.css @@ -11,6 +11,7 @@ governing permissions and limitations under the License. */ .spectrum-SideNav { + --spectrum-sidenav-focus-ring-size: var(--spectrum-focus-indicator-thickness); /* layout */ --spectrum-sidenav-min-height: var(--spectrum-component-height-100); --spectrum-sidenav-width: var(--spectrum-side-navigation-width); @@ -23,11 +24,12 @@ governing permissions and limitations under the License. /* color */ --spectrum-sidenav-header-color: var(--spectrum-gray-900); + --spectrum-sidenav-item-text-color-selected: var(--spectrum-gray-200); /* is spectrum-transparent an actual token??? */ - --spectrum-sidenav-disabled-color: var(--spectrum-transparent); + /* --spectrum-sidenav-disabled-color: transparent; --spectrum-sidenav-label-and-icon-disabled-color: var(--spectrum-disabled-content-color); --spectrum-sidenav-focus-indicator-color: var(--spectrum-focus-indicator-color); - --spectrum-sidenav-item-background-default: var(--spectrum-transparent); + --spectrum-sidenav-item-background-default: transparent; --spectrum-sidenav-item-background-hover: var(--spectrum-gray-200); --spectrum-sidenav-item-background-down: var(--spectrum-gray-300); --spectrum-sidenav-item-background-key-focus: var(--spectrum-gray-200); @@ -38,7 +40,7 @@ governing permissions and limitations under the License. --spectrum-sidenav-label-and-icon-default: var(--spectrum-neutral-content-color-default); --spectrum-sidenav-label-and-icon-hover: var(--spectrum-neutral-content-color-hover); --spectrum-sidenav-label-and-icon-down: var(--spectrum-neutral-content-color-down); - --spectrum-sidenav-label-and-icon-key-focus: var(--spectrum-neutral-content-color-key-focus); + --spectrum-sidenav-label-and-icon-key-focus: var(--spectrum-neutral-content-color-key-focus); */ /* WHY ARE THESE THE SAME? --spectrum-sidenav-label-and-icon-default-selected: var(--spectrum-neutral-content-color-default); --spectrum-sidenav-label-and-icon-hover-selected: var(--spectrum-neutral-content-color-hover); --spectrum-sidenav-label-and-icon-down-selected: var(--spectrum-neutral-content-color-down); @@ -47,10 +49,13 @@ governing permissions and limitations under the License. /* typography */ - --spectrum-sidenav-text-font-family: var(--spectrum-sans-serif-font-family); + --spectrum-sidenav-text-font-family: var(--spectrum-sans-serif-font-family-stack); --spectrum-sidenav-text-font-weight: var(--spectrum-regular-font-weight); --spectrum-sidenav-text-font-style: var(--spectrum-default-font-style); + --spectrum-sidenav-medium-font-size: var(--spectrum-font-size-200); + --spectrum-sidenav-header-line-height: var(--spectrum-line-height-100); /* ToDo */ + /* --spectrum-sidenav-header-medium-font-size: var(--spectrum-font-size-200); */ } .spectrum-SideNav { @@ -68,21 +73,21 @@ governing permissions and limitations under the License. &.is-selected { > .spectrum-SideNav-itemLink { color: var(--spectrum-sidenav-item-text-color-selected); - background-color: var(--spectrum-sidenav-item-background-color-selected); + background-color: var(--spectrum-gray-900); /* needs token */ } } - .is-active { + /* .is-active { > .spectrum-SideNav-itemLink { background-color: var(--spectrum-sidenav-item-background-color-down); } - } + } */ &.is-disabled { /* Disable all children */ .spectrum-SideNav-itemLink { - background-color: var(--spectrum-sidenav-item-background-color-disabled); - color: var(--spectrum-sidenav-item-text-color-disabled); + background-color: transparent; /* needs token */ + color: var(--spectrum-gray-500); /* needs token */ cursor: default; pointer-events: none; @@ -109,7 +114,7 @@ governing permissions and limitations under the License. font-family: var(--spectrum-sidenav-text-font-family); - font-size: var(--spectrum-sidenav-item-text-size); + font-size: var(--spectrum-sidenav-medium-font-size); font-weight: var(--spectrum-sidenav-text-font-weight); font-style: var(--spectrum-sidenav-text-font-style); text-decoration: none; @@ -119,8 +124,8 @@ governing permissions and limitations under the License. cursor: pointer; - transition: background-color var(--spectrum-global-animation-duration-100) ease-out, - color var(--spectrum-global-animation-duration-100) ease-out; + transition: background-color var(--spectrum-animation-duration-100) ease-out, + color var(--spectrum-animation-duration-100) ease-out; &:focus { outline: none; @@ -132,10 +137,10 @@ governing permissions and limitations under the License. inset: 0; pointer-events: none; - border: var(--spectrum-alias-focus-ring-size) solid transparent; - border-radius: var(--spectrum-sidenav-item-border-radius); + border: var(--spectrum-sidenav-focus-ring-size) solid transparent; + /* border-radius: var(--spectrum-sidenav-item-border-radius); */ - transition: border var(--spectrum-global-animation-duration-100) ease-out; + transition: border var(--spectrum-animation-duration-100) ease-out; } .spectrum-SideNav-itemIcon { @@ -144,53 +149,52 @@ governing permissions and limitations under the License. flex-shrink: 0; margin-inline-end: var(--spectrum-sidenav-icon-spacing); } - background-color: var(--spectrum-sidenav-item-background-color); - color: var(--spectrum-sidenav-item-text-color); + background-color: transparent; /* needs token */ + color: var(--spectrum-gray-800); /* needs token */ &:hover { - background-color: var(--spectrum-sidenav-item-background-color-hover); - color: var(--spectrum-sidenav-item-text-color-hover); + background-color: rgba(255,255,255,0.07); /* needs token */ + color: var(--spectrum-gray-900); /* needs token */ } - &:active { + /* &:active { background-color: var(--spectrum-sidenav-item-background-color-down); - } + } */ &:focus-ring { - background-color: var(--spectrum-sidenav-item-background-color-key-focus); - color: var(--spectrum-sidenav-item-text-color-key-focus); + /* background-color: var(--spectrum-sidenav-item-background-color-key-focus); */ + /* color: var(--spectrum-sidenav-item-text-color-key-focus); */ &::before { - border-color: var(--spectrum-sidenav-item-border-color-key-focus); + /* border-color: var(--spectrum-sidenav-item-border-color-key-focus); */ } } } .spectrum-SideNav-heading { - block-size: var(--spectrum-sidenav-heading-height); - line-height: var(--spectrum-sidenav-heading-height); + line-height: var(--spectrum-sidenav-header-line-height:); - margin-block-start: var(--spectrum-sidenav-heading-gap-top); + margin-block-start: 16px; /* needs tokens var(--spectrum-sidenav-heading-gap-top); */ margin-inline-end: 0; - margin-block-end: var(--spectrum-sidenav-heading-gap-bottom); + margin-block-end: 4px; /* needs token var(--spectrum-sidenav-heading-gap-bottom); */ margin-inline-start: 0; padding-block: 0; - padding-inline: var(--spectrum-sidenav-heading-padding-x); + padding-inline: 12px; /* needs token var(--spectrum-sidenav-heading-padding-x); */ - border-radius: var(--spectrum-sidenav-heading-border-radius); + border-radius: 4px; /* needs token var(--spectrum-sidenav-heading-border-radius); */ color: var(--spectrum-sidenav-header-color); - font-size: var(--spectrum-sidenav-heading-text-size); - font-weight: var(--spectrum-sidenav-heading-text-font-weight); + font-size: 11px; /* needs token var(--spectrum-sidenav-heading-text-size); */ + font-weight: 500; /* needs token var(--spectrum-sidenav-heading-text-font-weight); */ font-style: normal; - letter-spacing: var(--spectrum-sidenav-heading-text-letter-spacing); + letter-spacing: 0.06em; /* needs token var(--spectrum-sidenav-heading-text-letter-spacing); */ text-transform: uppercase; } .spectrum-SideNav--multiLevel { .spectrum-SideNav-itemLink { - font-weight: var(--spectrum-sidenav-multilevel-main-item-font-weight); + font-weight: 700; /* tokens needed var(--spectrum-sidenav-multilevel-main-item-font-weight); */ } .spectrum-SideNav { @@ -198,19 +202,19 @@ governing permissions and limitations under the License. padding: 0; .spectrum-SideNav-itemLink { - font-weight: var(--spectrum-sidenav-item-text-font-weight); + font-weight: 400; /* needs token var(--spectrum-sidenav-item-text-font-weight); */ /* needs token var(--spectrum-sidenav-item-padding-x) */ - padding-inline-start: calc( - var(--spectrum-sidenav-multilevel-item-margin-left) + + padding-inline-start: /* needs token */ calc( + 12px + 12px ); } /* needs token var(--spectrum-sidenav-item-padding-x) */ .spectrum-SideNav { .spectrum-SideNav-itemLink { - padding-inline-start: calc( - var(--spectrum-sidenav-multilevel-item-margin-left) + + padding-inline-start: /* needs token */ calc( + 12px + 12px ); } @@ -221,7 +225,7 @@ governing permissions and limitations under the License. @media (forced-colors: active) { .spectrum-SideNav-item { forced-color-adjust: none; - --spectrum-sidenav-item-text-color-selected: HighlightText; + /* --spectrum-sidenav-item-text-color-selected: HighlightText; --spectrum-sidenav-item-background-color-selected: Highlight; --spectrum-sidenav-item-background-color-down: Highlight; --spectrum-sidenav-item-background-color-disabled: ButtonFace; @@ -234,7 +238,7 @@ governing permissions and limitations under the License. --spectrum-sidenav-item-background-color-key-focus: ButtonFace; --spectrum-sidenav-item-text-color-key-focus: ButtonText; --spectrum-sidenav-item-border-color-key-focus: ButtonText; - --spectrum-sidenav-header-text-color: ButtonText; + --spectrum-sidenav-header-text-color: ButtonText; */ } } From 29cd2105e4b56a3293bad6bb513f1f7c2aa8ba8a Mon Sep 17 00:00:00 2001 From: Jenn Diaz Date: Fri, 19 May 2023 16:32:56 -0600 Subject: [PATCH 04/47] chore(sidenav)!: wip migrate tokens --- components/sidenav/index.css | 119 ++++++++++++++---------- components/sidenav/metadata/sidenav.yml | 8 +- 2 files changed, 75 insertions(+), 52 deletions(-) diff --git a/components/sidenav/index.css b/components/sidenav/index.css index 33924a6d345..22b0e51f3aa 100644 --- a/components/sidenav/index.css +++ b/components/sidenav/index.css @@ -12,6 +12,7 @@ governing permissions and limitations under the License. .spectrum-SideNav { --spectrum-sidenav-focus-ring-size: var(--spectrum-focus-indicator-thickness); + --spectrum-sidenav-focus-ring-gap: var(--spectrum-focus-indicator-gap); /* layout */ --spectrum-sidenav-min-height: var(--spectrum-component-height-100); --spectrum-sidenav-width: var(--spectrum-side-navigation-width); @@ -21,27 +22,36 @@ governing permissions and limitations under the License. --spectrum-sidenav-icon-size: var(--spectrum-workflow-icon-size-100); --spectrum-sidenav-icon-spacing: var(--spectrum-text-to-visual-100); --spectrum-sidenav-inline-padding: var(--spectrum-component-edge-to-text-100); + --spectrum-sidenav-gap: var(--spectrum-side-navigation-item-to-item); + --spectrum-sidenav-top-to-icon: var(--spectrum-component-top-to-workflow-icon-100); + + --spectrum-sidenav-start-to-content-second-level: var(--spectrum-side-navigation-second-level-edge-to-text); + --spectrum-sidenav-start-to-content-third-level: var(--spectrum-side-navigation-third-level-edge-to-text); /* color */ + --spectrum-sidenav-focus-ring-color: var(--spectrum-focus-indicator-color); --spectrum-sidenav-header-color: var(--spectrum-gray-900); - --spectrum-sidenav-item-text-color-selected: var(--spectrum-gray-200); + /* --spectrum-sidenav-item-text-color-selected: var(--spectrum-gray-200); */ /* is spectrum-transparent an actual token??? */ - /* --spectrum-sidenav-disabled-color: transparent; + /* --spectrum-sidenav-disabled-color: transparent; */ --spectrum-sidenav-label-and-icon-disabled-color: var(--spectrum-disabled-content-color); - --spectrum-sidenav-focus-indicator-color: var(--spectrum-focus-indicator-color); - --spectrum-sidenav-item-background-default: transparent; + /* + --spectrum-sidenav-item-background-default: transparent; */ --spectrum-sidenav-item-background-hover: var(--spectrum-gray-200); --spectrum-sidenav-item-background-down: var(--spectrum-gray-300); - --spectrum-sidenav-item-background-key-focus: var(--spectrum-gray-200); + /* --spectrum-sidenav-item-background-key-focus: var(--spectrum-gray-200); */ --spectrum-sidenav-item-background-default-selected: var(--spectrum-gray-200); - --spectrum-sidenav-item-background-hover-selected: var(--spectrum-gray-300); + /* --spectrum-sidenav-item-background-hover-selected: var(--spectrum-gray-300); + --spectrum-sidenav-item-background-down-selected: var(--spectrum-gray-300); - --spectrum-sidenav-item-background-key-focus-selected: var(--spectrum-gray-200); - --spectrum-sidenav-label-and-icon-default: var(--spectrum-neutral-content-color-default); - --spectrum-sidenav-label-and-icon-hover: var(--spectrum-neutral-content-color-hover); - --spectrum-sidenav-label-and-icon-down: var(--spectrum-neutral-content-color-down); - --spectrum-sidenav-label-and-icon-key-focus: var(--spectrum-neutral-content-color-key-focus); */ - /* WHY ARE THESE THE SAME? --spectrum-sidenav-label-and-icon-default-selected: var(--spectrum-neutral-content-color-default); + --spectrum-sidenav-item-background-key-focus-selected: var(--spectrum-gray-200); */ + --spectrum-sidenav-content-color-default: var(--spectrum-neutral-content-color-default); + --spectrum-sidenav-content-hover: var(--spectrum-neutral-content-color-hover); + --spectrum-sidenav-content-down: var(--spectrum-neutral-content-color-down); + /* --spectrum-sidenav-label-and-icon-key-focus: var(--spectrum-neutral-content-color-key-focus); */ + /* WHY ARE THESE THE SAME? */ + + /*--spectrum-sidenav-content-default-selected: var(--spectrum-neutral-content-color-default); --spectrum-sidenav-label-and-icon-hover-selected: var(--spectrum-neutral-content-color-hover); --spectrum-sidenav-label-and-icon-down-selected: var(--spectrum-neutral-content-color-down); --spectrum-sidenav-label-and-icon-key-focus-selected: var(--spectrum-neutral-content-color-key-focus); */ @@ -49,16 +59,21 @@ governing permissions and limitations under the License. /* typography */ - --spectrum-sidenav-text-font-family: var(--spectrum-sans-serif-font-family-stack); + --spectrum-sidenav-text-font-family: var(--spectrum-sans-font-family-stack); --spectrum-sidenav-text-font-weight: var(--spectrum-regular-font-weight); --spectrum-sidenav-text-font-style: var(--spectrum-default-font-style); --spectrum-sidenav-medium-font-size: var(--spectrum-font-size-200); + --spectrum-sidenav-lineheight: var(--spectrum-line-height-100); + --spectrum-sidenav-header-font-color: var(--spectrum-gray-900); --spectrum-sidenav-header-line-height: var(--spectrum-line-height-100); /* ToDo */ /* --spectrum-sidenav-header-medium-font-size: var(--spectrum-font-size-200); */ } .spectrum-SideNav { + display: flex; + flex-direction: column; + gap: var(--spectrum-sidenav-gap); list-style-type: none; margin: 0; padding: 0; @@ -66,28 +81,28 @@ governing permissions and limitations under the License. .spectrum-SideNav-item { list-style-type: none; - - margin-block: 4px; /* needs token */ margin-inline: 0; &.is-selected { > .spectrum-SideNav-itemLink { - color: var(--spectrum-sidenav-item-text-color-selected); - background-color: var(--spectrum-gray-900); /* needs token */ + color: var(--spectrum-sidenav-content-color-default); + background-color: var(--spectrum-sidenav-item-background-default-selected); /* needs token */ } } - /* .is-active { + &:active, + &.is-active { > .spectrum-SideNav-itemLink { - background-color: var(--spectrum-sidenav-item-background-color-down); + background-color: var(--spectrum-sidenav-item-background-down); + color: var(--spectrum-sidenav-content-down); } - } */ + } &.is-disabled { /* Disable all children */ .spectrum-SideNav-itemLink { background-color: transparent; /* needs token */ - color: var(--spectrum-gray-500); /* needs token */ + color: var(--spectrum-sidenav-label-and-icon-disabled-color); /* needs token */ cursor: default; pointer-events: none; @@ -98,17 +113,21 @@ governing permissions and limitations under the License. .spectrum-SideNav-itemLink { position: relative; display: inline-flex; - align-items: center; + /* align-items: center; */ justify-content: start; box-sizing: border-box; + background-color: transparent; /* needs token */ + color: var(--spectrum-sidenav-content-color-default); /* needs token */ + inline-size: var(--spectrum-sidenav-width); min-inline-size: var(--spectrum-sidenav-min-width); max-inline-size: var(--spectrum-sidenav-max-width); min-block-size: var(--spectrum-sidenav-min-height); - padding-inline: var(--spectrum-sidenav-inline-padding); + padding-inline-start: var(--spectrum-sidenav-inline-padding); + padding-inline-end: var(--spectrum-sidenav-inline-padding); border-radius: var(--spectrum-sidenav-border-radius); @@ -118,6 +137,14 @@ governing permissions and limitations under the License. font-weight: var(--spectrum-sidenav-text-font-weight); font-style: var(--spectrum-sidenav-text-font-style); text-decoration: none; + line-height: var(--spectrum-sidenav-lineheight); + + /* cjk language support for item counter */ + &:lang(ja), + &:lang(zh), + &:lang(ko) { + --spectrum-sidenav-lineheight: var(--spectrum-cjk-line-height-100); + } word-break: break-word; hyphens: auto; @@ -127,10 +154,6 @@ governing permissions and limitations under the License. transition: background-color var(--spectrum-animation-duration-100) ease-out, color var(--spectrum-animation-duration-100) ease-out; - &:focus { - outline: none; - } - &:before { content: ''; position: absolute; @@ -148,22 +171,24 @@ governing permissions and limitations under the License. block-size: var(--spectrum-sidenav-icon-size); flex-shrink: 0; margin-inline-end: var(--spectrum-sidenav-icon-spacing); + margin-block-start: var(--spectrum-sidenav-top-to-icon); } - background-color: transparent; /* needs token */ - color: var(--spectrum-gray-800); /* needs token */ + &:hover { - background-color: rgba(255,255,255,0.07); /* needs token */ - color: var(--spectrum-gray-900); /* needs token */ + background-color: var(--spectrum-sidenav-item-background-hover); /* needs token */ + color: var(--spectrum-sidenav-content-hover); /* needs token */ } - /* &:active { - background-color: var(--spectrum-sidenav-item-background-color-down); - } */ + /* &.is-active */ - &:focus-ring { - /* background-color: var(--spectrum-sidenav-item-background-color-key-focus); */ - /* color: var(--spectrum-sidenav-item-text-color-key-focus); */ + &.focus-ring { + ouline-style: solid; + outline-width: var(--spectrum-sidenav-focus-ring-size); + outline-offset: var(--spectrum-sidenav-focus-ring-gap); + outline-color: var(--spectrum-sidenav-focus-ring-color); + /* background-color: red; + color: blue; */ &::before { /* border-color: var(--spectrum-sidenav-item-border-color-key-focus); */ @@ -195,28 +220,26 @@ governing permissions and limitations under the License. .spectrum-SideNav--multiLevel { .spectrum-SideNav-itemLink { font-weight: 700; /* tokens needed var(--spectrum-sidenav-multilevel-main-item-font-weight); */ + color: var(--spectrum-sidenav-header-font-color); + background-color: pink; } .spectrum-SideNav { margin: 0; padding: 0; + padding-block-start: var(--spectrum-sidenav-gap); + /* this is 1 level nested */ .spectrum-SideNav-itemLink { font-weight: 400; /* needs token var(--spectrum-sidenav-item-text-font-weight); */ - - /* needs token var(--spectrum-sidenav-item-padding-x) */ - padding-inline-start: /* needs token */ calc( - 12px + - 12px - ); + background-color: AliceBlue; + padding-inline-start: var(--spectrum-sidenav-start-to-content-second-level); } - /* needs token var(--spectrum-sidenav-item-padding-x) */ + /* this is 2 levels nested */ .spectrum-SideNav { .spectrum-SideNav-itemLink { - padding-inline-start: /* needs token */ calc( - 12px + - 12px - ); + background-color: HoneyDew; + padding-inline-start: var(--spectrum-sidenav-start-to-content-third-level); } } } diff --git a/components/sidenav/metadata/sidenav.yml b/components/sidenav/metadata/sidenav.yml index 11c8bdbd20d..d14a86eef66 100644 --- a/components/sidenav/metadata/sidenav.yml +++ b/components/sidenav/metadata/sidenav.yml @@ -69,16 +69,16 @@ examples: - id: sidenav @@ -212,8 +207,8 @@ examples: Section Title 4 -
  • - +
  • + From 364ca2ee5e8dcc3e041c707028b5008e0899915e Mon Sep 17 00:00:00 2001 From: Jenn Diaz Date: Fri, 26 May 2023 11:54:53 -0600 Subject: [PATCH 12/47] chore(sidenav): rename and docs --- components/sidenav/index.css | 52 +++++++++---------------- components/sidenav/metadata/mods.md | 4 +- components/sidenav/metadata/sidenav.yml | 7 ++-- 3 files changed, 24 insertions(+), 39 deletions(-) diff --git a/components/sidenav/index.css b/components/sidenav/index.css index 7d56411caa7..7e916462cfd 100644 --- a/components/sidenav/index.css +++ b/components/sidenav/index.css @@ -72,8 +72,8 @@ governing permissions and limitations under the License. --spectrum-sidenav-text-font-family: var(--spectrum-sans-font-family-stack); --spectrum-sidenav-text-font-weight: var(--spectrum-regular-font-weight); --spectrum-sidenav-text-font-style: var(--spectrum-default-font-style); - --spectrum-sidenav-font-size: var(--spectrum-font-size-200); - --spectrum-sidenav-lineheight: var(--spectrum-line-height-100); + --spectrum-sidenav-text-font-size: var(--spectrum-font-size-200); + --spectrum-sidenav-text-lineheight: var(--spectrum-line-height-100); --spectrum-sidenav-header-font-family: var(--spectrum-sans-font-family-stack); @@ -141,6 +141,11 @@ governing permissions and limitations under the License. display: inline-flex; justify-content: start; box-sizing: border-box; + word-break: break-word; + hyphens: auto; + cursor: pointer; + transition: background-color var(--spectrum-animation-duration-100) ease-out, + color var(--spectrum-animation-duration-100) ease-out; padding-inline: var(--mod-sidenav-inline-padding, var(--spectrum-sidenav-inline-padding)); border-radius: var(--spectrum-sidenav-border-radius); @@ -153,26 +158,17 @@ governing permissions and limitations under the License. min-block-size: var(--mod-sidenav-min-height, var(--spectrum-sidenav-min-height)); font-family: var(--mod-sidenav-text-font-family, var(--spectrum-sidenav-text-font-family)); - font-size: var(--mod-sidenav-font-size, var(--spectrum-sidenav-font-size)); + font-size: var(--mod-sidenav-text-font-size, var(--spectrum-sidenav-text-font-size)); font-weight: var(--mod-sidenav-text-font-weight, var(--spectrum-sidenav-text-font-weight)); font-style: var(--mod-sidenav-text-font-style, var(--spectrum-sidenav-text-font-style)); text-decoration: none; - line-height: var(--mod-sidenav-lineheight, var(--spectrum-sidenav-lineheight)); - - /* cjk language support */ - &:lang(ja), - &:lang(zh), - &:lang(ko) { - --spectrum-sidenav-lineheight: var(--spectrum-cjk-line-height-100); - } - - word-break: break-word; - hyphens: auto; - - cursor: pointer; - - transition: background-color var(--spectrum-animation-duration-100) ease-out, - color var(--spectrum-animation-duration-100) ease-out; + line-height: var(--mod-sidenav-text-lineheight, var(--spectrum-sidenav-text-lineheight)); + /* cjk language support */ + &:lang(ja), + &:lang(zh), + &:lang(ko) { + --spectrum-sidenav-text-lineheight: var(--spectrum-cjk-line-height-100); + } /* use passthrough custom props */ .spectrum-SideNav-itemIcon { @@ -194,8 +190,8 @@ governing permissions and limitations under the License. } &:active { - background-color: var(--highcontrast-sidenav-item-background-down, var(--mod-sidenav-item-background-down, var(--spectrum-sidenav-item-background-down))); - color: var(--highcontrast-sidenav-content-color-down, var(--mod-sidenav-content-color-down, var(--spectrum-sidenav-content-color-down))); + background-color: var(--highcontrast-sidenav-item-background-down, var(--mod-sidenav-item-background-down, var(--spectrum-sidenav-item-background-down))); + color: var(--highcontrast-sidenav-content-color-down, var(--mod-sidenav-content-color-down, var(--spectrum-sidenav-content-color-down))); } &.is-keyboardFocused, @@ -211,8 +207,6 @@ governing permissions and limitations under the License. } /* this is the CATEGORY or heading variant */ .spectrum-SideNav-heading { - line-height: var(--mod-sidenav-header-line-height, var(--spectrum-sidenav-header-line-height)); - margin-block-start: 16px; /* needs tokens var(--spectrum-sidenav-heading-gap-top); */ margin-inline-end: 0; margin-block-end: 4px; /* needs token var(--spectrum-sidenav-heading-gap-bottom); */ @@ -227,7 +221,7 @@ governing permissions and limitations under the License. font-weight: 500; /* needs token var(--spectrum-sidenav-heading-text-font-weight); */ font-style: normal; letter-spacing: 0.06em; /* needs token var(--spectrum-sidenav-heading-text-letter-spacing); */ - + line-height: var(--mod-sidenav-header-line-height, var(--spectrum-sidenav-header-line-height)); text-transform: uppercase; } @@ -242,12 +236,10 @@ governing permissions and limitations under the License. } .spectrum-SideNav { - /* this is 1 level nested */ .spectrum-SideNav-itemLink { font-weight: var(--mod-sidenav-text-font-weight, var(--spectrum-sidenav-text-font-weight)); padding-inline-start: var(--mod-sidenav-start-to-content-second-level, var(--spectrum-sidenav-start-to-content-second-level)); } - /* this is 2 levels nested */ .spectrum-SideNav { .spectrum-SideNav-itemLink { padding-inline-start: var(--mod-sidenav-start-to-content-third-level, var(--spectrum-sidenav-start-to-content-third-level)); @@ -258,11 +250,9 @@ governing permissions and limitations under the License. .spectrum-SideNav--hasIcon { .spectrum-SideNav { - /* this is 1 level nested */ .spectrum-SideNav-itemLink { padding-inline-start: var(--mod-sidenav-start-to-content-with-icon-second-level, var(--spectrum-sidenav-start-to-content-with-icon-second-level)); } - /* this is 2 levels nested */ .spectrum-SideNav { .spectrum-SideNav-itemLink { padding-inline-start: var(--mod-sidenav-start-to-content-with-icon-third-level, var(--spectrum-sidenav-start-to-content-with-icon-third-level)); @@ -276,23 +266,17 @@ governing permissions and limitations under the License. forced-color-adjust: none; --highcontrast-sidenav-content-disabled-color: GrayText; --highcontrast-sidenav-background-disabled: ButtonFace; - --highcontrast-sidenav-focus-ring-color: ButtonText; - --highcontrast-sidenav-header-font-color: ButtonText; - --highcontrast-sidenav-content-color-default-selected: HighlightText; --highcontrast-sidenav-item-background-default-selected: Highlight; - --highcontrast-sidenav-background-default: ButtonFace; --highcontrast-sidenav-item-background-down: Highlight; --highcontrast-sidenav-background-hover: ButtonFace; --highcontrast-sidenav-background-key-focus: ButtonFace; - --highcontrast-sidenav-content-color-default: ButtonText; --highcontrast-sidenav-content-color-down: ButtonText; --highcontrast-sidenav-content-color-hover: ButtonText; --highcontrast-sidenav-content-color-key-focus: ButtonText; } } - diff --git a/components/sidenav/metadata/mods.md b/components/sidenav/metadata/mods.md index 8fdbf00dae0..5655e3c5a2d 100644 --- a/components/sidenav/metadata/mods.md +++ b/components/sidenav/metadata/mods.md @@ -19,7 +19,6 @@ | `--mod-sidenav-focus-ring-color` | | `--mod-sidenav-focus-ring-gap` | | `--mod-sidenav-focus-ring-size` | -| `--mod-sidenav-font-size` | | `--mod-sidenav-gap` | | `--mod-sidenav-header-color` | | `--mod-sidenav-header-font-color` | @@ -32,7 +31,6 @@ | `--mod-sidenav-item-background-default-selected` | | `--mod-sidenav-item-background-down` | | `--mod-sidenav-item-background-down-selected` | -| `--mod-sidenav-lineheight` | | `--mod-sidenav-max-width` | | `--mod-sidenav-min-height` | | `--mod-sidenav-min-width` | @@ -41,7 +39,9 @@ | `--mod-sidenav-start-to-content-with-icon-second-level` | | `--mod-sidenav-start-to-content-with-icon-third-level` | | `--mod-sidenav-text-font-family` | +| `--mod-sidenav-text-font-size` | | `--mod-sidenav-text-font-style` | | `--mod-sidenav-text-font-weight` | +| `--mod-sidenav-text-lineheight` | | `--mod-sidenav-top-to-label` | | `--mod-sidenav-width` | \ No newline at end of file diff --git a/components/sidenav/metadata/sidenav.yml b/components/sidenav/metadata/sidenav.yml index aa4754ca07f..d284f2e1584 100644 --- a/components/sidenav/metadata/sidenav.yml +++ b/components/sidenav/metadata/sidenav.yml @@ -6,7 +6,7 @@ description: | sections: - name: Migration Guide description: | - Migration Guide + Core token migration work and design updates added a span tag wrapping the link label text. examples: - id: sidenav @@ -16,6 +16,7 @@ examples: - id: sidenav name: Multilevel - description: When navigation is simple but categorical, use the single . + description: Use a multi-level side navigation when there are multiple layers of hierarchical navigation. markup: | - id: sidenav name: Icon - description: In multi-level side navigation, only the first-level items can have icons. Any sub-level items should always be text-only to ensure clear hierarchy. In cases where the navigation content might be user-generated, stick to text-only navigation items. + description: Icons can be displayed in first-level items of any type of side navigation (single level or multi-level). markup: | `; } + +export const SideNavItem = ({ + rootClass = "spectrum-SideNav", + secondlevelsubitems, + link, + title, + isSelected, + isDisabled, + id, + icon, + customClasses = [], + ...globals +}) => { + return html` +
  • ({ ...a, [c]: true }), {}), + })}> + + ${icon ? + Icon({ + ...globals, + iconName: icon, + customClasses: [`${rootClass}-itemIcon`] + }) + : ""} + ${title} + + ${when(secondlevelsubitems, () => html` +
      + ${repeat(secondlevelsubitems, (item) => item.id, (item) => { + return SideNavItem({ + ...globals, + ...item + }) + })} +
    ` + )} +
  • + ` +} From 471f332841988f7b60a4eb758ce419feefb6b12e Mon Sep 17 00:00:00 2001 From: Jenn Diaz Date: Fri, 26 May 2023 15:40:15 -0600 Subject: [PATCH 14/47] fix(sidenav): icon and category story bugs --- components/sidenav/stories/sidenav.stories.js | 39 +++++++++---------- components/sidenav/stories/template.js | 16 ++++---- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/components/sidenav/stories/sidenav.stories.js b/components/sidenav/stories/sidenav.stories.js index c7ed707fb7c..3f16da762c7 100644 --- a/components/sidenav/stories/sidenav.stories.js +++ b/components/sidenav/stories/sidenav.stories.js @@ -2,27 +2,24 @@ import { Template } from "./template"; export default { - title: "Components/Side nav", - description: - "SideNav lets users navigate the entire content of a product or a section. These can be used for a single level or a multi-level navigation.", - component: "Sidenav", - argTypes: { - items: { table: { disable: true } }, - variant: { table: { disable: true } }, - }, - args: { - rootClass: "spectrum-SideNav", - }, - parameters: { - actions: { - handles: [], - }, - status: { - type: process.env.MIGRATED_PACKAGES.includes("sidenav") - ? "migrated" - : undefined, - }, - }, + title: "Components/Side nav", + description: "SideNav lets users navigate the entire content of a product or a section. These can be used for a single level or a multi-level navigation.", + component: "Sidenav", + argTypes: { + items: { table: { disable: true }}, + variant: { table: { disable: true }} + }, + args: { + rootClass: "spectrum-SideNav", + }, + parameters: { + actions: { + handles: [] + }, + status: { + type: process.env.MIGRATED_PACKAGES.includes('sidenav') ? 'migrated' : undefined + } + } }; export const Default = Template.bind({}); diff --git a/components/sidenav/stories/template.js b/components/sidenav/stories/template.js index 7c8d8f9aca5..ca74ec408f3 100644 --- a/components/sidenav/stories/template.js +++ b/components/sidenav/stories/template.js @@ -16,12 +16,13 @@ export const Template = ({ items = [], ...globals }) => { + const hasIcon = !items.map(item => item.icon).includes(undefined) return html`