Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 5 additions & 1 deletion labs/gb/components/navbar/_nav-bar-tokens.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
--container-color: var(--md-sys-color-surface-container);
--container-elevation: var(--md-sys-elevation-shadow-2);
--container-height: 64px;
--container-leading-space: 0px;
--container-shadow-color: var(--md-sys-color-shadow);
--container-shape: var(--md-sys-shape-corner-none);
--container-trailing-space: 0px;
--item-active-icon-color: var(--md-sys-color-on-secondary-container);
--item-active-indicator-color: var(--md-sys-color-secondary-container);
--item-active-indicator-height: 32px;
Expand Down Expand Up @@ -43,8 +45,10 @@
}

@mixin item-horizontal {
--container-leading-space: 16px;
--container-trailing-space: 16px;
--item-active-indicator-height: 40px;
--item-active-indicator-icon-label-space: 8px;
--item-active-indicator-icon-label-space: 4px;
--item-active-indicator-leading-space: 16px;
--item-active-indicator-trailing-space: 16px;
--item-active-indicator-width: auto;
Expand Down
9 changes: 5 additions & 4 deletions labs/gb/components/navbar/demo/stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,22 +38,23 @@ const styles = css`
border: 1px solid var(--md-sys-color-outline-variant);
border-radius: 16px;
box-shadow: var(--md-sys-elevation-shadow-1);
box-sizing: border-box;
display: flex;
inline-size: 412px;
justify-content: center;
margin-bottom: 24px;
min-height: 160px;
min-inline-size: 320px;
overflow: hidden;
padding: 0;
width: 100%;
max-width: 640px;
resize: horizontal;
}

.demo-stack {
align-items: flex-start;
display: flex;
flex-direction: column;
gap: 24px;
width: 100%;
max-width: 640px;
}
`;

Expand Down
9 changes: 9 additions & 0 deletions labs/gb/components/navbar/nav-bar-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@ import {NavBarItemElement} from './nav-bar-item-element.js';
* @cssprop --container-color
* @cssprop --container-elevation
* @cssprop --container-height
* @cssprop --container-leading-space
* @cssprop --container-shadow-color
* @cssprop --container-shape
* @cssprop --container-trailing-space
* @cssprop --item-active-icon-color
* @cssprop --item-active-indicator-color
* @cssprop --item-active-indicator-height
Expand Down Expand Up @@ -83,6 +85,13 @@ export class NavBarElement extends AriaTablistElement {

protected override updated(changedProperties: PropertyValues<this>) {
super.updated(changedProperties);
// GM3 navigation bars move between items with Tab (not arrow keys), so
// opt out of the `tablist` focusgroup that AriaTablistElement sets. In
// browsers with native focusgroup support, that would otherwise collapse
// each bar to a single Tab stop.
if (this.getAttribute('focusgroup') !== 'none') {
this.setAttribute('focusgroup', 'none');
}
if (changedProperties.has('itemLayout')) {
this.syncItemsLayout();
}
Expand Down
4 changes: 4 additions & 0 deletions labs/gb/components/navbar/nav-bar-item-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ export class NavBarItemElement extends AriaTabElement {
min-width: 48px;
outline: none;
}

:host([item-layout='horizontal']) {
flex: 0 1 auto;
}
`,
];

Expand Down
52 changes: 48 additions & 4 deletions labs/gb/components/navbar/nav-bar.scss
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@

:host(md-gb-nav-bar-item[item-layout='horizontal']) {
@include nav-bar-tokens.item-horizontal;

// Horizontal items size to their content; extra space goes to the ends of
// the navigation bar instead of stretching each item.
flex: 0 1 auto;
}

:host(md-gb-nav-bar-item[item-layout='vertical']) {
Expand Down Expand Up @@ -78,6 +82,8 @@
justify-content: space-around;
margin: 0;
padding: 0;
padding-inline: var(--container-leading-space)
var(--container-trailing-space);
position: relative;
transition: all var(--motion-duration) var(--motion-easing);
user-select: none;
Expand All @@ -90,6 +96,8 @@

&.nav-bar-horizontal {
@include nav-bar-tokens.item-horizontal;

justify-content: center;
}

&.nav-bar-vertical {
Expand Down Expand Up @@ -130,6 +138,24 @@
user-select: none;
width: 100%;
-webkit-tap-highlight-color: transparent;
// The item's positioned descendants (the active indicator and badges)
// paint after the item's own outline, so they covered the focus ring.
// Draw the ring on `::after` above them instead; it inherits the
// `--focus-ring-*` values set by the focus ring classes.
isolation: isolate;
outline: none;

&::after {
animation: var(--focus-ring-animation, none);
border-radius: inherit;
content: '';
inset: 0;
outline: var(--focus-ring-outline, none);
outline-offset: var(--focus-ring-offset, 0);
pointer-events: none;
position: absolute;
z-index: 3;
}

&:disabled,
&[disabled],
Expand Down Expand Up @@ -160,6 +186,7 @@
border-radius: var(--item-active-indicator-shape);
color: var(--item-inactive-icon-color);
display: flex;
flex-shrink: 0;
height: var(--item-active-indicator-height);
isolation: isolate;
justify-content: center;
Expand Down Expand Up @@ -203,6 +230,11 @@
}

.nav-bar-item-badge {
// The badge is positioned inside the icon container, which centers the
// icon. These locate the icon's block-start and inline-end edges so badges
// anchor to the icon's top corner in both item layouts.
--_icon-block-start: calc((100% - var(--item-icon-size)) / 2);
--_icon-inline-end: calc(50% + var(--item-icon-size) / 2);
align-items: center;
background-color: var(--md-sys-color-error);
border-radius: var(--md-sys-shape-corner-full);
Expand All @@ -211,8 +243,10 @@
display: inline-flex;
font: var(--md-sys-typescale-label-sm);
height: 16px;
inset-block-start: -4px;
inset-inline-start: calc(50% + 2px);
// Large badges overlap the icon's top corner: they start 12px before the
// icon's inline-end edge and 2px above its block-start edge.
inset-block-start: calc(var(--_icon-block-start) - 2px);
inset-inline-start: calc(var(--_icon-inline-end) - 12px);
justify-content: center;
min-width: 16px;
padding-inline: 4px;
Expand All @@ -224,8 +258,9 @@

.nav-bar-item-badge-dot {
height: 6px;
inset-block-start: 0;
inset-inline-start: calc(50% + 6px);
// Small badges sit inside the icon's top corner, touching both edges.
inset-block-start: var(--_icon-block-start);
inset-inline-start: calc(var(--_icon-inline-end) - 6px);
min-width: 6px;
padding-inline: 0;
width: 6px;
Expand Down Expand Up @@ -254,12 +289,21 @@
.nav-bar-item-horizontal {
@include nav-bar-tokens.item-horizontal;

// Horizontal items size to their content; extra space goes to the ends of
// the navigation bar instead of stretching each item. This covers the
// CSS-only class API, where items are direct children of the bar.
.nav-bar-horizontal > & {
flex: 0 1 auto;
width: auto;
}

.nav-bar-item-content {
display: inline-flex;
flex-direction: row;
gap: var(--item-active-indicator-icon-label-space);
height: var(--item-active-indicator-height);
isolation: isolate;
max-inline-size: 100%;
padding-block: 0;
padding-inline: var(--item-active-indicator-leading-space)
var(--item-active-indicator-trailing-space);
Expand Down
Loading
Loading