From 6f840968e51391db98483fe3ae53196e1a6eded6 Mon Sep 17 00:00:00 2001 From: Ekaterina Kondareva <> Date: Fri, 13 Nov 2020 20:18:37 +0200 Subject: [PATCH] side navigation desktop: top menu --- src/components.d.ts | 28 ++++++++ .../hy-desktop-menu-links.scss | 3 + .../hy-desktop-menu-links.tsx | 67 +++++++++++++++++++ .../hy-desktop-menu-links/readme.md | 27 ++++++++ .../hy-desktop-menu-panel.scss | 7 ++ .../hy-desktop-menu-panel.tsx | 17 +++++ .../hy-desktop-menu-panel/readme.md | 21 ++++++ src/components/site-header/readme.md | 5 ++ src/components/site-header/site-header.scss | 9 ++- src/components/site-header/site-header.tsx | 31 +++++---- 10 files changed, 202 insertions(+), 13 deletions(-) create mode 100644 src/components/hy-desktop-menu-links/hy-desktop-menu-links.scss create mode 100644 src/components/hy-desktop-menu-links/hy-desktop-menu-links.tsx create mode 100644 src/components/hy-desktop-menu-links/readme.md create mode 100644 src/components/hy-desktop-menu-panel/hy-desktop-menu-panel.scss create mode 100644 src/components/hy-desktop-menu-panel/hy-desktop-menu-panel.tsx create mode 100644 src/components/hy-desktop-menu-panel/readme.md diff --git a/src/components.d.ts b/src/components.d.ts index 9ca95500..a6e62138 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -29,6 +29,7 @@ import { ProcessFlowBoxVariants, SiteLogoSize, } from './utils/utils'; +import {DesktopLinks} from './components/hy-desktop-menu-links/hy-desktop-menu-links'; import {FooterBaseLinks, FooterBaseSome} from './components/footer/hy-footer-base/hy-footer-base'; import {FooterInfoLinks} from './components/footer/hy-footer-info/hy-footer-info'; import {KeyFigureValue} from './components/hy-key-figure-group/hy-key-figure-group'; @@ -41,6 +42,7 @@ import {MenuLanguage} from './components/navigation/menu-language/menu-language' import {ComponentLabels} from './components/site-header/site-header'; import {ProcessFlowBoxValue} from './components/process/process'; import {ShortcutLinkValue} from './components/hy-shortcuts/hy-shortcuts'; +import {DesktopLinks as DesktopLinks1} from './components/site-header/site-header'; export namespace Components { interface ColorBox {} interface HyAccordionContainer { @@ -199,6 +201,10 @@ export namespace Components { url?: string; variant: CtaLinkVariants; } + interface HyDesktopMenuLinks { + dataDesktopLinks: DesktopLinks[] | string; + } + interface HyDesktopMenuPanel {} interface HyDocsContainer {} interface HyFooter {} interface HyFooterAction { @@ -491,6 +497,7 @@ export namespace Components { listHeading: string; } interface HySiteHeader { + dataDesktopLinks: DesktopLinks[] | string; dataMenuDonate: string; dataMenuLanguage: string; dataSiteHeaderLabels: string; @@ -659,6 +666,16 @@ declare global { prototype: HTMLHyCtaLinkElement; new (): HTMLHyCtaLinkElement; }; + interface HTMLHyDesktopMenuLinksElement extends Components.HyDesktopMenuLinks, HTMLStencilElement {} + var HTMLHyDesktopMenuLinksElement: { + prototype: HTMLHyDesktopMenuLinksElement; + new (): HTMLHyDesktopMenuLinksElement; + }; + interface HTMLHyDesktopMenuPanelElement extends Components.HyDesktopMenuPanel, HTMLStencilElement {} + var HTMLHyDesktopMenuPanelElement: { + prototype: HTMLHyDesktopMenuPanelElement; + new (): HTMLHyDesktopMenuPanelElement; + }; interface HTMLHyDocsContainerElement extends Components.HyDocsContainer, HTMLStencilElement {} var HTMLHyDocsContainerElement: { prototype: HTMLHyDocsContainerElement; @@ -923,6 +940,8 @@ declare global { 'hy-button': HTMLHyButtonElement; 'hy-cta-button': HTMLHyCtaButtonElement; 'hy-cta-link': HTMLHyCtaLinkElement; + 'hy-desktop-menu-links': HTMLHyDesktopMenuLinksElement; + 'hy-desktop-menu-panel': HTMLHyDesktopMenuPanelElement; 'hy-docs-container': HTMLHyDocsContainerElement; 'hy-footer': HTMLHyFooterElement; 'hy-footer-action': HTMLHyFooterActionElement; @@ -1133,6 +1152,10 @@ declare namespace LocalJSX { url?: string; variant?: CtaLinkVariants; } + interface HyDesktopMenuLinks { + dataDesktopLinks?: DesktopLinks[] | string; + } + interface HyDesktopMenuPanel {} interface HyDocsContainer {} interface HyFooter {} interface HyFooterAction { @@ -1431,6 +1454,7 @@ declare namespace LocalJSX { listHeading?: string; } interface HySiteHeader { + dataDesktopLinks?: DesktopLinks[] | string; dataMenuDonate?: string; dataMenuLanguage?: string; dataSiteHeaderLabels?: string; @@ -1546,6 +1570,8 @@ declare namespace LocalJSX { 'hy-button': HyButton; 'hy-cta-button': HyCtaButton; 'hy-cta-link': HyCtaLink; + 'hy-desktop-menu-links': HyDesktopMenuLinks; + 'hy-desktop-menu-panel': HyDesktopMenuPanel; 'hy-docs-container': HyDocsContainer; 'hy-footer': HyFooter; 'hy-footer-action': HyFooterAction; @@ -1615,6 +1641,8 @@ declare module '@stencil/core' { 'hy-button': LocalJSX.HyButton & JSXBase.HTMLAttributes<HTMLHyButtonElement>; 'hy-cta-button': LocalJSX.HyCtaButton & JSXBase.HTMLAttributes<HTMLHyCtaButtonElement>; 'hy-cta-link': LocalJSX.HyCtaLink & JSXBase.HTMLAttributes<HTMLHyCtaLinkElement>; + 'hy-desktop-menu-links': LocalJSX.HyDesktopMenuLinks & JSXBase.HTMLAttributes<HTMLHyDesktopMenuLinksElement>; + 'hy-desktop-menu-panel': LocalJSX.HyDesktopMenuPanel & JSXBase.HTMLAttributes<HTMLHyDesktopMenuPanelElement>; 'hy-docs-container': LocalJSX.HyDocsContainer & JSXBase.HTMLAttributes<HTMLHyDocsContainerElement>; 'hy-footer': LocalJSX.HyFooter & JSXBase.HTMLAttributes<HTMLHyFooterElement>; 'hy-footer-action': LocalJSX.HyFooterAction & JSXBase.HTMLAttributes<HTMLHyFooterActionElement>; diff --git a/src/components/hy-desktop-menu-links/hy-desktop-menu-links.scss b/src/components/hy-desktop-menu-links/hy-desktop-menu-links.scss new file mode 100644 index 00000000..5d4e87f3 --- /dev/null +++ b/src/components/hy-desktop-menu-links/hy-desktop-menu-links.scss @@ -0,0 +1,3 @@ +:host { + display: block; +} diff --git a/src/components/hy-desktop-menu-links/hy-desktop-menu-links.tsx b/src/components/hy-desktop-menu-links/hy-desktop-menu-links.tsx new file mode 100644 index 00000000..4a9e3c96 --- /dev/null +++ b/src/components/hy-desktop-menu-links/hy-desktop-menu-links.tsx @@ -0,0 +1,67 @@ +export interface DesktopLinks { + label: string; + url: string; + menuLinkId: string; +} + +import {Component, h, Element, Prop, State, Watch} from '@stencil/core'; + +@Component({ + tag: 'hy-desktop-menu-links', + styleUrl: 'hy-desktop-menu-links.scss', + shadow: true, +}) +export class HyDesktopMenuLinks { + @Element() el: HTMLElement; + /* + First level menu links to be displayed on Desktop screens. + * */ + @Prop() dataDesktopLinks: DesktopLinks[] | string; + private _dataDesktopLinks: DesktopLinks[]; + @State() firstLevelLinksList: Array<object> = []; + + @Watch('dataDesktopLinks') dataDesktopLinksWatcher(data: DesktopLinks[] | string) { + this._dataDesktopLinks = typeof data === 'string' ? JSON.parse(data) : data; + } + + componentWillLoad() { + this.dataDesktopLinksWatcher(this.dataDesktopLinks); + } + + handleMenuDesktopHover(id) { + console.log(id); + + let panel = (this.el.parentElement as HTMLElement).nextElementSibling; + if (panel) { + //@todo hide/show panel here + + //@todo show proper subtree on panel based on given menu-link-id + console.log(document.querySelectorAll('[trigger-item="' + id + '"]')[0]); + /* + <hy-menu-item menu-link-id="538c248e4fd3cde8e72463b2387b571f" url="/en/lets-research" label="Research" data-drupal-link-system-path="node/90" class="hy-menu-item hy-menu-item--desktop hydrated" depth="1" menu-type="desktop" menu-button-submenu-expand="Expand submenu for"> + * */ + /* + <hy-menu-level-container menu-level="2" aria-expanded="false" class="hy-menu-level-container hy-menu-level-container--level-2 hy-menu-level-container--mobile hydrated" tabindex="-1" depth="2" trigger-item="68f5a4fa9dae69bb944a173f3f8af88f"><!----><hy-menu-item menu-type="mobile" class="hy-menu-item hy-menu-item--mobile hydrated" depth="2"> + * */ + } + } + + componentDidLoad() { + const links = this._dataDesktopLinks as Array<DesktopLinks>; + let firstLevelLinksList = []; + + for (let i = 0; i < links.length; i++) { + let className = 'desktop-menu-link-' + links[i].menuLinkId; + firstLevelLinksList.push( + <a class={className} href={links[i].url} onMouseOver={() => this.handleMenuDesktopHover(links[i].menuLinkId)}> + {links[i].label} + </a> + ); + } + this.firstLevelLinksList = firstLevelLinksList; + } + + render() { + return <div class={'hy-site-header__menu-desktop'}>{this.firstLevelLinksList}</div>; + } +} diff --git a/src/components/hy-desktop-menu-links/readme.md b/src/components/hy-desktop-menu-links/readme.md new file mode 100644 index 00000000..3d6ce575 --- /dev/null +++ b/src/components/hy-desktop-menu-links/readme.md @@ -0,0 +1,27 @@ +# hy-desktop-menu-links + +<!-- Auto Generated Below --> + +## Properties + +| Property | Attribute | Description | Type | Default | +| ------------------ | -------------------- | ----------- | -------------------------- | ----------- | +| `dataDesktopLinks` | `data-desktop-links` | | `DesktopLinks[] \| string` | `undefined` | + +## Dependencies + +### Used by + +- [hy-site-header](../site-header) + +### Graph + +```mermaid +graph TD; + hy-site-header --> hy-desktop-menu-links + style hy-desktop-menu-links fill:#f9f,stroke:#333,stroke-width:4px +``` + +--- + +Helsinki University Design System diff --git a/src/components/hy-desktop-menu-panel/hy-desktop-menu-panel.scss b/src/components/hy-desktop-menu-panel/hy-desktop-menu-panel.scss new file mode 100644 index 00000000..7fda1ffc --- /dev/null +++ b/src/components/hy-desktop-menu-panel/hy-desktop-menu-panel.scss @@ -0,0 +1,7 @@ +:host { + display: block; +} + +.hy-desktop-menu-panel { + background-color: cyan; +} diff --git a/src/components/hy-desktop-menu-panel/hy-desktop-menu-panel.tsx b/src/components/hy-desktop-menu-panel/hy-desktop-menu-panel.tsx new file mode 100644 index 00000000..c045724e --- /dev/null +++ b/src/components/hy-desktop-menu-panel/hy-desktop-menu-panel.tsx @@ -0,0 +1,17 @@ +import {Component, h} from '@stencil/core'; + +@Component({ + tag: 'hy-desktop-menu-panel', + styleUrl: 'hy-desktop-menu-panel.scss', + shadow: true, +}) +export class HyDesktopMenuPanel { + render() { + const classAttributes = ['hy-desktop-menu-panel'].join(' '); + return ( + <div class={classAttributes}> + <slot></slot> + </div> + ); + } +} diff --git a/src/components/hy-desktop-menu-panel/readme.md b/src/components/hy-desktop-menu-panel/readme.md new file mode 100644 index 00000000..32711eb2 --- /dev/null +++ b/src/components/hy-desktop-menu-panel/readme.md @@ -0,0 +1,21 @@ +# hy-desktop-menu-panel + +<!-- Auto Generated Below --> + +## Dependencies + +### Used by + +- [hy-site-header](../site-header) + +### Graph + +```mermaid +graph TD; + hy-site-header --> hy-desktop-menu-panel + style hy-desktop-menu-panel fill:#f9f,stroke:#333,stroke-width:4px +``` + +--- + +Helsinki University Design System diff --git a/src/components/site-header/readme.md b/src/components/site-header/readme.md index 7c3ceb9e..1cc81add 100644 --- a/src/components/site-header/readme.md +++ b/src/components/site-header/readme.md @@ -6,6 +6,7 @@ | Property | Attribute | Description | Type | Default | | ---------------------- | ------------------------- | ----------- | ---------------------------------------------------------------------------- | ------------------ | +| `dataDesktopLinks` | `data-desktop-links` | | `DesktopLinks[] \| string` | `undefined` | | `dataMenuDonate` | `data-menu-donate` | | `string` | `undefined` | | `dataMenuLanguage` | `data-menu-language` | | `string` | `undefined` | | `dataSiteHeaderLabels` | `data-site-header-labels` | | `string` | `undefined` | @@ -20,18 +21,22 @@ ### Depends on - [hy-site-logo](site-logo) +- [hy-desktop-menu-links](../hy-desktop-menu-links) - [hy-menu-language](../navigation/menu-language) - [hy-site-search](site-search) - [hy-icon](../icon) +- [hy-desktop-menu-panel](../hy-desktop-menu-panel) ### Graph ```mermaid graph TD; hy-site-header --> hy-site-logo + hy-site-header --> hy-desktop-menu-links hy-site-header --> hy-menu-language hy-site-header --> hy-site-search hy-site-header --> hy-icon + hy-site-header --> hy-desktop-menu-panel hy-site-logo --> hy-icon hy-menu-language --> hy-menu-language-item hy-menu-language --> hy-icon diff --git a/src/components/site-header/site-header.scss b/src/components/site-header/site-header.scss index 71da362e..39a17b68 100644 --- a/src/components/site-header/site-header.scss +++ b/src/components/site-header/site-header.scss @@ -9,7 +9,7 @@ display: flex; flex-flow: row; place-content: center space-between; - position: relative; + //position: relative; z-index: 99; @include breakpoint($medium) { @@ -29,6 +29,13 @@ height: 120px; } + &__desktop-header { + background-color: red; + } + &__menu-desktop-container { + background-color: cyan; + } + &__logo-container { margin: 16px 8px; diff --git a/src/components/site-header/site-header.tsx b/src/components/site-header/site-header.tsx index 6ffe0687..a3f5fc81 100644 --- a/src/components/site-header/site-header.tsx +++ b/src/components/site-header/site-header.tsx @@ -1,3 +1,8 @@ +export interface DesktopLinks { + label: string; + url: string; + menuLinkId: string; +} export interface DonateLink { url: string; label: string; @@ -28,8 +33,13 @@ export class SiteHeader { @Prop() menuLabelOpen?: string; @Prop() menuLabelClose?: string; @Prop({reflect: true}) menuType: MenuType = MenuType.default; + /* + First level menu links to be displayed on Desktop screens. + * */ + @Prop() dataDesktopLinks: DesktopLinks[] | string; @State() isMobile: boolean; @State() isMenuOpen: boolean = false; + @State() isDesktopMenuOpen: boolean = false; private ro: ResizeObserver; private donateLink: DonateLink[]; private menuLabels: ComponentLabels[]; @@ -111,13 +121,15 @@ export class SiteHeader { switch (this.menuType) { case MenuType.desktop: - return ( + return [ <header class={classAttributes.join(' ')}> <div class={{'hy-backdrop': true, 'is-active': this.isMenuOpen}} /> <div class={'hy-site-header__logo-container'}> <hy-site-logo size={logoSize} color={logoColor} url={this.logoUrl} label={this.logoLabel} /> </div> - <slot name={'menu'} /> + + <hy-desktop-menu-links data-desktop-links={this.dataDesktopLinks}></hy-desktop-menu-links> + <div class={'menu--secondary'}> <hy-menu-language class={'menu--secondary__item is-first'} @@ -141,8 +153,11 @@ export class SiteHeader { ); })} </div> - </header> - ); + </header>, + <hy-desktop-menu-panel> + <slot name={'menu'} /> + </hy-desktop-menu-panel>, + ]; case MenuType.tablet: return ( <header class={classAttributes.join(' ')}> @@ -252,13 +267,5 @@ export class SiteHeader { </header> ); } - - /* return this.isMobile ? ( - // Mobile. - - ) : ( - // Desktop. - - ); */ } } -- GitLab