Skip to content

Commit

Permalink
Task/internal 28 update page header component 782 (#793)
Browse files Browse the repository at this point in the history
  • Loading branch information
bluemoonecho authored Jan 17, 2024
1 parent 77060e1 commit 724581e
Show file tree
Hide file tree
Showing 14 changed files with 443 additions and 362 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

### Added

- New Pageheader Organism-level component, that encapsulates what was previously an example component built using utility classes.

- Updates the layout of the Sidebar component, improvements to the scrolling behavior and uses the invisible button variant.

- Badge with Label, added an example showing a text label rendered next to a badge component, to the badge docs.
- A new layout component at `atoms/switcher`, that lays out its children in a horizontal row with consistent spacing between children. The layout switches to a vertical stack once the width of the component passes below a threshold, or the number of children goes over a limit.
- A new layout component at `atoms/stack`, that lays out its children vertically, with consistent spacing between children.
Expand Down
1 change: 1 addition & 0 deletions scss/bitstyles/organisms/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@
@forward './notification-center' as notification-center-*;
@forward './table' as table-*;
@forward './joined-ui' as joined-ui-*;
@forward './page-header' as page-header-*;
157 changes: 157 additions & 0 deletions scss/bitstyles/organisms/page-header/PageHeader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import icons from '../../../../assets/images/icons.svg';
import Button from '../../atoms/button/Button';

const PageHeader = ({
topLeft,
topRight,
centerLeft,
centerRight,
bottomLeft,
bottomRight,
}) => {
const pageHeader = document.createElement('header');
pageHeader.classList.add('o-page-header');
const content = document.createElement('div');
content.classList.add('a-content', 'o-page-header__content');

pageHeader.appendChild(content);

const contentPositions = [
{ position: 'top-left', content: topLeft },
{ position: 'top-right', content: topRight },
{ position: 'center-left', content: centerLeft },
{ position: 'center-right', content: centerRight },
{ position: 'bottom-left', content: bottomLeft },
{ position: 'bottom-right', content: bottomRight },
];

contentPositions.forEach((item) => {
if (item.content) {
const contentElement = document.createElement('div');
contentElement.classList.add(`o-page-header__${item.position}`);
contentElement.appendChild(item.content);
content.appendChild(contentElement);
}
});

return pageHeader;
};

export default PageHeader;

export const breadCrumbsMenu = document.createElement('ol');
breadCrumbsMenu.classList.add(
'u-h7',
'u-list-none',
'u-flex',
'u-flex-wrap',
'u-items-center'
);
breadCrumbsMenu.innerHTML = `
<li className="u-margin-s4-right u-flex u-items-center">
<a href="/">Main section</a>
<svg
width="18"
height="18"
className="a-icon a-icon--m u-fg-grayscale u-margin-s4-left"
aria-hidden="true"
focusable="false"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 100 100"
>
<use xlinkHref="${icons}#icon-caret-right" />
</svg>
</li>
<li className="u-margin-s4-right u-flex u-items-center">
<a href="/">Sub section</a>
<svg
width="18"
height="18"
className="a-icon a-icon--m u-fg-grayscale u-margin-s4-left"
aria-hidden="true"
focusable="false"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 100 100"
>
<use xlinkHref="${icons}#icon-caret-right" />
</svg>
</li>
<li className="u-margin-s4-right u-flex u-items-center">
<a href="/">Sub page</a>
<svg
width="18"
height="18"
className="a-icon a-icon--m u-fg-grayscale u-margin-s4-left"
aria-hidden="true"
focusable="false"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 100 100"
>
<use xlinkHref="${icons}#icon-caret-right" />
</svg>
</li>`;

export const header = document.createElement('header');
header.innerHTML = `
<div class="u-flex u-justify-between u-flex-wrap u-items-center u-margin-m-y">
<div class="u-flex u-flex-wrap u-items-center">
<h1 class="u-margin-m-right u-break-text">Title Header</h1>
<div class="u-flex-shrink-0 u-margin-m-bottom@s">
<span class="a-badge u-font-medium" data-theme="brand-1">Online</span>
</div>
</div>
</div>`;

export const tabs = document.createElement('ul');
tabs.classList.add(
'u-list-none',
'u-flex',
'u-overflow-x-auto',
'u-items-end',
'a-button--tab-container',
'u-margin-m-bottom'
);
tabs.setAttribute('role', 'tablist');
tabs.setAttribute('aria-label', 'Data');

const tabsListItem = document.createElement('li');
tabsListItem.classList.add('u-margin-s2-right');

const tabsButton = ({ label, ariaSelected, ariaControls }) =>
Button({
classname: ['a-button', 'a-button--tab'],
children: label,
role: 'tab',
ariaSelected,
ariaControls,
});

const tabsLabels = [
{
label: 'Tab1',
ariaSelected: true,
ariaControls: 'tab-panel-1',
},
{
label: 'Tab2',
ariaSelected: false,
ariaControls: 'tab-panel-2',
},
{
label: 'Tab3',
ariaSelected: false,
ariaControls: 'tab-panel-3',
},
];

tabsLabels.forEach((item) =>
tabs.appendChild(
tabsListItem.appendChild(
tabsButton({
label: item.label,
ariaSelected: item.ariaSelected,
ariaControls: item.ariaControls,
})
)
)
);
50 changes: 50 additions & 0 deletions scss/bitstyles/organisms/page-header/_index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
@forward 'settings';
@use './settings';
@use '../../tools/media-query';
@use '../../tools/classname';

#{classname.get($classname-items: 'page-header', $layer: 'organism')} {
padding-top: settings.$padding-top;
background-color: settings.$background-color;

@include media-query.get('m') {
&__content {
display: grid;
grid-template-areas:
'top-left top-right'
'center-left center-right'
'bottom-left bottom-right';
grid-template-columns: repeat(2, minmax(0, 1fr));
}

&__top-left {
grid-area: top-left;
}

&__top-right {
display: flex;
grid-area: top-right;
justify-content: flex-end;
}

&__center-left {
grid-area: center-left;
}

&__center-right {
display: flex;
grid-area: center-right;
justify-content: flex-end;
}

&__bottom-left {
grid-area: bottom-left;
}

&__bottom-right {
display: flex;
grid-area: bottom-right;
justify-content: flex-end;
}
}
}
6 changes: 6 additions & 0 deletions scss/bitstyles/organisms/page-header/_settings.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@use '../../tools/design-token';

$padding-top: var(design-token.get('size', 'm')) !default;
$background-color: var(
design-token.get('color', 'grayscale', 'light-3')
) !default;
56 changes: 56 additions & 0 deletions scss/bitstyles/organisms/page-header/page-header.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import PageHeader, { breadCrumbsMenu, header, tabs } from './PageHeader';

export default {
title: 'Organisms/Page Header',
component: PageHeader,
argTypes: {
topLeft: {
description: 'The top left area of the header',
},
topRight: {
description: 'The top right area of the header',
},
centerLeft: {
description: 'The center left of the header',
},
centerRight: {
description: 'The center right area of the header',
},
bottomLeft: {
description: 'The bottom left area of the header',
},
bottomRight: {
description: 'The bottom right area of the header',
},
},
};

const Template = (args) => PageHeader(args);

export const Default = Template.bind({});
Default.args = {
topLeft: breadCrumbsMenu,
topRight: breadCrumbsMenu.cloneNode(true),
centerLeft: header,
bottomLeft: tabs,
};
Default.parameters = {
zeplinLink: [
{
name: 'default',
link: 'https://app.zeplin.io/styleguide/63079b90d0bf4a646c46c227/components?coid=6407627ec0507f42b9eec653',
},
],
};

export const NoBottomSlot = Template.bind({});
NoBottomSlot.args = {
topLeft: breadCrumbsMenu.cloneNode(true),
centerLeft: header.cloneNode(true),
};

export const OnlyTopSlot = Template.bind({});
OnlyTopSlot.args = {
topLeft: header.cloneNode(true),
topRight: breadCrumbsMenu.cloneNode(true),
};
92 changes: 92 additions & 0 deletions scss/bitstyles/organisms/page-header/page-header.stories.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { Canvas, Meta, Story } from '@storybook/addon-docs';
import icons from '../../../../assets/images/icons.svg';
import PageHeader from './PageHeader.js';

<Meta title="Organisms/Page Header/Overview" />

# Page header

The intro to every page, containing slots for:

- [breadcrumbs](/docs/ui-navigation-breadcrumbs--breadcrumbs)
- page title
- status [badge](/docs/atoms-badge--badge)
- action [buttons](/docs/ui-buttons-buttons--page)
- [tabs](/docs/ui-navigation-tabs--tabs) for organising the content (note that no tabpanels are shown here)

<details class="u-margin-l3-y">
<summary class="u-h4 u-font-medium">Examples use</summary>
<ul>
<li>
<a href="/docs/atoms-button-base--button-element">a-button</a>
</li>
<li>
<a href="/docs/atoms-button-secondary--secondary">a-button--secondary</a>
</li>
<li>
<a href="/docs/atoms-button-tab--tab">a-button--tab</a>
</li>
<li>
<a href="/docs/atoms-badge--badge">a-badge</a>
</li>
<li>
<a href="/docs/atoms-content--content">a-content</a>
</li>
<li>
<a href="/docs/atoms-icon--icon">a-icon</a>
</li>
<li>
<a href="/docs/atoms-list-reset--list-reset">u-list-none</a>
</li>
<li>
<a href="/docs/utilities-background-color--grayscale-dark">u-bg</a>
</li>
<li>
<a href="/docs/utilities-break-text--break-text">u-break-text</a>
</li>
<li>
<a href="/docs/utilities-flex--flex">u-flex</a>
</li>
<li>
<a href="/docs/utilities-typography--typography">u-h6</a>
</li>
<li>
<a href="/docs/utilities-box-alignment--items-start">u-items-start</a>
</li>
<li>
<a href="/docs/utilities-box-alignment--justify-between">
u-justify-between
</a>
</li>
<li>
<a href="/docs/utilities-margin--margin-m">u-margin</a>
</li>
<li>
<a href="/docs/utilities-overflow--overflow-x">u-overflow</a>
</li>
<li>
<a href="/docs/utilities-padding--padding-m">u-padding</a>
</li>
<li>
<a href="/docs/utilities-relative--relative">u-relative</a>
</li>
</ul>
</details>

This first example shows a header with all rows filled:

<Canvas>
<Story id="organisms-page-header--default" />
</Canvas>

Only using the top and central slots:

<Canvas>
<Story id="organisms-page-header--no-bottom-slot" />
</Canvas>

This is a minimal example, with only the top slot:

<Canvas>
<Story id="organisms-page-header--only-top-slot" />
</Canvas>
1 change: 1 addition & 0 deletions scss/bitstyles/ui/extending-bitstyles.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Add your own components at the end of the `@use` statements importing from `bits
@use 'bitstyles/organisms/notification-center';
@use 'bitstyles/organisms/table';
@use 'bitstyles/organisms/joined-ui';
@use 'bitstyles/organisms/page-header';

//

Expand Down
Loading

0 comments on commit 724581e

Please sign in to comment.