feat(components): add offcanvas component
This commit is contained in:
parent
e0ed5a5ddd
commit
c47a2eff89
14 changed files with 233 additions and 129 deletions
|
|
@ -8,7 +8,8 @@
|
|||
"exports": {
|
||||
".": "./src/index.ts",
|
||||
"./navbar/*": "./src/navbar/*",
|
||||
"./accordion/*": "./src/accordion/*"
|
||||
"./accordion/*": "./src/accordion/*",
|
||||
"./offcanvas/*": "./src/offcanvas/*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "latest",
|
||||
|
|
|
|||
|
|
@ -1,59 +0,0 @@
|
|||
.off-canvas {
|
||||
.off-canvas-content {
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
height: 100vh;
|
||||
z-index: 5;
|
||||
|
||||
background-color: var(--prj-bg);
|
||||
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 100%;
|
||||
|
||||
padding: var(--prj-spacing-3);
|
||||
|
||||
transition: left 0.4s ease-in-out;
|
||||
}
|
||||
|
||||
&.active .off-canvas-content {
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
.off-canvas-backdrop {
|
||||
position: fixed;
|
||||
height: 100vh;
|
||||
z-index: 4;
|
||||
|
||||
background-color: rgba(0, 0, 0);
|
||||
opacity: 0;
|
||||
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 100%;
|
||||
|
||||
padding: var(--prj-spacing-3);
|
||||
|
||||
// Delay the left transition on remove so it's desn't appear to be sliding or to be not working
|
||||
transition:
|
||||
opacity 0.8s ease,
|
||||
left 0s linear 1s;
|
||||
}
|
||||
|
||||
&.active .off-canvas-backdrop {
|
||||
left: 0%;
|
||||
opacity: 40%;
|
||||
transition:
|
||||
opacity 0.8s ease,
|
||||
left 0s linear;
|
||||
}
|
||||
}
|
||||
|
||||
button.off-canvas-toggle {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
background: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
|
@ -1 +1,34 @@
|
|||
<h1>Hello World!</h1>
|
||||
{% macro navbar() %}
|
||||
<nav class="msp-navbar msp-navbar-desktop msp-d-none msp-d-lg-block msp-container">
|
||||
<ul class="msp-list-unstyle msp-hstack">
|
||||
{% for i in range(end=3) %}{% endfor %}
|
||||
</ul>
|
||||
</nav>
|
||||
{% endmacro navbar %}
|
||||
|
||||
|
||||
{% macro navbar_item(href, label) %}
|
||||
<li class="msp-nav-item">
|
||||
<a class="msp-nav-link active" href="{{ href }}">{{ label }}</a>
|
||||
</li>
|
||||
{% endmacro navbar_item %}
|
||||
|
||||
<div class="msp-text-end msp-d-lg-none">
|
||||
<OffCanvasBtn />
|
||||
<OffCanvas>
|
||||
<nav class="msp-navbar msp-navbar-mobile">
|
||||
<ul class="msp-list-unstyle msp-text-start">
|
||||
{
|
||||
links.map((link) => (
|
||||
<li class="msp-nav-item msp-mb-3">
|
||||
<a class="msp-nav-link" href={link.href}>{link.text}</a>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
<li class="msp-nav-item mb-3">
|
||||
<LangSelector />
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</OffCanvas>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,43 @@
|
|||
nav {
|
||||
nav.msp-navbar {
|
||||
width: 100%;
|
||||
|
||||
ul {
|
||||
padding: 0;
|
||||
|
||||
li {
|
||||
margin-bottom: 0;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
li > a {
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
a {
|
||||
--boder-color: transparent;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
text-decoration: none;
|
||||
|
||||
transition:
|
||||
background-color 200ms,
|
||||
color 200ms;
|
||||
}
|
||||
|
||||
a.active {
|
||||
border: 1px solid var(--msp-color-bg-accent);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
--border-color: var(--msp-color-bg-accent);
|
||||
background-color: var(--msp-color-bg-accent);
|
||||
color: var(--msp-color-text-accent);
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-desktop ul {
|
||||
.msp-navbar-desktop ul {
|
||||
width: fit-content;
|
||||
margin-left: auto;
|
||||
|
||||
|
|
@ -10,33 +45,3 @@ nav {
|
|||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li > a {
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
|
||||
a {
|
||||
--boder-color: transparent;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
text-decoration: none;
|
||||
|
||||
transition:
|
||||
background-color 200ms,
|
||||
color 200ms;
|
||||
}
|
||||
|
||||
a.active {
|
||||
border: 1px solid var(--prj-accent-bg);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
--border-color: var(--prj-accent-bg);
|
||||
background-color: var(--prj-accent-bg);
|
||||
color: var(--prj-accent-text);
|
||||
border: 1px solid var(--border-color);
|
||||
}
|
||||
|
|
|
|||
21
packages/components/src/offcanvas/index.ts
Normal file
21
packages/components/src/offcanvas/index.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import { qs, qsa } from "../utils";
|
||||
|
||||
window.onload = () => {
|
||||
qsa(".msp-offcanvas-toggle").forEach((item) => {
|
||||
item.addEventListener("click", () => {
|
||||
const target = item.dataset.mspTarget;
|
||||
|
||||
if (!target) {
|
||||
throw new Error("No target provided");
|
||||
}
|
||||
|
||||
const targetElement = qs(target);
|
||||
|
||||
if (!targetElement) {
|
||||
throw new Error("No target found");
|
||||
}
|
||||
|
||||
targetElement.classList.toggle("show");
|
||||
});
|
||||
});
|
||||
};
|
||||
66
packages/components/src/offcanvas/style.scss
Normal file
66
packages/components/src/offcanvas/style.scss
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
.msp-offcanvas {
|
||||
--msp-offcanvas-anim-duration: var(--msp-anim-duration-md);
|
||||
--msp-offcanvas-anim-curve-in: cubic-bezier(0.22, 0.61, 0.36, 1);
|
||||
--msp-offcanvas-anim-curve-out: cubic-bezier(0.55, 0.06, 0.68, 0.19);
|
||||
|
||||
&-content {
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
height: 100vh;
|
||||
z-index: 5;
|
||||
|
||||
background-color: var(--msp-color-bg);
|
||||
|
||||
top: 0;
|
||||
left: -100%;
|
||||
|
||||
padding: var(--msp-spacing-3);
|
||||
|
||||
transition: left var(--msp-offcanvas-anim-duration)
|
||||
var(--msp-offcanvas-anim-curve-out);
|
||||
|
||||
&-body,
|
||||
&-header,
|
||||
&-footer {
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
}
|
||||
}
|
||||
|
||||
&.show {
|
||||
.msp-offcanvas-backdrop {
|
||||
opacity: 40%;
|
||||
left: 0;
|
||||
|
||||
transition:
|
||||
opacity var(--msp-offcanvas-anim-duration)
|
||||
var(--msp-offcanvas-anim-curve-in),
|
||||
left 0s linear;
|
||||
}
|
||||
|
||||
.msp-offcanvas-content {
|
||||
left: 0;
|
||||
|
||||
transition: left var(--msp-offcanvas-anim-duration)
|
||||
var(--msp-offcanvas-anim-curve-in);
|
||||
}
|
||||
}
|
||||
|
||||
.msp-offcanvas-backdrop {
|
||||
position: fixed;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
z-index: 4;
|
||||
|
||||
background-color: rgba(0, 0, 0);
|
||||
opacity: 0;
|
||||
|
||||
top: 0;
|
||||
left: -100%;
|
||||
// Delay the width transition on remove so it's desn't appear to be sliding or to be not working
|
||||
transition:
|
||||
opacity var(--msp-offcanvas-anim-duration)
|
||||
var(--msp-offcanvas-anim-curve-out),
|
||||
left 0s linear var(--msp-offcanvas-anim-duration);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue