Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: Add collapsible menu to Header #1784

Merged
merged 64 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
730affb
Setup initial component
alimpens Nov 29, 2024
1e63ba3
Add tokens
alimpens Nov 29, 2024
17a7479
Use grid-area shorthand
alimpens Nov 30, 2024
98832e0
Move padding to header instead of grid
alimpens Dec 1, 2024
7fdceff
Make button bold on open without layout shift
alimpens Dec 1, 2024
d3f3259
Add animated menu icon
alimpens Dec 1, 2024
46b5702
Move subcomponent to separate file
alimpens Dec 4, 2024
600f87a
Update and document header props
alimpens Dec 4, 2024
51cddb1
Fix typo
alimpens Dec 4, 2024
bfc6d51
Add stories
alimpens Dec 4, 2024
2bbee62
Add ref, temp disable tests
alimpens Dec 4, 2024
fe05816
Close the menu when the menu button disappears
alimpens Dec 4, 2024
e26ae5e
Add showMenuButton enum, only render necessary markup
alimpens Dec 6, 2024
812aff7
Add story for header without menu
alimpens Dec 6, 2024
b5d1be9
Add secondary link list
alimpens Dec 6, 2024
32890bc
Hide cell instead of list, to prevent unwanted row gap
alimpens Dec 6, 2024
10742cb
Make story with always a menu button the default
alimpens Dec 6, 2024
7f77424
Rename menu prop to menuItems
alimpens Dec 6, 2024
ea2198b
Don't render Grid in Header itself, allow users to render what they w…
alimpens Dec 6, 2024
f41083b
Add NarrowScreenOnlyGridCell, use regular LinkList for content
alimpens Dec 9, 2024
da61baa
Use fixed instead of secondary as prop on MenuLink
alimpens Dec 9, 2024
8bf7f78
Change app name line height
alimpens Dec 9, 2024
d6b8b49
Disallow user-select for hidden duplicate brand section
alimpens Dec 9, 2024
e7e8312
Add missing token
alimpens Dec 9, 2024
746a0cf
Allow logo to grow to 56px
alimpens Dec 9, 2024
abe295c
Make sure app name line height override beats ams-heading
alimpens Dec 9, 2024
5852adb
Add extra padding block to header
alimpens Dec 9, 2024
6a8eb2a
Use noMenuButtonOnWideScreen boolean instead of showMenuButton enum
alimpens Dec 9, 2024
c915f14
Fix code view
alimpens Dec 9, 2024
3774a33
Make sure menu items have the same height, add padding block
alimpens Dec 9, 2024
2ef327b
Remove Header example from Avatar
alimpens Dec 10, 2024
aa90d32
Fix Header in Pages stories
alimpens Dec 10, 2024
077d165
Merge branch 'develop' of https://github.com/Amsterdam/design-system …
alimpens Dec 10, 2024
3830ac3
Fix build
alimpens Dec 10, 2024
3b02efa
Fix test
alimpens Dec 10, 2024
4df20e4
Use correct line height for app name
alimpens Dec 11, 2024
2a95aba
Add HeaderMenuLink tests and fix component
alimpens Dec 11, 2024
c7b4247
Group overlay CSS
alimpens Dec 11, 2024
aca9af8
Remove unnecessary classname
alimpens Dec 11, 2024
70f20f8
Add HeaderNarrowScreenOnlyGridCell tests
alimpens Dec 11, 2024
ce31dfa
Add Header tests
alimpens Dec 11, 2024
b4bd94b
Override grid inline padding from mega menu
alimpens Dec 11, 2024
0353786
Rename useMediaQuery to useIsAfterBreakpoint
alimpens Dec 13, 2024
7ea54ef
Use layout effect instead of regular effect
alimpens Dec 16, 2024
ac66c86
Rename brand section to branding, and app name to brand name
alimpens Dec 17, 2024
3eef970
Add comments
alimpens Dec 17, 2024
c5acb8c
Rename mixin
alimpens Dec 17, 2024
d5cf33f
Fix copy paste error
alimpens Dec 17, 2024
3d6c8b0
Fix typo
alimpens Dec 17, 2024
bdcc686
Use token for inline padding
alimpens Dec 18, 2024
0eab0c5
Rename GridCellNarrowWindowOnly
alimpens Dec 18, 2024
5ee9552
Revert deleting margin inline start
alimpens Dec 18, 2024
e324cd4
Update main README
alimpens Dec 18, 2024
fec77f7
Add docs
alimpens Dec 18, 2024
e0c637d
Rename noMenuButtonOnWideWindow
alimpens Dec 18, 2024
e71256c
Merge branch 'develop' of https://github.com/Amsterdam/design-system …
alimpens Dec 18, 2024
55d1744
Update spacing
alimpens Dec 20, 2024
2eebf8e
Menu items should be level 5
alimpens Dec 20, 2024
a819160
Merge branch 'develop' into feat/DES-884-update-header
VincentSmedinga Dec 20, 2024
7795bd3
Do not use Inloggen for disappearing links
alimpens Dec 20, 2024
f8c89bb
Merge branch 'feat/DES-884-update-header' of https://github.com/Amste…
alimpens Dec 20, 2024
0181ec1
Do not use grid space token for logo size
alimpens Dec 20, 2024
719c7fb
Merge branch 'develop' into feat/DES-884-update-header
VincentSmedinga Dec 20, 2024
cf84487
Allow custom headers for some kinds of pages
VincentSmedinga Dec 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions packages/css/src/components/header/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ Includes the name of the application if it is not the general website.
- It includes the logo of the City or the organization, the site title (except for the general website), and a menu with links to commonly used pages.
- The Header is important because it conveys our corporate identity and is the first thing people see.
Using it consistently helps users recognize and trust the website.
- It is the same on every page of the application.
- The page menu can contain a maximum of 5 items.
- The Header is the same on every page of the application, although full-screen pages may hide it, e.g. a video or a map.
- The inline menu can contain a maximum of 5 items.
The last two will often be ‘Search’ and ‘Menu’.
- Labels should be short to ensure the menu fits on one line, even on medium-wide screens.
- An icon can be added to the end of a link to make its function easier to find.
- The 'Menu' button opens a collapsible menu, which has room for more links.
- On narrow windows, links can move from the inline menu to the collapsible one.
- Labels should be short to help the inline menu fit on a single line whenever possible.
- An icon can be added to the end of a link to make its destination easier to guess.

## References

- A Header is a [landmark](https://www.w3.org/TR/wai-aria-practices-1.1/#aria_landmark_roles) and can be use to group navigation elements.
- A Header is a [landmark](https://www.w3.org/TR/wai-aria-practices-1.1/#aria_landmark_roles) and can be used to group navigation elements.
- [WCAG 3.2.3](https://wcag.com/designers/3-2-3-consistent-navigation/) Consistent Navigation: Navigation menus that appear on multiple pages are consistent.
234 changes: 182 additions & 52 deletions packages/css/src/components/header/header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,83 +4,213 @@
*/

@use "../../common/breakpoint" as *;
@use "../../common/text-rendering" as *;

.ams-header {
/*
* The branding section is created twice: once outside the navigation and once hidden inside it.
* This keeps all navigation in one nav element and lets the menu wrap around the branding section.
* Display grid is used to let both branding sections overlap.
*/
display: grid;
padding-block: var(--ams-header-padding-block);
padding-inline: var(--ams-header-padding-inline);
}

.ams-header__branding {
align-items: center;
align-self: start; // To align the branding section to the top of the header when it wraps
column-gap: var(--ams-header-branding-column-gap);
display: flex;
flex-wrap: wrap;
padding-block: var(--ams-header-padding-block);
row-gap: 1.5rem;
grid-area: 1 / 1; // To allow this section to overlap with the second branding section
}

@media screen and (min-width: $ams-breakpoint-wide) {
column-gap: var(--ams-header-column-gap);
flex-wrap: nowrap;
}
.ams-header__branding--hidden {
opacity: 0%;
VincentSmedinga marked this conversation as resolved.
Show resolved Hide resolved
user-select: none; // The hidden branding section should not be selectable
}

.ams-header__logo-link {
flex: none;
outline-offset: var(--ams-header-logo-link-outline-offset);
}

.ams-header__links {
display: none;
/* TODO Remove after updating Heading line heights in DES-973. */
.ams-heading.ams-header__brand-name {
line-height: 1.35;
}

.ams-header__navigation {
column-gap: var(--ams-header-navigation-column-gap);
display: flex;
flex-wrap: wrap;
grid-area: 1 / 1; // To allow this section to overlap with the branding section
// This section blocks pointer events initially, so the hidden branding section can't be activated.
// The menu and collapsible menu set it back to auto, to make sure they can be activated.
pointer-events: none;
row-gap: var(--ams-header-navigation-row-gap);
}

@mixin reset-list {
list-style: none;
margin-block: 0;
padding-inline-start: 0;
}

.ams-header__menu {
align-items: center;
column-gap: var(--ams-header-menu-column-gap);
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
margin-inline-start: auto;
pointer-events: auto; // Set pointer events back to auto to allow the menu to be activated
row-gap: var(--ams-header-menu-row-gap);

@media screen and (min-width: $ams-breakpoint-medium) {
display: block;
flex: 10 0 auto;
@include reset-list;
}

// Do not show menu items below the wide breakpoint...
.ams-header__menu-item {
@media screen and (not (min-width: $ams-breakpoint-wide)) {
display: none;
}
}

@media screen and (min-width: $ams-breakpoint-wide) {
order: 3;
// ...unless they're fixed.
.ams-header__menu-item--fixed {
display: revert;
}

@mixin header-menu-action {
color: var(--ams-header-menu-item-color);
font-family: var(--ams-header-menu-item-font-family);
font-size: var(--ams-header-menu-item-font-size);
font-weight: var(--ams-header-menu-item-font-weight);
line-height: var(--ams-header-menu-item-line-height);
outline-offset: var(--ams-header-menu-item-outline-offset);
padding-block: var(--ams-header-menu-item-padding-block);
touch-action: manipulation;
white-space: nowrap;

@include text-rendering;

&:hover {
color: var(--ams-header-menu-item-hover-color);
}
}

.ams-header__menu {
flex: 1;
padding-inline-start: var(--ams-page-menu-column-gap); // TODO Don’t use tokens of another component
text-align: end;
.ams-header__menu-link {
display: inline-block;
text-decoration-line: var(--ams-header-menu-link-text-decoration-line);
text-decoration-thickness: var(--ams-header-menu-link-text-decoration-thickness);
text-underline-offset: var(--ams-header-menu-link-text-underline-offset);

@include header-menu-action;

&:hover {
text-decoration-line: var(--ams-header-menu-link-hover-text-decoration-line);
}
}

.ams-header__mega-menu-button-item--hide-on-wide-window {
@media screen and (min-width: $ams-breakpoint-wide) {
order: 4;
padding-inline-start: 0;
display: none;
}
}

.ams-header__app-name {
flex: 1 1 100%;
@mixin reset-button {
background: none;
border: 0;
margin-block: 0; // [1]
margin-inline: 0; // [1]
padding-inline: 0;

@media screen and (min-width: $ams-breakpoint-wide) {
min-inline-size: 0;
order: 2;

.ams-header__app-name-heading {
display: block;
inline-size: 100%;
line-height: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
// [1] Remove the margin in older Safari.
}

.ams-header__mega-menu-button {
column-gap: var(--ams-header-menu-item-column-gap);
cursor: pointer;
display: grid;
grid-auto-flow: column;

@include header-menu-action;
@include reset-button;
}

.ams-header__mega-menu-button[aria-expanded="true"] {
font-weight: var(--ams-header-mega-menu-button-label-open-font-weight);
}

.ams-header__mega-menu-button-label,
.ams-header__mega-menu-button-hidden-label {
grid-area: 1 / 1; // To allow the label and the hidden label to overlap
}

// This hidden label is used to prevent a layout shift when the mega menu is opened
// and the button text becomes bold.
.ams-header__mega-menu-button-hidden-label {
font-weight: var(--ams-header-mega-menu-button-label-open-font-weight);
pointer-events: none;
user-select: none;
visibility: hidden;
}

.ams-header__menu-icon {
line {
stroke: currentColor;
stroke-width: 3px;
transform-origin: center;
transition:
translate 0.1s ease-in-out,
rotate 0.2s ease-in-out,
opacity 0.1s ease-in-out;

@media (prefers-reduced-motion) {
transition: none;
}
}

.ams-header__menu-icon-top {
translate: 0 -7px;
}

.ams-header__menu-icon-bottom {
translate: 0 7px;
}
}

// Temporary – will move to Mega Menu and/or Icon Button
.ams-header__menu-button {
background-color: transparent;
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><path fill='%23004699' fill-rule='evenodd' d='M0 3.238h32V7.81H0V3.238zm0 10.476h32v4.572H0v-4.572zM0 24.19h32v4.572H0V24.19z'/></svg>");
background-position: center right;
background-repeat: no-repeat;
background-size: 1.1875rem 1.1875rem;
border: 0;
color: var(--ams-page-menu-item-color);
font-family: var(--ams-page-menu-item-font-family);
font-size: var(--ams-page-menu-item-font-size);
font-weight: var(--ams-page-menu-item-font-weight);
line-height: var(--ams-page-menu-item-line-height);
margin-block: 0;
margin-inline: 0;
padding-inline: 0 1.875rem;
text-align: center;
touch-action: manipulation;
.ams-header__menu-icon--open {
.ams-header__menu-icon-top {
rotate: 45deg;
translate: 0;
}
.ams-header__menu-icon-middle {
opacity: 0%;
}
.ams-header__menu-icon-bottom {
rotate: -45deg;
translate: 0;
}
}

.ams-header__mega-menu {
inline-size: 100%;
pointer-events: auto; // Set pointer events back to auto to allow the mega menu to be activated

// Remove inline padding from Grids that are used in the mega menu.
// The grid inline padding is set on the header element.
& .ams-grid {
padding-inline: 0;
}
}

.ams-header__mega-menu--closed.ams-header__mega-menu--closed {
display: none;
}

.ams-header__grid-cell-narrow-window-only {
@media screen and (min-width: $ams-breakpoint-wide) {
display: none;
}
}
2 changes: 1 addition & 1 deletion packages/css/src/components/logo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ The sub-brands are:
- The logo links to the homepage of the website or application.
- If the application is a form, application, or tool without a homepage, the logo links to the page where the form, application, or tool is referred to.

The height of the logo is always 40 pixels.
The logo is 40 pixels tall at its minimum, growing to 56 pixels in wider windows.
This also applies to sub-brand logos.

## Download
Expand Down
1 change: 1 addition & 0 deletions packages/css/src/components/logo/logo.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
.ams-logo {
block-size: var(--ams-logo-block-size);
display: block;
min-block-size: var(--ams-logo-min-block-size);
}

.ams-logo__emblem {
Expand Down
Loading
Loading