Skip to content

Commit

Permalink
feat(sbb-header): introduce size s (#3047)
Browse files Browse the repository at this point in the history
  • Loading branch information
DavideMininni-Fincons authored Sep 12, 2024
1 parent dad8636 commit cd60922
Show file tree
Hide file tree
Showing 16 changed files with 286 additions and 88 deletions.
2 changes: 1 addition & 1 deletion .storybook/preview-head.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
}
}

@media screen and (width < 1023px) {
@media screen and (width < 1024px) {
.sbb-header-spacer {
display: none;
}
Expand Down
23 changes: 23 additions & 0 deletions src/elements/core/styles/core.scss
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,21 @@
// TODO: Check if infinity is supported by all browsers (e.g. Firefox) -> calc(1em * infinity);
--sbb-border-radius-infinity: 10000000em;

&:has(sbb-header[size='s']) {
--sbb-header-height: #{functions.px-to-rem-build(52)};
}

@include mediaqueries.mq($from: medium) {
// Header
--sbb-header-height: var(--sbb-spacing-fixed-24x);

// Time Input
--sbb-time-input-max-width: #{functions.px-to-rem-build(65)};
--sbb-time-input-s-max-width: #{functions.px-to-rem-build(58)};

&:has(sbb-header[size='s']) {
--sbb-header-height: var(--sbb-spacing-fixed-14x);
}
}
}
}
Expand Down Expand Up @@ -116,6 +124,21 @@ sbb-breadcrumb-group:not(:defined) {
pointer-events: all;
}

// Helper class for the application name and version in sbb-header.
.sbb-header-info {
@include typo.text-xs--regular;

display: flex;
padding-inline: var(--sbb-spacing-fixed-4x);
gap: var(--sbb-spacing-fixed-1x);
align-items: baseline;

strong + * {
font-size: var(--sbb-font-size-text-xxs);
color: var(--sbb-color-granite);
}
}

// In smaller title font-sizes, the space after the title is smaller than the default paragraph space before.
// Due to margin collapsing, the wrong paragraph space wins.
// To prevent the mistakenly large gap, we reset the paragraph space.
Expand Down
26 changes: 18 additions & 8 deletions src/elements/header/common/header-action.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,15 @@
--sbb-header-action-background-inset: 0;
--sbb-header-action-translate-y: 0;
--sbb-header-action-gap: var(--sbb-spacing-fixed-2x);
--sbb-header-action-icon-dimension: var(--sbb-size-icon-ui-small);

// If expanded, move it left by left padding.
// As result, the icon should be aligned with the left side of the page wrapper.
--sbb-header-first-item-margin-inline-start: calc(-1 * var(--sbb-header-action-padding-inline));
--_sbb-header-first-item-padding-shift: calc(-1 * var(--sbb-header-action-padding-inline));
--sbb-header-first-item-icon-shift: #{sbb.px-to-rem-build(2)};
--sbb-header-first-item-margin-inline-start: calc(
var(--_sbb-header-first-item-padding-shift) - var(--sbb-header-first-item-icon-shift)
);

@include sbb.if-forced-colors {
--sbb-header-action-border-color: CanvasText;
Expand Down Expand Up @@ -72,7 +77,10 @@
text-decoration: none;
min-height: var(--sbb-header-action-min-height);
min-width: var(--sbb-header-action-min-width);
padding-inline: var(--sbb-header-action-padding-inline);
padding-inline: var(
--sbb-header-action-padding-inline-zero,
var(--sbb-header-action-padding-inline)
);
cursor: pointer;
user-select: none;
outline: none;
Expand Down Expand Up @@ -121,8 +129,8 @@
--sbb-icon-svg-stroke-color: currentcolor;
--sbb-icon-svg-stroke-width: 1px;

min-width: var(--sbb-size-icon-ui-small);
min-height: var(--sbb-size-icon-ui-small);
min-width: var(--sbb-header-action-icon-dimension);
min-height: var(--sbb-header-action-icon-dimension);
line-height: 0;
}

Expand All @@ -142,10 +150,12 @@
// the first element in the header and needs left offset correction (see sbb-header.scss).
// To avoid duplicated css definitions, the value itself is assigned here in
// sbb-header-button/sbb-header-link instead of sbb-header.
//
// Move it left by 12px in collapsed width.
--sbb-header-first-item-margin-inline-start: #{sbb.px-to-rem-build(-12)};
--sbb-header-action-padding-inline: 0;

// Move it left by padding of header action to the icon itself.
--_sbb-header-first-item-padding-shift: calc(
-0.5 * (var(--sbb-header-action-min-width) - var(--sbb-header-action-icon-dimension))
);
--sbb-header-action-padding-inline-zero: 0;

.sbb-header-action__text {
@include sbb.screen-reader-only;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
export const snapshots = {};

snapshots["sbb-header renders DOM"] =
`<sbb-header>
`<sbb-header size="m">
</sbb-header>
`;
/* end snapshot sbb-header renders DOM */
Expand All @@ -24,7 +24,7 @@ snapshots["sbb-header renders Shadow DOM"] =
/* end snapshot sbb-header renders Shadow DOM */

snapshots["sbb-header renders actions and logo DOM"] =
`<sbb-header>
`<sbb-header size="m">
<sbb-header-link
data-action=""
data-link=""
Expand Down
9 changes: 9 additions & 0 deletions src/elements/header/header/header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

// Overwrites logo in slotted and default case
--sbb-logo-height: #{sbb.px-to-rem-build(16)};
--sbb-signet-height: #{sbb.px-to-rem-build(16)};
--sbb-header-position: fixed;
--sbb-header-transition-duration: var(
--sbb-disable-animation-zero-time,
Expand All @@ -20,6 +21,7 @@

@include sbb.mq($from: medium) {
--sbb-logo-height: #{sbb.px-to-rem-build(20)};
--sbb-signet-height: #{sbb.px-to-rem-build(20)};
}
}

Expand Down Expand Up @@ -105,6 +107,13 @@
margin-inline-start: var(--sbb-header-first-item-margin-inline-start);
}

::slotted(:is(sbb-header-button, sbb-header-link)) {
:host([size='s']) & {
--sbb-header-action-min-height: var(--sbb-size-element-xs);
--sbb-header-action-padding-inline: var(--sbb-spacing-fixed-4x);
}
}

::slotted(*) {
flex: 0 0 auto;
}
Expand Down
61 changes: 44 additions & 17 deletions src/elements/header/header/header.stories.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { withActions } from '@storybook/addon-actions/decorator';
import type { InputType } from '@storybook/types';
import type { Args, ArgTypes, Decorator, Meta, StoryObj } from '@storybook/web-components';
import type { TemplateResult } from 'lit';
import { nothing, type TemplateResult } from 'lit';
import { html } from 'lit';

import { sbbSpread } from '../../../storybook/helpers/spread.js';
Expand All @@ -13,6 +13,7 @@ import '../header-button.js';
import '../header-link.js';
import '../../divider.js';
import '../../menu.js';
import '../../signet.js';

const LoremIpsumTemplate = (): TemplateResult => html`
<div>
Expand All @@ -28,6 +29,13 @@ const LoremIpsumTemplate = (): TemplateResult => html`
<br />
`;

const appName = (): TemplateResult => html`
<span class="sbb-header-info">
<strong>Name</strong>
<span>V. 1.1</span>
</span>
`;

const HeaderBasicTemplate = (
{ attributes, ...args }: Args,
template: TemplateResult,
Expand All @@ -36,10 +44,11 @@ const HeaderBasicTemplate = (
<sbb-header-button icon-name="hamburger-menu-small" expand-from="small">
Menu
</sbb-header-button>
${args.size === 's' ? appName() : nothing}
<div class="sbb-header-spacer"></div>
<sbb-header-link href="https://www.sbb.ch" target="_blank" icon-name="magnifying-glass-small"
>Search</sbb-header-link
>
<sbb-header-link href="https://www.sbb.ch" target="_blank" icon-name="magnifying-glass-small">
Search
</sbb-header-link>
${template}
<sbb-header-button icon-name="globe-small" id="language-menu-trigger" class="last-element">
English
Expand All @@ -50,8 +59,24 @@ const HeaderBasicTemplate = (
<sbb-menu-button>Italiano</sbb-menu-button>
<sbb-menu-button icon-name="tick-small">English</sbb-menu-button>
</sbb-menu>
${args.size === 's'
? html`
<a slot="logo" aria-label="Homepage" href="/">
<sbb-signet slot="logo" protective-room="panel"></sbb-signet>
</a>
`
: html`
<a slot="logo" aria-label="Homepage" href="/">
<sbb-logo protective-room="none"></sbb-logo>
</a>
`}
</sbb-header>
<div ${sbbSpread(attributes)}>${new Array(12).fill(null).map(LoremIpsumTemplate)}</div>
<div
class=${args.expanded ? `sbb-page-spacing-expanded` : `sbb-page-spacing`}
${sbbSpread(attributes)}
>
${new Array(12).fill(null).map(LoremIpsumTemplate)}
</div>
`;

const Template = (args: Args): TemplateResult => html`
Expand Down Expand Up @@ -94,40 +119,39 @@ const expanded: InputType = {
control: {
type: 'boolean',
},
table: {
category: 'Header attribute',
},
};

const hideOnScroll: InputType = {
control: {
type: 'boolean',
},
table: {
category: 'Header attribute',
},
};

const scrollOrigin: InputType = {
control: {
type: 'text',
},
table: {
category: 'Header attribute',
};

const size: InputType = {
control: {
type: 'inline-radio',
},
options: ['m', 's'],
};

const argTypes: ArgTypes = {
expanded,
'hide-on-scroll': hideOnScroll,
'scroll-origin': scrollOrigin,
size,
};

const basicArgs: Args = {
expanded: false,
'hide-on-scroll': false,
'scroll-origin': undefined,
attributes: { class: 'sbb-page-spacing' },
size: size.options![0],
};

export const Basic: StoryObj = {
Expand All @@ -142,10 +166,15 @@ export const Expanded: StoryObj = {
args: {
...basicArgs,
expanded: true,
attributes: { class: 'sbb-page-spacing-expanded' },
},
};

export const SizeS: StoryObj = {
render: Template,
argTypes,
args: { ...basicArgs, size: size.options![1] },
};

export const WithUserMenu: StoryObj = {
render: TemplateWithUserMenu,
argTypes,
Expand All @@ -165,7 +194,6 @@ export const ExpandedScrollHide: StoryObj = {
...basicArgs,
expanded: true,
'hide-on-scroll': true,
attributes: { class: 'sbb-page-spacing-expanded' },
},
};

Expand All @@ -178,7 +206,6 @@ export const ContainerScrollOriginScrollHide: StoryObj = {
'scroll-origin': 'container',
attributes: {
id: 'container',
class: 'sbb-page-spacing',
style: 'height: 200px; overflow: auto;',
},
},
Expand Down
5 changes: 4 additions & 1 deletion src/elements/header/header/header.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ export class SbbHeaderElement extends SbbHydrationMixin(LitElement) {
@property({ attribute: 'hide-on-scroll', reflect: true, type: Boolean }) public hideOnScroll =
false;

/** Size of the header. */
@property({ reflect: true }) public size: 'm' | 's' = 'm';

@state() private _headerOnTop = true;

private _scrollElement: HTMLElement | Document | null | undefined;
Expand Down Expand Up @@ -126,7 +129,7 @@ export class SbbHeaderElement extends SbbHydrationMixin(LitElement) {
) {
this._closeOpenOverlays();
}
// Check if header is scrolled out of sight, scroll position > header height * 2.
// Check if the header is scrolled out of sight, scroll position > header height * 2.
if (currentScroll > this.offsetHeight * 2) {
this._headerOnTop = false;
if (currentScroll > 0 && this._lastScroll < currentScroll) {
Expand Down
Loading

0 comments on commit cd60922

Please sign in to comment.