Files
comp126/assignments/a4/components/header.js
2024-11-11 23:03:20 -05:00

337 lines
8.2 KiB
JavaScript

import { LitElement, html, css } from 'https://cdn.jsdelivr.net/gh/lit/dist@3/core/lit-core.min.js';
export class A4Header extends LitElement {
static properties = { open: false };
static styles = css`
:host {
display: block;
height: var(--header-height);
}
button {
cursor: pointer;
font-feature-settings: inherit;
font-variation-settings: inherit;
font-family: inherit;
font-size: 100%;
font-weight: inherit;
line-height: inherit;
letter-spacing: inherit;
color: inherit;
margin: 0;
padding: 0;
text-transform: none;
-webkit-appearance: button;
background-color: #0000;
background-image: none;
border: none;
}
a {
color: inherit;
text-decoration: inherit;
}
header {
position: absolute;
left: 0;
right: 0;
display: flex;
height: var(--header-height);
border-bottom: 1px solid rgb(17 24 39 / 0.1);
z-index: 50;
}
div.desktop {
width: 100%;
max-width: 80rem;
display: flex;
align-items: center;
justify-content: space-between;
margin: 0 auto;
padding: 0 1rem;
@media (min-width: 640px) {
padding: 0 1.5rem;
}
@media (min-width: 1024px) {
padding: 0 2rem;
}
& > div {
display: flex;
flex: 1;
align-items: center;
&:first-of-type {
column-gap: 1.5rem;
& > button {
margin: -0.75rem;
padding: 0.75rem;
color: var(--color-gray-700);
@media (min-width: 768px) {
display: none;
}
& > svg {
height: 1.5rem;
width: 1.5rem;
}
}
& > img {
height: 2rem;
width: auto;
}
}
&:last-of-type {
column-gap: 2rem;
justify-content: flex-end;
& > button {
margin: -0.75rem;
padding: 0.75rem;
color: var(--color-gray-400);
&:hover {
color: var(--color-gray-500);
}
& > svg {
height: 1.5rem;
width: 1.5rem;
}
}
}
}
& > nav {
display: none;
column-gap: 2.75rem;
font-size: 0.875rem;
line-height: 1.5rem;
font-weight: 600;
& > a:hover {
color: var(--color-gray-400);
}
@media (min-width: 768px) {
display: flex;
}
}
}
div.mobile {
& > div.backdrop {
display: fixed;
top: 0;
left: 0;
right: 0;
z-index: 50;
&.closed {
display: none;
}
}
& > div.foredrop {
&.closed {
height: 0vh;
@media (min-width: 640px) {
width: 0rem;
height: 100vw;
}
}
position: fixed;
top: 0;
left: 0;
bottom: 0;
z-index: 50;
width: 100%;
overflow-y: hidden;
background-color: white;
transition:
height 500ms linear,
width 250ms ease-in-out;
height: 100vh;
scrollbar-width: none;
overflow: -moz-scrollbars-none;
-ms-overflow-style: none;
&::-webkit-scrollbar {
display: none;
}
@media (min-width: 640px) {
max-width: 20rem;
width: 20rem;
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
--tw-ring-color: rgb(17 24 39 / 0.1);
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}
& > div {
padding: 0 1rem 1.5rem 1rem;
@media (min-width: 640px) {
padding: 0 1.5rem;
}
& > div {
&:first-of-type {
/* margin-left: -0.5rem; */
display: flex;
height: 4rem;
align-items: center;
column-gap: 1.5rem;
& > button {
margin: -0.75rem;
padding: 0.75rem;
color: var(--color-gray-700);
& > svg {
height: 1.5rem;
width: 1.5rem;
}
}
& > div {
& > a {
display: block;
margin: -1.25rem;
padding: 1.25rem;
& > img {
height: 2rem;
width: auto;
margin-top: 6px;
}
}
}
}
&:last-of-type {
margin-top: 0.5rem;
margin-top: 0.5rem;
margin-bottom: 0.5rem;
& > a {
display: block;
margin: -0.75rem;
padding: 0.75rem;
font-size: 1rem;
line-height: 1.75rem;
font-weight: 600;
text-align: left;
color: var(--color-gray-900);
&:hover {
background-color: var(--color-gray-50);
}
}
}
}
}
}
@media (min-width: 1024px) {
display: none;
}
}
`;
constructor() {
super();
this.open = false;
}
mobileTemplate() {
return html`<div class="mobile" role="dialog" aria-modal="true">
<div class="backdrop ${this.open ? 'open' : 'closed'}"></div>
<div class="foredrop ${this.open ? 'open' : 'closed'}">
<div>
<div>
<button type="button" @click=${() => (this.open = false)}>
<svg
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
aria-hidden="true"
data-slot="icon">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
</svg>
</button>
<div>
<a href="#">
<img src="./img/favicon.png" alt="Company Logo" />
</a>
</div>
</div>
<div>
<a href="#">Home</a>
<a href="#">About</a>
<a href="#">Story</a>
<a href="#">Adventures</a>
</div>
</div>
</div>
</div>`;
}
render() {
return html`<header>
<div class="desktop">
<div>
<button type="button" @click=${() => (this.open = true)}>
<svg viewBox="0 0 20 20" fill="currentColor" aria-hidden="true" data-slot="icon">
<path
fill-rule="evenodd"
d="M2 4.75A.75.75 0 0 1 2.75 4h14.5a.75.75 0 0 1 0 1.5H2.75A.75.75 0 0 1 2 4.75ZM2 10a.75.75 0 0 1 .75-.75h14.5a.75.75 0 0 1 0 1.5H2.75A.75.75 0 0 1 2 10Zm0 5.25a.75.75 0 0 1 .75-.75h14.5a.75.75 0 0 1 0 1.5H2.75a.75.75 0 0 1-.75-.75Z"
clip-rule="evenodd" />
</svg>
</button>
<img src="./img/favicon.png" alt="Company Logo" />
</div>
<nav>
<a href="#">Home</a>
<a href="#">About</a>
<a href="#">Story</a>
<a href="#">Adventures</a>
</nav>
<div>
<button type="button">
<svg
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
aria-hidden="true"
data-slot="icon">
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M14.857 17.082a23.848 23.848 0 0 0 5.454-1.31A8.967 8.967 0 0 1 18 9.75V9A6 6 0 0 0 6 9v.75a8.967 8.967 0 0 1-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 0 1-5.714 0m5.714 0a3 3 0 1 1-5.714 0" />
</svg>
</button>
</div>
</div>
${this.mobileTemplate()}
</header> `;
}
}
customElements.define('a4-header', A4Header);