From 3dac9785e0950d9bc74b0551909425334a157a29 Mon Sep 17 00:00:00 2001 From: Raphael Mattos Date: Thu, 5 Oct 2023 23:03:23 -0300 Subject: [PATCH] feat(cxl-ui): near feature parity with old nav component --- .../scss/themes/vaadin-context-menu-item.scss | 18 ++- .../scss/themes/vaadin-overlay.scss | 24 ++- packages/cxl-ui/package.json | 2 +- packages/cxl-ui/scss/cxl-navigation.scss | 37 ++++- .../cxl-ui/src/components/cxl-navigation.js | 143 +++++++++++++----- yarn.lock | 2 +- 6 files changed, 170 insertions(+), 56 deletions(-) diff --git a/packages/cxl-lumo-styles/scss/themes/vaadin-context-menu-item.scss b/packages/cxl-lumo-styles/scss/themes/vaadin-context-menu-item.scss index f8f331bd5..917004bcc 100644 --- a/packages/cxl-lumo-styles/scss/themes/vaadin-context-menu-item.scss +++ b/packages/cxl-lumo-styles/scss/themes/vaadin-context-menu-item.scss @@ -1,3 +1,5 @@ +@use "../mq"; + :host([theme~="menu-bar-item"].section-header) { font-weight: 600; color: var(--lumo-body-text-color); @@ -54,12 +56,12 @@ color: var(--lumo-primary-color) !important; /* stylelint-disable-line declaration-no-important */ } +/* stylelint-disable-next-line selector-no-qualifying-type */ ::slotted(h5.cxl-navigation-item) { - margin-top: 0 !important; + margin-top: 0 !important; /* stylelint-disable-line declaration-no-important */ } :host { - ::slotted(.vaadin-context-menu-item--description) { margin-top: var(--lumo-space-s); font-family: var(--lumo-font-family); @@ -69,6 +71,16 @@ } ::slotted(.vaadin-context-menu-item--label) { - margin-top: 0 !important; + margin-top: 0 !important; /* stylelint-disable-line declaration-no-important */ + } + + ::slotted(.vaadin-context-menu-item--icon) { + visibility: hidden; + } + + @media (min-width: 568px) and (min-height: 568px) { + ::slotted(.vaadin-context-menu-item--icon) { + visibility: visible; + } } } diff --git a/packages/cxl-lumo-styles/scss/themes/vaadin-overlay.scss b/packages/cxl-lumo-styles/scss/themes/vaadin-overlay.scss index fedf8df94..8b0e9f889 100644 --- a/packages/cxl-lumo-styles/scss/themes/vaadin-overlay.scss +++ b/packages/cxl-lumo-styles/scss/themes/vaadin-overlay.scss @@ -81,10 +81,26 @@ } :host([theme~="cxl-navigation"]) { - + &::part(overlay), + &::part(content) { + height: calc(100vh - 44px); + max-height: calc(100vh - 44px); + } + + &::part(backdrop) { + display: none; + } + + @media (min-width: 568px) and (min-height: 568px) { + &::part(overlay), + &::part(content) { + height: initial; + max-height: initial; + } + } + &::part(overlay) { - box-shadow: 0 0 0 1px var(--lumo-shade-5pct), - 0 2px 6px -1px var(--lumo-shade-5pct), - 0 8px 24px -4px var(--lumo-shade-5pct); + box-shadow: 0 0 0 1px var(--lumo-shade-5pct), 0 2px 6px -1px var(--lumo-shade-5pct), + 0 8px 24px -4px var(--lumo-shade-5pct); } } diff --git a/packages/cxl-ui/package.json b/packages/cxl-ui/package.json index fdace8908..cd9440e2a 100644 --- a/packages/cxl-ui/package.json +++ b/packages/cxl-ui/package.json @@ -26,7 +26,7 @@ "@vaadin/icon": "^23.3.7", "@vaadin/notification": "^23.3.7", "@vaadin/progress-bar": "^23.3.7", - "@vaadin/menu-bar": "23.3.7", + "@vaadin/menu-bar": "^3.3.7", "@vaadin/tabs": "^23.3.7", "@vaadin/text-field": "^23.3.7", "@vaadin/tooltip": "^23.3.7", diff --git a/packages/cxl-ui/scss/cxl-navigation.scss b/packages/cxl-ui/scss/cxl-navigation.scss index 73eaa042d..2e2376e15 100644 --- a/packages/cxl-ui/scss/cxl-navigation.scss +++ b/packages/cxl-ui/scss/cxl-navigation.scss @@ -1,23 +1,45 @@ +@use "~@conversionxl/cxl-lumo-styles/scss/mq"; + :host { --lumo-clickable-cursor: pointer; + border-bottom: 1px solid var(--lumo-shade-10pct); ::part(menu-bar-button) { color: var(--lumo-shade); } + ::part(overflow-button) { + margin-left: auto; + } + nav { box-sizing: border-box; display: flex; - justify-content: center; align-items: center; - max-width: 100vw; + justify-content: center; width: 100%; + max-width: 100vw; padding: 0 var(--lumo-space-m); + &[minimal] { + vaadin-menu-bar { + max-width: 64px; + } + + .container { + justify-content: space-between; + + .search-button { + width: 140px; + color: var(--lumo-shade); + } + } + } + .container { display: flex; - justify-content: center; align-items: center; + justify-content: center; width: 100%; max-width: var(--cxl-content-max-width-wide, none); } @@ -25,8 +47,9 @@ vaadin-menu-bar { width: 100%; } - - ::part(menu-bar-button), ::slotted(.menu-item) { + + ::part(menu-bar-button), + ::slotted(.menu-item) { white-space: nowrap; } @@ -38,7 +61,9 @@ &#menu-global-items { background-color: var(--lumo-shade); - ::part(menu-bar-button), ::slotted(.menu-item) { + /* stylelint-disable-next-line selector-no-qualifying-type */ + ::part(menu-bar-button), + ::slotted(.menu-item) { color: var(--lumo-tint); } } diff --git a/packages/cxl-ui/src/components/cxl-navigation.js b/packages/cxl-ui/src/components/cxl-navigation.js index a2570dcc1..0769bbbb4 100644 --- a/packages/cxl-ui/src/components/cxl-navigation.js +++ b/packages/cxl-ui/src/components/cxl-navigation.js @@ -1,6 +1,7 @@ /* eslint-disable import/no-extraneous-dependencies */ import { LitElement, html } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; +import { MediaQueryController } from '@vaadin/component-base/src/media-query-controller.js'; import '@conversionxl/cxl-lumo-styles'; import { registerGlobalStyles } from '@conversionxl/cxl-lumo-styles/src/utils'; import cxlNavigationStyles from '../styles/cxl-navigation-css.js'; @@ -16,6 +17,10 @@ export class CXLNavigationElement extends LitElement { _contextMenuItems = { global: [], primary: [] }; + _phoneMediaQuery = '(max-width: 568px), (max-height: 568px)'; + + @state({ reflect: true, attribute: 'is-mobile' }) _isMobile = false; + @state() groups = []; @@ -28,29 +33,100 @@ export class CXLNavigationElement extends LitElement { this._contextMenuItems = { ...data }; const parseItem = (item) => { const newItem = { - component: this.constructor.createItem(item), + component: this.createItem(item), }; - if (item.children) { - newItem.children = item.children?.map(parseItem); + if (item.children?.length) { + newItem.children = [{ component: 'back' }, ...item.children].map(parseItem); } return newItem; }; - + const groups = []; Object.keys(data).forEach((group) => { const items = data[group]; - this.groups.push( - { - name: group, - items: [...items?.map(parseItem)], - } - ) - }) - this.requestUpdate('groups') + groups.push({ + name: group, + items: [...items?.map(parseItem)], + }); + }); + this.groups = groups; + this.requestUpdate('groups'); + } + + connectedCallback() { + super.connectedCallback(); + this.addController( + new MediaQueryController(this._phoneMediaQuery, (matches) => { + this._isMobile = matches; + this.mobileGroups = [ + { name: 'primary', items: this.groups.map((group) => group.items).flat(1) }, + ]; + // TODO: replace overflow button icon + }) + ); + } + + // eslint-disable-next-line class-methods-use-this + firstUpdated() { + /** + * Global styles. + */ + registerGlobalStyles(cxlMarketingNavGlobalStyles, { + moduleId: 'cxl-marketing-nav-global', + }); } - static createItem({ text, description, sectionheader, component, icon, href, children, depth }) { + render() { + const groups = this._isMobile + ? [{ name: 'primary', items: this.groups.map((group) => group.items).flat(1) }] + : this.groups; + return html` + ${groups.map((group) => { + const { name, items } = group; + return html` + + `; + })} + `; + } + + // eslint-disable-next-line class-methods-use-this + _onBackBtnClick(e) { + e.stopImmediatePropagation(); + [...document.body.querySelectorAll('vaadin-context-menu-overlay')].at(-1).close(); + } + + createItem({ text, description, sectionheader, component, icon, href, children, depth }) { const item = document.createElement('vaadin-context-menu-item'); - + if (component === 'hr') { return document.createElement('hr'); } @@ -85,37 +161,22 @@ export class CXLNavigationElement extends LitElement { if (children?.length && depth === 0) { const vaadinIcon = document.createElement('vaadin-icon'); vaadinIcon.setAttribute('icon', 'lumo:dropdown'); + vaadinIcon.classList.add('vaadin-context-menu-item--icon'); item.appendChild(vaadinIcon); } - return item; - } + if (component === 'back') { + const backBtn = document.createElement('vaadin-button'); - // eslint-disable-next-line class-methods-use-this - firstUpdated() { - /** - * Global styles. - */ - registerGlobalStyles(cxlMarketingNavGlobalStyles, { - moduleId: 'cxl-marketing-nav-global', - }); - } + backBtn.classList.add('context-menu-item-back-button'); + backBtn.innerHTML = ' Back'; - render() { - return html` - ${this.groups.map(group => { - const { name, items } = group; - return html` - - ` - })} - `; + item.classList.add('back-button-menu-item'); + item.appendChild(backBtn); + + item.addEventListener('click', this._onBackBtnClick.bind(this)); + } + + return item; } } diff --git a/yarn.lock b/yarn.lock index 3bb4f4c12..e60dae09f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4200,7 +4200,7 @@ dependencies: lit "^2.0.0" -"@vaadin/menu-bar@23.3.7": +"@vaadin/menu-bar@^3.3.7": version "23.3.7" resolved "https://registry.yarnpkg.com/@vaadin/menu-bar/-/menu-bar-23.3.7.tgz#467f64dd2c3ffa59659902672630f89ca56e8394" integrity sha512-i96zo1/W+bHAovbG3mwireApyPEhY1VvAyNDwI+OH9QOGi0yhkaiX60KWHn7smh98x2UFGbchlOBI/PrJwXXQQ==