From 3cbdc17ec9382ead5e7fdb49795023c1284df6b9 Mon Sep 17 00:00:00 2001 From: Conor Britain Date: Fri, 8 Jul 2022 19:00:47 -0400 Subject: [PATCH] _content: update header nav with dropdowns and subnavs Adds dropdown menus as well as fixed open/closed states. Adds submenus to mobile header nav. Change-Id: I0fdf6fd81008857b1ed28f0a8388de8e004eb722 Reviewed-on: https://go-review.googlesource.com/c/website/+/435522 Reviewed-by: Jamal Carvalho Reviewed-by: Hyang-Ah Hana Kim TryBot-Result: Gopher Robot Run-TryBot: Hyang-Ah Hana Kim --- .eslintrc.yaml | 3 +- _content/css/styles.css | 319 +++++++++++++++--- _content/images/logos/social/github.svg | 3 + .../images/logos/social/google-groups.svg | 8 + _content/images/logos/social/reddit.svg | 3 + _content/images/logos/social/slack.svg | 10 + .../images/logos/social/stack-overflow.svg | 4 + _content/images/logos/social/twitter.svg | 3 + _content/index.md | 1 + _content/js/site.js | 216 ++++++++++-- _content/menus.yaml | 141 +++++--- _content/site.tmpl | 72 +++- 12 files changed, 658 insertions(+), 125 deletions(-) create mode 100644 _content/images/logos/social/github.svg create mode 100644 _content/images/logos/social/google-groups.svg create mode 100644 _content/images/logos/social/reddit.svg create mode 100644 _content/images/logos/social/slack.svg create mode 100644 _content/images/logos/social/stack-overflow.svg create mode 100644 _content/images/logos/social/twitter.svg diff --git a/.eslintrc.yaml b/.eslintrc.yaml index a3c2d0a3..2b0e04c7 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -6,9 +6,10 @@ rules: require-jsdoc: 'off' indent: 'off' arrow-parens: 'off' + comma-dangle: ['error', {'functions': 'never'}] overrides: - files: - - "*.ts" + - '*.ts' parser: '@typescript-eslint/parser' env: browser: true diff --git a/_content/css/styles.css b/_content/css/styles.css index b065921b..3da7b11f 100644 --- a/_content/css/styles.css +++ b/_content/css/styles.css @@ -6,7 +6,7 @@ /* Colors */ --gray-1: #202224; - --gray-2: #2D2D2D; + --gray-2: #2d2d2d; --gray-3: #555759; --gray-4: #6e7072; --gray-5: #848688; @@ -23,19 +23,19 @@ --blue-light: #f2fafd; --black-1: #000; --black-2: #111111; - --deep-cerulian: #007F9f; + --deep-cerulian: #007f9f; --green: #3a6e11; --green-light: #5fda64; --pink: #c85e7a; --pink-light: #fdecf1; --purple: #542c7d; - --shark: #2B2D2F; + --shark: #2b2d2f; --slate: #253443; /* Footer background. */ --tundora: #414141; --white: #fff; --yellow: #fddd00; --yellow-light: #fff8cc; - --testimonial: #007F9f; + --testimonial: #007f9f; /* Color Intents */ --color-brand-primary: var(--turq-dark); @@ -141,36 +141,36 @@ box-sizing: border-box; } @media (prefers-color-scheme: dark) { - [data-theme="auto"] .DarkMode-img { + [data-theme='auto'] .DarkMode-img { display: block; } - [data-theme="auto"] .LightMode-img { + [data-theme='auto'] .LightMode-img { display: none; } } @media (prefers-color-scheme: light) { - [data-theme="auto"] .DarkMode-img { + [data-theme='auto'] .DarkMode-img { display: none; } - [data-theme="auto"] .LightMode-img { + [data-theme='auto'] .LightMode-img { display: block; } } -[data-theme="dark"] .DarkMode-img { +[data-theme='dark'] .DarkMode-img { display: block; } -[data-theme="dark"] .LightMode-img { +[data-theme='dark'] .LightMode-img { display: none; } -[data-theme="light"] .DarkMode-img { +[data-theme='light'] .DarkMode-img { display: none; } -[data-theme="light"] .LightMode-img { +[data-theme='light'] .LightMode-img { display: block; } body { - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif, - 'Apple Color Emoji', 'Segoe UI Emoji'; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, + sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji'; max-height: 100%; line-height: 1.4; } @@ -180,7 +180,15 @@ select, textarea { font: inherit; } -h1, h2, h3, h4, h5, h6, p, ol, ul { +h1, +h2, +h3, +h4, +h5, +h6, +p, +ol, +ul { margin-top: 1rem; margin-bottom: 1rem; } @@ -223,7 +231,8 @@ pre .selection, pre .selection-comment { background: var(--yellow); } -pre .ln { /* line number */ +pre .ln { + /* line number */ color: #999; } pre ins { @@ -264,7 +273,9 @@ a:hover { } @media print { /* display: flex makes the printer slice text lines in half */ - .Site { display: block; } + .Site { + display: block; + } } .bluebg { background: var(--color-background-banner); @@ -411,7 +422,8 @@ a.Footer-link--primary { width: auto; } .go-Icon--inverted { - filter: brightness(0) saturate(100%) invert(100%) sepia(97%) saturate(13%) hue-rotate(245deg) brightness(103%) contrast(107%); + filter: brightness(0) saturate(100%) invert(100%) sepia(97%) saturate(13%) + hue-rotate(245deg) brightness(103%) contrast(107%); } .Footer-feedbackButton { background: none; @@ -437,6 +449,7 @@ a.Footer-link--primary { margin: 0; max-width: none; } +/* Start nav */ .Header-nav { align-items: center; display: flex; @@ -468,6 +481,10 @@ a.Footer-link--primary { } .Header-menuItem { display: none; + position: relative; +} +.Header-menuItem .js-desktop-menu-hover > i { + pointer-events: none; } .Header-menu { align-items: stretch; @@ -479,13 +496,15 @@ a.Footer-link--primary { } @media only screen and (min-width: 57.7rem) { - .Header, .PlayPage { + .Header, + .PlayPage { padding: 0 1.5rem; } .Header-menuItem { align-items: stretch; display: inline-flex; flex: none; + margin: 0 0.3125rem; } .Header-menu { justify-content: flex-end; @@ -494,19 +513,28 @@ a.Footer-link--primary { display: none; } } -.Header-menuItem a:link, -.Header-menuItem a:visited { +.Header-menuItem > a:link, +.Header-menuItem > a:visited { align-items: center; border-bottom: 0.1875rem solid transparent; border-top: 0.1875rem solid transparent; /* To ensure the text remains centered. */ color: var(--color-text); display: inline-flex; - margin: 0 0.3125rem; - padding: 0 0.9375rem; + padding: 0 1.5rem; text-align: center; text-decoration: none; width: 100%; } +.Header--dark + .Header-menuItem:hover + > a:not(.forced-closed).js-desktop-menu-hover, +.Header--dark + .Header-menuItem:focus-within + > a:not(.forced-closed).js-desktop-menu-hover { + background: var(--color-background); + color: var(--color-text-link); + border-color: var(--color-background); +} .Header--dark .Header-menuItem a:link, .Header--dark .Header-menuItem a:visited { color: var(--white); @@ -517,9 +545,11 @@ a.Footer-link--primary { font-weight: bold; } .Header-menuItem a:hover { - border-bottom-color: var(--white); color: var(--color-text); } +.Header-menuItem a:not(.forced-closed):hover { + border-bottom-color: var(--white); +} .Header-navOpen { background: no-repeat center/2rem url('/images/menu-24px.svg'); border: none; @@ -543,6 +573,21 @@ a.Footer-link--primary { width: 85%; z-index: 20; } +.NavigationDrawer-submenuItem { + width: 100%; +} + +.NavigationDrawer-submenuItem .NavigationDrawer-header { + min-height: 4.0625rem; + font-size: 1.375rem; + display: flex; + align-items: center; + justify-content: flex-start; + padding: 0.5rem; + padding-left: 1.5rem; + color: var(--color-text-link); +} + .NavigationDrawer.is-active { transform: translateX(0); } @@ -550,7 +595,26 @@ a.Footer-link--primary { align-items: center; display: flex; justify-content: space-between; + border-bottom: 0.0625rem solid #eeeeee; + margin-bottom: 0.5rem; } +.NavigationDrawer-listItem.NavigationDrawer-hasSubnav > a i { + float: right; + margin-right: -0.5rem; +} +.NavigationDrawer-listItem.NavigationDrawer-hasSubnav + .NavigationDrawer-header + a { + margin-left: 0; +} + +.NavigationDrawer-listItem .material-icons { + color: var(--color-text-link); + margin-right: 0.5rem; + display: inline-block; + vertical-align: sub; +} + .NavigationDrawer-logo { display: block; height: 2rem; @@ -565,13 +629,27 @@ a.Footer-link--primary { .NavigationDrawer-listItem { font-size: 1.125rem; margin: 0 0.5rem; + color: var(--color-text-subtle); } +.NavigationDrawer-listItem > div:not(.NavigationDrawer), .NavigationDrawer-listItem a:link, .NavigationDrawer-listItem a:visited { display: block; margin: 0 1rem; padding: 0.5rem; } +@media only screen and (max-width: 57.7rem) { + .NavigationDrawer-listItem .Header-socialIcons { + padding: 0.5rem 0; + } + + .NavigationDrawer-listItem a.Header-socialIcon { + padding: 0 0.5rem; + margin: 0; + display: inline-block; + } +} + .NavigationDrawer-listItem--active { background-color: #bfeaf4; border-radius: 0.4rem; @@ -589,6 +667,98 @@ a.Footer-link--primary { background-color: rgba(0, 0, 0, 0.32); display: block; } +.Header-submenu { + padding: 1.5rem 1.5rem 0; + list-style-type: none; + background: transparent; + visibility: hidden; + opacity: 0; + display: none; + transition: all 0.2s ease; + margin-top: 3.5rem; + position: absolute; + flex-direction: column; + flex-wrap: wrap; + color: var(--color-text); + background-color: var(--color-background); + border: 0.0625rem solid var(--color-brand-primary); + border-width: 0 0.0625rem 0.0625rem; +} +.Header-menuItem:hover + > .js-desktop-menu-hover:not(.forced-closed) + ~ .Header-submenu, +.Header-menuItem:focus-within + > .js-desktop-menu-hover:not(.forced-closed) + ~ .Header-submenu { + visibility: visible; + opacity: 1; + display: flex; +} +.Header-submenu .Header-submenuItem a:link, +.Header-submenu .Header-submenuItem a:visited { + margin: 0; + padding: 0; + border-bottom: none; + font-weight: 400; +} +.Header-submenu p { + max-width: 15.5rem; +} +.Header-submenu a:link:hover, +.Header-submenu a:visited:hover { + text-decoration: none; + border-bottom: 0.125rem solid var(--color-text-link); +} + +.Header-submenu .Header-submenuItem { + padding-bottom: 1.5rem; +} + +.Header-submenu .Header-submenuItem p { + font-size: 0.875rem; + color: var(--color-text-subtle); + margin-top: 0.55rem; + margin-bottom: 0; +} +.Header-submenu .Header-submenuItem i { + margin-left: 0.25rem; + transform: translateY(0.1rem); /* to get bottom alignment w/ text */ + font-size: 0.75rem; +} +.Header-menuItem .Header-submenuItem a:link, +.Header-menuItem .Header-submenuItem a:visited { + color: var(--color-text-link); + display: inline-flex; + align-items: baseline; + margin-bottom: -0.125rem; +} +.Header-menu li:nth-child(1) .Header-submenu { + width: 18.5rem; + left: -1px; +} +.Header-menu li:nth-child(3) .Header-submenu { + left: -12rem; + height: 19.275rem; + width: 37.25rem; +} +.Header-menu li:nth-child(5) .Header-submenu { + right: -1px; + height: 17.65rem; + width: 37.25rem; +} +.Header-socialIcons { + display: flex; + flex-wrap: wrap; +} +.Header-menuItem a.Header-socialIcon { + flex: 0 1 auto; + display: inline-flex; + width: auto; +} +.Header-menuItem a.Header-socialIcon:not(:last-child) { + margin-right: 0.75rem; +} +/* End nav */ .Article { color: var(--color-text); margin: 0 auto 1.875rem; @@ -1521,7 +1691,11 @@ a.WhoUsesCaseStudy-librariesViewMoreLink { } .UseCase-logo { align-items: center; - background: linear-gradient(10.64deg, var(--color-text-link) 0%, #00a29c 100%); + background: linear-gradient( + 10.64deg, + var(--color-text-link) 0%, + #00a29c 100% + ); border-radius: 50%; display: flex; height: 3.75rem; @@ -1908,8 +2082,8 @@ a.WhoUsesCaseStudy-librariesViewMoreLink { background-size: 75rem 75rem; padding: 0 2.25rem 0; } -[data-theme="dark"] .Learn-hero .BreadcrumbNav-li:not(:last-child):after, -[data-theme="dark"] .Security-hero .BreadcrumbNav-li:not(:last-child):after { +[data-theme='dark'] .Learn-hero .BreadcrumbNav-li:not(:last-child):after, +[data-theme='dark'] .Security-hero .BreadcrumbNav-li:not(:last-child):after { background: url('/images/icons/arrow-forward.svg') no-repeat; content: ' '; display: block; @@ -1918,8 +2092,12 @@ a.WhoUsesCaseStudy-librariesViewMoreLink { width: 1rem; } @media (prefers-color-scheme: dark) { - :root:not([data-theme='light']) .Learn-hero .BreadcrumbNav-li:not(:last-child):after, - :root:not([data-theme='light']) .Security-hero .BreadcrumbNav-li:not(:last-child):after { + :root:not([data-theme='light']) + .Learn-hero + .BreadcrumbNav-li:not(:last-child):after, + :root:not([data-theme='light']) + .Security-hero + .BreadcrumbNav-li:not(:last-child):after { background: url('/images/icons/arrow-forward.svg') no-repeat; } } @@ -3102,7 +3280,11 @@ p.BackgroundQuote-body { } .StarItem-icon { align-items: center; - background: linear-gradient(10.64deg, var(--color-brand-primary) 0%, #00a29c 100%); + background: linear-gradient( + 10.64deg, + var(--color-brand-primary) 0%, + #00a29c 100% + ); border-radius: 50%; display: flex; height: 1.5rem; @@ -3443,7 +3625,11 @@ a.UseCase-anchorLink.selected::before { color: var(--color-text); } .WhoUsesSubPage-heroImg { - background: -webkit-linear-gradient(0deg, var(--color-background-accented) 50vw, #bfeaf4 50vw); + background: -webkit-linear-gradient( + 0deg, + var(--color-background-accented) 50vw, + #bfeaf4 50vw + ); display: flex; max-width: 75.75rem; padding-left: 1.5rem; @@ -3465,7 +3651,11 @@ a.UseCase-anchorLink.selected::before { line-height: 3rem; } .WhoUsesSubPage-heroImg { - background: -webkit-linear-gradient(0deg, var(--color-background-accented) 40vw, #bfeaf4 40vw); + background: -webkit-linear-gradient( + 0deg, + var(--color-background-accented) 40vw, + #bfeaf4 40vw + ); } .WhoUsesSubPage-heroImg img { max-height: 15.625rem; @@ -3477,7 +3667,11 @@ a.UseCase-anchorLink.selected::before { margin-top: 0; } .WhoUsesSubPage-heroInner--caseStudy { - background: -webkit-linear-gradient(0deg, var(--color-background-accented) 70vw, #bfeaf4 70vw); + background: -webkit-linear-gradient( + 0deg, + var(--color-background-accented) 70vw, + #bfeaf4 70vw + ); flex-direction: row; } .WhoUsesSubPage-heroContent--caseStudy { @@ -3701,7 +3895,8 @@ img.PullQuote-image { color: #999; font-size: smaller; } -#blog #content .iframe, #content .image { +#blog #content .iframe, +#content .image { margin: 20px; } #blog #content .title { @@ -3720,7 +3915,8 @@ img.PullQuote-image { #blog .Article[data-slug='/blog/go-fonts'] code { font-family: 'Go Mono', monospace; } -#blog pre, #blog code { +#blog pre, +#blog code { font-family: monospace; } #blog svg { @@ -3826,7 +4022,8 @@ a.error { text-align: center; border-radius: 0.3125rem; } -.Security-gridContainer, .Security-comingSoon { +.Security-gridContainer, +.Security-comingSoon { padding: 3rem 1.5rem 1rem; } .Security-card .Card-content ul { @@ -3868,7 +4065,7 @@ a.error { justify-content: center; } .Security-comingSoonTitle h3 { - color: #71757B; + color: #71757b; font-weight: normal; font-size: 1.5rem; } @@ -3881,7 +4078,8 @@ a.error { .Security-getStarted { background: var(--color-brand-primary); } -.Security-getStarted, .Security-recentupdates { +.Security-getStarted, +.Security-recentupdates { padding: 2.5rem 0; } .Security-getStarted .Security-sectionHeader { @@ -3910,8 +4108,8 @@ a.error { flex: 1; } .Security-comingSoonImage img { - width: 100%; - max-width: 14.063rem; + width: 100%; + max-width: 14.063rem; } .Security-secondary-cta { background-color: var(--color-brand-primary); @@ -3952,8 +4150,9 @@ a.error { max-width: 100%; } @media only screen and (min-width: 72.75rem) { - .Security-getStarted, .Security-recentupdates { - padding: 3.75rem 0 5rem 0; + .Security-getStarted, + .Security-recentupdates { + padding: 3.75rem 0 5rem 0; } .Security-getStarted .Security-sectionHeader { margin-bottom: 2.5rem; @@ -3980,7 +4179,11 @@ a.error { } .Security-secondary-cta { background: #beeaf5; - background-image: radial-gradient( 60.0625rem 60.0625rem, var(--color-brand-primary) 50%, #beeaf5 50% ); + background-image: radial-gradient( + 60.0625rem 60.0625rem, + var(--color-brand-primary) 50%, + #beeaf5 50% + ); background-position: -13rem 50%; background-size: 75rem 75rem; background-repeat: no-repeat; @@ -4094,7 +4297,9 @@ a.error { gap: 0.5rem; justify-content: flex-end; } -.Playground-selectExample, .Playground-selectGoVersion, .Playground-shareURL { +.Playground-selectExample, +.Playground-selectGoVersion, +.Playground-shareURL { background-color: var(--color-background); border-radius: 3px; border: var(--border); @@ -4119,7 +4324,9 @@ a.error { .Playground-controls { flex-wrap: nowrap; } - .Playground-selectExample, .Playground-selectGoVersion, .Playground-shareURL { + .Playground-selectExample, + .Playground-selectGoVersion, + .Playground-shareURL { margin: 0 0.4375rem 0 0; width: auto; } @@ -4171,7 +4378,7 @@ h2.Playground-about { background-color: var(--color-background-accented); border: none; border-radius: 0.1875rem; - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2); + box-shadow: 0 0.125rem 5px rgba(0, 0, 0, 0.2); box-sizing: border-box; color: var(--color-text-link); cursor: pointer; @@ -4184,7 +4391,7 @@ h2.Playground-about { text-decoration: none; } .Button:active { - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); + box-shadow: 0 0.0625rem 3px rgba(0, 0, 0, 0.2); } .Button--primary, .Button--primary:link, @@ -4431,7 +4638,7 @@ th.pkg-name { } .DocTable-cell p, .DocTable-cell pre { - margin: 0rem 0rem 0.875rem; + margin: 0rem 0rem 0.875rem; } .DocTable-row--highlighted { background: #f0f0f0; @@ -4471,10 +4678,12 @@ table.downloadtable { table.downloadtable tr { background-color: var(--color-background-accented); } -table.downloadtable tr:nth-child(2n), table.downloadtable tr.first { +table.downloadtable tr:nth-child(2n), +table.downloadtable tr.first { background-color: var(--color-background); } -table.downloadtable td, table.downloadtable th { +table.downloadtable td, +table.downloadtable th { white-space: nowrap; padding: 6px 10px; } @@ -4487,9 +4696,9 @@ table.downloadtable tr.highlight td { a.downloadBox { display: block; color: #222; - border: 1px solid #375EAB; + border: 0.0625rem solid #375eab; border-radius: 5px; - background: #E0EBF5; + background: #e0ebf5; width: 280px; float: left; margin-left: 10px; @@ -4521,13 +4730,15 @@ a.downloadBox:hover .filename { .downloadBox .checksum { font-size: 5pt; } -#manual-nav dl, #pkg-examples dl{ +#manual-nav dl, +#pkg-examples dl { margin-left: 1.25rem; font-size: 0.875rem; margin-block-end: 0; margin-block-start: 0; } -#manual-nav dd, #pkg-examples dd { +#manual-nav dd, +#pkg-examples dd { margin: 0 0 0 1.25rem; font-size: 0.875rem; } diff --git a/_content/images/logos/social/github.svg b/_content/images/logos/social/github.svg new file mode 100644 index 00000000..b58697a3 --- /dev/null +++ b/_content/images/logos/social/github.svg @@ -0,0 +1,3 @@ + + + diff --git a/_content/images/logos/social/google-groups.svg b/_content/images/logos/social/google-groups.svg new file mode 100644 index 00000000..bd4ee2d9 --- /dev/null +++ b/_content/images/logos/social/google-groups.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/_content/images/logos/social/reddit.svg b/_content/images/logos/social/reddit.svg new file mode 100644 index 00000000..33986af4 --- /dev/null +++ b/_content/images/logos/social/reddit.svg @@ -0,0 +1,3 @@ + + + diff --git a/_content/images/logos/social/slack.svg b/_content/images/logos/social/slack.svg new file mode 100644 index 00000000..787e2f97 --- /dev/null +++ b/_content/images/logos/social/slack.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/_content/images/logos/social/stack-overflow.svg b/_content/images/logos/social/stack-overflow.svg new file mode 100644 index 00000000..4288f3bd --- /dev/null +++ b/_content/images/logos/social/stack-overflow.svg @@ -0,0 +1,4 @@ + + + + diff --git a/_content/images/logos/social/twitter.svg b/_content/images/logos/social/twitter.svg new file mode 100644 index 00000000..4d930f98 --- /dev/null +++ b/_content/images/logos/social/twitter.svg @@ -0,0 +1,3 @@ + + + diff --git a/_content/index.md b/_content/index.md index b2230917..1dbeb47d 100644 --- a/_content/index.md +++ b/_content/index.md @@ -4,6 +4,7 @@ summary: Go is an open source programming language that makes it easy to build s --- {{$canShare := not googleCN}} +
diff --git a/_content/js/site.js b/_content/js/site.js index dda15d20..52d04a2e 100644 --- a/_content/js/site.js +++ b/_content/js/site.js @@ -11,12 +11,89 @@ window.initFuncs = []; 'use strict'; function registerHeaderListeners() { + // Desktop menu hover state + const menuItemHovers = document.querySelectorAll('.js-desktop-menu-hover'); + menuItemHovers.forEach(menuItemHover => { + // when user clicks on the dropdown menu item on desktop or mobile, + // force the menu to stay open until the user clicks off of it. + menuItemHover.addEventListener('mouseenter', e => { + const forced = document.querySelector('.forced-open'); + if (forced && forced !== menuItemHover) { + forced.blur(); + forced.classList.remove('forced-open'); + } + // prevents menus that have been tabbed into from staying open + // when you hover over another menu + e.target.focus(); + e.target.blur(); + }); + const toggleForcedOpen = e => { + const isForced = e.target.classList.contains('forced-open'); + const target = e.currentTarget; + if (isForced) { + target.removeEventListener('blur', e => + target.classList.remove('forced-open') + ); + target.classList.remove('forced-open'); + target.classList.add('forced-closed'); + target.blur(); + target.parentNode.addEventListener('mouseout', () => { + target.classList.remove('forced-closed'); + }); + } else { + target.classList.remove('forced-closed'); + target.classList.add('forced-open'); + target.focus(); + target.addEventListener('blur', e => + target.classList.remove('forced-open') + ); + target.parentNode.removeEventListener('mouseout', () => { + target.classList.remove('forced-closed'); + }); + } + }; + menuItemHover.addEventListener('click', toggleForcedOpen); + }); + + // ensure desktop submenus are closed when esc is pressed + const headerItems = document.querySelectorAll('.Header-menuItem'); + headerItems.forEach(header => { + header.addEventListener('keyup', e => { + if (e.key === 'Escape') { + e.target.blur(); + } + }); + }); + + // Mobile menu subnav menus const header = document.querySelector('.js-header'); - const menuButtons = document.querySelectorAll('.js-headerMenuButton'); - menuButtons.forEach(button => { + const headerbuttons = document.querySelectorAll('.js-headerMenuButton'); + headerbuttons.forEach(button => { button.addEventListener('click', e => { e.preventDefault(); - header.classList.toggle('is-active'); + const isActive = header.classList.contains('is-active'); + if (isActive) { + handleNavigationDrawerInactive(header); + } else { + handleNavigationDrawerActive(header); + } + button.setAttribute('aria-expanded', isActive); + }); + }); + + const scrim = document.querySelector('.js-scrim'); + scrim.addEventListener('click', e => { + e.preventDefault(); + + // find any active submenus and close them + const activeSubnavs = document.querySelectorAll( + '.NavigationDrawer-submenuItem.is-active' + ); + activeSubnavs.forEach(subnav => handleNavigationDrawerInactive(subnav)); + + handleNavigationDrawerInactive(header); + + headerbuttons.forEach(button => { button.setAttribute( 'aria-expanded', header.classList.contains('is-active') @@ -24,17 +101,110 @@ window.initFuncs = []; }); }); - const scrim = document.querySelector('.js-scrim'); - scrim.addEventListener('click', e => { - e.preventDefault(); - header.classList.remove('is-active'); - menuButtons.forEach(button => { - button.setAttribute( - 'aria-expanded', - header.classList.contains('is-active') - ); + const getNavigationDrawerMenuItems = navigationDrawer => [ + navigationDrawer.querySelector('.NavigationDrawer-header > a'), + ...navigationDrawer.querySelectorAll( + ':scope > .NavigationDrawer-nav > .NavigationDrawer-list > .NavigationDrawer-listItem > a, :scope > .NavigationDrawer-nav > .NavigationDrawer-list > .NavigationDrawer-listItem > .Header-socialIcons > a' + ), + ]; + + const getNavigationDrawerIsSubnav = navigationDrawer => + navigationDrawer.classList.contains('NavigationDrawer-submenuItem'); + + const handleNavigationDrawerInactive = navigationDrawer => { + const menuItems = getNavigationDrawerMenuItems(navigationDrawer); + navigationDrawer.classList.remove('is-active'); + const parentMenuItem = navigationDrawer + .closest('.NavigationDrawer-listItem') + ?.querySelector(':scope > a'); + parentMenuItem?.focus(); + + menuItems.forEach(item => item.setAttribute('tabindex', '-1')); + + menuItems[0].removeEventListener( + 'keydown', + handleMenuItemTabLeft.bind(navigationDrawer) + ); + menuItems[menuItems.length - 1].removeEventListener( + 'keydown', + handleMenuItemTabRight.bind(navigationDrawer) + ); + + if (navigationDrawer === header) { + headerbuttons[0]?.focus(); + } + }; + + const handleNavigationDrawerActive = navigationDrawer => { + const menuItems = getNavigationDrawerMenuItems(navigationDrawer); + + navigationDrawer.classList.add('is-active'); + menuItems.forEach(item => item.setAttribute('tabindex', '0')); + menuItems[0].focus(); + + menuItems[0].addEventListener( + 'keydown', + handleMenuItemTabLeft.bind(this, navigationDrawer) + ); + menuItems[menuItems.length - 1].addEventListener( + 'keydown', + handleMenuItemTabRight.bind(this, navigationDrawer) + ); + }; + + const handleMenuItemTabLeft = (navigationDrawer, e) => { + if (e.key === 'Tab' && e.shiftKey) { + e.preventDefault(); + handleNavigationDrawerInactive(navigationDrawer); + } + }; + + const handleMenuItemTabRight = (navigationDrawer, e) => { + if (e.key === 'Tab' && !e.shiftKey) { + e.preventDefault(); + handleNavigationDrawerInactive(navigationDrawer); + } + }; + + const prepMobileNavigationDrawer = navigationDrawer => { + const isSubnav = getNavigationDrawerIsSubnav(navigationDrawer); + const menuItems = getNavigationDrawerMenuItems(navigationDrawer); + + navigationDrawer.addEventListener('keyup', e => { + if (e.key === 'Escape') { + handleNavigationDrawerInactive(navigationDrawer); + } }); - }); + + menuItems.forEach(item => { + const parentLi = item.closest('li'); + if ( + parentLi && + parentLi.classList.contains('js-mobile-subnav-trigger') + ) { + const submenu = parentLi.querySelector( + '.NavigationDrawer-submenuItem' + ); + item.addEventListener('click', () => { + handleNavigationDrawerActive(submenu); + }); + } + }); + if (isSubnav) { + handleNavigationDrawerInactive(navigationDrawer); + navigationDrawer + .querySelector('.NavigationDrawer-header') + .addEventListener('click', e => { + e.preventDefault(); + handleNavigationDrawerInactive(navigationDrawer); + }); + } + }; + + document + .querySelectorAll('.NavigationDrawer') + .forEach(drawer => prepMobileNavigationDrawer(drawer)); + handleNavigationDrawerInactive(header); } function registerSolutionsTabs() { @@ -45,7 +215,7 @@ window.initFuncs = []; const tabs = tabList.querySelectorAll('[role="tab"]'); let tabFocus = getTabFocus(); - changeTabs({ target: tabs[tabFocus] }) + changeTabs({target: tabs[tabFocus]}); tabs.forEach(tab => { tab.addEventListener('click', changeTabs); @@ -113,7 +283,7 @@ window.initFuncs = []; // Set this tab as selected target.setAttribute('aria-selected', true); - setTabFocus(target.id) + setTabFocus(target.id); // Hide all tab panels grandparent @@ -162,9 +332,7 @@ window.initFuncs = []; async function getLatestVersion() { let version = 'go1.17'; // fallback version if fetch fails try { - const versionData = await ( - await fetch('/dl/?mode=json') - ).json(); + const versionData = await (await fetch('/dl/?mode=json')).json(); if (!versionData.length) { return version; } @@ -183,8 +351,10 @@ window.initFuncs = []; */ function initialThemeSetup() { - const theme = document.cookie.match(/prefers-color-scheme=(light|dark|auto)/)?.[1] - + const themeCookie = document.cookie.match( + /prefers-color-scheme=(light|dark|auto)/ + ); + const theme = themeCookie && themeCookie.length > 0 && themeCookie[1]; if (theme) { document.querySelector('html').setAttribute('data-theme', theme); } @@ -202,7 +372,8 @@ window.initFuncs = []; } /** - * toggleTheme switches the preferred color scheme between auto, light, and dark. + * toggleTheme switches the preferred color scheme between auto, light, and + * dark. */ function toggleTheme() { let nextTheme = 'dark'; @@ -218,8 +389,7 @@ window.initFuncs = []; domain = 'domain=.go.dev;'; } document.documentElement.setAttribute('data-theme', nextTheme); - document.cookie = - `prefers-color-scheme=${nextTheme};${domain}path=/;max-age=31536000;`; + document.cookie = `prefers-color-scheme=${nextTheme};${domain}path=/;max-age=31536000;`; } initialThemeSetup(); diff --git a/_content/menus.yaml b/_content/menus.yaml index 1814cabb..314fd52e 100644 --- a/_content/menus.yaml +++ b/_content/menus.yaml @@ -1,72 +1,127 @@ main: - name: Why Go url: /solutions/ - - name: Get Started + children: + - name: Case Studies + explanation: Common problems companies solve with Go + url: /solutions#case-studies + - name: Use Cases + explanation: Stories about how and why companies use Go + url: /solutions#use-cases + - name: Security Policy + explanation: How Go can help keep you secure by default + url: /security/policy/ + - name: Learn url: /learn/ - name: Docs url: /doc/ + children: + - name: Effective Go + explanation: Tips for writing clear, performant, and idiomatic Go code + url: /doc/effective_go + - name: Go User Manual + explanation: A complete introduction to building software with Go + url: /doc + - name: Standard library + explanation: Reference documentation for Go's standard library + url: https://pkg.go.dev/std + - name: Release Notes + explanation: Learn what's new in each Go release + url: /doc/devel/release - name: Packages url: https://pkg.go.dev - - name: Play - url: /play/ - - name: Blog - url: /blog/ + - name: Community + url: /example/ + children: + - name: Recorded Talks + explanation: Videos from prior events + url: /talks/ + - name: Meetups + explanation: Meet other local Go developers + url: https://www.meetup.com/pro/go + external: true + - name: Conferences + explanation: Learn and network with Go developers from around the world + url: https://github.com/golang/go/wiki/Conferences + external: true + - name: Go blog + explanation: The Go project's official blog. + url: /blog + - name: Go project + explanation: Get help and stay informed from Go + url: /help + - name: Get connected + socialIconsList: + [ + { + img: google-groups.svg, + url: 'https://groups.google.com/g/golang-nuts', + }, + {img: github.svg, url: 'https://github.com/golang'}, + {img: twitter.svg, url: 'https://twitter.com/golang'}, + {img: reddit.svg, url: 'https://www.reddit.com/r/golang/'}, + {img: slack.svg, url: 'https://invite.slack.golangbridge.org/'}, + { + img: stack-overflow.svg, + url: 'https://stackoverflow.com/collectives/go', + }, + ] footer: - name: Why Go url: /solutions/ children: - - name: Use Cases - url: /solutions/#use-cases - - name: Case Studies - url: /solutions/#case-studies + - name: Use Cases + url: /solutions/#use-cases + - name: Case Studies + url: /solutions/#case-studies - name: Get Started url: /learn/ children: - - name: Playground - url: /play - - name: Tour - url: /tour/ - - name: Stack Overflow - url: https://stackoverflow.com/questions/tagged/go?tab=Newest - - name: Help - url: /help/ + - name: Playground + url: /play + - name: Tour + url: /tour/ + - name: Stack Overflow + url: https://stackoverflow.com/questions/tagged/go?tab=Newest + - name: Help + url: /help/ - name: Packages url: https://pkg.go.dev children: - - name: Standard Library - url: /pkg/ + - name: Standard Library + url: /pkg/ - name: About url: /project children: - - name: Download - url: /dl/ - - name: Blog - url: /blog/ - - name: Issue Tracker - url: https://github.com/golang/go/issues - - name: Release Notes - url: /doc/devel/release - - name: Brand Guidelines - url: /blog/go-brand - - name: Code of Conduct - url: /conduct + - name: Download + url: /dl/ + - name: Blog + url: /blog/ + - name: Issue Tracker + url: https://github.com/golang/go/issues + - name: Release Notes + url: /doc/devel/release + - name: Brand Guidelines + url: /blog/go-brand + - name: Code of Conduct + url: /conduct - name: Connect url: https://www.twitter.com/golang children: - - name: Twitter - url: https://www.twitter.com/golang - - name: GitHub - url: https://github.com/golang - - name: Slack - url: https://invite.slack.golangbridge.org/ - - name: r/golang - url: https://reddit.com/r/golang - - name: Meetup - url: https://www.meetup.com/pro/go - - name: Golang Weekly - url: https://golangweekly.com/ + - name: Twitter + url: https://www.twitter.com/golang + - name: GitHub + url: https://github.com/golang + - name: Slack + url: https://invite.slack.golangbridge.org/ + - name: r/golang + url: https://reddit.com/r/golang + - name: Meetup + url: https://www.meetup.com/pro/go + - name: Golang Weekly + url: https://golangweekly.com/ diff --git a/_content/site.tmpl b/_content/site.tmpl index 8559996e..65ee1ba1 100644 --- a/_content/site.tmpl +++ b/_content/site.tmpl @@ -62,7 +62,35 @@ {{- $currentPage := .}} {{- range $menus.main}}
  • - {{.name}} + + {{.name}} {{if .children}}arrow_drop_down{{end}} + + {{- if .children}} + + {{- end}}
  • {{- end}} @@ -95,9 +123,45 @@
    + + + {{ else }} + + {{ end }} {{- end}}