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

Task/internal 31 update sidebar component 763 #794

Merged
merged 14 commits into from
Jan 16, 2024
216 changes: 216 additions & 0 deletions scss/bitstyles/organisms/sidebar/Sidebar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
import logoLarge from '../../../../test/assets/images/logoLarge.svg';
import Button from '../../atoms/button/Button';
import icons from '../../../../assets/images/icons.svg';

export const logoImg = document.createElement('img');
logoImg.src = logoLarge;
logoImg.width = '150';
logoImg.height = '50';
logoImg.alt = 'Company logo';
logoImg.classList.add(
'u-flex-shrink-0',
'u-margin-m-left',
'u-margin-m-right',
'u-margin-m-bottom'
);

export const buttonList = document.createElement('ul');
buttonList.classList.add(
'u-flex-grow-1',
'u-flex-shrink-1',
'u-overflow-y-auto',
'u-list-none',
'u-flex',
'u-flex-col',
'u-items-start',
'u-items-stretch',
'u-padding-s4-right',
'u-padding-s4-left'
);

const listItem = document.createElement('li');
listItem.classList.add('u-margin-s2-bottom', 'u-flex');

const buttomComponent = (label) =>
Button({
classname: ['u-justify-start'],
children: `<svg width="20" height="20" class="a-icon a-icon--m" aria-hidden="true" focusable="false"><use xlink:href="${icons}#icon-caret-right"></use></svg><span class="u-margin-s1-left">${label}</span>`,
colorVariant: ['transparent'],
});

const labels = [
'Dashboard',
'Projects',
'Team',
'Customers',
'Bookings',
'Sales',
];

labels.forEach((label) =>
buttonList.appendChild(listItem.appendChild(buttomComponent(label)))
);

export const bottom = document.createElement('div');
bottom.innerHTML = `
<hr class="u-border-grayscale-light-1-top" />
<div
class="u-flex-shrink-0 u-padding-s4-y u-margin-s4-left u-margin-s4-right u-border-grayscale-dark-top u-relative"
x-data="{ dropdownOpen: false }"
>
<button
type="button"
class="a-button a-button--large a-button--transparent"
aria-controls="dropdown-4"
@click="dropdownOpen = !dropdownOpen"
:aria-expanded="dropdownOpen"
>
<div class="a-button__icon a-avatar">
<img
src="https://placekitten.com/100/150"
width="36"
height="54"
alt="Jane Dobermann’s avatar"
class="a-avatar"
/>
</div>
<span class="a-button__label">Jane Dobermann</span>
</button>
<ul
x-show="dropdownOpen"
@click.away="dropdownOpen = false"
id="dropdown-4"
class="a-dropdown a-dropdown--full-width a-dropdown--top u-overflow-y-auto u-list-none u-margin-s2-bottom"
>
<li>
<a href="/" class="a-button a-button--transparent"> Settings </a>
</li>
<li>
<a href="/" class="a-button a-button--transparent"> Help </a>
</li>
<li>
<a href="/" class="a-button a-button--transparent"> Privacy </a>
</li>
<li role="separator"></li>
<li>
<a href="/" class="a-button a-button--transparent"> Sign out </a>
</li>
</ul>
</div>
`;

const Sidebar = ({ topSlot, children, bottomSlot, mainContent = '' }) => {
const sidebar = document.createElement('div');
sidebar.classList.add('u-flex', 'u-height-100vh', 'u-relative');

const nav = document.createElement('nav');
nav.classList.add('u-flex');
sidebar.appendChild(nav);

const sidebarLarge = document.createElement('div');
sidebarLarge.classList.add(
'u-hidden',
'o-sidebar--large',
'u-flex-shrink-0',
'u-bg-grayscale-light-4',
'u-padding-m-top',
'u-flex@l',
'u-flex-col'
);
nav.appendChild(sidebarLarge);

const sidebarSmall = document.createElement('div');
sidebarSmall.classList.add(
'o-sidebar--small',
'u-bg-grayscale-light-4',
'u-shadow-brand-1',
'u-flex',
'u-flex-col',
'u-hidden@l'
);
nav.appendChild(sidebarSmall);

let sidebarOpen = false;

const toggleSidebar = () => {
sidebarOpen = !sidebarOpen;
sidebarSmall.style.display = sidebarOpen ? 'flex' : 'none';
};

const closeButton = () =>
Button({
children: `<svg width="20" height="20" class="a-icon a-icon--m" aria-hidden="true" focusable="false"><use xlink:href="${icons}#icon-cross"></use></svg><span class="u-sr-only">Close Sidebar</span>`,
colorVariant: ['transparent'],
shapeVariant: ['square'],
onClick: () => toggleSidebar(),
});

sidebarSmall.appendChild(closeButton());

sidebarSmall.setAttribute('x-transition:enter', 'is-transitioning');
sidebarSmall.setAttribute('x-transition:enter-start', 'is-off-screen');
sidebarSmall.setAttribute('x-transition:enter-end', 'is-on-screen');
sidebarSmall.setAttribute('x-transition:leave', 'is-transitioning');
sidebarSmall.setAttribute('x-transition:leave-start', 'is-on-screen');
sidebarSmall.setAttribute('x-transition:leave-end', 'is-off-screen');

if (topSlot) {
sidebarLarge.appendChild(topSlot.cloneNode(true));
sidebarSmall.appendChild(topSlot);
}
if (children) {
sidebarLarge.appendChild(children.cloneNode(true));
sidebarSmall.appendChild(children);
}
if (bottomSlot) {
sidebarLarge.appendChild(bottomSlot.cloneNode(true));
sidebarSmall.appendChild(bottomSlot);
}

const main = document.createElement('main');
main.classList.add(
'u-flex-grow-1',
'u-padding-l4-left@l',
'u-padding-l3-right@l',
'u-padding-l3-bottom',
'u-padding-m',
'u-overflow-y-auto'
);
sidebar.appendChild(main);

const headerContainer = document.createElement('div');
headerContainer.classList.add(
'u-flex',
'u-items-center',
'u-margin-m-bottom'
);
main.appendChild(headerContainer);

const openButton = () =>
Button({
classname: [
'u-flex-shrink-0',
'u-margin-neg-m-left',
'u-margin-s4-right',
'u-hidden@l',
],
children: `<svg width="20" height="20" class="a-icon a-icon--m" aria-hidden="true" focusable="false"><use xlink:href="${icons}#icon-hamburger"></use></svg><span class="u-sr-only">Open Sidebar</span>`,
colorVariant: ['secondary'],
shapeVariant: ['square'],
onClick: () => toggleSidebar(),
});
headerContainer.appendChild(openButton());

const header = document.createElement('h1');
header.classList.add('u-margin-0');
header.innerHTML = 'Projects';
headerContainer.appendChild(header);

const mainContentDiv = document.createElement('div');
mainContentDiv.innerHTML = mainContent;
main.appendChild(mainContentDiv);

return sidebar;
};

export default Sidebar;
2 changes: 1 addition & 1 deletion scss/bitstyles/organisms/sidebar/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
}

#{classname.get($classname-items: 'sidebar--small', $layer: 'organism')} {
position: fixed;
position: absolute;
z-index: settings.$z-index;
top: 0;
bottom: 0;
Expand Down
50 changes: 50 additions & 0 deletions scss/bitstyles/organisms/sidebar/sidebar.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import Sidebar, { logoImg, buttonList, bottom } from './Sidebar';

export default {
title: 'Organisms/Sidebar',
component: Sidebar,
argTypes: {
topSlot: {
description:
'The top area of the sidebar, can be a compony logo for example',
},
children: {
description:
'All the items that will go on the center of the sidebar, a list of buttons for example',
},
bottomSlot: {
description:
'The bottom area of the sidebar, a footer, or avatar link for example ',
},
mainContent: {
description:
'Content that goes on the main area, not part of the sidebar',
},
},
};

const mainContent = `Cotton candy chupa chups gummi bears cupcake candy canes sweet gummi bears macaroon lollipop. Danish toffee cheesecake chocolate bar jelly-o chocolate cake. Candy canes gummi bears pie fruitcake candy canes powder cheesecake. Jelly marshmallow marzipan apple pie jelly cupcake. Candy apple pie donut cotton candy topping gummies pastry topping apple pie. Gummies ice cream cookie pudding caramels candy canes pie. Ice cream macaroon halvah pastry lemon drops cheesecake.</p>`;

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

export const Default = Template.bind({});
Default.args = {
topSlot: logoImg,
children: buttonList,
bottomSlot: bottom,
mainContent,
};
Default.parameters = {
zeplinLink: [
{
name: 'base',
link: 'https://app.zeplin.io/styleguide/63079b90d0bf4a646c46c227/components?coid=63c7b0d90bf0da0ef88e1f19',
},
],
};

export const Minimal = Template.bind({});
Minimal.args = {
children: buttonList.cloneNode(true),
mainContent,
};
Loading